SemaOpenMP.cpp revision 1.1.1.1 1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/CXXInheritance.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/StmtCXX.h"
22 #include "clang/AST/StmtOpenMP.h"
23 #include "clang/AST/StmtVisitor.h"
24 #include "clang/AST/TypeOrdering.h"
25 #include "clang/Basic/OpenMPKinds.h"
26 #include "clang/Sema/Initialization.h"
27 #include "clang/Sema/Lookup.h"
28 #include "clang/Sema/Scope.h"
29 #include "clang/Sema/ScopeInfo.h"
30 #include "clang/Sema/SemaInternal.h"
31 #include "llvm/ADT/PointerEmbeddedInt.h"
32 using namespace clang;
33
34 //===----------------------------------------------------------------------===//
35 // Stack of data-sharing attributes for variables
36 //===----------------------------------------------------------------------===//
37
38 static const Expr *checkMapClauseExpressionBase(
39 Sema &SemaRef, Expr *E,
40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
41 OpenMPClauseKind CKind, bool NoDiagnose);
42
43 namespace {
44 /// Default data sharing attributes, which can be applied to directive.
45 enum DefaultDataSharingAttributes {
46 DSA_unspecified = 0, /// Data sharing attribute not specified.
47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
49 };
50
51 /// Attributes of the defaultmap clause.
52 enum DefaultMapAttributes {
53 DMA_unspecified, /// Default mapping is not specified.
54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
55 };
56
57 /// Stack for tracking declarations used in OpenMP directives and
58 /// clauses and their data-sharing attributes.
59 class DSAStackTy {
60 public:
61 struct DSAVarData {
62 OpenMPDirectiveKind DKind = OMPD_unknown;
63 OpenMPClauseKind CKind = OMPC_unknown;
64 const Expr *RefExpr = nullptr;
65 DeclRefExpr *PrivateCopy = nullptr;
66 SourceLocation ImplicitDSALoc;
67 DSAVarData() = default;
68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
69 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
70 SourceLocation ImplicitDSALoc)
71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
73 };
74 using OperatorOffsetTy =
75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
76 using DoacrossDependMapTy =
77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
78
79 private:
80 struct DSAInfo {
81 OpenMPClauseKind Attributes = OMPC_unknown;
82 /// Pointer to a reference expression and a flag which shows that the
83 /// variable is marked as lastprivate(true) or not (false).
84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
85 DeclRefExpr *PrivateCopy = nullptr;
86 };
87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90 using LoopControlVariablesMapTy =
91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
92 /// Struct that associates a component with the clause kind where they are
93 /// found.
94 struct MappedExprComponentTy {
95 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
96 OpenMPClauseKind Kind = OMPC_unknown;
97 };
98 using MappedExprComponentsTy =
99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100 using CriticalsWithHintsTy =
101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102 struct ReductionData {
103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
104 SourceRange ReductionRange;
105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106 ReductionData() = default;
107 void set(BinaryOperatorKind BO, SourceRange RR) {
108 ReductionRange = RR;
109 ReductionOp = BO;
110 }
111 void set(const Expr *RefExpr, SourceRange RR) {
112 ReductionRange = RR;
113 ReductionOp = RefExpr;
114 }
115 };
116 using DeclReductionMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
118
119 struct SharingMapTy {
120 DeclSAMapTy SharingMap;
121 DeclReductionMapTy ReductionMap;
122 AlignedMapTy AlignedMap;
123 MappedExprComponentsTy MappedExprComponents;
124 LoopControlVariablesMapTy LCVMap;
125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
126 SourceLocation DefaultAttrLoc;
127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
128 SourceLocation DefaultMapAttrLoc;
129 OpenMPDirectiveKind Directive = OMPD_unknown;
130 DeclarationNameInfo DirectiveName;
131 Scope *CurScope = nullptr;
132 SourceLocation ConstructLoc;
133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
134 /// get the data (loop counters etc.) about enclosing loop-based construct.
135 /// This data is required during codegen.
136 DoacrossDependMapTy DoacrossDepends;
137 /// First argument (Expr *) contains optional argument of the
138 /// 'ordered' clause, the second one is true if the regions has 'ordered'
139 /// clause, false otherwise.
140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
141 unsigned AssociatedLoops = 1;
142 bool HasMutipleLoops = false;
143 const Decl *PossiblyLoopCounter = nullptr;
144 bool NowaitRegion = false;
145 bool CancelRegion = false;
146 bool LoopStart = false;
147 bool BodyComplete = false;
148 SourceLocation InnerTeamsRegionLoc;
149 /// Reference to the taskgroup task_reduction reference expression.
150 Expr *TaskgroupReductionRef = nullptr;
151 llvm::DenseSet<QualType> MappedClassesQualTypes;
152 /// List of globals marked as declare target link in this target region
153 /// (isOpenMPTargetExecutionDirective(Directive) == true).
154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
156 Scope *CurScope, SourceLocation Loc)
157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
158 ConstructLoc(Loc) {}
159 SharingMapTy() = default;
160 };
161
162 using StackTy = SmallVector<SharingMapTy, 4>;
163
164 /// Stack of used declaration and their data-sharing attributes.
165 DeclSAMapTy Threadprivates;
166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
168 /// true, if check for DSA must be from parent directive, false, if
169 /// from current directive.
170 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
171 Sema &SemaRef;
172 bool ForceCapturing = false;
173 /// true if all the variables in the target executable directives must be
174 /// captured by reference.
175 bool ForceCaptureByReferenceInTargetExecutable = false;
176 CriticalsWithHintsTy Criticals;
177 unsigned IgnoredStackElements = 0;
178
179 /// Iterators over the stack iterate in order from innermost to outermost
180 /// directive.
181 using const_iterator = StackTy::const_reverse_iterator;
182 const_iterator begin() const {
183 return Stack.empty() ? const_iterator()
184 : Stack.back().first.rbegin() + IgnoredStackElements;
185 }
186 const_iterator end() const {
187 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
188 }
189 using iterator = StackTy::reverse_iterator;
190 iterator begin() {
191 return Stack.empty() ? iterator()
192 : Stack.back().first.rbegin() + IgnoredStackElements;
193 }
194 iterator end() {
195 return Stack.empty() ? iterator() : Stack.back().first.rend();
196 }
197
198 // Convenience operations to get at the elements of the stack.
199
200 bool isStackEmpty() const {
201 return Stack.empty() ||
202 Stack.back().second != CurrentNonCapturingFunctionScope ||
203 Stack.back().first.size() <= IgnoredStackElements;
204 }
205 size_t getStackSize() const {
206 return isStackEmpty() ? 0
207 : Stack.back().first.size() - IgnoredStackElements;
208 }
209
210 SharingMapTy *getTopOfStackOrNull() {
211 size_t Size = getStackSize();
212 if (Size == 0)
213 return nullptr;
214 return &Stack.back().first[Size - 1];
215 }
216 const SharingMapTy *getTopOfStackOrNull() const {
217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
218 }
219 SharingMapTy &getTopOfStack() {
220 assert(!isStackEmpty() && "no current directive");
221 return *getTopOfStackOrNull();
222 }
223 const SharingMapTy &getTopOfStack() const {
224 return const_cast<DSAStackTy&>(*this).getTopOfStack();
225 }
226
227 SharingMapTy *getSecondOnStackOrNull() {
228 size_t Size = getStackSize();
229 if (Size <= 1)
230 return nullptr;
231 return &Stack.back().first[Size - 2];
232 }
233 const SharingMapTy *getSecondOnStackOrNull() const {
234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
235 }
236
237 /// Get the stack element at a certain level (previously returned by
238 /// \c getNestingLevel).
239 ///
240 /// Note that nesting levels count from outermost to innermost, and this is
241 /// the reverse of our iteration order where new inner levels are pushed at
242 /// the front of the stack.
243 SharingMapTy &getStackElemAtLevel(unsigned Level) {
244 assert(Level < getStackSize() && "no such stack element");
245 return Stack.back().first[Level];
246 }
247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
249 }
250
251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
252
253 /// Checks if the variable is a local for OpenMP region.
254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
255
256 /// Vector of previously declared requires directives
257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
258 /// omp_allocator_handle_t type.
259 QualType OMPAllocatorHandleT;
260 /// Expression for the predefined allocators.
261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
262 nullptr};
263 /// Vector of previously encountered target directives
264 SmallVector<SourceLocation, 2> TargetLocations;
265
266 public:
267 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
268
269 /// Sets omp_allocator_handle_t type.
270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
271 /// Gets omp_allocator_handle_t type.
272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
273 /// Sets the given default allocator.
274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
275 Expr *Allocator) {
276 OMPPredefinedAllocators[AllocatorKind] = Allocator;
277 }
278 /// Returns the specified default allocator.
279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
280 return OMPPredefinedAllocators[AllocatorKind];
281 }
282
283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
284 OpenMPClauseKind getClauseParsingMode() const {
285 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
286 return ClauseKindMode;
287 }
288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
289
290 bool isBodyComplete() const {
291 const SharingMapTy *Top = getTopOfStackOrNull();
292 return Top && Top->BodyComplete;
293 }
294 void setBodyComplete() {
295 getTopOfStack().BodyComplete = true;
296 }
297
298 bool isForceVarCapturing() const { return ForceCapturing; }
299 void setForceVarCapturing(bool V) { ForceCapturing = V; }
300
301 void setForceCaptureByReferenceInTargetExecutable(bool V) {
302 ForceCaptureByReferenceInTargetExecutable = V;
303 }
304 bool isForceCaptureByReferenceInTargetExecutable() const {
305 return ForceCaptureByReferenceInTargetExecutable;
306 }
307
308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
309 Scope *CurScope, SourceLocation Loc) {
310 assert(!IgnoredStackElements &&
311 "cannot change stack while ignoring elements");
312 if (Stack.empty() ||
313 Stack.back().second != CurrentNonCapturingFunctionScope)
314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
316 Stack.back().first.back().DefaultAttrLoc = Loc;
317 }
318
319 void pop() {
320 assert(!IgnoredStackElements &&
321 "cannot change stack while ignoring elements");
322 assert(!Stack.back().first.empty() &&
323 "Data-sharing attributes stack is empty!");
324 Stack.back().first.pop_back();
325 }
326
327 /// RAII object to temporarily leave the scope of a directive when we want to
328 /// logically operate in its parent.
329 class ParentDirectiveScope {
330 DSAStackTy &Self;
331 bool Active;
332 public:
333 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
334 : Self(Self), Active(false) {
335 if (Activate)
336 enable();
337 }
338 ~ParentDirectiveScope() { disable(); }
339 void disable() {
340 if (Active) {
341 --Self.IgnoredStackElements;
342 Active = false;
343 }
344 }
345 void enable() {
346 if (!Active) {
347 ++Self.IgnoredStackElements;
348 Active = true;
349 }
350 }
351 };
352
353 /// Marks that we're started loop parsing.
354 void loopInit() {
355 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
356 "Expected loop-based directive.");
357 getTopOfStack().LoopStart = true;
358 }
359 /// Start capturing of the variables in the loop context.
360 void loopStart() {
361 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
362 "Expected loop-based directive.");
363 getTopOfStack().LoopStart = false;
364 }
365 /// true, if variables are captured, false otherwise.
366 bool isLoopStarted() const {
367 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
368 "Expected loop-based directive.");
369 return !getTopOfStack().LoopStart;
370 }
371 /// Marks (or clears) declaration as possibly loop counter.
372 void resetPossibleLoopCounter(const Decl *D = nullptr) {
373 getTopOfStack().PossiblyLoopCounter =
374 D ? D->getCanonicalDecl() : D;
375 }
376 /// Gets the possible loop counter decl.
377 const Decl *getPossiblyLoopCunter() const {
378 return getTopOfStack().PossiblyLoopCounter;
379 }
380 /// Start new OpenMP region stack in new non-capturing function.
381 void pushFunction() {
382 assert(!IgnoredStackElements &&
383 "cannot change stack while ignoring elements");
384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
385 assert(!isa<CapturingScopeInfo>(CurFnScope));
386 CurrentNonCapturingFunctionScope = CurFnScope;
387 }
388 /// Pop region stack for non-capturing function.
389 void popFunction(const FunctionScopeInfo *OldFSI) {
390 assert(!IgnoredStackElements &&
391 "cannot change stack while ignoring elements");
392 if (!Stack.empty() && Stack.back().second == OldFSI) {
393 assert(Stack.back().first.empty());
394 Stack.pop_back();
395 }
396 CurrentNonCapturingFunctionScope = nullptr;
397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
398 if (!isa<CapturingScopeInfo>(FSI)) {
399 CurrentNonCapturingFunctionScope = FSI;
400 break;
401 }
402 }
403 }
404
405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
407 }
408 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
409 getCriticalWithHint(const DeclarationNameInfo &Name) const {
410 auto I = Criticals.find(Name.getAsString());
411 if (I != Criticals.end())
412 return I->second;
413 return std::make_pair(nullptr, llvm::APSInt());
414 }
415 /// If 'aligned' declaration for given variable \a D was not seen yet,
416 /// add it and return NULL; otherwise return previous occurrence's expression
417 /// for diagnostics.
418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
419
420 /// Register specified variable as loop control variable.
421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
422 /// Check if the specified variable is a loop control variable for
423 /// current region.
424 /// \return The index of the loop control variable in the list of associated
425 /// for-loops (from outer to inner).
426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
427 /// Check if the specified variable is a loop control variable for
428 /// parent region.
429 /// \return The index of the loop control variable in the list of associated
430 /// for-loops (from outer to inner).
431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
432 /// Get the loop control variable for the I-th loop (or nullptr) in
433 /// parent directive.
434 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
435
436 /// Adds explicit data sharing attribute to the specified declaration.
437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
438 DeclRefExpr *PrivateCopy = nullptr);
439
440 /// Adds additional information for the reduction items with the reduction id
441 /// represented as an operator.
442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
443 BinaryOperatorKind BOK);
444 /// Adds additional information for the reduction items with the reduction id
445 /// represented as reduction identifier.
446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
447 const Expr *ReductionRef);
448 /// Returns the location and reduction operation from the innermost parent
449 /// region for the given \p D.
450 const DSAVarData
451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
452 BinaryOperatorKind &BOK,
453 Expr *&TaskgroupDescriptor) const;
454 /// Returns the location and reduction operation from the innermost parent
455 /// region for the given \p D.
456 const DSAVarData
457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
458 const Expr *&ReductionRef,
459 Expr *&TaskgroupDescriptor) const;
460 /// Return reduction reference expression for the current taskgroup.
461 Expr *getTaskgroupReductionRef() const {
462 assert(getTopOfStack().Directive == OMPD_taskgroup &&
463 "taskgroup reference expression requested for non taskgroup "
464 "directive.");
465 return getTopOfStack().TaskgroupReductionRef;
466 }
467 /// Checks if the given \p VD declaration is actually a taskgroup reduction
468 /// descriptor variable at the \p Level of OpenMP regions.
469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
470 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
472 ->getDecl() == VD;
473 }
474
475 /// Returns data sharing attributes from top of the stack for the
476 /// specified declaration.
477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
478 /// Returns data-sharing attributes for the specified declaration.
479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
480 /// Checks if the specified variables has data-sharing attributes which
481 /// match specified \a CPred predicate in any directive which matches \a DPred
482 /// predicate.
483 const DSAVarData
484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
486 bool FromParent) const;
487 /// Checks if the specified variables has data-sharing attributes which
488 /// match specified \a CPred predicate in any innermost directive which
489 /// matches \a DPred predicate.
490 const DSAVarData
491 hasInnermostDSA(ValueDecl *D,
492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
494 bool FromParent) const;
495 /// Checks if the specified variables has explicit data-sharing
496 /// attributes which match specified \a CPred predicate at the specified
497 /// OpenMP region.
498 bool hasExplicitDSA(const ValueDecl *D,
499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
500 unsigned Level, bool NotLastprivate = false) const;
501
502 /// Returns true if the directive at level \Level matches in the
503 /// specified \a DPred predicate.
504 bool hasExplicitDirective(
505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
506 unsigned Level) const;
507
508 /// Finds a directive which matches specified \a DPred predicate.
509 bool hasDirective(
510 const llvm::function_ref<bool(
511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
512 DPred,
513 bool FromParent) const;
514
515 /// Returns currently analyzed directive.
516 OpenMPDirectiveKind getCurrentDirective() const {
517 const SharingMapTy *Top = getTopOfStackOrNull();
518 return Top ? Top->Directive : OMPD_unknown;
519 }
520 /// Returns directive kind at specified level.
521 OpenMPDirectiveKind getDirective(unsigned Level) const {
522 assert(!isStackEmpty() && "No directive at specified level.");
523 return getStackElemAtLevel(Level).Directive;
524 }
525 /// Returns the capture region at the specified level.
526 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
527 unsigned OpenMPCaptureLevel) const {
528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
530 return CaptureRegions[OpenMPCaptureLevel];
531 }
532 /// Returns parent directive.
533 OpenMPDirectiveKind getParentDirective() const {
534 const SharingMapTy *Parent = getSecondOnStackOrNull();
535 return Parent ? Parent->Directive : OMPD_unknown;
536 }
537
538 /// Add requires decl to internal vector
539 void addRequiresDecl(OMPRequiresDecl *RD) {
540 RequiresDecls.push_back(RD);
541 }
542
543 /// Checks if the defined 'requires' directive has specified type of clause.
544 template <typename ClauseType>
545 bool hasRequiresDeclWithClause() {
546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
548 return isa<ClauseType>(C);
549 });
550 });
551 }
552
553 /// Checks for a duplicate clause amongst previously declared requires
554 /// directives
555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
556 bool IsDuplicate = false;
557 for (OMPClause *CNew : ClauseList) {
558 for (const OMPRequiresDecl *D : RequiresDecls) {
559 for (const OMPClause *CPrev : D->clauselists()) {
560 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
561 SemaRef.Diag(CNew->getBeginLoc(),
562 diag::err_omp_requires_clause_redeclaration)
563 << getOpenMPClauseName(CNew->getClauseKind());
564 SemaRef.Diag(CPrev->getBeginLoc(),
565 diag::note_omp_requires_previous_clause)
566 << getOpenMPClauseName(CPrev->getClauseKind());
567 IsDuplicate = true;
568 }
569 }
570 }
571 }
572 return IsDuplicate;
573 }
574
575 /// Add location of previously encountered target to internal vector
576 void addTargetDirLocation(SourceLocation LocStart) {
577 TargetLocations.push_back(LocStart);
578 }
579
580 // Return previously encountered target region locations.
581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
582 return TargetLocations;
583 }
584
585 /// Set default data sharing attribute to none.
586 void setDefaultDSANone(SourceLocation Loc) {
587 getTopOfStack().DefaultAttr = DSA_none;
588 getTopOfStack().DefaultAttrLoc = Loc;
589 }
590 /// Set default data sharing attribute to shared.
591 void setDefaultDSAShared(SourceLocation Loc) {
592 getTopOfStack().DefaultAttr = DSA_shared;
593 getTopOfStack().DefaultAttrLoc = Loc;
594 }
595 /// Set default data mapping attribute to 'tofrom:scalar'.
596 void setDefaultDMAToFromScalar(SourceLocation Loc) {
597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar;
598 getTopOfStack().DefaultMapAttrLoc = Loc;
599 }
600
601 DefaultDataSharingAttributes getDefaultDSA() const {
602 return isStackEmpty() ? DSA_unspecified
603 : getTopOfStack().DefaultAttr;
604 }
605 SourceLocation getDefaultDSALocation() const {
606 return isStackEmpty() ? SourceLocation()
607 : getTopOfStack().DefaultAttrLoc;
608 }
609 DefaultMapAttributes getDefaultDMA() const {
610 return isStackEmpty() ? DMA_unspecified
611 : getTopOfStack().DefaultMapAttr;
612 }
613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
614 return getStackElemAtLevel(Level).DefaultMapAttr;
615 }
616 SourceLocation getDefaultDMALocation() const {
617 return isStackEmpty() ? SourceLocation()
618 : getTopOfStack().DefaultMapAttrLoc;
619 }
620
621 /// Checks if the specified variable is a threadprivate.
622 bool isThreadPrivate(VarDecl *D) {
623 const DSAVarData DVar = getTopDSA(D, false);
624 return isOpenMPThreadPrivate(DVar.CKind);
625 }
626
627 /// Marks current region as ordered (it has an 'ordered' clause).
628 void setOrderedRegion(bool IsOrdered, const Expr *Param,
629 OMPOrderedClause *Clause) {
630 if (IsOrdered)
631 getTopOfStack().OrderedRegion.emplace(Param, Clause);
632 else
633 getTopOfStack().OrderedRegion.reset();
634 }
635 /// Returns true, if region is ordered (has associated 'ordered' clause),
636 /// false - otherwise.
637 bool isOrderedRegion() const {
638 if (const SharingMapTy *Top = getTopOfStackOrNull())
639 return Top->OrderedRegion.hasValue();
640 return false;
641 }
642 /// Returns optional parameter for the ordered region.
643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
644 if (const SharingMapTy *Top = getTopOfStackOrNull())
645 if (Top->OrderedRegion.hasValue())
646 return Top->OrderedRegion.getValue();
647 return std::make_pair(nullptr, nullptr);
648 }
649 /// Returns true, if parent region is ordered (has associated
650 /// 'ordered' clause), false - otherwise.
651 bool isParentOrderedRegion() const {
652 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
653 return Parent->OrderedRegion.hasValue();
654 return false;
655 }
656 /// Returns optional parameter for the ordered region.
657 std::pair<const Expr *, OMPOrderedClause *>
658 getParentOrderedRegionParam() const {
659 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
660 if (Parent->OrderedRegion.hasValue())
661 return Parent->OrderedRegion.getValue();
662 return std::make_pair(nullptr, nullptr);
663 }
664 /// Marks current region as nowait (it has a 'nowait' clause).
665 void setNowaitRegion(bool IsNowait = true) {
666 getTopOfStack().NowaitRegion = IsNowait;
667 }
668 /// Returns true, if parent region is nowait (has associated
669 /// 'nowait' clause), false - otherwise.
670 bool isParentNowaitRegion() const {
671 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
672 return Parent->NowaitRegion;
673 return false;
674 }
675 /// Marks parent region as cancel region.
676 void setParentCancelRegion(bool Cancel = true) {
677 if (SharingMapTy *Parent = getSecondOnStackOrNull())
678 Parent->CancelRegion |= Cancel;
679 }
680 /// Return true if current region has inner cancel construct.
681 bool isCancelRegion() const {
682 const SharingMapTy *Top = getTopOfStackOrNull();
683 return Top ? Top->CancelRegion : false;
684 }
685
686 /// Set collapse value for the region.
687 void setAssociatedLoops(unsigned Val) {
688 getTopOfStack().AssociatedLoops = Val;
689 if (Val > 1)
690 getTopOfStack().HasMutipleLoops = true;
691 }
692 /// Return collapse value for region.
693 unsigned getAssociatedLoops() const {
694 const SharingMapTy *Top = getTopOfStackOrNull();
695 return Top ? Top->AssociatedLoops : 0;
696 }
697 /// Returns true if the construct is associated with multiple loops.
698 bool hasMutipleLoops() const {
699 const SharingMapTy *Top = getTopOfStackOrNull();
700 return Top ? Top->HasMutipleLoops : false;
701 }
702
703 /// Marks current target region as one with closely nested teams
704 /// region.
705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
706 if (SharingMapTy *Parent = getSecondOnStackOrNull())
707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
708 }
709 /// Returns true, if current region has closely nested teams region.
710 bool hasInnerTeamsRegion() const {
711 return getInnerTeamsRegionLoc().isValid();
712 }
713 /// Returns location of the nested teams region (if any).
714 SourceLocation getInnerTeamsRegionLoc() const {
715 const SharingMapTy *Top = getTopOfStackOrNull();
716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
717 }
718
719 Scope *getCurScope() const {
720 const SharingMapTy *Top = getTopOfStackOrNull();
721 return Top ? Top->CurScope : nullptr;
722 }
723 SourceLocation getConstructLoc() const {
724 const SharingMapTy *Top = getTopOfStackOrNull();
725 return Top ? Top->ConstructLoc : SourceLocation();
726 }
727
728 /// Do the check specified in \a Check to all component lists and return true
729 /// if any issue is found.
730 bool checkMappableExprComponentListsForDecl(
731 const ValueDecl *VD, bool CurrentRegionOnly,
732 const llvm::function_ref<
733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
734 OpenMPClauseKind)>
735 Check) const {
736 if (isStackEmpty())
737 return false;
738 auto SI = begin();
739 auto SE = end();
740
741 if (SI == SE)
742 return false;
743
744 if (CurrentRegionOnly)
745 SE = std::next(SI);
746 else
747 std::advance(SI, 1);
748
749 for (; SI != SE; ++SI) {
750 auto MI = SI->MappedExprComponents.find(VD);
751 if (MI != SI->MappedExprComponents.end())
752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
753 MI->second.Components)
754 if (Check(L, MI->second.Kind))
755 return true;
756 }
757 return false;
758 }
759
760 /// Do the check specified in \a Check to all component lists at a given level
761 /// and return true if any issue is found.
762 bool checkMappableExprComponentListsForDeclAtLevel(
763 const ValueDecl *VD, unsigned Level,
764 const llvm::function_ref<
765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
766 OpenMPClauseKind)>
767 Check) const {
768 if (getStackSize() <= Level)
769 return false;
770
771 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
772 auto MI = StackElem.MappedExprComponents.find(VD);
773 if (MI != StackElem.MappedExprComponents.end())
774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
775 MI->second.Components)
776 if (Check(L, MI->second.Kind))
777 return true;
778 return false;
779 }
780
781 /// Create a new mappable expression component list associated with a given
782 /// declaration and initialize it with the provided list of components.
783 void addMappableExpressionComponents(
784 const ValueDecl *VD,
785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
786 OpenMPClauseKind WhereFoundClauseKind) {
787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
788 // Create new entry and append the new components there.
789 MEC.Components.resize(MEC.Components.size() + 1);
790 MEC.Components.back().append(Components.begin(), Components.end());
791 MEC.Kind = WhereFoundClauseKind;
792 }
793
794 unsigned getNestingLevel() const {
795 assert(!isStackEmpty());
796 return getStackSize() - 1;
797 }
798 void addDoacrossDependClause(OMPDependClause *C,
799 const OperatorOffsetTy &OpsOffs) {
800 SharingMapTy *Parent = getSecondOnStackOrNull();
801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
802 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
803 }
804 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
805 getDoacrossDependClauses() const {
806 const SharingMapTy &StackElem = getTopOfStack();
807 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
809 return llvm::make_range(Ref.begin(), Ref.end());
810 }
811 return llvm::make_range(StackElem.DoacrossDepends.end(),
812 StackElem.DoacrossDepends.end());
813 }
814
815 // Store types of classes which have been explicitly mapped
816 void addMappedClassesQualTypes(QualType QT) {
817 SharingMapTy &StackElem = getTopOfStack();
818 StackElem.MappedClassesQualTypes.insert(QT);
819 }
820
821 // Return set of mapped classes types
822 bool isClassPreviouslyMapped(QualType QT) const {
823 const SharingMapTy &StackElem = getTopOfStack();
824 return StackElem.MappedClassesQualTypes.count(QT) != 0;
825 }
826
827 /// Adds global declare target to the parent target region.
828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
831 "Expected declare target link global.");
832 for (auto &Elem : *this) {
833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
834 Elem.DeclareTargetLinkVarDecls.push_back(E);
835 return;
836 }
837 }
838 }
839
840 /// Returns the list of globals with declare target link if current directive
841 /// is target.
842 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
844 "Expected target executable directive.");
845 return getTopOfStack().DeclareTargetLinkVarDecls;
846 }
847 };
848
849 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
851 }
852
853 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
855 DKind == OMPD_unknown;
856 }
857
858 } // namespace
859
860 static const Expr *getExprAsWritten(const Expr *E) {
861 if (const auto *FE = dyn_cast<FullExpr>(E))
862 E = FE->getSubExpr();
863
864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
865 E = MTE->GetTemporaryExpr();
866
867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
868 E = Binder->getSubExpr();
869
870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
871 E = ICE->getSubExprAsWritten();
872 return E->IgnoreParens();
873 }
874
875 static Expr *getExprAsWritten(Expr *E) {
876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
877 }
878
879 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
882 D = ME->getMemberDecl();
883 const auto *VD = dyn_cast<VarDecl>(D);
884 const auto *FD = dyn_cast<FieldDecl>(D);
885 if (VD != nullptr) {
886 VD = VD->getCanonicalDecl();
887 D = VD;
888 } else {
889 assert(FD);
890 FD = FD->getCanonicalDecl();
891 D = FD;
892 }
893 return D;
894 }
895
896 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
897 return const_cast<ValueDecl *>(
898 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
899 }
900
901 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
902 ValueDecl *D) const {
903 D = getCanonicalDecl(D);
904 auto *VD = dyn_cast<VarDecl>(D);
905 const auto *FD = dyn_cast<FieldDecl>(D);
906 DSAVarData DVar;
907 if (Iter == end()) {
908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
909 // in a region but not in construct]
910 // File-scope or namespace-scope variables referenced in called routines
911 // in the region are shared unless they appear in a threadprivate
912 // directive.
913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
914 DVar.CKind = OMPC_shared;
915
916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
917 // in a region but not in construct]
918 // Variables with static storage duration that are declared in called
919 // routines in the region are shared.
920 if (VD && VD->hasGlobalStorage())
921 DVar.CKind = OMPC_shared;
922
923 // Non-static data members are shared by default.
924 if (FD)
925 DVar.CKind = OMPC_shared;
926
927 return DVar;
928 }
929
930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
931 // in a Construct, C/C++, predetermined, p.1]
932 // Variables with automatic storage duration that are declared in a scope
933 // inside the construct are private.
934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
936 DVar.CKind = OMPC_private;
937 return DVar;
938 }
939
940 DVar.DKind = Iter->Directive;
941 // Explicitly specified attributes and local variables with predetermined
942 // attributes.
943 if (Iter->SharingMap.count(D)) {
944 const DSAInfo &Data = Iter->SharingMap.lookup(D);
945 DVar.RefExpr = Data.RefExpr.getPointer();
946 DVar.PrivateCopy = Data.PrivateCopy;
947 DVar.CKind = Data.Attributes;
948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
949 return DVar;
950 }
951
952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
953 // in a Construct, C/C++, implicitly determined, p.1]
954 // In a parallel or task construct, the data-sharing attributes of these
955 // variables are determined by the default clause, if present.
956 switch (Iter->DefaultAttr) {
957 case DSA_shared:
958 DVar.CKind = OMPC_shared;
959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
960 return DVar;
961 case DSA_none:
962 return DVar;
963 case DSA_unspecified:
964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
965 // in a Construct, implicitly determined, p.2]
966 // In a parallel construct, if no default clause is present, these
967 // variables are shared.
968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
969 if ((isOpenMPParallelDirective(DVar.DKind) &&
970 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
971 isOpenMPTeamsDirective(DVar.DKind)) {
972 DVar.CKind = OMPC_shared;
973 return DVar;
974 }
975
976 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
977 // in a Construct, implicitly determined, p.4]
978 // In a task construct, if no default clause is present, a variable that in
979 // the enclosing context is determined to be shared by all implicit tasks
980 // bound to the current team is shared.
981 if (isOpenMPTaskingDirective(DVar.DKind)) {
982 DSAVarData DVarTemp;
983 const_iterator I = Iter, E = end();
984 do {
985 ++I;
986 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
987 // Referenced in a Construct, implicitly determined, p.6]
988 // In a task construct, if no default clause is present, a variable
989 // whose data-sharing attribute is not determined by the rules above is
990 // firstprivate.
991 DVarTemp = getDSA(I, D);
992 if (DVarTemp.CKind != OMPC_shared) {
993 DVar.RefExpr = nullptr;
994 DVar.CKind = OMPC_firstprivate;
995 return DVar;
996 }
997 } while (I != E && !isImplicitTaskingRegion(I->Directive));
998 DVar.CKind =
999 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1000 return DVar;
1001 }
1002 }
1003 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1004 // in a Construct, implicitly determined, p.3]
1005 // For constructs other than task, if no default clause is present, these
1006 // variables inherit their data-sharing attributes from the enclosing
1007 // context.
1008 return getDSA(++Iter, D);
1009 }
1010
1011 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1012 const Expr *NewDE) {
1013 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1014 D = getCanonicalDecl(D);
1015 SharingMapTy &StackElem = getTopOfStack();
1016 auto It = StackElem.AlignedMap.find(D);
1017 if (It == StackElem.AlignedMap.end()) {
1018 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1019 StackElem.AlignedMap[D] = NewDE;
1020 return nullptr;
1021 }
1022 assert(It->second && "Unexpected nullptr expr in the aligned map");
1023 return It->second;
1024 }
1025
1026 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1027 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1028 D = getCanonicalDecl(D);
1029 SharingMapTy &StackElem = getTopOfStack();
1030 StackElem.LCVMap.try_emplace(
1031 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1032 }
1033
1034 const DSAStackTy::LCDeclInfo
1035 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1037 D = getCanonicalDecl(D);
1038 const SharingMapTy &StackElem = getTopOfStack();
1039 auto It = StackElem.LCVMap.find(D);
1040 if (It != StackElem.LCVMap.end())
1041 return It->second;
1042 return {0, nullptr};
1043 }
1044
1045 const DSAStackTy::LCDeclInfo
1046 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1047 const SharingMapTy *Parent = getSecondOnStackOrNull();
1048 assert(Parent && "Data-sharing attributes stack is empty");
1049 D = getCanonicalDecl(D);
1050 auto It = Parent->LCVMap.find(D);
1051 if (It != Parent->LCVMap.end())
1052 return It->second;
1053 return {0, nullptr};
1054 }
1055
1056 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1057 const SharingMapTy *Parent = getSecondOnStackOrNull();
1058 assert(Parent && "Data-sharing attributes stack is empty");
1059 if (Parent->LCVMap.size() < I)
1060 return nullptr;
1061 for (const auto &Pair : Parent->LCVMap)
1062 if (Pair.second.first == I)
1063 return Pair.first;
1064 return nullptr;
1065 }
1066
1067 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1068 DeclRefExpr *PrivateCopy) {
1069 D = getCanonicalDecl(D);
1070 if (A == OMPC_threadprivate) {
1071 DSAInfo &Data = Threadprivates[D];
1072 Data.Attributes = A;
1073 Data.RefExpr.setPointer(E);
1074 Data.PrivateCopy = nullptr;
1075 } else {
1076 DSAInfo &Data = getTopOfStack().SharingMap[D];
1077 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1078 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1079 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1080 (isLoopControlVariable(D).first && A == OMPC_private));
1081 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1082 Data.RefExpr.setInt(/*IntVal=*/true);
1083 return;
1084 }
1085 const bool IsLastprivate =
1086 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1087 Data.Attributes = A;
1088 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1089 Data.PrivateCopy = PrivateCopy;
1090 if (PrivateCopy) {
1091 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1092 Data.Attributes = A;
1093 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1094 Data.PrivateCopy = nullptr;
1095 }
1096 }
1097 }
1098
1099 /// Build a variable declaration for OpenMP loop iteration variable.
1100 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1101 StringRef Name, const AttrVec *Attrs = nullptr,
1102 DeclRefExpr *OrigRef = nullptr) {
1103 DeclContext *DC = SemaRef.CurContext;
1104 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1105 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1106 auto *Decl =
1107 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1108 if (Attrs) {
1109 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1110 I != E; ++I)
1111 Decl->addAttr(*I);
1112 }
1113 Decl->setImplicit();
1114 if (OrigRef) {
1115 Decl->addAttr(
1116 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1117 }
1118 return Decl;
1119 }
1120
1121 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1122 SourceLocation Loc,
1123 bool RefersToCapture = false) {
1124 D->setReferenced();
1125 D->markUsed(S.Context);
1126 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1127 SourceLocation(), D, RefersToCapture, Loc, Ty,
1128 VK_LValue);
1129 }
1130
1131 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1132 BinaryOperatorKind BOK) {
1133 D = getCanonicalDecl(D);
1134 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1135 assert(
1136 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1137 "Additional reduction info may be specified only for reduction items.");
1138 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1139 assert(ReductionData.ReductionRange.isInvalid() &&
1140 getTopOfStack().Directive == OMPD_taskgroup &&
1141 "Additional reduction info may be specified only once for reduction "
1142 "items.");
1143 ReductionData.set(BOK, SR);
1144 Expr *&TaskgroupReductionRef =
1145 getTopOfStack().TaskgroupReductionRef;
1146 if (!TaskgroupReductionRef) {
1147 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1148 SemaRef.Context.VoidPtrTy, ".task_red.");
1149 TaskgroupReductionRef =
1150 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1151 }
1152 }
1153
1154 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1155 const Expr *ReductionRef) {
1156 D = getCanonicalDecl(D);
1157 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1158 assert(
1159 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1160 "Additional reduction info may be specified only for reduction items.");
1161 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1162 assert(ReductionData.ReductionRange.isInvalid() &&
1163 getTopOfStack().Directive == OMPD_taskgroup &&
1164 "Additional reduction info may be specified only once for reduction "
1165 "items.");
1166 ReductionData.set(ReductionRef, SR);
1167 Expr *&TaskgroupReductionRef =
1168 getTopOfStack().TaskgroupReductionRef;
1169 if (!TaskgroupReductionRef) {
1170 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1171 SemaRef.Context.VoidPtrTy, ".task_red.");
1172 TaskgroupReductionRef =
1173 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1174 }
1175 }
1176
1177 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1178 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1179 Expr *&TaskgroupDescriptor) const {
1180 D = getCanonicalDecl(D);
1181 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1182 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1183 const DSAInfo &Data = I->SharingMap.lookup(D);
1184 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1185 continue;
1186 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1187 if (!ReductionData.ReductionOp ||
1188 ReductionData.ReductionOp.is<const Expr *>())
1189 return DSAVarData();
1190 SR = ReductionData.ReductionRange;
1191 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1192 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1193 "expression for the descriptor is not "
1194 "set.");
1195 TaskgroupDescriptor = I->TaskgroupReductionRef;
1196 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1197 Data.PrivateCopy, I->DefaultAttrLoc);
1198 }
1199 return DSAVarData();
1200 }
1201
1202 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1203 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1204 Expr *&TaskgroupDescriptor) const {
1205 D = getCanonicalDecl(D);
1206 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1207 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1208 const DSAInfo &Data = I->SharingMap.lookup(D);
1209 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1210 continue;
1211 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1212 if (!ReductionData.ReductionOp ||
1213 !ReductionData.ReductionOp.is<const Expr *>())
1214 return DSAVarData();
1215 SR = ReductionData.ReductionRange;
1216 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1217 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1218 "expression for the descriptor is not "
1219 "set.");
1220 TaskgroupDescriptor = I->TaskgroupReductionRef;
1221 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1222 Data.PrivateCopy, I->DefaultAttrLoc);
1223 }
1224 return DSAVarData();
1225 }
1226
1227 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1228 D = D->getCanonicalDecl();
1229 for (const_iterator E = end(); I != E; ++I) {
1230 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1231 isOpenMPTargetExecutionDirective(I->Directive)) {
1232 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1233 Scope *CurScope = getCurScope();
1234 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1235 CurScope = CurScope->getParent();
1236 return CurScope != TopScope;
1237 }
1238 }
1239 return false;
1240 }
1241
1242 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1243 bool AcceptIfMutable = true,
1244 bool *IsClassType = nullptr) {
1245 ASTContext &Context = SemaRef.getASTContext();
1246 Type = Type.getNonReferenceType().getCanonicalType();
1247 bool IsConstant = Type.isConstant(Context);
1248 Type = Context.getBaseElementType(Type);
1249 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1250 ? Type->getAsCXXRecordDecl()
1251 : nullptr;
1252 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1253 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1254 RD = CTD->getTemplatedDecl();
1255 if (IsClassType)
1256 *IsClassType = RD;
1257 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1258 RD->hasDefinition() && RD->hasMutableFields());
1259 }
1260
1261 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1262 QualType Type, OpenMPClauseKind CKind,
1263 SourceLocation ELoc,
1264 bool AcceptIfMutable = true,
1265 bool ListItemNotVar = false) {
1266 ASTContext &Context = SemaRef.getASTContext();
1267 bool IsClassType;
1268 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1269 unsigned Diag = ListItemNotVar
1270 ? diag::err_omp_const_list_item
1271 : IsClassType ? diag::err_omp_const_not_mutable_variable
1272 : diag::err_omp_const_variable;
1273 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1274 if (!ListItemNotVar && D) {
1275 const VarDecl *VD = dyn_cast<VarDecl>(D);
1276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1277 VarDecl::DeclarationOnly;
1278 SemaRef.Diag(D->getLocation(),
1279 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1280 << D;
1281 }
1282 return true;
1283 }
1284 return false;
1285 }
1286
1287 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1288 bool FromParent) {
1289 D = getCanonicalDecl(D);
1290 DSAVarData DVar;
1291
1292 auto *VD = dyn_cast<VarDecl>(D);
1293 auto TI = Threadprivates.find(D);
1294 if (TI != Threadprivates.end()) {
1295 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1296 DVar.CKind = OMPC_threadprivate;
1297 return DVar;
1298 }
1299 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1300 DVar.RefExpr = buildDeclRefExpr(
1301 SemaRef, VD, D->getType().getNonReferenceType(),
1302 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1303 DVar.CKind = OMPC_threadprivate;
1304 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1305 return DVar;
1306 }
1307 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1308 // in a Construct, C/C++, predetermined, p.1]
1309 // Variables appearing in threadprivate directives are threadprivate.
1310 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1311 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1312 SemaRef.getLangOpts().OpenMPUseTLS &&
1313 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1314 (VD && VD->getStorageClass() == SC_Register &&
1315 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1316 DVar.RefExpr = buildDeclRefExpr(
1317 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1318 DVar.CKind = OMPC_threadprivate;
1319 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1320 return DVar;
1321 }
1322 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1323 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1324 !isLoopControlVariable(D).first) {
1325 const_iterator IterTarget =
1326 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1327 return isOpenMPTargetExecutionDirective(Data.Directive);
1328 });
1329 if (IterTarget != end()) {
1330 const_iterator ParentIterTarget = IterTarget + 1;
1331 for (const_iterator Iter = begin();
1332 Iter != ParentIterTarget; ++Iter) {
1333 if (isOpenMPLocal(VD, Iter)) {
1334 DVar.RefExpr =
1335 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1336 D->getLocation());
1337 DVar.CKind = OMPC_threadprivate;
1338 return DVar;
1339 }
1340 }
1341 if (!isClauseParsingMode() || IterTarget != begin()) {
1342 auto DSAIter = IterTarget->SharingMap.find(D);
1343 if (DSAIter != IterTarget->SharingMap.end() &&
1344 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1345 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1346 DVar.CKind = OMPC_threadprivate;
1347 return DVar;
1348 }
1349 const_iterator End = end();
1350 if (!SemaRef.isOpenMPCapturedByRef(
1351 D, std::distance(ParentIterTarget, End),
1352 /*OpenMPCaptureLevel=*/0)) {
1353 DVar.RefExpr =
1354 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1355 IterTarget->ConstructLoc);
1356 DVar.CKind = OMPC_threadprivate;
1357 return DVar;
1358 }
1359 }
1360 }
1361 }
1362
1363 if (isStackEmpty())
1364 // Not in OpenMP execution region and top scope was already checked.
1365 return DVar;
1366
1367 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1368 // in a Construct, C/C++, predetermined, p.4]
1369 // Static data members are shared.
1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1371 // in a Construct, C/C++, predetermined, p.7]
1372 // Variables with static storage duration that are declared in a scope
1373 // inside the construct are shared.
1374 if (VD && VD->isStaticDataMember()) {
1375 // Check for explicitly specified attributes.
1376 const_iterator I = begin();
1377 const_iterator EndI = end();
1378 if (FromParent && I != EndI)
1379 ++I;
1380 auto It = I->SharingMap.find(D);
1381 if (It != I->SharingMap.end()) {
1382 const DSAInfo &Data = It->getSecond();
1383 DVar.RefExpr = Data.RefExpr.getPointer();
1384 DVar.PrivateCopy = Data.PrivateCopy;
1385 DVar.CKind = Data.Attributes;
1386 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1387 DVar.DKind = I->Directive;
1388 return DVar;
1389 }
1390
1391 DVar.CKind = OMPC_shared;
1392 return DVar;
1393 }
1394
1395 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1396 // The predetermined shared attribute for const-qualified types having no
1397 // mutable members was removed after OpenMP 3.1.
1398 if (SemaRef.LangOpts.OpenMP <= 31) {
1399 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1400 // in a Construct, C/C++, predetermined, p.6]
1401 // Variables with const qualified type having no mutable member are
1402 // shared.
1403 if (isConstNotMutableType(SemaRef, D->getType())) {
1404 // Variables with const-qualified type having no mutable member may be
1405 // listed in a firstprivate clause, even if they are static data members.
1406 DSAVarData DVarTemp = hasInnermostDSA(
1407 D,
1408 [](OpenMPClauseKind C) {
1409 return C == OMPC_firstprivate || C == OMPC_shared;
1410 },
1411 MatchesAlways, FromParent);
1412 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1413 return DVarTemp;
1414
1415 DVar.CKind = OMPC_shared;
1416 return DVar;
1417 }
1418 }
1419
1420 // Explicitly specified attributes and local variables with predetermined
1421 // attributes.
1422 const_iterator I = begin();
1423 const_iterator EndI = end();
1424 if (FromParent && I != EndI)
1425 ++I;
1426 auto It = I->SharingMap.find(D);
1427 if (It != I->SharingMap.end()) {
1428 const DSAInfo &Data = It->getSecond();
1429 DVar.RefExpr = Data.RefExpr.getPointer();
1430 DVar.PrivateCopy = Data.PrivateCopy;
1431 DVar.CKind = Data.Attributes;
1432 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1433 DVar.DKind = I->Directive;
1434 }
1435
1436 return DVar;
1437 }
1438
1439 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1440 bool FromParent) const {
1441 if (isStackEmpty()) {
1442 const_iterator I;
1443 return getDSA(I, D);
1444 }
1445 D = getCanonicalDecl(D);
1446 const_iterator StartI = begin();
1447 const_iterator EndI = end();
1448 if (FromParent && StartI != EndI)
1449 ++StartI;
1450 return getDSA(StartI, D);
1451 }
1452
1453 const DSAStackTy::DSAVarData
1454 DSAStackTy::hasDSA(ValueDecl *D,
1455 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1456 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1457 bool FromParent) const {
1458 if (isStackEmpty())
1459 return {};
1460 D = getCanonicalDecl(D);
1461 const_iterator I = begin();
1462 const_iterator EndI = end();
1463 if (FromParent && I != EndI)
1464 ++I;
1465 for (; I != EndI; ++I) {
1466 if (!DPred(I->Directive) &&
1467 !isImplicitOrExplicitTaskingRegion(I->Directive))
1468 continue;
1469 const_iterator NewI = I;
1470 DSAVarData DVar = getDSA(NewI, D);
1471 if (I == NewI && CPred(DVar.CKind))
1472 return DVar;
1473 }
1474 return {};
1475 }
1476
1477 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1478 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1479 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1480 bool FromParent) const {
1481 if (isStackEmpty())
1482 return {};
1483 D = getCanonicalDecl(D);
1484 const_iterator StartI = begin();
1485 const_iterator EndI = end();
1486 if (FromParent && StartI != EndI)
1487 ++StartI;
1488 if (StartI == EndI || !DPred(StartI->Directive))
1489 return {};
1490 const_iterator NewI = StartI;
1491 DSAVarData DVar = getDSA(NewI, D);
1492 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1493 }
1494
1495 bool DSAStackTy::hasExplicitDSA(
1496 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1497 unsigned Level, bool NotLastprivate) const {
1498 if (getStackSize() <= Level)
1499 return false;
1500 D = getCanonicalDecl(D);
1501 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1502 auto I = StackElem.SharingMap.find(D);
1503 if (I != StackElem.SharingMap.end() &&
1504 I->getSecond().RefExpr.getPointer() &&
1505 CPred(I->getSecond().Attributes) &&
1506 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1507 return true;
1508 // Check predetermined rules for the loop control variables.
1509 auto LI = StackElem.LCVMap.find(D);
1510 if (LI != StackElem.LCVMap.end())
1511 return CPred(OMPC_private);
1512 return false;
1513 }
1514
1515 bool DSAStackTy::hasExplicitDirective(
1516 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1517 unsigned Level) const {
1518 if (getStackSize() <= Level)
1519 return false;
1520 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1521 return DPred(StackElem.Directive);
1522 }
1523
1524 bool DSAStackTy::hasDirective(
1525 const llvm::function_ref<bool(OpenMPDirectiveKind,
1526 const DeclarationNameInfo &, SourceLocation)>
1527 DPred,
1528 bool FromParent) const {
1529 // We look only in the enclosing region.
1530 size_t Skip = FromParent ? 2 : 1;
1531 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1532 I != E; ++I) {
1533 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1534 return true;
1535 }
1536 return false;
1537 }
1538
1539 void Sema::InitDataSharingAttributesStack() {
1540 VarDataSharingAttributesStack = new DSAStackTy(*this);
1541 }
1542
1543 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1544
1545 void Sema::pushOpenMPFunctionRegion() {
1546 DSAStack->pushFunction();
1547 }
1548
1549 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1550 DSAStack->popFunction(OldFSI);
1551 }
1552
1553 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1554 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1555 "Expected OpenMP device compilation.");
1556 return !S.isInOpenMPTargetExecutionDirective() &&
1557 !S.isInOpenMPDeclareTargetContext();
1558 }
1559
1560 namespace {
1561 /// Status of the function emission on the host/device.
1562 enum class FunctionEmissionStatus {
1563 Emitted,
1564 Discarded,
1565 Unknown,
1566 };
1567 } // anonymous namespace
1568
1569 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1570 unsigned DiagID) {
1571 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1572 "Expected OpenMP device compilation.");
1573 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1574 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1575 switch (FES) {
1576 case FunctionEmissionStatus::Emitted:
1577 Kind = DeviceDiagBuilder::K_Immediate;
1578 break;
1579 case FunctionEmissionStatus::Unknown:
1580 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred
1581 : DeviceDiagBuilder::K_Immediate;
1582 break;
1583 case FunctionEmissionStatus::TemplateDiscarded:
1584 case FunctionEmissionStatus::OMPDiscarded:
1585 Kind = DeviceDiagBuilder::K_Nop;
1586 break;
1587 case FunctionEmissionStatus::CUDADiscarded:
1588 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1589 break;
1590 }
1591
1592 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1593 }
1594
1595 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1596 unsigned DiagID) {
1597 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1598 "Expected OpenMP host compilation.");
1599 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1600 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1601 switch (FES) {
1602 case FunctionEmissionStatus::Emitted:
1603 Kind = DeviceDiagBuilder::K_Immediate;
1604 break;
1605 case FunctionEmissionStatus::Unknown:
1606 Kind = DeviceDiagBuilder::K_Deferred;
1607 break;
1608 case FunctionEmissionStatus::TemplateDiscarded:
1609 case FunctionEmissionStatus::OMPDiscarded:
1610 case FunctionEmissionStatus::CUDADiscarded:
1611 Kind = DeviceDiagBuilder::K_Nop;
1612 break;
1613 }
1614
1615 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1616 }
1617
1618 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
1619 bool CheckForDelayedContext) {
1620 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1621 "Expected OpenMP device compilation.");
1622 assert(Callee && "Callee may not be null.");
1623 Callee = Callee->getMostRecentDecl();
1624 FunctionDecl *Caller = getCurFunctionDecl();
1625
1626 // host only function are not available on the device.
1627 if (Caller) {
1628 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1629 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1630 assert(CallerS != FunctionEmissionStatus::CUDADiscarded &&
1631 CalleeS != FunctionEmissionStatus::CUDADiscarded &&
1632 "CUDADiscarded unexpected in OpenMP device function check");
1633 if ((CallerS == FunctionEmissionStatus::Emitted ||
1634 (!isOpenMPDeviceDelayedContext(*this) &&
1635 CallerS == FunctionEmissionStatus::Unknown)) &&
1636 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1637 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
1638 OMPC_device_type, OMPC_DEVICE_TYPE_host);
1639 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
1640 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1641 diag::note_omp_marked_device_type_here)
1642 << HostDevTy;
1643 return;
1644 }
1645 }
1646 // If the caller is known-emitted, mark the callee as known-emitted.
1647 // Otherwise, mark the call in our call graph so we can traverse it later.
1648 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) ||
1649 (!Caller && !CheckForDelayedContext) ||
1650 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1651 markKnownEmitted(*this, Caller, Callee, Loc,
1652 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) {
1653 return CheckForDelayedContext &&
1654 S.getEmissionStatus(FD) ==
1655 FunctionEmissionStatus::Emitted;
1656 });
1657 else if (Caller)
1658 DeviceCallGraph[Caller].insert({Callee, Loc});
1659 }
1660
1661 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee,
1662 bool CheckCaller) {
1663 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1664 "Expected OpenMP host compilation.");
1665 assert(Callee && "Callee may not be null.");
1666 Callee = Callee->getMostRecentDecl();
1667 FunctionDecl *Caller = getCurFunctionDecl();
1668
1669 // device only function are not available on the host.
1670 if (Caller) {
1671 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1672 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1673 assert(
1674 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded &&
1675 CalleeS != FunctionEmissionStatus::CUDADiscarded)) &&
1676 "CUDADiscarded unexpected in OpenMP host function check");
1677 if (CallerS == FunctionEmissionStatus::Emitted &&
1678 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1679 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
1680 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
1681 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
1682 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1683 diag::note_omp_marked_device_type_here)
1684 << NoHostDevTy;
1685 return;
1686 }
1687 }
1688 // If the caller is known-emitted, mark the callee as known-emitted.
1689 // Otherwise, mark the call in our call graph so we can traverse it later.
1690 if (!shouldIgnoreInHostDeviceCheck(Callee)) {
1691 if ((!CheckCaller && !Caller) ||
1692 (Caller &&
1693 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1694 markKnownEmitted(
1695 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) {
1696 return CheckCaller &&
1697 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted;
1698 });
1699 else if (Caller)
1700 DeviceCallGraph[Caller].insert({Callee, Loc});
1701 }
1702 }
1703
1704 void Sema::checkOpenMPDeviceExpr(const Expr *E) {
1705 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
1706 "OpenMP device compilation mode is expected.");
1707 QualType Ty = E->getType();
1708 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
1709 ((Ty->isFloat128Type() ||
1710 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) &&
1711 !Context.getTargetInfo().hasFloat128Type()) ||
1712 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
1713 !Context.getTargetInfo().hasInt128Type()))
1714 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type)
1715 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
1716 << Context.getTargetInfo().getTriple().str() << E->getSourceRange();
1717 }
1718
1719 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1720 unsigned OpenMPCaptureLevel) const {
1721 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1722
1723 ASTContext &Ctx = getASTContext();
1724 bool IsByRef = true;
1725
1726 // Find the directive that is associated with the provided scope.
1727 D = cast<ValueDecl>(D->getCanonicalDecl());
1728 QualType Ty = D->getType();
1729
1730 bool IsVariableUsedInMapClause = false;
1731 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1732 // This table summarizes how a given variable should be passed to the device
1733 // given its type and the clauses where it appears. This table is based on
1734 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1735 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1736 //
1737 // =========================================================================
1738 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1739 // | |(tofrom:scalar)| | pvt | | | |
1740 // =========================================================================
1741 // | scl | | | | - | | bycopy|
1742 // | scl | | - | x | - | - | bycopy|
1743 // | scl | | x | - | - | - | null |
1744 // | scl | x | | | - | | byref |
1745 // | scl | x | - | x | - | - | bycopy|
1746 // | scl | x | x | - | - | - | null |
1747 // | scl | | - | - | - | x | byref |
1748 // | scl | x | - | - | - | x | byref |
1749 //
1750 // | agg | n.a. | | | - | | byref |
1751 // | agg | n.a. | - | x | - | - | byref |
1752 // | agg | n.a. | x | - | - | - | null |
1753 // | agg | n.a. | - | - | - | x | byref |
1754 // | agg | n.a. | - | - | - | x[] | byref |
1755 //
1756 // | ptr | n.a. | | | - | | bycopy|
1757 // | ptr | n.a. | - | x | - | - | bycopy|
1758 // | ptr | n.a. | x | - | - | - | null |
1759 // | ptr | n.a. | - | - | - | x | byref |
1760 // | ptr | n.a. | - | - | - | x[] | bycopy|
1761 // | ptr | n.a. | - | - | x | | bycopy|
1762 // | ptr | n.a. | - | - | x | x | bycopy|
1763 // | ptr | n.a. | - | - | x | x[] | bycopy|
1764 // =========================================================================
1765 // Legend:
1766 // scl - scalar
1767 // ptr - pointer
1768 // agg - aggregate
1769 // x - applies
1770 // - - invalid in this combination
1771 // [] - mapped with an array section
1772 // byref - should be mapped by reference
1773 // byval - should be mapped by value
1774 // null - initialize a local variable to null on the device
1775 //
1776 // Observations:
1777 // - All scalar declarations that show up in a map clause have to be passed
1778 // by reference, because they may have been mapped in the enclosing data
1779 // environment.
1780 // - If the scalar value does not fit the size of uintptr, it has to be
1781 // passed by reference, regardless the result in the table above.
1782 // - For pointers mapped by value that have either an implicit map or an
1783 // array section, the runtime library may pass the NULL value to the
1784 // device instead of the value passed to it by the compiler.
1785
1786 if (Ty->isReferenceType())
1787 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1788
1789 // Locate map clauses and see if the variable being captured is referred to
1790 // in any of those clauses. Here we only care about variables, not fields,
1791 // because fields are part of aggregates.
1792 bool IsVariableAssociatedWithSection = false;
1793
1794 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1795 D, Level,
1796 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1797 OMPClauseMappableExprCommon::MappableExprComponentListRef
1798 MapExprComponents,
1799 OpenMPClauseKind WhereFoundClauseKind) {
1800 // Only the map clause information influences how a variable is
1801 // captured. E.g. is_device_ptr does not require changing the default
1802 // behavior.
1803 if (WhereFoundClauseKind != OMPC_map)
1804 return false;
1805
1806 auto EI = MapExprComponents.rbegin();
1807 auto EE = MapExprComponents.rend();
1808
1809 assert(EI != EE && "Invalid map expression!");
1810
1811 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1812 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1813
1814 ++EI;
1815 if (EI == EE)
1816 return false;
1817
1818 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1819 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1820 isa<MemberExpr>(EI->getAssociatedExpression())) {
1821 IsVariableAssociatedWithSection = true;
1822 // There is nothing more we need to know about this variable.
1823 return true;
1824 }
1825
1826 // Keep looking for more map info.
1827 return false;
1828 });
1829
1830 if (IsVariableUsedInMapClause) {
1831 // If variable is identified in a map clause it is always captured by
1832 // reference except if it is a pointer that is dereferenced somehow.
1833 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1834 } else {
1835 // By default, all the data that has a scalar type is mapped by copy
1836 // (except for reduction variables).
1837 IsByRef =
1838 (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1839 !Ty->isAnyPointerType()) ||
1840 !Ty->isScalarType() ||
1841 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1842 DSAStack->hasExplicitDSA(
1843 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1844 }
1845 }
1846
1847 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1848 IsByRef =
1849 ((IsVariableUsedInMapClause &&
1850 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
1851 OMPD_target) ||
1852 !DSAStack->hasExplicitDSA(
1853 D,
1854 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1855 Level, /*NotLastprivate=*/true)) &&
1856 // If the variable is artificial and must be captured by value - try to
1857 // capture by value.
1858 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1859 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1860 }
1861
1862 // When passing data by copy, we need to make sure it fits the uintptr size
1863 // and alignment, because the runtime library only deals with uintptr types.
1864 // If it does not fit the uintptr size, we need to pass the data by reference
1865 // instead.
1866 if (!IsByRef &&
1867 (Ctx.getTypeSizeInChars(Ty) >
1868 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1869 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1870 IsByRef = true;
1871 }
1872
1873 return IsByRef;
1874 }
1875
1876 unsigned Sema::getOpenMPNestingLevel() const {
1877 assert(getLangOpts().OpenMP);
1878 return DSAStack->getNestingLevel();
1879 }
1880
1881 bool Sema::isInOpenMPTargetExecutionDirective() const {
1882 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1883 !DSAStack->isClauseParsingMode()) ||
1884 DSAStack->hasDirective(
1885 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1886 SourceLocation) -> bool {
1887 return isOpenMPTargetExecutionDirective(K);
1888 },
1889 false);
1890 }
1891
1892 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
1893 unsigned StopAt) {
1894 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1895 D = getCanonicalDecl(D);
1896
1897 auto *VD = dyn_cast<VarDecl>(D);
1898 // Do not capture constexpr variables.
1899 if (VD && VD->isConstexpr())
1900 return nullptr;
1901
1902 // If we want to determine whether the variable should be captured from the
1903 // perspective of the current capturing scope, and we've already left all the
1904 // capturing scopes of the top directive on the stack, check from the
1905 // perspective of its parent directive (if any) instead.
1906 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
1907 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
1908
1909 // If we are attempting to capture a global variable in a directive with
1910 // 'target' we return true so that this global is also mapped to the device.
1911 //
1912 if (VD && !VD->hasLocalStorage() &&
1913 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1914 if (isInOpenMPDeclareTargetContext()) {
1915 // Try to mark variable as declare target if it is used in capturing
1916 // regions.
1917 if (LangOpts.OpenMP <= 45 &&
1918 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1919 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
1920 return nullptr;
1921 } else if (isInOpenMPTargetExecutionDirective()) {
1922 // If the declaration is enclosed in a 'declare target' directive,
1923 // then it should not be captured.
1924 //
1925 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1926 return nullptr;
1927 return VD;
1928 }
1929 }
1930
1931 if (CheckScopeInfo) {
1932 bool OpenMPFound = false;
1933 for (unsigned I = StopAt + 1; I > 0; --I) {
1934 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
1935 if(!isa<CapturingScopeInfo>(FSI))
1936 return nullptr;
1937 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
1938 if (RSI->CapRegionKind == CR_OpenMP) {
1939 OpenMPFound = true;
1940 break;
1941 }
1942 }
1943 if (!OpenMPFound)
1944 return nullptr;
1945 }
1946
1947 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1948 (!DSAStack->isClauseParsingMode() ||
1949 DSAStack->getParentDirective() != OMPD_unknown)) {
1950 auto &&Info = DSAStack->isLoopControlVariable(D);
1951 if (Info.first ||
1952 (VD && VD->hasLocalStorage() &&
1953 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
1954 (VD && DSAStack->isForceVarCapturing()))
1955 return VD ? VD : Info.second;
1956 DSAStackTy::DSAVarData DVarPrivate =
1957 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1958 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1959 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1960 // Threadprivate variables must not be captured.
1961 if (isOpenMPThreadPrivate(DVarPrivate.CKind))
1962 return nullptr;
1963 // The variable is not private or it is the variable in the directive with
1964 // default(none) clause and not used in any clause.
1965 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
1966 [](OpenMPDirectiveKind) { return true; },
1967 DSAStack->isClauseParsingMode());
1968 if (DVarPrivate.CKind != OMPC_unknown ||
1969 (VD && DSAStack->getDefaultDSA() == DSA_none))
1970 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1971 }
1972 return nullptr;
1973 }
1974
1975 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1976 unsigned Level) const {
1977 SmallVector<OpenMPDirectiveKind, 4> Regions;
1978 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1979 FunctionScopesIndex -= Regions.size();
1980 }
1981
1982 void Sema::startOpenMPLoop() {
1983 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1984 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
1985 DSAStack->loopInit();
1986 }
1987
1988 void Sema::startOpenMPCXXRangeFor() {
1989 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1990 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1991 DSAStack->resetPossibleLoopCounter();
1992 DSAStack->loopStart();
1993 }
1994 }
1995
1996 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
1997 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1998 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1999 if (DSAStack->getAssociatedLoops() > 0 &&
2000 !DSAStack->isLoopStarted()) {
2001 DSAStack->resetPossibleLoopCounter(D);
2002 DSAStack->loopStart();
2003 return true;
2004 }
2005 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2006 DSAStack->isLoopControlVariable(D).first) &&
2007 !DSAStack->hasExplicitDSA(
2008 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2009 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2010 return true;
2011 }
2012 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2013 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2014 DSAStack->isForceVarCapturing() &&
2015 !DSAStack->hasExplicitDSA(
2016 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2017 return true;
2018 }
2019 return DSAStack->hasExplicitDSA(
2020 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
2021 (DSAStack->isClauseParsingMode() &&
2022 DSAStack->getClauseParsingMode() == OMPC_private) ||
2023 // Consider taskgroup reduction descriptor variable a private to avoid
2024 // possible capture in the region.
2025 (DSAStack->hasExplicitDirective(
2026 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
2027 Level) &&
2028 DSAStack->isTaskgroupReductionRef(D, Level));
2029 }
2030
2031 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2032 unsigned Level) {
2033 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2034 D = getCanonicalDecl(D);
2035 OpenMPClauseKind OMPC = OMPC_unknown;
2036 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2037 const unsigned NewLevel = I - 1;
2038 if (DSAStack->hasExplicitDSA(D,
2039 [&OMPC](const OpenMPClauseKind K) {
2040 if (isOpenMPPrivate(K)) {
2041 OMPC = K;
2042 return true;
2043 }
2044 return false;
2045 },
2046 NewLevel))
2047 break;
2048 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2049 D, NewLevel,
2050 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2051 OpenMPClauseKind) { return true; })) {
2052 OMPC = OMPC_map;
2053 break;
2054 }
2055 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2056 NewLevel)) {
2057 OMPC = OMPC_map;
2058 if (D->getType()->isScalarType() &&
2059 DSAStack->getDefaultDMAAtLevel(NewLevel) !=
2060 DefaultMapAttributes::DMA_tofrom_scalar)
2061 OMPC = OMPC_firstprivate;
2062 break;
2063 }
2064 }
2065 if (OMPC != OMPC_unknown)
2066 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
2067 }
2068
2069 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
2070 unsigned Level) const {
2071 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2072 // Return true if the current level is no longer enclosed in a target region.
2073
2074 const auto *VD = dyn_cast<VarDecl>(D);
2075 return VD && !VD->hasLocalStorage() &&
2076 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2077 Level);
2078 }
2079
2080 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2081
2082 void Sema::finalizeOpenMPDelayedAnalysis() {
2083 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2084 // Diagnose implicit declare target functions and their callees.
2085 for (const auto &CallerCallees : DeviceCallGraph) {
2086 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2087 OMPDeclareTargetDeclAttr::getDeviceType(
2088 CallerCallees.getFirst()->getMostRecentDecl());
2089 // Ignore host functions during device analyzis.
2090 if (LangOpts.OpenMPIsDevice && DevTy &&
2091 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2092 continue;
2093 // Ignore nohost functions during host analyzis.
2094 if (!LangOpts.OpenMPIsDevice && DevTy &&
2095 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2096 continue;
2097 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation>
2098 &Callee : CallerCallees.getSecond()) {
2099 const FunctionDecl *FD = Callee.first->getMostRecentDecl();
2100 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2101 OMPDeclareTargetDeclAttr::getDeviceType(FD);
2102 if (LangOpts.OpenMPIsDevice && DevTy &&
2103 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2104 // Diagnose host function called during device codegen.
2105 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
2106 OMPC_device_type, OMPC_DEVICE_TYPE_host);
2107 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2108 << HostDevTy << 0;
2109 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2110 diag::note_omp_marked_device_type_here)
2111 << HostDevTy;
2112 continue;
2113 }
2114 if (!LangOpts.OpenMPIsDevice && DevTy &&
2115 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2116 // Diagnose nohost function called during host codegen.
2117 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2118 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2119 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2120 << NoHostDevTy << 1;
2121 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2122 diag::note_omp_marked_device_type_here)
2123 << NoHostDevTy;
2124 continue;
2125 }
2126 }
2127 }
2128 }
2129
2130 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2131 const DeclarationNameInfo &DirName,
2132 Scope *CurScope, SourceLocation Loc) {
2133 DSAStack->push(DKind, DirName, CurScope, Loc);
2134 PushExpressionEvaluationContext(
2135 ExpressionEvaluationContext::PotentiallyEvaluated);
2136 }
2137
2138 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2139 DSAStack->setClauseParsingMode(K);
2140 }
2141
2142 void Sema::EndOpenMPClause() {
2143 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2144 }
2145
2146 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2147 ArrayRef<OMPClause *> Clauses);
2148
2149 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2150 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2151 // A variable of class type (or array thereof) that appears in a lastprivate
2152 // clause requires an accessible, unambiguous default constructor for the
2153 // class type, unless the list item is also specified in a firstprivate
2154 // clause.
2155 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2156 for (OMPClause *C : D->clauses()) {
2157 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2158 SmallVector<Expr *, 8> PrivateCopies;
2159 for (Expr *DE : Clause->varlists()) {
2160 if (DE->isValueDependent() || DE->isTypeDependent()) {
2161 PrivateCopies.push_back(nullptr);
2162 continue;
2163 }
2164 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2165 auto *VD = cast<VarDecl>(DRE->getDecl());
2166 QualType Type = VD->getType().getNonReferenceType();
2167 const DSAStackTy::DSAVarData DVar =
2168 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2169 if (DVar.CKind == OMPC_lastprivate) {
2170 // Generate helper private variable and initialize it with the
2171 // default value. The address of the original variable is replaced
2172 // by the address of the new private variable in CodeGen. This new
2173 // variable is not added to IdResolver, so the code in the OpenMP
2174 // region uses original variable for proper diagnostics.
2175 VarDecl *VDPrivate = buildVarDecl(
2176 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2177 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2178 ActOnUninitializedDecl(VDPrivate);
2179 if (VDPrivate->isInvalidDecl()) {
2180 PrivateCopies.push_back(nullptr);
2181 continue;
2182 }
2183 PrivateCopies.push_back(buildDeclRefExpr(
2184 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2185 } else {
2186 // The variable is also a firstprivate, so initialization sequence
2187 // for private copy is generated already.
2188 PrivateCopies.push_back(nullptr);
2189 }
2190 }
2191 Clause->setPrivateCopies(PrivateCopies);
2192 }
2193 }
2194 // Check allocate clauses.
2195 if (!CurContext->isDependentContext())
2196 checkAllocateClauses(*this, DSAStack, D->clauses());
2197 }
2198
2199 DSAStack->pop();
2200 DiscardCleanupsInEvaluationContext();
2201 PopExpressionEvaluationContext();
2202 }
2203
2204 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2205 Expr *NumIterations, Sema &SemaRef,
2206 Scope *S, DSAStackTy *Stack);
2207
2208 namespace {
2209
2210 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2211 private:
2212 Sema &SemaRef;
2213
2214 public:
2215 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2216 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2217 NamedDecl *ND = Candidate.getCorrectionDecl();
2218 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2219 return VD->hasGlobalStorage() &&
2220 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2221 SemaRef.getCurScope());
2222 }
2223 return false;
2224 }
2225
2226 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2227 return std::make_unique<VarDeclFilterCCC>(*this);
2228 }
2229
2230 };
2231
2232 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2233 private:
2234 Sema &SemaRef;
2235
2236 public:
2237 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2238 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2239 NamedDecl *ND = Candidate.getCorrectionDecl();
2240 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2241 isa<FunctionDecl>(ND))) {
2242 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2243 SemaRef.getCurScope());
2244 }
2245 return false;
2246 }
2247
2248 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2249 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2250 }
2251 };
2252
2253 } // namespace
2254
2255 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2256 CXXScopeSpec &ScopeSpec,
2257 const DeclarationNameInfo &Id,
2258 OpenMPDirectiveKind Kind) {
2259 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2260 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2261
2262 if (Lookup.isAmbiguous())
2263 return ExprError();
2264
2265 VarDecl *VD;
2266 if (!Lookup.isSingleResult()) {
2267 VarDeclFilterCCC CCC(*this);
2268 if (TypoCorrection Corrected =
2269 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2270 CTK_ErrorRecovery)) {
2271 diagnoseTypo(Corrected,
2272 PDiag(Lookup.empty()
2273 ? diag::err_undeclared_var_use_suggest
2274 : diag::err_omp_expected_var_arg_suggest)
2275 << Id.getName());
2276 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2277 } else {
2278 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2279 : diag::err_omp_expected_var_arg)
2280 << Id.getName();
2281 return ExprError();
2282 }
2283 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2284 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2285 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2286 return ExprError();
2287 }
2288 Lookup.suppressDiagnostics();
2289
2290 // OpenMP [2.9.2, Syntax, C/C++]
2291 // Variables must be file-scope, namespace-scope, or static block-scope.
2292 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2293 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2294 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2295 bool IsDecl =
2296 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2297 Diag(VD->getLocation(),
2298 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2299 << VD;
2300 return ExprError();
2301 }
2302
2303 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2304 NamedDecl *ND = CanonicalVD;
2305 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2306 // A threadprivate directive for file-scope variables must appear outside
2307 // any definition or declaration.
2308 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2309 !getCurLexicalContext()->isTranslationUnit()) {
2310 Diag(Id.getLoc(), diag::err_omp_var_scope)
2311 << getOpenMPDirectiveName(Kind) << VD;
2312 bool IsDecl =
2313 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2314 Diag(VD->getLocation(),
2315 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2316 << VD;
2317 return ExprError();
2318 }
2319 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2320 // A threadprivate directive for static class member variables must appear
2321 // in the class definition, in the same scope in which the member
2322 // variables are declared.
2323 if (CanonicalVD->isStaticDataMember() &&
2324 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2325 Diag(Id.getLoc(), diag::err_omp_var_scope)
2326 << getOpenMPDirectiveName(Kind) << VD;
2327 bool IsDecl =
2328 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2329 Diag(VD->getLocation(),
2330 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2331 << VD;
2332 return ExprError();
2333 }
2334 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2335 // A threadprivate directive for namespace-scope variables must appear
2336 // outside any definition or declaration other than the namespace
2337 // definition itself.
2338 if (CanonicalVD->getDeclContext()->isNamespace() &&
2339 (!getCurLexicalContext()->isFileContext() ||
2340 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2341 Diag(Id.getLoc(), diag::err_omp_var_scope)
2342 << getOpenMPDirectiveName(Kind) << VD;
2343 bool IsDecl =
2344 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2345 Diag(VD->getLocation(),
2346 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2347 << VD;
2348 return ExprError();
2349 }
2350 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2351 // A threadprivate directive for static block-scope variables must appear
2352 // in the scope of the variable and not in a nested scope.
2353 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2354 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2355 Diag(Id.getLoc(), diag::err_omp_var_scope)
2356 << getOpenMPDirectiveName(Kind) << VD;
2357 bool IsDecl =
2358 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2359 Diag(VD->getLocation(),
2360 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2361 << VD;
2362 return ExprError();
2363 }
2364
2365 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2366 // A threadprivate directive must lexically precede all references to any
2367 // of the variables in its list.
2368 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2369 !DSAStack->isThreadPrivate(VD)) {
2370 Diag(Id.getLoc(), diag::err_omp_var_used)
2371 << getOpenMPDirectiveName(Kind) << VD;
2372 return ExprError();
2373 }
2374
2375 QualType ExprType = VD->getType().getNonReferenceType();
2376 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2377 SourceLocation(), VD,
2378 /*RefersToEnclosingVariableOrCapture=*/false,
2379 Id.getLoc(), ExprType, VK_LValue);
2380 }
2381
2382 Sema::DeclGroupPtrTy
2383 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2384 ArrayRef<Expr *> VarList) {
2385 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2386 CurContext->addDecl(D);
2387 return DeclGroupPtrTy::make(DeclGroupRef(D));
2388 }
2389 return nullptr;
2390 }
2391
2392 namespace {
2393 class LocalVarRefChecker final
2394 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2395 Sema &SemaRef;
2396
2397 public:
2398 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2399 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2400 if (VD->hasLocalStorage()) {
2401 SemaRef.Diag(E->getBeginLoc(),
2402 diag::err_omp_local_var_in_threadprivate_init)
2403 << E->getSourceRange();
2404 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2405 << VD << VD->getSourceRange();
2406 return true;
2407 }
2408 }
2409 return false;
2410 }
2411 bool VisitStmt(const Stmt *S) {
2412 for (const Stmt *Child : S->children()) {
2413 if (Child && Visit(Child))
2414 return true;
2415 }
2416 return false;
2417 }
2418 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2419 };
2420 } // namespace
2421
2422 OMPThreadPrivateDecl *
2423 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2424 SmallVector<Expr *, 8> Vars;
2425 for (Expr *RefExpr : VarList) {
2426 auto *DE = cast<DeclRefExpr>(RefExpr);
2427 auto *VD = cast<VarDecl>(DE->getDecl());
2428 SourceLocation ILoc = DE->getExprLoc();
2429
2430 // Mark variable as used.
2431 VD->setReferenced();
2432 VD->markUsed(Context);
2433
2434 QualType QType = VD->getType();
2435 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2436 // It will be analyzed later.
2437 Vars.push_back(DE);
2438 continue;
2439 }
2440
2441 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2442 // A threadprivate variable must not have an incomplete type.
2443 if (RequireCompleteType(ILoc, VD->getType(),
2444 diag::err_omp_threadprivate_incomplete_type)) {
2445 continue;
2446 }
2447
2448 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2449 // A threadprivate variable must not have a reference type.
2450 if (VD->getType()->isReferenceType()) {
2451 Diag(ILoc, diag::err_omp_ref_type_arg)
2452 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2453 bool IsDecl =
2454 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2455 Diag(VD->getLocation(),
2456 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2457 << VD;
2458 continue;
2459 }
2460
2461 // Check if this is a TLS variable. If TLS is not being supported, produce
2462 // the corresponding diagnostic.
2463 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2464 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2465 getLangOpts().OpenMPUseTLS &&
2466 getASTContext().getTargetInfo().isTLSSupported())) ||
2467 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2468 !VD->isLocalVarDecl())) {
2469 Diag(ILoc, diag::err_omp_var_thread_local)
2470 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2471 bool IsDecl =
2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2473 Diag(VD->getLocation(),
2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2475 << VD;
2476 continue;
2477 }
2478
2479 // Check if initial value of threadprivate variable reference variable with
2480 // local storage (it is not supported by runtime).
2481 if (const Expr *Init = VD->getAnyInitializer()) {
2482 LocalVarRefChecker Checker(*this);
2483 if (Checker.Visit(Init))
2484 continue;
2485 }
2486
2487 Vars.push_back(RefExpr);
2488 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
2489 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2490 Context, SourceRange(Loc, Loc)));
2491 if (ASTMutationListener *ML = Context.getASTMutationListener())
2492 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2493 }
2494 OMPThreadPrivateDecl *D = nullptr;
2495 if (!Vars.empty()) {
2496 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2497 Vars);
2498 D->setAccess(AS_public);
2499 }
2500 return D;
2501 }
2502
2503 static OMPAllocateDeclAttr::AllocatorTypeTy
2504 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2505 if (!Allocator)
2506 return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2507 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2508 Allocator->isInstantiationDependent() ||
2509 Allocator->containsUnexpandedParameterPack())
2510 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2511 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2512 const Expr *AE = Allocator->IgnoreParenImpCasts();
2513 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2514 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2515 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2516 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2517 llvm::FoldingSetNodeID AEId, DAEId;
2518 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2519 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2520 if (AEId == DAEId) {
2521 AllocatorKindRes = AllocatorKind;
2522 break;
2523 }
2524 }
2525 return AllocatorKindRes;
2526 }
2527
2528 static bool checkPreviousOMPAllocateAttribute(
2529 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2530 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2531 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2532 return false;
2533 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2534 Expr *PrevAllocator = A->getAllocator();
2535 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2536 getAllocatorKind(S, Stack, PrevAllocator);
2537 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2538 if (AllocatorsMatch &&
2539 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2540 Allocator && PrevAllocator) {
2541 const Expr *AE = Allocator->IgnoreParenImpCasts();
2542 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
2543 llvm::FoldingSetNodeID AEId, PAEId;
2544 AE->Profile(AEId, S.Context, /*Canonical=*/true);
2545 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
2546 AllocatorsMatch = AEId == PAEId;
2547 }
2548 if (!AllocatorsMatch) {
2549 SmallString<256> AllocatorBuffer;
2550 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2551 if (Allocator)
2552 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
2553 SmallString<256> PrevAllocatorBuffer;
2554 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2555 if (PrevAllocator)
2556 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
2557 S.getPrintingPolicy());
2558
2559 SourceLocation AllocatorLoc =
2560 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
2561 SourceRange AllocatorRange =
2562 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
2563 SourceLocation PrevAllocatorLoc =
2564 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2565 SourceRange PrevAllocatorRange =
2566 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2567 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2568 << (Allocator ? 1 : 0) << AllocatorStream.str()
2569 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2570 << AllocatorRange;
2571 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2572 << PrevAllocatorRange;
2573 return true;
2574 }
2575 return false;
2576 }
2577
2578 static void
2579 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
2580 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2581 Expr *Allocator, SourceRange SR) {
2582 if (VD->hasAttr<OMPAllocateDeclAttr>())
2583 return;
2584 if (Allocator &&
2585 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2586 Allocator->isInstantiationDependent() ||
2587 Allocator->containsUnexpandedParameterPack()))
2588 return;
2589 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
2590 Allocator, SR);
2591 VD->addAttr(A);
2592 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
2593 ML->DeclarationMarkedOpenMPAllocate(VD, A);
2594 }
2595
2596 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
2597 SourceLocation Loc, ArrayRef<Expr *> VarList,
2598 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
2599 assert(Clauses.size() <= 1 && "Expected at most one clause.");
2600 Expr *Allocator = nullptr;
2601 if (Clauses.empty()) {
2602 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
2603 // allocate directives that appear in a target region must specify an
2604 // allocator clause unless a requires directive with the dynamic_allocators
2605 // clause is present in the same compilation unit.
2606 if (LangOpts.OpenMPIsDevice &&
2607 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
2608 targetDiag(Loc, diag::err_expected_allocator_clause);
2609 } else {
2610 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
2611 }
2612 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2613 getAllocatorKind(*this, DSAStack, Allocator);
2614 SmallVector<Expr *, 8> Vars;
2615 for (Expr *RefExpr : VarList) {
2616 auto *DE = cast<DeclRefExpr>(RefExpr);
2617 auto *VD = cast<VarDecl>(DE->getDecl());
2618
2619 // Check if this is a TLS variable or global register.
2620 if (VD->getTLSKind() != VarDecl::TLS_None ||
2621 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2622 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2623 !VD->isLocalVarDecl()))
2624 continue;
2625
2626 // If the used several times in the allocate directive, the same allocator
2627 // must be used.
2628 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
2629 AllocatorKind, Allocator))
2630 continue;
2631
2632 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
2633 // If a list item has a static storage type, the allocator expression in the
2634 // allocator clause must be a constant expression that evaluates to one of
2635 // the predefined memory allocator values.
2636 if (Allocator && VD->hasGlobalStorage()) {
2637 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
2638 Diag(Allocator->getExprLoc(),
2639 diag::err_omp_expected_predefined_allocator)
2640 << Allocator->getSourceRange();
2641 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2642 VarDecl::DeclarationOnly;
2643 Diag(VD->getLocation(),
2644 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2645 << VD;
2646 continue;
2647 }
2648 }
2649
2650 Vars.push_back(RefExpr);
2651 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
2652 DE->getSourceRange());
2653 }
2654 if (Vars.empty())
2655 return nullptr;
2656 if (!Owner)
2657 Owner = getCurLexicalContext();
2658 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
2659 D->setAccess(AS_public);
2660 Owner->addDecl(D);
2661 return DeclGroupPtrTy::make(DeclGroupRef(D));
2662 }
2663
2664 Sema::DeclGroupPtrTy
2665 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
2666 ArrayRef<OMPClause *> ClauseList) {
2667 OMPRequiresDecl *D = nullptr;
2668 if (!CurContext->isFileContext()) {
2669 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2670 } else {
2671 D = CheckOMPRequiresDecl(Loc, ClauseList);
2672 if (D) {
2673 CurContext->addDecl(D);
2674 DSAStack->addRequiresDecl(D);
2675 }
2676 }
2677 return DeclGroupPtrTy::make(DeclGroupRef(D));
2678 }
2679
2680 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
2681 ArrayRef<OMPClause *> ClauseList) {
2682 /// For target specific clauses, the requires directive cannot be
2683 /// specified after the handling of any of the target regions in the
2684 /// current compilation unit.
2685 ArrayRef<SourceLocation> TargetLocations =
2686 DSAStack->getEncounteredTargetLocs();
2687 if (!TargetLocations.empty()) {
2688 for (const OMPClause *CNew : ClauseList) {
2689 // Check if any of the requires clauses affect target regions.
2690 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2691 isa<OMPUnifiedAddressClause>(CNew) ||
2692 isa<OMPReverseOffloadClause>(CNew) ||
2693 isa<OMPDynamicAllocatorsClause>(CNew)) {
2694 Diag(Loc, diag::err_omp_target_before_requires)
2695 << getOpenMPClauseName(CNew->getClauseKind());
2696 for (SourceLocation TargetLoc : TargetLocations) {
2697 Diag(TargetLoc, diag::note_omp_requires_encountered_target);
2698 }
2699 }
2700 }
2701 }
2702
2703 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
2704 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2705 ClauseList);
2706 return nullptr;
2707 }
2708
2709 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2710 const ValueDecl *D,
2711 const DSAStackTy::DSAVarData &DVar,
2712 bool IsLoopIterVar = false) {
2713 if (DVar.RefExpr) {
2714 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2715 << getOpenMPClauseName(DVar.CKind);
2716 return;
2717 }
2718 enum {
2719 PDSA_StaticMemberShared,
2720 PDSA_StaticLocalVarShared,
2721 PDSA_LoopIterVarPrivate,
2722 PDSA_LoopIterVarLinear,
2723 PDSA_LoopIterVarLastprivate,
2724 PDSA_ConstVarShared,
2725 PDSA_GlobalVarShared,
2726 PDSA_TaskVarFirstprivate,
2727 PDSA_LocalVarPrivate,
2728 PDSA_Implicit
2729 } Reason = PDSA_Implicit;
2730 bool ReportHint = false;
2731 auto ReportLoc = D->getLocation();
2732 auto *VD = dyn_cast<VarDecl>(D);
2733 if (IsLoopIterVar) {
2734 if (DVar.CKind == OMPC_private)
2735 Reason = PDSA_LoopIterVarPrivate;
2736 else if (DVar.CKind == OMPC_lastprivate)
2737 Reason = PDSA_LoopIterVarLastprivate;
2738 else
2739 Reason = PDSA_LoopIterVarLinear;
2740 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2741 DVar.CKind == OMPC_firstprivate) {
2742 Reason = PDSA_TaskVarFirstprivate;
2743 ReportLoc = DVar.ImplicitDSALoc;
2744 } else if (VD && VD->isStaticLocal())
2745 Reason = PDSA_StaticLocalVarShared;
2746 else if (VD && VD->isStaticDataMember())
2747 Reason = PDSA_StaticMemberShared;
2748 else if (VD && VD->isFileVarDecl())
2749 Reason = PDSA_GlobalVarShared;
2750 else if (D->getType().isConstant(SemaRef.getASTContext()))
2751 Reason = PDSA_ConstVarShared;
2752 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2753 ReportHint = true;
2754 Reason = PDSA_LocalVarPrivate;
2755 }
2756 if (Reason != PDSA_Implicit) {
2757 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2758 << Reason << ReportHint
2759 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2760 } else if (DVar.ImplicitDSALoc.isValid()) {
2761 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2762 << getOpenMPClauseName(DVar.CKind);
2763 }
2764 }
2765
2766 namespace {
2767 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
2768 DSAStackTy *Stack;
2769 Sema &SemaRef;
2770 bool ErrorFound = false;
2771 CapturedStmt *CS = nullptr;
2772 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2773 llvm::SmallVector<Expr *, 4> ImplicitMap;
2774 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2775 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2776
2777 void VisitSubCaptures(OMPExecutableDirective *S) {
2778 // Check implicitly captured variables.
2779 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2780 return;
2781 visitSubCaptures(S->getInnermostCapturedStmt());
2782 }
2783
2784 public:
2785 void VisitDeclRefExpr(DeclRefExpr *E) {
2786 if (E->isTypeDependent() || E->isValueDependent() ||
2787 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2788 return;
2789 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2790 // Check the datasharing rules for the expressions in the clauses.
2791 if (!CS) {
2792 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
2793 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
2794 Visit(CED->getInit());
2795 return;
2796 }
2797 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
2798 // Do not analyze internal variables and do not enclose them into
2799 // implicit clauses.
2800 return;
2801 VD = VD->getCanonicalDecl();
2802 // Skip internally declared variables.
2803 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
2804 return;
2805
2806 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
2807 // Check if the variable has explicit DSA set and stop analysis if it so.
2808 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2809 return;
2810
2811 // Skip internally declared static variables.
2812 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
2813 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2814 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
2815 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
2816 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2817 return;
2818
2819 SourceLocation ELoc = E->getExprLoc();
2820 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2821 // The default(none) clause requires that each variable that is referenced
2822 // in the construct, and does not have a predetermined data-sharing
2823 // attribute, must have its data-sharing attribute explicitly determined
2824 // by being listed in a data-sharing attribute clause.
2825 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2826 isImplicitOrExplicitTaskingRegion(DKind) &&
2827 VarsWithInheritedDSA.count(VD) == 0) {
2828 VarsWithInheritedDSA[VD] = E;
2829 return;
2830 }
2831
2832 if (isOpenMPTargetExecutionDirective(DKind) &&
2833 !Stack->isLoopControlVariable(VD).first) {
2834 if (!Stack->checkMappableExprComponentListsForDecl(
2835 VD, /*CurrentRegionOnly=*/true,
2836 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2837 StackComponents,
2838 OpenMPClauseKind) {
2839 // Variable is used if it has been marked as an array, array
2840 // section or the variable iself.
2841 return StackComponents.size() == 1 ||
2842 std::all_of(
2843 std::next(StackComponents.rbegin()),
2844 StackComponents.rend(),
2845 [](const OMPClauseMappableExprCommon::
2846 MappableComponent &MC) {
2847 return MC.getAssociatedDeclaration() ==
2848 nullptr &&
2849 (isa<OMPArraySectionExpr>(
2850 MC.getAssociatedExpression()) ||
2851 isa<ArraySubscriptExpr>(
2852 MC.getAssociatedExpression()));
2853 });
2854 })) {
2855 bool IsFirstprivate = false;
2856 // By default lambdas are captured as firstprivates.
2857 if (const auto *RD =
2858 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2859 IsFirstprivate = RD->isLambda();
2860 IsFirstprivate =
2861 IsFirstprivate ||
2862 (VD->getType().getNonReferenceType()->isScalarType() &&
2863 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2864 if (IsFirstprivate)
2865 ImplicitFirstprivate.emplace_back(E);
2866 else
2867 ImplicitMap.emplace_back(E);
2868 return;
2869 }
2870 }
2871
2872 // OpenMP [2.9.3.6, Restrictions, p.2]
2873 // A list item that appears in a reduction clause of the innermost
2874 // enclosing worksharing or parallel construct may not be accessed in an
2875 // explicit task.
2876 DVar = Stack->hasInnermostDSA(
2877 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2878 [](OpenMPDirectiveKind K) {
2879 return isOpenMPParallelDirective(K) ||
2880 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2881 },
2882 /*FromParent=*/true);
2883 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2884 ErrorFound = true;
2885 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2886 reportOriginalDsa(SemaRef, Stack, VD, DVar);
2887 return;
2888 }
2889
2890 // Define implicit data-sharing attributes for task.
2891 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
2892 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2893 !Stack->isLoopControlVariable(VD).first) {
2894 ImplicitFirstprivate.push_back(E);
2895 return;
2896 }
2897
2898 // Store implicitly used globals with declare target link for parent
2899 // target.
2900 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
2901 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2902 Stack->addToParentTargetRegionLinkGlobals(E);
2903 return;
2904 }
2905 }
2906 }
2907 void VisitMemberExpr(MemberExpr *E) {
2908 if (E->isTypeDependent() || E->isValueDependent() ||
2909 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2910 return;
2911 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
2912 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2913 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
2914 if (!FD)
2915 return;
2916 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
2917 // Check if the variable has explicit DSA set and stop analysis if it
2918 // so.
2919 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2920 return;
2921
2922 if (isOpenMPTargetExecutionDirective(DKind) &&
2923 !Stack->isLoopControlVariable(FD).first &&
2924 !Stack->checkMappableExprComponentListsForDecl(
2925 FD, /*CurrentRegionOnly=*/true,
2926 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2927 StackComponents,
2928 OpenMPClauseKind) {
2929 return isa<CXXThisExpr>(
2930 cast<MemberExpr>(
2931 StackComponents.back().getAssociatedExpression())
2932 ->getBase()
2933 ->IgnoreParens());
2934 })) {
2935 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2936 // A bit-field cannot appear in a map clause.
2937 //
2938 if (FD->isBitField())
2939 return;
2940
2941 // Check to see if the member expression is referencing a class that
2942 // has already been explicitly mapped
2943 if (Stack->isClassPreviouslyMapped(TE->getType()))
2944 return;
2945
2946 ImplicitMap.emplace_back(E);
2947 return;
2948 }
2949
2950 SourceLocation ELoc = E->getExprLoc();
2951 // OpenMP [2.9.3.6, Restrictions, p.2]
2952 // A list item that appears in a reduction clause of the innermost
2953 // enclosing worksharing or parallel construct may not be accessed in
2954 // an explicit task.
2955 DVar = Stack->hasInnermostDSA(
2956 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2957 [](OpenMPDirectiveKind K) {
2958 return isOpenMPParallelDirective(K) ||
2959 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2960 },
2961 /*FromParent=*/true);
2962 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2963 ErrorFound = true;
2964 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2965 reportOriginalDsa(SemaRef, Stack, FD, DVar);
2966 return;
2967 }
2968
2969 // Define implicit data-sharing attributes for task.
2970 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
2971 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2972 !Stack->isLoopControlVariable(FD).first) {
2973 // Check if there is a captured expression for the current field in the
2974 // region. Do not mark it as firstprivate unless there is no captured
2975 // expression.
2976 // TODO: try to make it firstprivate.
2977 if (DVar.CKind != OMPC_unknown)
2978 ImplicitFirstprivate.push_back(E);
2979 }
2980 return;
2981 }
2982 if (isOpenMPTargetExecutionDirective(DKind)) {
2983 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2984 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2985 /*NoDiagnose=*/true))
2986 return;
2987 const auto *VD = cast<ValueDecl>(
2988 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2989 if (!Stack->checkMappableExprComponentListsForDecl(
2990 VD, /*CurrentRegionOnly=*/true,
2991 [&CurComponents](
2992 OMPClauseMappableExprCommon::MappableExprComponentListRef
2993 StackComponents,
2994 OpenMPClauseKind) {
2995 auto CCI = CurComponents.rbegin();
2996 auto CCE = CurComponents.rend();
2997 for (const auto &SC : llvm::reverse(StackComponents)) {
2998 // Do both expressions have the same kind?
2999 if (CCI->getAssociatedExpression()->getStmtClass() !=
3000 SC.getAssociatedExpression()->getStmtClass())
3001 if (!(isa<OMPArraySectionExpr>(
3002 SC.getAssociatedExpression()) &&
3003 isa<ArraySubscriptExpr>(
3004 CCI->getAssociatedExpression())))
3005 return false;
3006
3007 const Decl *CCD = CCI->getAssociatedDeclaration();
3008 const Decl *SCD = SC.getAssociatedDeclaration();
3009 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3010 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3011 if (SCD != CCD)
3012 return false;
3013 std::advance(CCI, 1);
3014 if (CCI == CCE)
3015 break;
3016 }
3017 return true;
3018 })) {
3019 Visit(E->getBase());
3020 }
3021 } else {
3022 Visit(E->getBase());
3023 }
3024 }
3025 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3026 for (OMPClause *C : S->clauses()) {
3027 // Skip analysis of arguments of implicitly defined firstprivate clause
3028 // for task|target directives.
3029 // Skip analysis of arguments of implicitly defined map clause for target
3030 // directives.
3031 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3032 C->isImplicit())) {
3033 for (Stmt *CC : C->children()) {
3034 if (CC)
3035 Visit(CC);
3036 }
3037 }
3038 }
3039 // Check implicitly captured variables.
3040 VisitSubCaptures(S);
3041 }
3042 void VisitStmt(Stmt *S) {
3043 for (Stmt *C : S->children()) {
3044 if (C) {
3045 // Check implicitly captured variables in the task-based directives to
3046 // check if they must be firstprivatized.
3047 Visit(C);
3048 }
3049 }
3050 }
3051
3052 void visitSubCaptures(CapturedStmt *S) {
3053 for (const CapturedStmt::Capture &Cap : S->captures()) {
3054 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3055 continue;
3056 VarDecl *VD = Cap.getCapturedVar();
3057 // Do not try to map the variable if it or its sub-component was mapped
3058 // already.
3059 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3060 Stack->checkMappableExprComponentListsForDecl(
3061 VD, /*CurrentRegionOnly=*/true,
3062 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3063 OpenMPClauseKind) { return true; }))
3064 continue;
3065 DeclRefExpr *DRE = buildDeclRefExpr(
3066 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3067 Cap.getLocation(), /*RefersToCapture=*/true);
3068 Visit(DRE);
3069 }
3070 }
3071 bool isErrorFound() const { return ErrorFound; }
3072 ArrayRef<Expr *> getImplicitFirstprivate() const {
3073 return ImplicitFirstprivate;
3074 }
3075 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
3076 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3077 return VarsWithInheritedDSA;
3078 }
3079
3080 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3081 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3082 // Process declare target link variables for the target directives.
3083 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3084 for (DeclRefExpr *E : Stack->getLinkGlobals())
3085 Visit(E);
3086 }
3087 }
3088 };
3089 } // namespace
3090
3091 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3092 switch (DKind) {
3093 case OMPD_parallel:
3094 case OMPD_parallel_for:
3095 case OMPD_parallel_for_simd:
3096 case OMPD_parallel_sections:
3097 case OMPD_teams:
3098 case OMPD_teams_distribute:
3099 case OMPD_teams_distribute_simd: {
3100 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3101 QualType KmpInt32PtrTy =
3102 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3103 Sema::CapturedParamNameType Params[] = {
3104 std::make_pair(".global_tid.", KmpInt32PtrTy),
3105 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3106 std::make_pair(StringRef(), QualType()) // __context with shared vars
3107 };
3108 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3109 Params);
3110 break;
3111 }
3112 case OMPD_target_teams:
3113 case OMPD_target_parallel:
3114 case OMPD_target_parallel_for:
3115 case OMPD_target_parallel_for_simd:
3116 case OMPD_target_teams_distribute:
3117 case OMPD_target_teams_distribute_simd: {
3118 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3119 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3120 QualType KmpInt32PtrTy =
3121 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3122 QualType Args[] = {VoidPtrTy};
3123 FunctionProtoType::ExtProtoInfo EPI;
3124 EPI.Variadic = true;
3125 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3126 Sema::CapturedParamNameType Params[] = {
3127 std::make_pair(".global_tid.", KmpInt32Ty),
3128 std::make_pair(".part_id.", KmpInt32PtrTy),
3129 std::make_pair(".privates.", VoidPtrTy),
3130 std::make_pair(
3131 ".copy_fn.",
3132 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3133 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3134 std::make_pair(StringRef(), QualType()) // __context with shared vars
3135 };
3136 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3137 Params, /*OpenMPCaptureLevel=*/0);
3138 // Mark this captured region as inlined, because we don't use outlined
3139 // function directly.
3140 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3141 AlwaysInlineAttr::CreateImplicit(
3142 Context, {}, AttributeCommonInfo::AS_Keyword,
3143 AlwaysInlineAttr::Keyword_forceinline));
3144 Sema::CapturedParamNameType ParamsTarget[] = {
3145 std::make_pair(StringRef(), QualType()) // __context with shared vars
3146 };
3147 // Start a captured region for 'target' with no implicit parameters.
3148 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3149 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3150 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3151 std::make_pair(".global_tid.", KmpInt32PtrTy),
3152 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3153 std::make_pair(StringRef(), QualType()) // __context with shared vars
3154 };
3155 // Start a captured region for 'teams' or 'parallel'. Both regions have
3156 // the same implicit parameters.
3157 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3158 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3159 break;
3160 }
3161 case OMPD_target:
3162 case OMPD_target_simd: {
3163 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3164 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3165 QualType KmpInt32PtrTy =
3166 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3167 QualType Args[] = {VoidPtrTy};
3168 FunctionProtoType::ExtProtoInfo EPI;
3169 EPI.Variadic = true;
3170 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3171 Sema::CapturedParamNameType Params[] = {
3172 std::make_pair(".global_tid.", KmpInt32Ty),
3173 std::make_pair(".part_id.", KmpInt32PtrTy),
3174 std::make_pair(".privates.", VoidPtrTy),
3175 std::make_pair(
3176 ".copy_fn.",
3177 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3178 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3179 std::make_pair(StringRef(), QualType()) // __context with shared vars
3180 };
3181 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3182 Params, /*OpenMPCaptureLevel=*/0);
3183 // Mark this captured region as inlined, because we don't use outlined
3184 // function directly.
3185 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3186 AlwaysInlineAttr::CreateImplicit(
3187 Context, {}, AttributeCommonInfo::AS_Keyword,
3188 AlwaysInlineAttr::Keyword_forceinline));
3189 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3190 std::make_pair(StringRef(), QualType()),
3191 /*OpenMPCaptureLevel=*/1);
3192 break;
3193 }
3194 case OMPD_simd:
3195 case OMPD_for:
3196 case OMPD_for_simd:
3197 case OMPD_sections:
3198 case OMPD_section:
3199 case OMPD_single:
3200 case OMPD_master:
3201 case OMPD_critical:
3202 case OMPD_taskgroup:
3203 case OMPD_distribute:
3204 case OMPD_distribute_simd:
3205 case OMPD_ordered:
3206 case OMPD_atomic:
3207 case OMPD_target_data: {
3208 Sema::CapturedParamNameType Params[] = {
3209 std::make_pair(StringRef(), QualType()) // __context with shared vars
3210 };
3211 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3212 Params);
3213 break;
3214 }
3215 case OMPD_task: {
3216 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3217 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3218 QualType KmpInt32PtrTy =
3219 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3220 QualType Args[] = {VoidPtrTy};
3221 FunctionProtoType::ExtProtoInfo EPI;
3222 EPI.Variadic = true;
3223 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3224 Sema::CapturedParamNameType Params[] = {
3225 std::make_pair(".global_tid.", KmpInt32Ty),
3226 std::make_pair(".part_id.", KmpInt32PtrTy),
3227 std::make_pair(".privates.", VoidPtrTy),
3228 std::make_pair(
3229 ".copy_fn.",
3230 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3231 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3232 std::make_pair(StringRef(), QualType()) // __context with shared vars
3233 };
3234 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3235 Params);
3236 // Mark this captured region as inlined, because we don't use outlined
3237 // function directly.
3238 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3239 AlwaysInlineAttr::CreateImplicit(
3240 Context, {}, AttributeCommonInfo::AS_Keyword,
3241 AlwaysInlineAttr::Keyword_forceinline));
3242 break;
3243 }
3244 case OMPD_taskloop:
3245 case OMPD_taskloop_simd:
3246 case OMPD_master_taskloop:
3247 case OMPD_master_taskloop_simd: {
3248 QualType KmpInt32Ty =
3249 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3250 .withConst();
3251 QualType KmpUInt64Ty =
3252 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3253 .withConst();
3254 QualType KmpInt64Ty =
3255 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3256 .withConst();
3257 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3258 QualType KmpInt32PtrTy =
3259 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3260 QualType Args[] = {VoidPtrTy};
3261 FunctionProtoType::ExtProtoInfo EPI;
3262 EPI.Variadic = true;
3263 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3264 Sema::CapturedParamNameType Params[] = {
3265 std::make_pair(".global_tid.", KmpInt32Ty),
3266 std::make_pair(".part_id.", KmpInt32PtrTy),
3267 std::make_pair(".privates.", VoidPtrTy),
3268 std::make_pair(
3269 ".copy_fn.",
3270 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3271 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3272 std::make_pair(".lb.", KmpUInt64Ty),
3273 std::make_pair(".ub.", KmpUInt64Ty),
3274 std::make_pair(".st.", KmpInt64Ty),
3275 std::make_pair(".liter.", KmpInt32Ty),
3276 std::make_pair(".reductions.", VoidPtrTy),
3277 std::make_pair(StringRef(), QualType()) // __context with shared vars
3278 };
3279 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3280 Params);
3281 // Mark this captured region as inlined, because we don't use outlined
3282 // function directly.
3283 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3284 AlwaysInlineAttr::CreateImplicit(
3285 Context, {}, AttributeCommonInfo::AS_Keyword,
3286 AlwaysInlineAttr::Keyword_forceinline));
3287 break;
3288 }
3289 case OMPD_parallel_master_taskloop: {
3290 QualType KmpInt32Ty =
3291 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3292 .withConst();
3293 QualType KmpUInt64Ty =
3294 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3295 .withConst();
3296 QualType KmpInt64Ty =
3297 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3298 .withConst();
3299 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3300 QualType KmpInt32PtrTy =
3301 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3302 Sema::CapturedParamNameType ParamsParallel[] = {
3303 std::make_pair(".global_tid.", KmpInt32PtrTy),
3304 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3305 std::make_pair(StringRef(), QualType()) // __context with shared vars
3306 };
3307 // Start a captured region for 'parallel'.
3308 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3309 ParamsParallel, /*OpenMPCaptureLevel=*/1);
3310 QualType Args[] = {VoidPtrTy};
3311 FunctionProtoType::ExtProtoInfo EPI;
3312 EPI.Variadic = true;
3313 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3314 Sema::CapturedParamNameType Params[] = {
3315 std::make_pair(".global_tid.", KmpInt32Ty),
3316 std::make_pair(".part_id.", KmpInt32PtrTy),
3317 std::make_pair(".privates.", VoidPtrTy),
3318 std::make_pair(
3319 ".copy_fn.",
3320 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3321 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3322 std::make_pair(".lb.", KmpUInt64Ty),
3323 std::make_pair(".ub.", KmpUInt64Ty),
3324 std::make_pair(".st.", KmpInt64Ty),
3325 std::make_pair(".liter.", KmpInt32Ty),
3326 std::make_pair(".reductions.", VoidPtrTy),
3327 std::make_pair(StringRef(), QualType()) // __context with shared vars
3328 };
3329 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3330 Params, /*OpenMPCaptureLevel=*/2);
3331 // Mark this captured region as inlined, because we don't use outlined
3332 // function directly.
3333 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3334 AlwaysInlineAttr::CreateImplicit(
3335 Context, {}, AttributeCommonInfo::AS_Keyword,
3336 AlwaysInlineAttr::Keyword_forceinline));
3337 break;
3338 }
3339 case OMPD_distribute_parallel_for_simd:
3340 case OMPD_distribute_parallel_for: {
3341 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3342 QualType KmpInt32PtrTy =
3343 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3344 Sema::CapturedParamNameType Params[] = {
3345 std::make_pair(".global_tid.", KmpInt32PtrTy),
3346 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3347 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3348 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3349 std::make_pair(StringRef(), QualType()) // __context with shared vars
3350 };
3351 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3352 Params);
3353 break;
3354 }
3355 case OMPD_target_teams_distribute_parallel_for:
3356 case OMPD_target_teams_distribute_parallel_for_simd: {
3357 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3358 QualType KmpInt32PtrTy =
3359 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3360 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3361
3362 QualType Args[] = {VoidPtrTy};
3363 FunctionProtoType::ExtProtoInfo EPI;
3364 EPI.Variadic = true;
3365 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3366 Sema::CapturedParamNameType Params[] = {
3367 std::make_pair(".global_tid.", KmpInt32Ty),
3368 std::make_pair(".part_id.", KmpInt32PtrTy),
3369 std::make_pair(".privates.", VoidPtrTy),
3370 std::make_pair(
3371 ".copy_fn.",
3372 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3373 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3374 std::make_pair(StringRef(), QualType()) // __context with shared vars
3375 };
3376 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3377 Params, /*OpenMPCaptureLevel=*/0);
3378 // Mark this captured region as inlined, because we don't use outlined
3379 // function directly.
3380 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3381 AlwaysInlineAttr::CreateImplicit(
3382 Context, {}, AttributeCommonInfo::AS_Keyword,
3383 AlwaysInlineAttr::Keyword_forceinline));
3384 Sema::CapturedParamNameType ParamsTarget[] = {
3385 std::make_pair(StringRef(), QualType()) // __context with shared vars
3386 };
3387 // Start a captured region for 'target' with no implicit parameters.
3388 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3389 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3390
3391 Sema::CapturedParamNameType ParamsTeams[] = {
3392 std::make_pair(".global_tid.", KmpInt32PtrTy),
3393 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3394 std::make_pair(StringRef(), QualType()) // __context with shared vars
3395 };
3396 // Start a captured region for 'target' with no implicit parameters.
3397 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3398 ParamsTeams, /*OpenMPCaptureLevel=*/2);
3399
3400 Sema::CapturedParamNameType ParamsParallel[] = {
3401 std::make_pair(".global_tid.", KmpInt32PtrTy),
3402 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3403 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3404 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3405 std::make_pair(StringRef(), QualType()) // __context with shared vars
3406 };
3407 // Start a captured region for 'teams' or 'parallel'. Both regions have
3408 // the same implicit parameters.
3409 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3410 ParamsParallel, /*OpenMPCaptureLevel=*/3);
3411 break;
3412 }
3413
3414 case OMPD_teams_distribute_parallel_for:
3415 case OMPD_teams_distribute_parallel_for_simd: {
3416 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3417 QualType KmpInt32PtrTy =
3418 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3419
3420 Sema::CapturedParamNameType ParamsTeams[] = {
3421 std::make_pair(".global_tid.", KmpInt32PtrTy),
3422 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3423 std::make_pair(StringRef(), QualType()) // __context with shared vars
3424 };
3425 // Start a captured region for 'target' with no implicit parameters.
3426 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3427 ParamsTeams, /*OpenMPCaptureLevel=*/0);
3428
3429 Sema::CapturedParamNameType ParamsParallel[] = {
3430 std::make_pair(".global_tid.", KmpInt32PtrTy),
3431 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3432 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3433 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3434 std::make_pair(StringRef(), QualType()) // __context with shared vars
3435 };
3436 // Start a captured region for 'teams' or 'parallel'. Both regions have
3437 // the same implicit parameters.
3438 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3439 ParamsParallel, /*OpenMPCaptureLevel=*/1);
3440 break;
3441 }
3442 case OMPD_target_update:
3443 case OMPD_target_enter_data:
3444 case OMPD_target_exit_data: {
3445 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3446 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3447 QualType KmpInt32PtrTy =
3448 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3449 QualType Args[] = {VoidPtrTy};
3450 FunctionProtoType::ExtProtoInfo EPI;
3451 EPI.Variadic = true;
3452 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3453 Sema::CapturedParamNameType Params[] = {
3454 std::make_pair(".global_tid.", KmpInt32Ty),
3455 std::make_pair(".part_id.", KmpInt32PtrTy),
3456 std::make_pair(".privates.", VoidPtrTy),
3457 std::make_pair(
3458 ".copy_fn.",
3459 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3460 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3461 std::make_pair(StringRef(), QualType()) // __context with shared vars
3462 };
3463 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3464 Params);
3465 // Mark this captured region as inlined, because we don't use outlined
3466 // function directly.
3467 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3468 AlwaysInlineAttr::CreateImplicit(
3469 Context, {}, AttributeCommonInfo::AS_Keyword,
3470 AlwaysInlineAttr::Keyword_forceinline));
3471 break;
3472 }
3473 case OMPD_threadprivate:
3474 case OMPD_allocate:
3475 case OMPD_taskyield:
3476 case OMPD_barrier:
3477 case OMPD_taskwait:
3478 case OMPD_cancellation_point:
3479 case OMPD_cancel:
3480 case OMPD_flush:
3481 case OMPD_declare_reduction:
3482 case OMPD_declare_mapper:
3483 case OMPD_declare_simd:
3484 case OMPD_declare_target:
3485 case OMPD_end_declare_target:
3486 case OMPD_requires:
3487 case OMPD_declare_variant:
3488 llvm_unreachable("OpenMP Directive is not allowed");
3489 case OMPD_unknown:
3490 llvm_unreachable("Unknown OpenMP directive");
3491 }
3492 }
3493
3494 int Sema::getNumberOfConstructScopes(unsigned Level) const {
3495 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
3496 }
3497
3498 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
3499 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3500 getOpenMPCaptureRegions(CaptureRegions, DKind);
3501 return CaptureRegions.size();
3502 }
3503
3504 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
3505 Expr *CaptureExpr, bool WithInit,
3506 bool AsExpression) {
3507 assert(CaptureExpr);
3508 ASTContext &C = S.getASTContext();
3509 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
3510 QualType Ty = Init->getType();
3511 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
3512 if (S.getLangOpts().CPlusPlus) {
3513 Ty = C.getLValueReferenceType(Ty);
3514 } else {
3515 Ty = C.getPointerType(Ty);
3516 ExprResult Res =
3517 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
3518 if (!Res.isUsable())
3519 return nullptr;
3520 Init = Res.get();
3521 }
3522 WithInit = true;
3523 }
3524 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
3525 CaptureExpr->getBeginLoc());
3526 if (!WithInit)
3527 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
3528 S.CurContext->addHiddenDecl(CED);
3529 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
3530 return CED;
3531 }
3532
3533 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
3534 bool WithInit) {
3535 OMPCapturedExprDecl *CD;
3536 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
3537 CD = cast<OMPCapturedExprDecl>(VD);
3538 else
3539 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
3540 /*AsExpression=*/false);
3541 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3542 CaptureExpr->getExprLoc());
3543 }
3544
3545 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
3546 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
3547 if (!Ref) {
3548 OMPCapturedExprDecl *CD = buildCaptureDecl(
3549 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
3550 /*WithInit=*/true, /*AsExpression=*/true);
3551 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3552 CaptureExpr->getExprLoc());
3553 }
3554 ExprResult Res = Ref;
3555 if (!S.getLangOpts().CPlusPlus &&
3556 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
3557 Ref->getType()->isPointerType()) {
3558 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
3559 if (!Res.isUsable())
3560 return ExprError();
3561 }
3562 return S.DefaultLvalueConversion(Res.get());
3563 }
3564
3565 namespace {
3566 // OpenMP directives parsed in this section are represented as a
3567 // CapturedStatement with an associated statement. If a syntax error
3568 // is detected during the parsing of the associated statement, the
3569 // compiler must abort processing and close the CapturedStatement.
3570 //
3571 // Combined directives such as 'target parallel' have more than one
3572 // nested CapturedStatements. This RAII ensures that we unwind out
3573 // of all the nested CapturedStatements when an error is found.
3574 class CaptureRegionUnwinderRAII {
3575 private:
3576 Sema &S;
3577 bool &ErrorFound;
3578 OpenMPDirectiveKind DKind = OMPD_unknown;
3579
3580 public:
3581 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
3582 OpenMPDirectiveKind DKind)
3583 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3584 ~CaptureRegionUnwinderRAII() {
3585 if (ErrorFound) {
3586 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
3587 while (--ThisCaptureLevel >= 0)
3588 S.ActOnCapturedRegionError();
3589 }
3590 }
3591 };
3592 } // namespace
3593
3594 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
3595 // Capture variables captured by reference in lambdas for target-based
3596 // directives.
3597 if (!CurContext->isDependentContext() &&
3598 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
3599 isOpenMPTargetDataManagementDirective(
3600 DSAStack->getCurrentDirective()))) {
3601 QualType Type = V->getType();
3602 if (const auto *RD = Type.getCanonicalType()
3603 .getNonReferenceType()
3604 ->getAsCXXRecordDecl()) {
3605 bool SavedForceCaptureByReferenceInTargetExecutable =
3606 DSAStack->isForceCaptureByReferenceInTargetExecutable();
3607 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3608 /*V=*/true);
3609 if (RD->isLambda()) {
3610 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
3611 FieldDecl *ThisCapture;
3612 RD->getCaptureFields(Captures, ThisCapture);
3613 for (const LambdaCapture &LC : RD->captures()) {
3614 if (LC.getCaptureKind() == LCK_ByRef) {
3615 VarDecl *VD = LC.getCapturedVar();
3616 DeclContext *VDC = VD->getDeclContext();
3617 if (!VDC->Encloses(CurContext))
3618 continue;
3619 MarkVariableReferenced(LC.getLocation(), VD);
3620 } else if (LC.getCaptureKind() == LCK_This) {
3621 QualType ThisTy = getCurrentThisType();
3622 if (!ThisTy.isNull() &&
3623 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
3624 CheckCXXThisCapture(LC.getLocation());
3625 }
3626 }
3627 }
3628 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3629 SavedForceCaptureByReferenceInTargetExecutable);
3630 }
3631 }
3632 }
3633
3634 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
3635 ArrayRef<OMPClause *> Clauses) {
3636 bool ErrorFound = false;
3637 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3638 *this, ErrorFound, DSAStack->getCurrentDirective());
3639 if (!S.isUsable()) {
3640 ErrorFound = true;
3641 return StmtError();
3642 }
3643
3644 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3645 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
3646 OMPOrderedClause *OC = nullptr;
3647 OMPScheduleClause *SC = nullptr;
3648 SmallVector<const OMPLinearClause *, 4> LCs;
3649 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
3650 // This is required for proper codegen.
3651 for (OMPClause *Clause : Clauses) {
3652 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
3653 Clause->getClauseKind() == OMPC_in_reduction) {
3654 // Capture taskgroup task_reduction descriptors inside the tasking regions
3655 // with the corresponding in_reduction items.
3656 auto *IRC = cast<OMPInReductionClause>(Clause);
3657 for (Expr *E : IRC->taskgroup_descriptors())
3658 if (E)
3659 MarkDeclarationsReferencedInExpr(E);
3660 }
3661 if (isOpenMPPrivate(Clause->getClauseKind()) ||
3662 Clause->getClauseKind() == OMPC_copyprivate ||
3663 (getLangOpts().OpenMPUseTLS &&
3664 getASTContext().getTargetInfo().isTLSSupported() &&
3665 Clause->getClauseKind() == OMPC_copyin)) {
3666 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
3667 // Mark all variables in private list clauses as used in inner region.
3668 for (Stmt *VarRef : Clause->children()) {
3669 if (auto *E = cast_or_null<Expr>(VarRef)) {
3670 MarkDeclarationsReferencedInExpr(E);
3671 }
3672 }
3673 DSAStack->setForceVarCapturing(/*V=*/false);
3674 } else if (CaptureRegions.size() > 1 ||
3675 CaptureRegions.back() != OMPD_unknown) {
3676 if (auto *C = OMPClauseWithPreInit::get(Clause))
3677 PICs.push_back(C);
3678 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
3679 if (Expr *E = C->getPostUpdateExpr())
3680 MarkDeclarationsReferencedInExpr(E);
3681 }
3682 }
3683 if (Clause->getClauseKind() == OMPC_schedule)
3684 SC = cast<OMPScheduleClause>(Clause);
3685 else if (Clause->getClauseKind() == OMPC_ordered)
3686 OC = cast<OMPOrderedClause>(Clause);
3687 else if (Clause->getClauseKind() == OMPC_linear)
3688 LCs.push_back(cast<OMPLinearClause>(Clause));
3689 }
3690 // OpenMP, 2.7.1 Loop Construct, Restrictions
3691 // The nonmonotonic modifier cannot be specified if an ordered clause is
3692 // specified.
3693 if (SC &&
3694 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3695 SC->getSecondScheduleModifier() ==
3696 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3697 OC) {
3698 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
3699 ? SC->getFirstScheduleModifierLoc()
3700 : SC->getSecondScheduleModifierLoc(),
3701 diag::err_omp_schedule_nonmonotonic_ordered)
3702 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3703 ErrorFound = true;
3704 }
3705 if (!LCs.empty() && OC && OC->getNumForLoops()) {
3706 for (const OMPLinearClause *C : LCs) {
3707 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
3708 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3709 }
3710 ErrorFound = true;
3711 }
3712 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
3713 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
3714 OC->getNumForLoops()) {
3715 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3716 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
3717 ErrorFound = true;
3718 }
3719 if (ErrorFound) {
3720 return StmtError();
3721 }
3722 StmtResult SR = S;
3723 unsigned CompletedRegions = 0;
3724 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
3725 // Mark all variables in private list clauses as used in inner region.
3726 // Required for proper codegen of combined directives.
3727 // TODO: add processing for other clauses.
3728 if (ThisCaptureRegion != OMPD_unknown) {
3729 for (const clang::OMPClauseWithPreInit *C : PICs) {
3730 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3731 // Find the particular capture region for the clause if the
3732 // directive is a combined one with multiple capture regions.
3733 // If the directive is not a combined one, the capture region
3734 // associated with the clause is OMPD_unknown and is generated
3735 // only once.
3736 if (CaptureRegion == ThisCaptureRegion ||
3737 CaptureRegion == OMPD_unknown) {
3738 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
3739 for (Decl *D : DS->decls())
3740 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3741 }
3742 }
3743 }
3744 }
3745 if (++CompletedRegions == CaptureRegions.size())
3746 DSAStack->setBodyComplete();
3747 SR = ActOnCapturedRegionEnd(SR.get());
3748 }
3749 return SR;
3750 }
3751
3752 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
3753 OpenMPDirectiveKind CancelRegion,
3754 SourceLocation StartLoc) {
3755 // CancelRegion is only needed for cancel and cancellation_point.
3756 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3757 return false;
3758
3759 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3760 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3761 return false;
3762
3763 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3764 << getOpenMPDirectiveName(CancelRegion);
3765 return true;
3766 }
3767
3768 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
3769 OpenMPDirectiveKind CurrentRegion,
3770 const DeclarationNameInfo &CurrentName,
3771 OpenMPDirectiveKind CancelRegion,
3772 SourceLocation StartLoc) {
3773 if (Stack->getCurScope()) {
3774 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3775 OpenMPDirectiveKind OffendingRegion = ParentRegion;
3776 bool NestingProhibited = false;
3777 bool CloseNesting = true;
3778 bool OrphanSeen = false;
3779 enum {
3780 NoRecommend,
3781 ShouldBeInParallelRegion,
3782 ShouldBeInOrderedRegion,
3783 ShouldBeInTargetRegion,
3784 ShouldBeInTeamsRegion
3785 } Recommend = NoRecommend;
3786 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
3787 // OpenMP [2.16, Nesting of Regions]
3788 // OpenMP constructs may not be nested inside a simd region.
3789 // OpenMP [2.8.1,simd Construct, Restrictions]
3790 // An ordered construct with the simd clause is the only OpenMP
3791 // construct that can appear in the simd region.
3792 // Allowing a SIMD construct nested in another SIMD construct is an
3793 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
3794 // message.
3795 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
3796 ? diag::err_omp_prohibited_region_simd
3797 : diag::warn_omp_nesting_simd);
3798 return CurrentRegion != OMPD_simd;
3799 }
3800 if (ParentRegion == OMPD_atomic) {
3801 // OpenMP [2.16, Nesting of Regions]
3802 // OpenMP constructs may not be nested inside an atomic region.
3803 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3804 return true;
3805 }
3806 if (CurrentRegion == OMPD_section) {
3807 // OpenMP [2.7.2, sections Construct, Restrictions]
3808 // Orphaned section directives are prohibited. That is, the section
3809 // directives must appear within the sections construct and must not be
3810 // encountered elsewhere in the sections region.
3811 if (ParentRegion != OMPD_sections &&
3812 ParentRegion != OMPD_parallel_sections) {
3813 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3814 << (ParentRegion != OMPD_unknown)
3815 << getOpenMPDirectiveName(ParentRegion);
3816 return true;
3817 }
3818 return false;
3819 }
3820 // Allow some constructs (except teams and cancellation constructs) to be
3821 // orphaned (they could be used in functions, called from OpenMP regions
3822 // with the required preconditions).
3823 if (ParentRegion == OMPD_unknown &&
3824 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
3825 CurrentRegion != OMPD_cancellation_point &&
3826 CurrentRegion != OMPD_cancel)
3827 return false;
3828 if (CurrentRegion == OMPD_cancellation_point ||
3829 CurrentRegion == OMPD_cancel) {
3830 // OpenMP [2.16, Nesting of Regions]
3831 // A cancellation point construct for which construct-type-clause is
3832 // taskgroup must be nested inside a task construct. A cancellation
3833 // point construct for which construct-type-clause is not taskgroup must
3834 // be closely nested inside an OpenMP construct that matches the type
3835 // specified in construct-type-clause.
3836 // A cancel construct for which construct-type-clause is taskgroup must be
3837 // nested inside a task construct. A cancel construct for which
3838 // construct-type-clause is not taskgroup must be closely nested inside an
3839 // OpenMP construct that matches the type specified in
3840 // construct-type-clause.
3841 NestingProhibited =
3842 !((CancelRegion == OMPD_parallel &&
3843 (ParentRegion == OMPD_parallel ||
3844 ParentRegion == OMPD_target_parallel)) ||
3845 (CancelRegion == OMPD_for &&
3846 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3847 ParentRegion == OMPD_target_parallel_for ||
3848 ParentRegion == OMPD_distribute_parallel_for ||
3849 ParentRegion == OMPD_teams_distribute_parallel_for ||
3850 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
3851 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3852 (CancelRegion == OMPD_sections &&
3853 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3854 ParentRegion == OMPD_parallel_sections)));
3855 OrphanSeen = ParentRegion == OMPD_unknown;
3856 } else if (CurrentRegion == OMPD_master) {
3857 // OpenMP [2.16, Nesting of Regions]
3858 // A master region may not be closely nested inside a worksharing,
3859 // atomic, or explicit task region.
3860 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3861 isOpenMPTaskingDirective(ParentRegion);
3862 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
3863 // OpenMP [2.16, Nesting of Regions]
3864 // A critical region may not be nested (closely or otherwise) inside a
3865 // critical region with the same name. Note that this restriction is not
3866 // sufficient to prevent deadlock.
3867 SourceLocation PreviousCriticalLoc;
3868 bool DeadLock = Stack->hasDirective(
3869 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
3870 const DeclarationNameInfo &DNI,
3871 SourceLocation Loc) {
3872 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
3873 PreviousCriticalLoc = Loc;
3874 return true;
3875 }
3876 return false;
3877 },
3878 false /* skip top directive */);
3879 if (DeadLock) {
3880 SemaRef.Diag(StartLoc,
3881 diag::err_omp_prohibited_region_critical_same_name)
3882 << CurrentName.getName();
3883 if (PreviousCriticalLoc.isValid())
3884 SemaRef.Diag(PreviousCriticalLoc,
3885 diag::note_omp_previous_critical_region);
3886 return true;
3887 }
3888 } else if (CurrentRegion == OMPD_barrier) {
3889 // OpenMP [2.16, Nesting of Regions]
3890 // A barrier region may not be closely nested inside a worksharing,
3891 // explicit task, critical, ordered, atomic, or master region.
3892 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3893 isOpenMPTaskingDirective(ParentRegion) ||
3894 ParentRegion == OMPD_master ||
3895 ParentRegion == OMPD_critical ||
3896 ParentRegion == OMPD_ordered;
3897 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
3898 !isOpenMPParallelDirective(CurrentRegion) &&
3899 !isOpenMPTeamsDirective(CurrentRegion)) {
3900 // OpenMP [2.16, Nesting of Regions]
3901 // A worksharing region may not be closely nested inside a worksharing,
3902 // explicit task, critical, ordered, atomic, or master region.
3903 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3904 isOpenMPTaskingDirective(ParentRegion) ||
3905 ParentRegion == OMPD_master ||
3906 ParentRegion == OMPD_critical ||
3907 ParentRegion == OMPD_ordered;
3908 Recommend = ShouldBeInParallelRegion;
3909 } else if (CurrentRegion == OMPD_ordered) {
3910 // OpenMP [2.16, Nesting of Regions]
3911 // An ordered region may not be closely nested inside a critical,
3912 // atomic, or explicit task region.
3913 // An ordered region must be closely nested inside a loop region (or
3914 // parallel loop region) with an ordered clause.
3915 // OpenMP [2.8.1,simd Construct, Restrictions]
3916 // An ordered construct with the simd clause is the only OpenMP construct
3917 // that can appear in the simd region.
3918 NestingProhibited = ParentRegion == OMPD_critical ||
3919 isOpenMPTaskingDirective(ParentRegion) ||
3920 !(isOpenMPSimdDirective(ParentRegion) ||
3921 Stack->isParentOrderedRegion());
3922 Recommend = ShouldBeInOrderedRegion;
3923 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
3924 // OpenMP [2.16, Nesting of Regions]
3925 // If specified, a teams construct must be contained within a target
3926 // construct.
3927 NestingProhibited =
3928 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
3929 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
3930 ParentRegion != OMPD_target);
3931 OrphanSeen = ParentRegion == OMPD_unknown;
3932 Recommend = ShouldBeInTargetRegion;
3933 }
3934 if (!NestingProhibited &&
3935 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
3936 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
3937 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
3938 // OpenMP [2.16, Nesting of Regions]
3939 // distribute, parallel, parallel sections, parallel workshare, and the
3940 // parallel loop and parallel loop SIMD constructs are the only OpenMP
3941 // constructs that can be closely nested in the teams region.
3942 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3943 !isOpenMPDistributeDirective(CurrentRegion);
3944 Recommend = ShouldBeInParallelRegion;
3945 }
3946 if (!NestingProhibited &&
3947 isOpenMPNestingDistributeDirective(CurrentRegion)) {
3948 // OpenMP 4.5 [2.17 Nesting of Regions]
3949 // The region associated with the distribute construct must be strictly
3950 // nested inside a teams region
3951 NestingProhibited =
3952 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
3953 Recommend = ShouldBeInTeamsRegion;
3954 }
3955 if (!NestingProhibited &&
3956 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3957 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3958 // OpenMP 4.5 [2.17 Nesting of Regions]
3959 // If a target, target update, target data, target enter data, or
3960 // target exit data construct is encountered during execution of a
3961 // target region, the behavior is unspecified.
3962 NestingProhibited = Stack->hasDirective(
3963 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
3964 SourceLocation) {
3965 if (isOpenMPTargetExecutionDirective(K)) {
3966 OffendingRegion = K;
3967 return true;
3968 }
3969 return false;
3970 },
3971 false /* don't skip top directive */);
3972 CloseNesting = false;
3973 }
3974 if (NestingProhibited) {
3975 if (OrphanSeen) {
3976 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3977 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
3978 } else {
3979 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3980 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3981 << Recommend << getOpenMPDirectiveName(CurrentRegion);
3982 }
3983 return true;
3984 }
3985 }
3986 return false;
3987 }
3988
3989 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
3990 ArrayRef<OMPClause *> Clauses,
3991 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3992 bool ErrorFound = false;
3993 unsigned NamedModifiersNumber = 0;
3994 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
3995 OMPD_unknown + 1);
3996 SmallVector<SourceLocation, 4> NameModifierLoc;
3997 for (const OMPClause *C : Clauses) {
3998 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3999 // At most one if clause without a directive-name-modifier can appear on
4000 // the directive.
4001 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4002 if (FoundNameModifiers[CurNM]) {
4003 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4004 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4005 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4006 ErrorFound = true;
4007 } else if (CurNM != OMPD_unknown) {
4008 NameModifierLoc.push_back(IC->getNameModifierLoc());
4009 ++NamedModifiersNumber;
4010 }
4011 FoundNameModifiers[CurNM] = IC;
4012 if (CurNM == OMPD_unknown)
4013 continue;
4014 // Check if the specified name modifier is allowed for the current
4015 // directive.
4016 // At most one if clause with the particular directive-name-modifier can
4017 // appear on the directive.
4018 bool MatchFound = false;
4019 for (auto NM : AllowedNameModifiers) {
4020 if (CurNM == NM) {
4021 MatchFound = true;
4022 break;
4023 }
4024 }
4025 if (!MatchFound) {
4026 S.Diag(IC->getNameModifierLoc(),
4027 diag::err_omp_wrong_if_directive_name_modifier)
4028 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4029 ErrorFound = true;
4030 }
4031 }
4032 }
4033 // If any if clause on the directive includes a directive-name-modifier then
4034 // all if clauses on the directive must include a directive-name-modifier.
4035 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4036 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4037 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4038 diag::err_omp_no_more_if_clause);
4039 } else {
4040 std::string Values;
4041 std::string Sep(", ");
4042 unsigned AllowedCnt = 0;
4043 unsigned TotalAllowedNum =
4044 AllowedNameModifiers.size() - NamedModifiersNumber;
4045 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4046 ++Cnt) {
4047 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4048 if (!FoundNameModifiers[NM]) {
4049 Values += "'";
4050 Values += getOpenMPDirectiveName(NM);
4051 Values += "'";
4052 if (AllowedCnt + 2 == TotalAllowedNum)
4053 Values += " or ";
4054 else if (AllowedCnt + 1 != TotalAllowedNum)
4055 Values += Sep;
4056 ++AllowedCnt;
4057 }
4058 }
4059 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4060 diag::err_omp_unnamed_if_clause)
4061 << (TotalAllowedNum > 1) << Values;
4062 }
4063 for (SourceLocation Loc : NameModifierLoc) {
4064 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4065 }
4066 ErrorFound = true;
4067 }
4068 return ErrorFound;
4069 }
4070
4071 static std::pair<ValueDecl *, bool>
4072 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
4073 SourceRange &ERange, bool AllowArraySection = false) {
4074 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4075 RefExpr->containsUnexpandedParameterPack())
4076 return std::make_pair(nullptr, true);
4077
4078 // OpenMP [3.1, C/C++]
4079 // A list item is a variable name.
4080 // OpenMP [2.9.3.3, Restrictions, p.1]
4081 // A variable that is part of another variable (as an array or
4082 // structure element) cannot appear in a private clause.
4083 RefExpr = RefExpr->IgnoreParens();
4084 enum {
4085 NoArrayExpr = -1,
4086 ArraySubscript = 0,
4087 OMPArraySection = 1
4088 } IsArrayExpr = NoArrayExpr;
4089 if (AllowArraySection) {
4090 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4091 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4092 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4093 Base = TempASE->getBase()->IgnoreParenImpCasts();
4094 RefExpr = Base;
4095 IsArrayExpr = ArraySubscript;
4096 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4097 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4098 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4099 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4100 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4101 Base = TempASE->getBase()->IgnoreParenImpCasts();
4102 RefExpr = Base;
4103 IsArrayExpr = OMPArraySection;
4104 }
4105 }
4106 ELoc = RefExpr->getExprLoc();
4107 ERange = RefExpr->getSourceRange();
4108 RefExpr = RefExpr->IgnoreParenImpCasts();
4109 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4110 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4111 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4112 (S.getCurrentThisType().isNull() || !ME ||
4113 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4114 !isa<FieldDecl>(ME->getMemberDecl()))) {
4115 if (IsArrayExpr != NoArrayExpr) {
4116 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4117 << ERange;
4118 } else {
4119 S.Diag(ELoc,
4120 AllowArraySection
4121 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4122 : diag::err_omp_expected_var_name_member_expr)
4123 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4124 }
4125 return std::make_pair(nullptr, false);
4126 }
4127 return std::make_pair(
4128 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4129 }
4130
4131 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4132 ArrayRef<OMPClause *> Clauses) {
4133 assert(!S.CurContext->isDependentContext() &&
4134 "Expected non-dependent context.");
4135 auto AllocateRange =
4136 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4137 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4138 DeclToCopy;
4139 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4140 return isOpenMPPrivate(C->getClauseKind());
4141 });
4142 for (OMPClause *Cl : PrivateRange) {
4143 MutableArrayRef<Expr *>::iterator I, It, Et;
4144 if (Cl->getClauseKind() == OMPC_private) {
4145 auto *PC = cast<OMPPrivateClause>(Cl);
4146 I = PC->private_copies().begin();
4147 It = PC->varlist_begin();
4148 Et = PC->varlist_end();
4149 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4150 auto *PC = cast<OMPFirstprivateClause>(Cl);
4151 I = PC->private_copies().begin();
4152 It = PC->varlist_begin();
4153 Et = PC->varlist_end();
4154 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4155 auto *PC = cast<OMPLastprivateClause>(Cl);
4156 I = PC->private_copies().begin();
4157 It = PC->varlist_begin();
4158 Et = PC->varlist_end();
4159 } else if (Cl->getClauseKind() == OMPC_linear) {
4160 auto *PC = cast<OMPLinearClause>(Cl);
4161 I = PC->privates().begin();
4162 It = PC->varlist_begin();
4163 Et = PC->varlist_end();
4164 } else if (Cl->getClauseKind() == OMPC_reduction) {
4165 auto *PC = cast<OMPReductionClause>(Cl);
4166 I = PC->privates().begin();
4167 It = PC->varlist_begin();
4168 Et = PC->varlist_end();
4169 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4170 auto *PC = cast<OMPTaskReductionClause>(Cl);
4171 I = PC->privates().begin();
4172 It = PC->varlist_begin();
4173 Et = PC->varlist_end();
4174 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4175 auto *PC = cast<OMPInReductionClause>(Cl);
4176 I = PC->privates().begin();
4177 It = PC->varlist_begin();
4178 Et = PC->varlist_end();
4179 } else {
4180 llvm_unreachable("Expected private clause.");
4181 }
4182 for (Expr *E : llvm::make_range(It, Et)) {
4183 if (!*I) {
4184 ++I;
4185 continue;
4186 }
4187 SourceLocation ELoc;
4188 SourceRange ERange;
4189 Expr *SimpleRefExpr = E;
4190 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4191 /*AllowArraySection=*/true);
4192 DeclToCopy.try_emplace(Res.first,
4193 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4194 ++I;
4195 }
4196 }
4197 for (OMPClause *C : AllocateRange) {
4198 auto *AC = cast<OMPAllocateClause>(C);
4199 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4200 getAllocatorKind(S, Stack, AC->getAllocator());
4201 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4202 // For task, taskloop or target directives, allocation requests to memory
4203 // allocators with the trait access set to thread result in unspecified
4204 // behavior.
4205 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4206 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4207 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4208 S.Diag(AC->getAllocator()->getExprLoc(),
4209 diag::warn_omp_allocate_thread_on_task_target_directive)
4210 << getOpenMPDirectiveName(Stack->getCurrentDirective());
4211 }
4212 for (Expr *E : AC->varlists()) {
4213 SourceLocation ELoc;
4214 SourceRange ERange;
4215 Expr *SimpleRefExpr = E;
4216 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4217 ValueDecl *VD = Res.first;
4218 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4219 if (!isOpenMPPrivate(Data.CKind)) {
4220 S.Diag(E->getExprLoc(),
4221 diag::err_omp_expected_private_copy_for_allocate);
4222 continue;
4223 }
4224 VarDecl *PrivateVD = DeclToCopy[VD];
4225 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4226 AllocatorKind, AC->getAllocator()))
4227 continue;
4228 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4229 E->getSourceRange());
4230 }
4231 }
4232 }
4233
4234 StmtResult Sema::ActOnOpenMPExecutableDirective(
4235 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
4236 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4237 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4238 StmtResult Res = StmtError();
4239 // First check CancelRegion which is then used in checkNestingOfRegions.
4240 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4241 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
4242 StartLoc))
4243 return StmtError();
4244
4245 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
4246 VarsWithInheritedDSAType VarsWithInheritedDSA;
4247 bool ErrorFound = false;
4248 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4249 if (AStmt && !CurContext->isDependentContext()) {
4250 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4251
4252 // Check default data sharing attributes for referenced variables.
4253 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
4254 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4255 Stmt *S = AStmt;
4256 while (--ThisCaptureLevel >= 0)
4257 S = cast<CapturedStmt>(S)->getCapturedStmt();
4258 DSAChecker.Visit(S);
4259 if (!isOpenMPTargetDataManagementDirective(Kind) &&
4260 !isOpenMPTaskingDirective(Kind)) {
4261 // Visit subcaptures to generate implicit clauses for captured vars.
4262 auto *CS = cast<CapturedStmt>(AStmt);
4263 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4264 getOpenMPCaptureRegions(CaptureRegions, Kind);
4265 // Ignore outer tasking regions for target directives.
4266 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4267 CS = cast<CapturedStmt>(CS->getCapturedStmt());
4268 DSAChecker.visitSubCaptures(CS);
4269 }
4270 if (DSAChecker.isErrorFound())
4271 return StmtError();
4272 // Generate list of implicitly defined firstprivate variables.
4273 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
4274
4275 SmallVector<Expr *, 4> ImplicitFirstprivates(
4276 DSAChecker.getImplicitFirstprivate().begin(),
4277 DSAChecker.getImplicitFirstprivate().end());
4278 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
4279 DSAChecker.getImplicitMap().end());
4280 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
4281 for (OMPClause *C : Clauses) {
4282 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
4283 for (Expr *E : IRC->taskgroup_descriptors())
4284 if (E)
4285 ImplicitFirstprivates.emplace_back(E);
4286 }
4287 }
4288 if (!ImplicitFirstprivates.empty()) {
4289 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
4290 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
4291 SourceLocation())) {
4292 ClausesWithImplicit.push_back(Implicit);
4293 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
4294 ImplicitFirstprivates.size();
4295 } else {
4296 ErrorFound = true;
4297 }
4298 }
4299 if (!ImplicitMaps.empty()) {
4300 CXXScopeSpec MapperIdScopeSpec;
4301 DeclarationNameInfo MapperId;
4302 if (OMPClause *Implicit = ActOnOpenMPMapClause(
4303 llvm::None, llvm::None, MapperIdScopeSpec, MapperId,
4304 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(),
4305 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) {
4306 ClausesWithImplicit.emplace_back(Implicit);
4307 ErrorFound |=
4308 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
4309 } else {
4310 ErrorFound = true;
4311 }
4312 }
4313 }
4314
4315 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
4316 switch (Kind) {
4317 case OMPD_parallel:
4318 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
4319 EndLoc);
4320 AllowedNameModifiers.push_back(OMPD_parallel);
4321 break;
4322 case OMPD_simd:
4323 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4324 VarsWithInheritedDSA);
4325 break;
4326 case OMPD_for:
4327 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4328 VarsWithInheritedDSA);
4329 break;
4330 case OMPD_for_simd:
4331 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4332 EndLoc, VarsWithInheritedDSA);
4333 break;
4334 case OMPD_sections:
4335 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
4336 EndLoc);
4337 break;
4338 case OMPD_section:
4339 assert(ClausesWithImplicit.empty() &&
4340 "No clauses are allowed for 'omp section' directive");
4341 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
4342 break;
4343 case OMPD_single:
4344 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
4345 EndLoc);
4346 break;
4347 case OMPD_master:
4348 assert(ClausesWithImplicit.empty() &&
4349 "No clauses are allowed for 'omp master' directive");
4350 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
4351 break;
4352 case OMPD_critical:
4353 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
4354 StartLoc, EndLoc);
4355 break;
4356 case OMPD_parallel_for:
4357 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4358 EndLoc, VarsWithInheritedDSA);
4359 AllowedNameModifiers.push_back(OMPD_parallel);
4360 break;
4361 case OMPD_parallel_for_simd:
4362 Res = ActOnOpenMPParallelForSimdDirective(
4363 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4364 AllowedNameModifiers.push_back(OMPD_parallel);
4365 break;
4366 case OMPD_parallel_sections:
4367 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4368 StartLoc, EndLoc);
4369 AllowedNameModifiers.push_back(OMPD_parallel);
4370 break;
4371 case OMPD_task:
4372 Res =
4373 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4374 AllowedNameModifiers.push_back(OMPD_task);
4375 break;
4376 case OMPD_taskyield:
4377 assert(ClausesWithImplicit.empty() &&
4378 "No clauses are allowed for 'omp taskyield' directive");
4379 assert(AStmt == nullptr &&
4380 "No associated statement allowed for 'omp taskyield' directive");
4381 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4382 break;
4383 case OMPD_barrier:
4384 assert(ClausesWithImplicit.empty() &&
4385 "No clauses are allowed for 'omp barrier' directive");
4386 assert(AStmt == nullptr &&
4387 "No associated statement allowed for 'omp barrier' directive");
4388 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4389 break;
4390 case OMPD_taskwait:
4391 assert(ClausesWithImplicit.empty() &&
4392 "No clauses are allowed for 'omp taskwait' directive");
4393 assert(AStmt == nullptr &&
4394 "No associated statement allowed for 'omp taskwait' directive");
4395 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4396 break;
4397 case OMPD_taskgroup:
4398 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4399 EndLoc);
4400 break;
4401 case OMPD_flush:
4402 assert(AStmt == nullptr &&
4403 "No associated statement allowed for 'omp flush' directive");
4404 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4405 break;
4406 case OMPD_ordered:
4407 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4408 EndLoc);
4409 break;
4410 case OMPD_atomic:
4411 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4412 EndLoc);
4413 break;
4414 case OMPD_teams:
4415 Res =
4416 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4417 break;
4418 case OMPD_target:
4419 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4420 EndLoc);
4421 AllowedNameModifiers.push_back(OMPD_target);
4422 break;
4423 case OMPD_target_parallel:
4424 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4425 StartLoc, EndLoc);
4426 AllowedNameModifiers.push_back(OMPD_target);
4427 AllowedNameModifiers.push_back(OMPD_parallel);
4428 break;
4429 case OMPD_target_parallel_for:
4430 Res = ActOnOpenMPTargetParallelForDirective(
4431 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4432 AllowedNameModifiers.push_back(OMPD_target);
4433 AllowedNameModifiers.push_back(OMPD_parallel);
4434 break;
4435 case OMPD_cancellation_point:
4436 assert(ClausesWithImplicit.empty() &&
4437 "No clauses are allowed for 'omp cancellation point' directive");
4438 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
4439 "cancellation point' directive");
4440 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4441 break;
4442 case OMPD_cancel:
4443 assert(AStmt == nullptr &&
4444 "No associated statement allowed for 'omp cancel' directive");
4445 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4446 CancelRegion);
4447 AllowedNameModifiers.push_back(OMPD_cancel);
4448 break;
4449 case OMPD_target_data:
4450 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4451 EndLoc);
4452 AllowedNameModifiers.push_back(OMPD_target_data);
4453 break;
4454 case OMPD_target_enter_data:
4455 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
4456 EndLoc, AStmt);
4457 AllowedNameModifiers.push_back(OMPD_target_enter_data);
4458 break;
4459 case OMPD_target_exit_data:
4460 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
4461 EndLoc, AStmt);
4462 AllowedNameModifiers.push_back(OMPD_target_exit_data);
4463 break;
4464 case OMPD_taskloop:
4465 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4466 EndLoc, VarsWithInheritedDSA);
4467 AllowedNameModifiers.push_back(OMPD_taskloop);
4468 break;
4469 case OMPD_taskloop_simd:
4470 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4471 EndLoc, VarsWithInheritedDSA);
4472 AllowedNameModifiers.push_back(OMPD_taskloop);
4473 break;
4474 case OMPD_master_taskloop:
4475 Res = ActOnOpenMPMasterTaskLoopDirective(
4476 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4477 AllowedNameModifiers.push_back(OMPD_taskloop);
4478 break;
4479 case OMPD_master_taskloop_simd:
4480 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
4481 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4482 AllowedNameModifiers.push_back(OMPD_taskloop);
4483 break;
4484 case OMPD_parallel_master_taskloop:
4485 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
4486 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4487 AllowedNameModifiers.push_back(OMPD_taskloop);
4488 AllowedNameModifiers.push_back(OMPD_parallel);
4489 break;
4490 case OMPD_distribute:
4491 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4492 EndLoc, VarsWithInheritedDSA);
4493 break;
4494 case OMPD_target_update:
4495 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4496 EndLoc, AStmt);
4497 AllowedNameModifiers.push_back(OMPD_target_update);
4498 break;
4499 case OMPD_distribute_parallel_for:
4500 Res = ActOnOpenMPDistributeParallelForDirective(
4501 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4502 AllowedNameModifiers.push_back(OMPD_parallel);
4503 break;
4504 case OMPD_distribute_parallel_for_simd:
4505 Res = ActOnOpenMPDistributeParallelForSimdDirective(
4506 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4507 AllowedNameModifiers.push_back(OMPD_parallel);
4508 break;
4509 case OMPD_distribute_simd:
4510 Res = ActOnOpenMPDistributeSimdDirective(
4511 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4512 break;
4513 case OMPD_target_parallel_for_simd:
4514 Res = ActOnOpenMPTargetParallelForSimdDirective(
4515 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4516 AllowedNameModifiers.push_back(OMPD_target);
4517 AllowedNameModifiers.push_back(OMPD_parallel);
4518 break;
4519 case OMPD_target_simd:
4520 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4521 EndLoc, VarsWithInheritedDSA);
4522 AllowedNameModifiers.push_back(OMPD_target);
4523 break;
4524 case OMPD_teams_distribute:
4525 Res = ActOnOpenMPTeamsDistributeDirective(
4526 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4527 break;
4528 case OMPD_teams_distribute_simd:
4529 Res = ActOnOpenMPTeamsDistributeSimdDirective(
4530 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4531 break;
4532 case OMPD_teams_distribute_parallel_for_simd:
4533 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4534 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4535 AllowedNameModifiers.push_back(OMPD_parallel);
4536 break;
4537 case OMPD_teams_distribute_parallel_for:
4538 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4539 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4540 AllowedNameModifiers.push_back(OMPD_parallel);
4541 break;
4542 case OMPD_target_teams:
4543 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4544 EndLoc);
4545 AllowedNameModifiers.push_back(OMPD_target);
4546 break;
4547 case OMPD_target_teams_distribute:
4548 Res = ActOnOpenMPTargetTeamsDistributeDirective(
4549 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4550 AllowedNameModifiers.push_back(OMPD_target);
4551 break;
4552 case OMPD_target_teams_distribute_parallel_for:
4553 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4554 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4555 AllowedNameModifiers.push_back(OMPD_target);
4556 AllowedNameModifiers.push_back(OMPD_parallel);
4557 break;
4558 case OMPD_target_teams_distribute_parallel_for_simd:
4559 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4560 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4561 AllowedNameModifiers.push_back(OMPD_target);
4562 AllowedNameModifiers.push_back(OMPD_parallel);
4563 break;
4564 case OMPD_target_teams_distribute_simd:
4565 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4566 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4567 AllowedNameModifiers.push_back(OMPD_target);
4568 break;
4569 case OMPD_declare_target:
4570 case OMPD_end_declare_target:
4571 case OMPD_threadprivate:
4572 case OMPD_allocate:
4573 case OMPD_declare_reduction:
4574 case OMPD_declare_mapper:
4575 case OMPD_declare_simd:
4576 case OMPD_requires:
4577 case OMPD_declare_variant:
4578 llvm_unreachable("OpenMP Directive is not allowed");
4579 case OMPD_unknown:
4580 llvm_unreachable("Unknown OpenMP directive");
4581 }
4582
4583 ErrorFound = Res.isInvalid() || ErrorFound;
4584
4585 // Check variables in the clauses if default(none) was specified.
4586 if (DSAStack->getDefaultDSA() == DSA_none) {
4587 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
4588 for (OMPClause *C : Clauses) {
4589 switch (C->getClauseKind()) {
4590 case OMPC_num_threads:
4591 case OMPC_dist_schedule:
4592 // Do not analyse if no parent teams directive.
4593 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()))
4594 break;
4595 continue;
4596 case OMPC_if:
4597 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) &&
4598 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
4599 break;
4600 continue;
4601 case OMPC_schedule:
4602 break;
4603 case OMPC_grainsize:
4604 case OMPC_num_tasks:
4605 case OMPC_final:
4606 case OMPC_priority:
4607 // Do not analyze if no parent parallel directive.
4608 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective()))
4609 break;
4610 continue;
4611 case OMPC_ordered:
4612 case OMPC_device:
4613 case OMPC_num_teams:
4614 case OMPC_thread_limit:
4615 case OMPC_hint:
4616 case OMPC_collapse:
4617 case OMPC_safelen:
4618 case OMPC_simdlen:
4619 case OMPC_default:
4620 case OMPC_proc_bind:
4621 case OMPC_private:
4622 case OMPC_firstprivate:
4623 case OMPC_lastprivate:
4624 case OMPC_shared:
4625 case OMPC_reduction:
4626 case OMPC_task_reduction:
4627 case OMPC_in_reduction:
4628 case OMPC_linear:
4629 case OMPC_aligned:
4630 case OMPC_copyin:
4631 case OMPC_copyprivate:
4632 case OMPC_nowait:
4633 case OMPC_untied:
4634 case OMPC_mergeable:
4635 case OMPC_allocate:
4636 case OMPC_read:
4637 case OMPC_write:
4638 case OMPC_update:
4639 case OMPC_capture:
4640 case OMPC_seq_cst:
4641 case OMPC_depend:
4642 case OMPC_threads:
4643 case OMPC_simd:
4644 case OMPC_map:
4645 case OMPC_nogroup:
4646 case OMPC_defaultmap:
4647 case OMPC_to:
4648 case OMPC_from:
4649 case OMPC_use_device_ptr:
4650 case OMPC_is_device_ptr:
4651 continue;
4652 case OMPC_allocator:
4653 case OMPC_flush:
4654 case OMPC_threadprivate:
4655 case OMPC_uniform:
4656 case OMPC_unknown:
4657 case OMPC_unified_address:
4658 case OMPC_unified_shared_memory:
4659 case OMPC_reverse_offload:
4660 case OMPC_dynamic_allocators:
4661 case OMPC_atomic_default_mem_order:
4662 case OMPC_device_type:
4663 case OMPC_match:
4664 llvm_unreachable("Unexpected clause");
4665 }
4666 for (Stmt *CC : C->children()) {
4667 if (CC)
4668 DSAChecker.Visit(CC);
4669 }
4670 }
4671 for (auto &P : DSAChecker.getVarsWithInheritedDSA())
4672 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
4673 }
4674 for (const auto &P : VarsWithInheritedDSA) {
4675 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
4676 continue;
4677 ErrorFound = true;
4678 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
4679 << P.first << P.second->getSourceRange();
4680 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
4681 }
4682
4683 if (!AllowedNameModifiers.empty())
4684 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
4685 ErrorFound;
4686
4687 if (ErrorFound)
4688 return StmtError();
4689
4690 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) {
4691 Res.getAs<OMPExecutableDirective>()
4692 ->getStructuredBlock()
4693 ->setIsOMPStructuredBlock(true);
4694 }
4695
4696 if (!CurContext->isDependentContext() &&
4697 isOpenMPTargetExecutionDirective(Kind) &&
4698 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
4699 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
4700 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
4701 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
4702 // Register target to DSA Stack.
4703 DSAStack->addTargetDirLocation(StartLoc);
4704 }
4705
4706 return Res;
4707 }
4708
4709 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
4710 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
4711 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
4712 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
4713 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
4714 assert(Aligneds.size() == Alignments.size());
4715 assert(Linears.size() == LinModifiers.size());
4716 assert(Linears.size() == Steps.size());
4717 if (!DG || DG.get().isNull())
4718 return DeclGroupPtrTy();
4719
4720 const int SimdId = 0;
4721 if (!DG.get().isSingleDecl()) {
4722 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
4723 << SimdId;
4724 return DG;
4725 }
4726 Decl *ADecl = DG.get().getSingleDecl();
4727 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
4728 ADecl = FTD->getTemplatedDecl();
4729
4730 auto *FD = dyn_cast<FunctionDecl>(ADecl);
4731 if (!FD) {
4732 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
4733 return DeclGroupPtrTy();
4734 }
4735
4736 // OpenMP [2.8.2, declare simd construct, Description]
4737 // The parameter of the simdlen clause must be a constant positive integer
4738 // expression.
4739 ExprResult SL;
4740 if (Simdlen)
4741 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
4742 // OpenMP [2.8.2, declare simd construct, Description]
4743 // The special this pointer can be used as if was one of the arguments to the
4744 // function in any of the linear, aligned, or uniform clauses.
4745 // The uniform clause declares one or more arguments to have an invariant
4746 // value for all concurrent invocations of the function in the execution of a
4747 // single SIMD loop.
4748 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
4749 const Expr *UniformedLinearThis = nullptr;
4750 for (const Expr *E : Uniforms) {
4751 E = E->IgnoreParenImpCasts();
4752 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4753 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
4754 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4755 FD->getParamDecl(PVD->getFunctionScopeIndex())
4756 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
4757 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
4758 continue;
4759 }
4760 if (isa<CXXThisExpr>(E)) {
4761 UniformedLinearThis = E;
4762 continue;
4763 }
4764 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4765 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4766 }
4767 // OpenMP [2.8.2, declare simd construct, Description]
4768 // The aligned clause declares that the object to which each list item points
4769 // is aligned to the number of bytes expressed in the optional parameter of
4770 // the aligned clause.
4771 // The special this pointer can be used as if was one of the arguments to the
4772 // function in any of the linear, aligned, or uniform clauses.
4773 // The type of list items appearing in the aligned clause must be array,
4774 // pointer, reference to array, or reference to pointer.
4775 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
4776 const Expr *AlignedThis = nullptr;
4777 for (const Expr *E : Aligneds) {
4778 E = E->IgnoreParenImpCasts();
4779 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4780 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4781 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
4782 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4783 FD->getParamDecl(PVD->getFunctionScopeIndex())
4784 ->getCanonicalDecl() == CanonPVD) {
4785 // OpenMP [2.8.1, simd construct, Restrictions]
4786 // A list-item cannot appear in more than one aligned clause.
4787 if (AlignedArgs.count(CanonPVD) > 0) {
4788 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4789 << 1 << E->getSourceRange();
4790 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
4791 diag::note_omp_explicit_dsa)
4792 << getOpenMPClauseName(OMPC_aligned);
4793 continue;
4794 }
4795 AlignedArgs[CanonPVD] = E;
4796 QualType QTy = PVD->getType()
4797 .getNonReferenceType()
4798 .getUnqualifiedType()
4799 .getCanonicalType();
4800 const Type *Ty = QTy.getTypePtrOrNull();
4801 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
4802 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
4803 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
4804 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
4805 }
4806 continue;
4807 }
4808 }
4809 if (isa<CXXThisExpr>(E)) {
4810 if (AlignedThis) {
4811 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4812 << 2 << E->getSourceRange();
4813 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
4814 << getOpenMPClauseName(OMPC_aligned);
4815 }
4816 AlignedThis = E;
4817 continue;
4818 }
4819 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4820 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4821 }
4822 // The optional parameter of the aligned clause, alignment, must be a constant
4823 // positive integer expression. If no optional parameter is specified,
4824 // implementation-defined default alignments for SIMD instructions on the
4825 // target platforms are assumed.
4826 SmallVector<const Expr *, 4> NewAligns;
4827 for (Expr *E : Alignments) {
4828 ExprResult Align;
4829 if (E)
4830 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
4831 NewAligns.push_back(Align.get());
4832 }
4833 // OpenMP [2.8.2, declare simd construct, Description]
4834 // The linear clause declares one or more list items to be private to a SIMD
4835 // lane and to have a linear relationship with respect to the iteration space
4836 // of a loop.
4837 // The special this pointer can be used as if was one of the arguments to the
4838 // function in any of the linear, aligned, or uniform clauses.
4839 // When a linear-step expression is specified in a linear clause it must be
4840 // either a constant integer expression or an integer-typed parameter that is
4841 // specified in a uniform clause on the directive.
4842 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
4843 const bool IsUniformedThis = UniformedLinearThis != nullptr;
4844 auto MI = LinModifiers.begin();
4845 for (const Expr *E : Linears) {
4846 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
4847 ++MI;
4848 E = E->IgnoreParenImpCasts();
4849 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4850 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4851 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
4852 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4853 FD->getParamDecl(PVD->getFunctionScopeIndex())
4854 ->getCanonicalDecl() == CanonPVD) {
4855 // OpenMP [2.15.3.7, linear Clause, Restrictions]
4856 // A list-item cannot appear in more than one linear clause.
4857 if (LinearArgs.count(CanonPVD) > 0) {
4858 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4859 << getOpenMPClauseName(OMPC_linear)
4860 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
4861 Diag(LinearArgs[CanonPVD]->getExprLoc(),
4862 diag::note_omp_explicit_dsa)
4863 << getOpenMPClauseName(OMPC_linear);
4864 continue;
4865 }
4866 // Each argument can appear in at most one uniform or linear clause.
4867 if (UniformedArgs.count(CanonPVD) > 0) {
4868 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4869 << getOpenMPClauseName(OMPC_linear)
4870 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
4871 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
4872 diag::note_omp_explicit_dsa)
4873 << getOpenMPClauseName(OMPC_uniform);
4874 continue;
4875 }
4876 LinearArgs[CanonPVD] = E;
4877 if (E->isValueDependent() || E->isTypeDependent() ||
4878 E->isInstantiationDependent() ||
4879 E->containsUnexpandedParameterPack())
4880 continue;
4881 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
4882 PVD->getOriginalType());
4883 continue;
4884 }
4885 }
4886 if (isa<CXXThisExpr>(E)) {
4887 if (UniformedLinearThis) {
4888 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4889 << getOpenMPClauseName(OMPC_linear)
4890 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
4891 << E->getSourceRange();
4892 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
4893 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
4894 : OMPC_linear);
4895 continue;
4896 }
4897 UniformedLinearThis = E;
4898 if (E->isValueDependent() || E->isTypeDependent() ||
4899 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
4900 continue;
4901 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
4902 E->getType());
4903 continue;
4904 }
4905 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4906 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4907 }
4908 Expr *Step = nullptr;
4909 Expr *NewStep = nullptr;
4910 SmallVector<Expr *, 4> NewSteps;
4911 for (Expr *E : Steps) {
4912 // Skip the same step expression, it was checked already.
4913 if (Step == E || !E) {
4914 NewSteps.push_back(E ? NewStep : nullptr);
4915 continue;
4916 }
4917 Step = E;
4918 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
4919 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4920 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
4921 if (UniformedArgs.count(CanonPVD) == 0) {
4922 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
4923 << Step->getSourceRange();
4924 } else if (E->isValueDependent() || E->isTypeDependent() ||
4925 E->isInstantiationDependent() ||
4926 E->containsUnexpandedParameterPack() ||
4927 CanonPVD->getType()->hasIntegerRepresentation()) {
4928 NewSteps.push_back(Step);
4929 } else {
4930 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
4931 << Step->getSourceRange();
4932 }
4933 continue;
4934 }
4935 NewStep = Step;
4936 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
4937 !Step->isInstantiationDependent() &&
4938 !Step->containsUnexpandedParameterPack()) {
4939 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
4940 .get();
4941 if (NewStep)
4942 NewStep = VerifyIntegerConstantExpression(NewStep).get();
4943 }
4944 NewSteps.push_back(NewStep);
4945 }
4946 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
4947 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
4948 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
4949 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
4950 const_cast<Expr **>(Linears.data()), Linears.size(),
4951 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
4952 NewSteps.data(), NewSteps.size(), SR);
4953 ADecl->addAttr(NewAttr);
4954 return DG;
4955 }
4956
4957 Optional<std::pair<FunctionDecl *, Expr *>>
4958 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
4959 Expr *VariantRef, SourceRange SR) {
4960 if (!DG || DG.get().isNull())
4961 return None;
4962
4963 const int VariantId = 1;
4964 // Must be applied only to single decl.
4965 if (!DG.get().isSingleDecl()) {
4966 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
4967 << VariantId << SR;
4968 return None;
4969 }
4970 Decl *ADecl = DG.get().getSingleDecl();
4971 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
4972 ADecl = FTD->getTemplatedDecl();
4973
4974 // Decl must be a function.
4975 auto *FD = dyn_cast<FunctionDecl>(ADecl);
4976 if (!FD) {
4977 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
4978 << VariantId << SR;
4979 return None;
4980 }
4981
4982 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
4983 return FD->hasAttrs() &&
4984 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
4985 FD->hasAttr<TargetAttr>());
4986 };
4987 // OpenMP is not compatible with CPU-specific attributes.
4988 if (HasMultiVersionAttributes(FD)) {
4989 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
4990 << SR;
4991 return None;
4992 }
4993
4994 // Allow #pragma omp declare variant only if the function is not used.
4995 if (FD->isUsed(false))
4996 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
4997 << FD->getLocation();
4998
4999 // Check if the function was emitted already.
5000 const FunctionDecl *Definition;
5001 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
5002 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
5003 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
5004 << FD->getLocation();
5005
5006 // The VariantRef must point to function.
5007 if (!VariantRef) {
5008 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
5009 return None;
5010 }
5011
5012 // Do not check templates, wait until instantiation.
5013 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() ||
5014 VariantRef->containsUnexpandedParameterPack() ||
5015 VariantRef->isInstantiationDependent() || FD->isDependentContext())
5016 return std::make_pair(FD, VariantRef);
5017
5018 // Convert VariantRef expression to the type of the original function to
5019 // resolve possible conflicts.
5020 ExprResult VariantRefCast;
5021 if (LangOpts.CPlusPlus) {
5022 QualType FnPtrType;
5023 auto *Method = dyn_cast<CXXMethodDecl>(FD);
5024 if (Method && !Method->isStatic()) {
5025 const Type *ClassType =
5026 Context.getTypeDeclType(Method->getParent()).getTypePtr();
5027 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
5028 ExprResult ER;
5029 {
5030 // Build adrr_of unary op to correctly handle type checks for member
5031 // functions.
5032 Sema::TentativeAnalysisScope Trap(*this);
5033 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
5034 VariantRef);
5035 }
5036 if (!ER.isUsable()) {
5037 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5038 << VariantId << VariantRef->getSourceRange();
5039 return None;
5040 }
5041 VariantRef = ER.get();
5042 } else {
5043 FnPtrType = Context.getPointerType(FD->getType());
5044 }
5045 ImplicitConversionSequence ICS =
5046 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
5047 /*SuppressUserConversions=*/false,
5048 /*AllowExplicit=*/false,
5049 /*InOverloadResolution=*/false,
5050 /*CStyle=*/false,
5051 /*AllowObjCWritebackConversion=*/false);
5052 if (ICS.isFailure()) {
5053 Diag(VariantRef->getExprLoc(),
5054 diag::err_omp_declare_variant_incompat_types)
5055 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange();
5056 return None;
5057 }
5058 VariantRefCast = PerformImplicitConversion(
5059 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
5060 if (!VariantRefCast.isUsable())
5061 return None;
5062 // Drop previously built artificial addr_of unary op for member functions.
5063 if (Method && !Method->isStatic()) {
5064 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
5065 if (auto *UO = dyn_cast<UnaryOperator>(
5066 PossibleAddrOfVariantRef->IgnoreImplicit()))
5067 VariantRefCast = UO->getSubExpr();
5068 }
5069 } else {
5070 VariantRefCast = VariantRef;
5071 }
5072
5073 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
5074 if (!ER.isUsable() ||
5075 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
5076 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5077 << VariantId << VariantRef->getSourceRange();
5078 return None;
5079 }
5080
5081 // The VariantRef must point to function.
5082 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
5083 if (!DRE) {
5084 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5085 << VariantId << VariantRef->getSourceRange();
5086 return None;
5087 }
5088 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
5089 if (!NewFD) {
5090 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5091 << VariantId << VariantRef->getSourceRange();
5092 return None;
5093 }
5094
5095 // Check if variant function is not marked with declare variant directive.
5096 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
5097 Diag(VariantRef->getExprLoc(),
5098 diag::warn_omp_declare_variant_marked_as_declare_variant)
5099 << VariantRef->getSourceRange();
5100 SourceRange SR =
5101 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
5102 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
5103 return None;
5104 }
5105
5106 enum DoesntSupport {
5107 VirtFuncs = 1,
5108 Constructors = 3,
5109 Destructors = 4,
5110 DeletedFuncs = 5,
5111 DefaultedFuncs = 6,
5112 ConstexprFuncs = 7,
5113 ConstevalFuncs = 8,
5114 };
5115 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
5116 if (CXXFD->isVirtual()) {
5117 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5118 << VirtFuncs;
5119 return None;
5120 }
5121
5122 if (isa<CXXConstructorDecl>(FD)) {
5123 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5124 << Constructors;
5125 return None;
5126 }
5127
5128 if (isa<CXXDestructorDecl>(FD)) {
5129 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5130 << Destructors;
5131 return None;
5132 }
5133 }
5134
5135 if (FD->isDeleted()) {
5136 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5137 << DeletedFuncs;
5138 return None;
5139 }
5140
5141 if (FD->isDefaulted()) {
5142 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5143 << DefaultedFuncs;
5144 return None;
5145 }
5146
5147 if (FD->isConstexpr()) {
5148 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5149 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
5150 return None;
5151 }
5152
5153 // Check general compatibility.
5154 if (areMultiversionVariantFunctionsCompatible(
5155 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto),
5156 PartialDiagnosticAt(
5157 SR.getBegin(),
5158 PDiag(diag::note_omp_declare_variant_specified_here) << SR),
5159 PartialDiagnosticAt(
5160 VariantRef->getExprLoc(),
5161 PDiag(diag::err_omp_declare_variant_doesnt_support)),
5162 PartialDiagnosticAt(VariantRef->getExprLoc(),
5163 PDiag(diag::err_omp_declare_variant_diff)
5164 << FD->getLocation()),
5165 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
5166 /*CLinkageMayDiffer=*/true))
5167 return None;
5168 return std::make_pair(FD, cast<Expr>(DRE));
5169 }
5170
5171 void Sema::ActOnOpenMPDeclareVariantDirective(
5172 FunctionDecl *FD, Expr *VariantRef, SourceRange SR,
5173 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
5174 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown ||
5175 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown)
5176 return;
5177 Expr *Score = nullptr;
5178 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown;
5179 if (Data.CtxScore.isUsable()) {
5180 ST = OMPDeclareVariantAttr::ScoreSpecified;
5181 Score = Data.CtxScore.get();
5182 if (!Score->isTypeDependent() && !Score->isValueDependent() &&
5183 !Score->isInstantiationDependent() &&
5184 !Score->containsUnexpandedParameterPack()) {
5185 llvm::APSInt Result;
5186 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result);
5187 if (ICE.isInvalid())
5188 return;
5189 }
5190 }
5191 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
5192 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx,
5193 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR);
5194 FD->addAttr(NewAttr);
5195 }
5196
5197 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc,
5198 FunctionDecl *Func,
5199 bool MightBeOdrUse) {
5200 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
5201
5202 if (!Func->isDependentContext() && Func->hasAttrs()) {
5203 for (OMPDeclareVariantAttr *A :
5204 Func->specific_attrs<OMPDeclareVariantAttr>()) {
5205 // TODO: add checks for active OpenMP context where possible.
5206 Expr *VariantRef = A->getVariantFuncRef();
5207 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts());
5208 auto *F = cast<FunctionDecl>(DRE->getDecl());
5209 if (!F->isDefined() && F->isTemplateInstantiation())
5210 InstantiateFunctionDefinition(Loc, F->getFirstDecl());
5211 MarkFunctionReferenced(Loc, F, MightBeOdrUse);
5212 }
5213 }
5214 }
5215
5216 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
5217 Stmt *AStmt,
5218 SourceLocation StartLoc,
5219 SourceLocation EndLoc) {
5220 if (!AStmt)
5221 return StmtError();
5222
5223 auto *CS = cast<CapturedStmt>(AStmt);
5224 // 1.2.2 OpenMP Language Terminology
5225 // Structured block - An executable statement with a single entry at the
5226 // top and a single exit at the bottom.
5227 // The point of exit cannot be a branch out of the structured block.
5228 // longjmp() and throw() must not violate the entry/exit criteria.
5229 CS->getCapturedDecl()->setNothrow();
5230
5231 setFunctionHasBranchProtectedScope();
5232
5233 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5234 DSAStack->isCancelRegion());
5235 }
5236
5237 namespace {
5238 /// Iteration space of a single for loop.
5239 struct LoopIterationSpace final {
5240 /// True if the condition operator is the strict compare operator (<, > or
5241 /// !=).
5242 bool IsStrictCompare = false;
5243 /// Condition of the loop.
5244 Expr *PreCond = nullptr;
5245 /// This expression calculates the number of iterations in the loop.
5246 /// It is always possible to calculate it before starting the loop.
5247 Expr *NumIterations = nullptr;
5248 /// The loop counter variable.
5249 Expr *CounterVar = nullptr;
5250 /// Private loop counter variable.
5251 Expr *PrivateCounterVar = nullptr;
5252 /// This is initializer for the initial value of #CounterVar.
5253 Expr *CounterInit = nullptr;
5254 /// This is step for the #CounterVar used to generate its update:
5255 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
5256 Expr *CounterStep = nullptr;
5257 /// Should step be subtracted?
5258 bool Subtract = false;
5259 /// Source range of the loop init.
5260 SourceRange InitSrcRange;
5261 /// Source range of the loop condition.
5262 SourceRange CondSrcRange;
5263 /// Source range of the loop increment.
5264 SourceRange IncSrcRange;
5265 /// Minimum value that can have the loop control variable. Used to support
5266 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
5267 /// since only such variables can be used in non-loop invariant expressions.
5268 Expr *MinValue = nullptr;
5269 /// Maximum value that can have the loop control variable. Used to support
5270 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
5271 /// since only such variables can be used in non-loop invariant expressions.
5272 Expr *MaxValue = nullptr;
5273 /// true, if the lower bound depends on the outer loop control var.
5274 bool IsNonRectangularLB = false;
5275 /// true, if the upper bound depends on the outer loop control var.
5276 bool IsNonRectangularUB = false;
5277 /// Index of the loop this loop depends on and forms non-rectangular loop
5278 /// nest.
5279 unsigned LoopDependentIdx = 0;
5280 /// Final condition for the non-rectangular loop nest support. It is used to
5281 /// check that the number of iterations for this particular counter must be
5282 /// finished.
5283 Expr *FinalCondition = nullptr;
5284 };
5285
5286 /// Helper class for checking canonical form of the OpenMP loops and
5287 /// extracting iteration space of each loop in the loop nest, that will be used
5288 /// for IR generation.
5289 class OpenMPIterationSpaceChecker {
5290 /// Reference to Sema.
5291 Sema &SemaRef;
5292 /// Data-sharing stack.
5293 DSAStackTy &Stack;
5294 /// A location for diagnostics (when there is no some better location).
5295 SourceLocation DefaultLoc;
5296 /// A location for diagnostics (when increment is not compatible).
5297 SourceLocation ConditionLoc;
5298 /// A source location for referring to loop init later.
5299 SourceRange InitSrcRange;
5300 /// A source location for referring to condition later.
5301 SourceRange ConditionSrcRange;
5302 /// A source location for referring to increment later.
5303 SourceRange IncrementSrcRange;
5304 /// Loop variable.
5305 ValueDecl *LCDecl = nullptr;
5306 /// Reference to loop variable.
5307 Expr *LCRef = nullptr;
5308 /// Lower bound (initializer for the var).
5309 Expr *LB = nullptr;
5310 /// Upper bound.
5311 Expr *UB = nullptr;
5312 /// Loop step (increment).
5313 Expr *Step = nullptr;
5314 /// This flag is true when condition is one of:
5315 /// Var < UB
5316 /// Var <= UB
5317 /// UB > Var
5318 /// UB >= Var
5319 /// This will have no value when the condition is !=
5320 llvm::Optional<bool> TestIsLessOp;
5321 /// This flag is true when condition is strict ( < or > ).
5322 bool TestIsStrictOp = false;
5323 /// This flag is true when step is subtracted on each iteration.
5324 bool SubtractStep = false;
5325 /// The outer loop counter this loop depends on (if any).
5326 const ValueDecl *DepDecl = nullptr;
5327 /// Contains number of loop (starts from 1) on which loop counter init
5328 /// expression of this loop depends on.
5329 Optional<unsigned> InitDependOnLC;
5330 /// Contains number of loop (starts from 1) on which loop counter condition
5331 /// expression of this loop depends on.
5332 Optional<unsigned> CondDependOnLC;
5333 /// Checks if the provide statement depends on the loop counter.
5334 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
5335 /// Original condition required for checking of the exit condition for
5336 /// non-rectangular loop.
5337 Expr *Condition = nullptr;
5338
5339 public:
5340 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
5341 SourceLocation DefaultLoc)
5342 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
5343 ConditionLoc(DefaultLoc) {}
5344 /// Check init-expr for canonical loop form and save loop counter
5345 /// variable - #Var and its initialization value - #LB.
5346 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
5347 /// Check test-expr for canonical form, save upper-bound (#UB), flags
5348 /// for less/greater and for strict/non-strict comparison.
5349 bool checkAndSetCond(Expr *S);
5350 /// Check incr-expr for canonical loop form and return true if it
5351 /// does not conform, otherwise save loop step (#Step).
5352 bool checkAndSetInc(Expr *S);
5353 /// Return the loop counter variable.
5354 ValueDecl *getLoopDecl() const { return LCDecl; }
5355 /// Return the reference expression to loop counter variable.
5356 Expr *getLoopDeclRefExpr() const { return LCRef; }
5357 /// Source range of the loop init.
5358 SourceRange getInitSrcRange() const { return InitSrcRange; }
5359 /// Source range of the loop condition.
5360 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
5361 /// Source range of the loop increment.
5362 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
5363 /// True if the step should be subtracted.
5364 bool shouldSubtractStep() const { return SubtractStep; }
5365 /// True, if the compare operator is strict (<, > or !=).
5366 bool isStrictTestOp() const { return TestIsStrictOp; }
5367 /// Build the expression to calculate the number of iterations.
5368 Expr *buildNumIterations(
5369 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
5370 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5371 /// Build the precondition expression for the loops.
5372 Expr *
5373 buildPreCond(Scope *S, Expr *Cond,
5374 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5375 /// Build reference expression to the counter be used for codegen.
5376 DeclRefExpr *
5377 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5378 DSAStackTy &DSA) const;
5379 /// Build reference expression to the private counter be used for
5380 /// codegen.
5381 Expr *buildPrivateCounterVar() const;
5382 /// Build initialization of the counter be used for codegen.
5383 Expr *buildCounterInit() const;
5384 /// Build step of the counter be used for codegen.
5385 Expr *buildCounterStep() const;
5386 /// Build loop data with counter value for depend clauses in ordered
5387 /// directives.
5388 Expr *
5389 buildOrderedLoopData(Scope *S, Expr *Counter,
5390 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5391 SourceLocation Loc, Expr *Inc = nullptr,
5392 OverloadedOperatorKind OOK = OO_Amp);
5393 /// Builds the minimum value for the loop counter.
5394 std::pair<Expr *, Expr *> buildMinMaxValues(
5395 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5396 /// Builds final condition for the non-rectangular loops.
5397 Expr *buildFinalCondition(Scope *S) const;
5398 /// Return true if any expression is dependent.
5399 bool dependent() const;
5400 /// Returns true if the initializer forms non-rectangular loop.
5401 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
5402 /// Returns true if the condition forms non-rectangular loop.
5403 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
5404 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
5405 unsigned getLoopDependentIdx() const {
5406 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
5407 }
5408
5409 private:
5410 /// Check the right-hand side of an assignment in the increment
5411 /// expression.
5412 bool checkAndSetIncRHS(Expr *RHS);
5413 /// Helper to set loop counter variable and its initializer.
5414 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
5415 bool EmitDiags);
5416 /// Helper to set upper bound.
5417 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
5418 SourceRange SR, SourceLocation SL);
5419 /// Helper to set loop increment.
5420 bool setStep(Expr *NewStep, bool Subtract);
5421 };
5422
5423 bool OpenMPIterationSpaceChecker::dependent() const {
5424 if (!LCDecl) {
5425 assert(!LB && !UB && !Step);
5426 return false;
5427 }
5428 return LCDecl->getType()->isDependentType() ||
5429 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
5430 (Step && Step->isValueDependent());
5431 }
5432
5433 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
5434 Expr *NewLCRefExpr,
5435 Expr *NewLB, bool EmitDiags) {
5436 // State consistency checking to ensure correct usage.
5437 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
5438 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
5439 if (!NewLCDecl || !NewLB)
5440 return true;
5441 LCDecl = getCanonicalDecl(NewLCDecl);
5442 LCRef = NewLCRefExpr;
5443 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
5444 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
5445 if ((Ctor->isCopyOrMoveConstructor() ||
5446 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
5447 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
5448 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
5449 LB = NewLB;
5450 if (EmitDiags)
5451 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
5452 return false;
5453 }
5454
5455 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
5456 llvm::Optional<bool> LessOp,
5457 bool StrictOp, SourceRange SR,
5458 SourceLocation SL) {
5459 // State consistency checking to ensure correct usage.
5460 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
5461 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
5462 if (!NewUB)
5463 return true;
5464 UB = NewUB;
5465 if (LessOp)
5466 TestIsLessOp = LessOp;
5467 TestIsStrictOp = StrictOp;
5468 ConditionSrcRange = SR;
5469 ConditionLoc = SL;
5470 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
5471 return false;
5472 }
5473
5474 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
5475 // State consistency checking to ensure correct usage.
5476 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
5477 if (!NewStep)
5478 return true;
5479 if (!NewStep->isValueDependent()) {
5480 // Check that the step is integer expression.
5481 SourceLocation StepLoc = NewStep->getBeginLoc();
5482 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
5483 StepLoc, getExprAsWritten(NewStep));
5484 if (Val.isInvalid())
5485 return true;
5486 NewStep = Val.get();
5487
5488 // OpenMP [2.6, Canonical Loop Form, Restrictions]
5489 // If test-expr is of form var relational-op b and relational-op is < or
5490 // <= then incr-expr must cause var to increase on each iteration of the
5491 // loop. If test-expr is of form var relational-op b and relational-op is
5492 // > or >= then incr-expr must cause var to decrease on each iteration of
5493 // the loop.
5494 // If test-expr is of form b relational-op var and relational-op is < or
5495 // <= then incr-expr must cause var to decrease on each iteration of the
5496 // loop. If test-expr is of form b relational-op var and relational-op is
5497 // > or >= then incr-expr must cause var to increase on each iteration of
5498 // the loop.
5499 llvm::APSInt Result;
5500 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
5501 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
5502 bool IsConstNeg =
5503 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
5504 bool IsConstPos =
5505 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
5506 bool IsConstZero = IsConstant && !Result.getBoolValue();
5507
5508 // != with increment is treated as <; != with decrement is treated as >
5509 if (!TestIsLessOp.hasValue())
5510 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
5511 if (UB && (IsConstZero ||
5512 (TestIsLessOp.getValue() ?
5513 (IsConstNeg || (IsUnsigned && Subtract)) :
5514 (IsConstPos || (IsUnsigned && !Subtract))))) {
5515 SemaRef.Diag(NewStep->getExprLoc(),
5516 diag::err_omp_loop_incr_not_compatible)
5517 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
5518 SemaRef.Diag(ConditionLoc,
5519 diag::note_omp_loop_cond_requres_compatible_incr)
5520 << TestIsLessOp.getValue() << ConditionSrcRange;
5521 return true;
5522 }
5523 if (TestIsLessOp.getValue() == Subtract) {
5524 NewStep =
5525 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
5526 .get();
5527 Subtract = !Subtract;
5528 }
5529 }
5530
5531 Step = NewStep;
5532 SubtractStep = Subtract;
5533 return false;
5534 }
5535
5536 namespace {
5537 /// Checker for the non-rectangular loops. Checks if the initializer or
5538 /// condition expression references loop counter variable.
5539 class LoopCounterRefChecker final
5540 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
5541 Sema &SemaRef;
5542 DSAStackTy &Stack;
5543 const ValueDecl *CurLCDecl = nullptr;
5544 const ValueDecl *DepDecl = nullptr;
5545 const ValueDecl *PrevDepDecl = nullptr;
5546 bool IsInitializer = true;
5547 unsigned BaseLoopId = 0;
5548 bool checkDecl(const Expr *E, const ValueDecl *VD) {
5549 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
5550 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
5551 << (IsInitializer ? 0 : 1);
5552 return false;
5553 }
5554 const auto &&Data = Stack.isLoopControlVariable(VD);
5555 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
5556 // The type of the loop iterator on which we depend may not have a random
5557 // access iterator type.
5558 if (Data.first && VD->getType()->isRecordType()) {
5559 SmallString<128> Name;
5560 llvm::raw_svector_ostream OS(Name);
5561 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
5562 /*Qualified=*/true);
5563 SemaRef.Diag(E->getExprLoc(),
5564 diag::err_omp_wrong_dependency_iterator_type)
5565 << OS.str();
5566 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
5567 return false;
5568 }
5569 if (Data.first &&
5570 (DepDecl || (PrevDepDecl &&
5571 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
5572 if (!DepDecl && PrevDepDecl)
5573 DepDecl = PrevDepDecl;
5574 SmallString<128> Name;
5575 llvm::raw_svector_ostream OS(Name);
5576 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
5577 /*Qualified=*/true);
5578 SemaRef.Diag(E->getExprLoc(),
5579 diag::err_omp_invariant_or_linear_dependency)
5580 << OS.str();
5581 return false;
5582 }
5583 if (Data.first) {
5584 DepDecl = VD;
5585 BaseLoopId = Data.first;
5586 }
5587 return Data.first;
5588 }
5589
5590 public:
5591 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5592 const ValueDecl *VD = E->getDecl();
5593 if (isa<VarDecl>(VD))
5594 return checkDecl(E, VD);
5595 return false;
5596 }
5597 bool VisitMemberExpr(const MemberExpr *E) {
5598 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
5599 const ValueDecl *VD = E->getMemberDecl();
5600 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
5601 return checkDecl(E, VD);
5602 }
5603 return false;
5604 }
5605 bool VisitStmt(const Stmt *S) {
5606 bool Res = false;
5607 for (const Stmt *Child : S->children())
5608 Res = (Child && Visit(Child)) || Res;
5609 return Res;
5610 }
5611 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
5612 const ValueDecl *CurLCDecl, bool IsInitializer,
5613 const ValueDecl *PrevDepDecl = nullptr)
5614 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
5615 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
5616 unsigned getBaseLoopId() const {
5617 assert(CurLCDecl && "Expected loop dependency.");
5618 return BaseLoopId;
5619 }
5620 const ValueDecl *getDepDecl() const {
5621 assert(CurLCDecl && "Expected loop dependency.");
5622 return DepDecl;
5623 }
5624 };
5625 } // namespace
5626
5627 Optional<unsigned>
5628 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
5629 bool IsInitializer) {
5630 // Check for the non-rectangular loops.
5631 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
5632 DepDecl);
5633 if (LoopStmtChecker.Visit(S)) {
5634 DepDecl = LoopStmtChecker.getDepDecl();
5635 return LoopStmtChecker.getBaseLoopId();
5636 }
5637 return llvm::None;
5638 }
5639
5640 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
5641 // Check init-expr for canonical loop form and save loop counter
5642 // variable - #Var and its initialization value - #LB.
5643 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
5644 // var = lb
5645 // integer-type var = lb
5646 // random-access-iterator-type var = lb
5647 // pointer-type var = lb
5648 //
5649 if (!S) {
5650 if (EmitDiags) {
5651 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
5652 }
5653 return true;
5654 }
5655 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
5656 if (!ExprTemp->cleanupsHaveSideEffects())
5657 S = ExprTemp->getSubExpr();
5658
5659 InitSrcRange = S->getSourceRange();
5660 if (Expr *E = dyn_cast<Expr>(S))
5661 S = E->IgnoreParens();
5662 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
5663 if (BO->getOpcode() == BO_Assign) {
5664 Expr *LHS = BO->getLHS()->IgnoreParens();
5665 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
5666 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
5667 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
5668 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5669 EmitDiags);
5670 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
5671 }
5672 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
5673 if (ME->isArrow() &&
5674 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5675 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5676 EmitDiags);
5677 }
5678 }
5679 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
5680 if (DS->isSingleDecl()) {
5681 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
5682 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
5683 // Accept non-canonical init form here but emit ext. warning.
5684 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
5685 SemaRef.Diag(S->getBeginLoc(),
5686 diag::ext_omp_loop_not_canonical_init)
5687 << S->getSourceRange();
5688 return setLCDeclAndLB(
5689 Var,
5690 buildDeclRefExpr(SemaRef, Var,
5691 Var->getType().getNonReferenceType(),
5692 DS->getBeginLoc()),
5693 Var->getInit(), EmitDiags);
5694 }
5695 }
5696 }
5697 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
5698 if (CE->getOperator() == OO_Equal) {
5699 Expr *LHS = CE->getArg(0);
5700 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
5701 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
5702 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
5703 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5704 EmitDiags);
5705 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
5706 }
5707 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
5708 if (ME->isArrow() &&
5709 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5710 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5711 EmitDiags);
5712 }
5713 }
5714 }
5715
5716 if (dependent() || SemaRef.CurContext->isDependentContext())
5717 return false;
5718 if (EmitDiags) {
5719 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
5720 << S->getSourceRange();
5721 }
5722 return true;
5723 }
5724
5725 /// Ignore parenthesizes, implicit casts, copy constructor and return the
5726 /// variable (which may be the loop variable) if possible.
5727 static const ValueDecl *getInitLCDecl(const Expr *E) {
5728 if (!E)
5729 return nullptr;
5730 E = getExprAsWritten(E);
5731 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
5732 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
5733 if ((Ctor->isCopyOrMoveConstructor() ||
5734 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
5735 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
5736 E = CE->getArg(0)->IgnoreParenImpCasts();
5737 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
5738 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
5739 return getCanonicalDecl(VD);
5740 }
5741 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
5742 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5743 return getCanonicalDecl(ME->getMemberDecl());
5744 return nullptr;
5745 }
5746
5747 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
5748 // Check test-expr for canonical form, save upper-bound UB, flags for
5749 // less/greater and for strict/non-strict comparison.
5750 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
5751 // var relational-op b
5752 // b relational-op var
5753 //
5754 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
5755 if (!S) {
5756 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
5757 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
5758 return true;
5759 }
5760 Condition = S;
5761 S = getExprAsWritten(S);
5762 SourceLocation CondLoc = S->getBeginLoc();
5763 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
5764 if (BO->isRelationalOp()) {
5765 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5766 return setUB(BO->getRHS(),
5767 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
5768 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5769 BO->getSourceRange(), BO->getOperatorLoc());
5770 if (getInitLCDecl(BO->getRHS()) == LCDecl)
5771 return setUB(BO->getLHS(),
5772 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
5773 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5774 BO->getSourceRange(), BO->getOperatorLoc());
5775 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
5776 return setUB(
5777 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
5778 /*LessOp=*/llvm::None,
5779 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
5780 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
5781 if (CE->getNumArgs() == 2) {
5782 auto Op = CE->getOperator();
5783 switch (Op) {
5784 case OO_Greater:
5785 case OO_GreaterEqual:
5786 case OO_Less:
5787 case OO_LessEqual:
5788 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5789 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
5790 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5791 CE->getOperatorLoc());
5792 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
5793 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
5794 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5795 CE->getOperatorLoc());
5796 break;
5797 case OO_ExclaimEqual:
5798 if (IneqCondIsCanonical)
5799 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
5800 : CE->getArg(0),
5801 /*LessOp=*/llvm::None,
5802 /*StrictOp=*/true, CE->getSourceRange(),
5803 CE->getOperatorLoc());
5804 break;
5805 default:
5806 break;
5807 }
5808 }
5809 }
5810 if (dependent() || SemaRef.CurContext->isDependentContext())
5811 return false;
5812 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
5813 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
5814 return true;
5815 }
5816
5817 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
5818 // RHS of canonical loop form increment can be:
5819 // var + incr
5820 // incr + var
5821 // var - incr
5822 //
5823 RHS = RHS->IgnoreParenImpCasts();
5824 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
5825 if (BO->isAdditiveOp()) {
5826 bool IsAdd = BO->getOpcode() == BO_Add;
5827 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5828 return setStep(BO->getRHS(), !IsAdd);
5829 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
5830 return setStep(BO->getLHS(), /*Subtract=*/false);
5831 }
5832 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
5833 bool IsAdd = CE->getOperator() == OO_Plus;
5834 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
5835 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5836 return setStep(CE->getArg(1), !IsAdd);
5837 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
5838 return setStep(CE->getArg(0), /*Subtract=*/false);
5839 }
5840 }
5841 if (dependent() || SemaRef.CurContext->isDependentContext())
5842 return false;
5843 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
5844 << RHS->getSourceRange() << LCDecl;
5845 return true;
5846 }
5847
5848 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
5849 // Check incr-expr for canonical loop form and return true if it
5850 // does not conform.
5851 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
5852 // ++var
5853 // var++
5854 // --var
5855 // var--
5856 // var += incr
5857 // var -= incr
5858 // var = var + incr
5859 // var = incr + var
5860 // var = var - incr
5861 //
5862 if (!S) {
5863 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
5864 return true;
5865 }
5866 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
5867 if (!ExprTemp->cleanupsHaveSideEffects())
5868 S = ExprTemp->getSubExpr();
5869
5870 IncrementSrcRange = S->getSourceRange();
5871 S = S->IgnoreParens();
5872 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
5873 if (UO->isIncrementDecrementOp() &&
5874 getInitLCDecl(UO->getSubExpr()) == LCDecl)
5875 return setStep(SemaRef
5876 .ActOnIntegerConstant(UO->getBeginLoc(),
5877 (UO->isDecrementOp() ? -1 : 1))
5878 .get(),
5879 /*Subtract=*/false);
5880 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
5881 switch (BO->getOpcode()) {
5882 case BO_AddAssign:
5883 case BO_SubAssign:
5884 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5885 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
5886 break;
5887 case BO_Assign:
5888 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5889 return checkAndSetIncRHS(BO->getRHS());
5890 break;
5891 default:
5892 break;
5893 }
5894 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
5895 switch (CE->getOperator()) {
5896 case OO_PlusPlus:
5897 case OO_MinusMinus:
5898 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5899 return setStep(SemaRef
5900 .ActOnIntegerConstant(
5901 CE->getBeginLoc(),
5902 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
5903 .get(),
5904 /*Subtract=*/false);
5905 break;
5906 case OO_PlusEqual:
5907 case OO_MinusEqual:
5908 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5909 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
5910 break;
5911 case OO_Equal:
5912 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5913 return checkAndSetIncRHS(CE->getArg(1));
5914 break;
5915 default:
5916 break;
5917 }
5918 }
5919 if (dependent() || SemaRef.CurContext->isDependentContext())
5920 return false;
5921 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
5922 << S->getSourceRange() << LCDecl;
5923 return true;
5924 }
5925
5926 static ExprResult
5927 tryBuildCapture(Sema &SemaRef, Expr *Capture,
5928 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5929 if (SemaRef.CurContext->isDependentContext())
5930 return ExprResult(Capture);
5931 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
5932 return SemaRef.PerformImplicitConversion(
5933 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
5934 /*AllowExplicit=*/true);
5935 auto I = Captures.find(Capture);
5936 if (I != Captures.end())
5937 return buildCapture(SemaRef, Capture, I->second);
5938 DeclRefExpr *Ref = nullptr;
5939 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
5940 Captures[Capture] = Ref;
5941 return Res;
5942 }
5943
5944 /// Build the expression to calculate the number of iterations.
5945 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
5946 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
5947 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
5948 ExprResult Diff;
5949 QualType VarType = LCDecl->getType().getNonReferenceType();
5950 if (VarType->isIntegerType() || VarType->isPointerType() ||
5951 SemaRef.getLangOpts().CPlusPlus) {
5952 Expr *LBVal = LB;
5953 Expr *UBVal = UB;
5954 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
5955 // max(LB(MinVal), LB(MaxVal))
5956 if (InitDependOnLC) {
5957 const LoopIterationSpace &IS =
5958 ResultIterSpaces[ResultIterSpaces.size() - 1 -
5959 InitDependOnLC.getValueOr(
5960 CondDependOnLC.getValueOr(0))];
5961 if (!IS.MinValue || !IS.MaxValue)
5962 return nullptr;
5963 // OuterVar = Min
5964 ExprResult MinValue =
5965 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
5966 if (!MinValue.isUsable())
5967 return nullptr;
5968
5969 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
5970 IS.CounterVar, MinValue.get());
5971 if (!LBMinVal.isUsable())
5972 return nullptr;
5973 // OuterVar = Min, LBVal
5974 LBMinVal =
5975 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
5976 if (!LBMinVal.isUsable())
5977 return nullptr;
5978 // (OuterVar = Min, LBVal)
5979 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
5980 if (!LBMinVal.isUsable())
5981 return nullptr;
5982
5983 // OuterVar = Max
5984 ExprResult MaxValue =
5985 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
5986 if (!MaxValue.isUsable())
5987 return nullptr;
5988
5989 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
5990 IS.CounterVar, MaxValue.get());
5991 if (!LBMaxVal.isUsable())
5992 return nullptr;
5993 // OuterVar = Max, LBVal
5994 LBMaxVal =
5995 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
5996 if (!LBMaxVal.isUsable())
5997 return nullptr;
5998 // (OuterVar = Max, LBVal)
5999 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
6000 if (!LBMaxVal.isUsable())
6001 return nullptr;
6002
6003 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
6004 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
6005 if (!LBMin || !LBMax)
6006 return nullptr;
6007 // LB(MinVal) < LB(MaxVal)
6008 ExprResult MinLessMaxRes =
6009 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
6010 if (!MinLessMaxRes.isUsable())
6011 return nullptr;
6012 Expr *MinLessMax =
6013 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
6014 if (!MinLessMax)
6015 return nullptr;
6016 if (TestIsLessOp.getValue()) {
6017 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
6018 // LB(MaxVal))
6019 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6020 MinLessMax, LBMin, LBMax);
6021 if (!MinLB.isUsable())
6022 return nullptr;
6023 LBVal = MinLB.get();
6024 } else {
6025 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
6026 // LB(MaxVal))
6027 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6028 MinLessMax, LBMax, LBMin);
6029 if (!MaxLB.isUsable())
6030 return nullptr;
6031 LBVal = MaxLB.get();
6032 }
6033 }
6034 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
6035 // min(UB(MinVal), UB(MaxVal))
6036 if (CondDependOnLC) {
6037 const LoopIterationSpace &IS =
6038 ResultIterSpaces[ResultIterSpaces.size() - 1 -
6039 InitDependOnLC.getValueOr(
6040 CondDependOnLC.getValueOr(0))];
6041 if (!IS.MinValue || !IS.MaxValue)
6042 return nullptr;
6043 // OuterVar = Min
6044 ExprResult MinValue =
6045 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
6046 if (!MinValue.isUsable())
6047 return nullptr;
6048
6049 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6050 IS.CounterVar, MinValue.get());
6051 if (!UBMinVal.isUsable())
6052 return nullptr;
6053 // OuterVar = Min, UBVal
6054 UBMinVal =
6055 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
6056 if (!UBMinVal.isUsable())
6057 return nullptr;
6058 // (OuterVar = Min, UBVal)
6059 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
6060 if (!UBMinVal.isUsable())
6061 return nullptr;
6062
6063 // OuterVar = Max
6064 ExprResult MaxValue =
6065 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
6066 if (!MaxValue.isUsable())
6067 return nullptr;
6068
6069 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6070 IS.CounterVar, MaxValue.get());
6071 if (!UBMaxVal.isUsable())
6072 return nullptr;
6073 // OuterVar = Max, UBVal
6074 UBMaxVal =
6075 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
6076 if (!UBMaxVal.isUsable())
6077 return nullptr;
6078 // (OuterVar = Max, UBVal)
6079 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
6080 if (!UBMaxVal.isUsable())
6081 return nullptr;
6082
6083 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
6084 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
6085 if (!UBMin || !UBMax)
6086 return nullptr;
6087 // UB(MinVal) > UB(MaxVal)
6088 ExprResult MinGreaterMaxRes =
6089 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
6090 if (!MinGreaterMaxRes.isUsable())
6091 return nullptr;
6092 Expr *MinGreaterMax =
6093 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
6094 if (!MinGreaterMax)
6095 return nullptr;
6096 if (TestIsLessOp.getValue()) {
6097 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
6098 // UB(MaxVal))
6099 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
6100 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
6101 if (!MaxUB.isUsable())
6102 return nullptr;
6103 UBVal = MaxUB.get();
6104 } else {
6105 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
6106 // UB(MaxVal))
6107 ExprResult MinUB = SemaRef.ActOnConditionalOp(
6108 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
6109 if (!MinUB.isUsable())
6110 return nullptr;
6111 UBVal = MinUB.get();
6112 }
6113 }
6114 // Upper - Lower
6115 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
6116 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
6117 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
6118 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
6119 if (!Upper || !Lower)
6120 return nullptr;
6121
6122 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6123
6124 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
6125 // BuildBinOp already emitted error, this one is to point user to upper
6126 // and lower bound, and to tell what is passed to 'operator-'.
6127 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
6128 << Upper->getSourceRange() << Lower->getSourceRange();
6129 return nullptr;
6130 }
6131 }
6132
6133 if (!Diff.isUsable())
6134 return nullptr;
6135
6136 // Upper - Lower [- 1]
6137 if (TestIsStrictOp)
6138 Diff = SemaRef.BuildBinOp(
6139 S, DefaultLoc, BO_Sub, Diff.get(),
6140 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6141 if (!Diff.isUsable())
6142 return nullptr;
6143
6144 // Upper - Lower [- 1] + Step
6145 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6146 if (!NewStep.isUsable())
6147 return nullptr;
6148 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
6149 if (!Diff.isUsable())
6150 return nullptr;
6151
6152 // Parentheses (for dumping/debugging purposes only).
6153 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6154 if (!Diff.isUsable())
6155 return nullptr;
6156
6157 // (Upper - Lower [- 1] + Step) / Step
6158 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6159 if (!Diff.isUsable())
6160 return nullptr;
6161
6162 // OpenMP runtime requires 32-bit or 64-bit loop variables.
6163 QualType Type = Diff.get()->getType();
6164 ASTContext &C = SemaRef.Context;
6165 bool UseVarType = VarType->hasIntegerRepresentation() &&
6166 C.getTypeSize(Type) > C.getTypeSize(VarType);
6167 if (!Type->isIntegerType() || UseVarType) {
6168 unsigned NewSize =
6169 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
6170 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
6171 : Type->hasSignedIntegerRepresentation();
6172 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
6173 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
6174 Diff = SemaRef.PerformImplicitConversion(
6175 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
6176 if (!Diff.isUsable())
6177 return nullptr;
6178 }
6179 }
6180 if (LimitedType) {
6181 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
6182 if (NewSize != C.getTypeSize(Type)) {
6183 if (NewSize < C.getTypeSize(Type)) {
6184 assert(NewSize == 64 && "incorrect loop var size");
6185 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
6186 << InitSrcRange << ConditionSrcRange;
6187 }
6188 QualType NewType = C.getIntTypeForBitwidth(
6189 NewSize, Type->hasSignedIntegerRepresentation() ||
6190 C.getTypeSize(Type) < NewSize);
6191 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
6192 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
6193 Sema::AA_Converting, true);
6194 if (!Diff.isUsable())
6195 return nullptr;
6196 }
6197 }
6198 }
6199
6200 return Diff.get();
6201 }
6202
6203 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
6204 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6205 // Do not build for iterators, they cannot be used in non-rectangular loop
6206 // nests.
6207 if (LCDecl->getType()->isRecordType())
6208 return std::make_pair(nullptr, nullptr);
6209 // If we subtract, the min is in the condition, otherwise the min is in the
6210 // init value.
6211 Expr *MinExpr = nullptr;
6212 Expr *MaxExpr = nullptr;
6213 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
6214 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
6215 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
6216 : CondDependOnLC.hasValue();
6217 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
6218 : InitDependOnLC.hasValue();
6219 Expr *Lower =
6220 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
6221 Expr *Upper =
6222 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
6223 if (!Upper || !Lower)
6224 return std::make_pair(nullptr, nullptr);
6225
6226 if (TestIsLessOp.getValue())
6227 MinExpr = Lower;
6228 else
6229 MaxExpr = Upper;
6230
6231 // Build minimum/maximum value based on number of iterations.
6232 ExprResult Diff;
6233 QualType VarType = LCDecl->getType().getNonReferenceType();
6234
6235 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6236 if (!Diff.isUsable())
6237 return std::make_pair(nullptr, nullptr);
6238
6239 // Upper - Lower [- 1]
6240 if (TestIsStrictOp)
6241 Diff = SemaRef.BuildBinOp(
6242 S, DefaultLoc, BO_Sub, Diff.get(),
6243 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6244 if (!Diff.isUsable())
6245 return std::make_pair(nullptr, nullptr);
6246
6247 // Upper - Lower [- 1] + Step
6248 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6249 if (!NewStep.isUsable())
6250 return std::make_pair(nullptr, nullptr);
6251
6252 // Parentheses (for dumping/debugging purposes only).
6253 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6254 if (!Diff.isUsable())
6255 return std::make_pair(nullptr, nullptr);
6256
6257 // (Upper - Lower [- 1]) / Step
6258 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6259 if (!Diff.isUsable())
6260 return std::make_pair(nullptr, nullptr);
6261
6262 // ((Upper - Lower [- 1]) / Step) * Step
6263 // Parentheses (for dumping/debugging purposes only).
6264 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6265 if (!Diff.isUsable())
6266 return std::make_pair(nullptr, nullptr);
6267
6268 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
6269 if (!Diff.isUsable())
6270 return std::make_pair(nullptr, nullptr);
6271
6272 // Convert to the original type or ptrdiff_t, if original type is pointer.
6273 if (!VarType->isAnyPointerType() &&
6274 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) {
6275 Diff = SemaRef.PerformImplicitConversion(
6276 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true);
6277 } else if (VarType->isAnyPointerType() &&
6278 !SemaRef.Context.hasSameType(
6279 Diff.get()->getType(),
6280 SemaRef.Context.getUnsignedPointerDiffType())) {
6281 Diff = SemaRef.PerformImplicitConversion(
6282 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
6283 Sema::AA_Converting, /*AllowExplicit=*/true);
6284 }
6285 if (!Diff.isUsable())
6286 return std::make_pair(nullptr, nullptr);
6287
6288 // Parentheses (for dumping/debugging purposes only).
6289 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6290 if (!Diff.isUsable())
6291 return std::make_pair(nullptr, nullptr);
6292
6293 if (TestIsLessOp.getValue()) {
6294 // MinExpr = Lower;
6295 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
6296 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get());
6297 if (!Diff.isUsable())
6298 return std::make_pair(nullptr, nullptr);
6299 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6300 if (!Diff.isUsable())
6301 return std::make_pair(nullptr, nullptr);
6302 MaxExpr = Diff.get();
6303 } else {
6304 // MaxExpr = Upper;
6305 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
6306 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
6307 if (!Diff.isUsable())
6308 return std::make_pair(nullptr, nullptr);
6309 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6310 if (!Diff.isUsable())
6311 return std::make_pair(nullptr, nullptr);
6312 MinExpr = Diff.get();
6313 }
6314
6315 return std::make_pair(MinExpr, MaxExpr);
6316 }
6317
6318 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
6319 if (InitDependOnLC || CondDependOnLC)
6320 return Condition;
6321 return nullptr;
6322 }
6323
6324 Expr *OpenMPIterationSpaceChecker::buildPreCond(
6325 Scope *S, Expr *Cond,
6326 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6327 // Do not build a precondition when the condition/initialization is dependent
6328 // to prevent pessimistic early loop exit.
6329 // TODO: this can be improved by calculating min/max values but not sure that
6330 // it will be very effective.
6331 if (CondDependOnLC || InitDependOnLC)
6332 return SemaRef.PerformImplicitConversion(
6333 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
6334 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6335 /*AllowExplicit=*/true).get();
6336
6337 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
6338 Sema::TentativeAnalysisScope Trap(SemaRef);
6339
6340 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
6341 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
6342 if (!NewLB.isUsable() || !NewUB.isUsable())
6343 return nullptr;
6344
6345 ExprResult CondExpr =
6346 SemaRef.BuildBinOp(S, DefaultLoc,
6347 TestIsLessOp.getValue() ?
6348 (TestIsStrictOp ? BO_LT : BO_LE) :
6349 (TestIsStrictOp ? BO_GT : BO_GE),
6350 NewLB.get(), NewUB.get());
6351 if (CondExpr.isUsable()) {
6352 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
6353 SemaRef.Context.BoolTy))
6354 CondExpr = SemaRef.PerformImplicitConversion(
6355 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6356 /*AllowExplicit=*/true);
6357 }
6358
6359 // Otherwise use original loop condition and evaluate it in runtime.
6360 return CondExpr.isUsable() ? CondExpr.get() : Cond;
6361 }
6362
6363 /// Build reference expression to the counter be used for codegen.
6364 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
6365 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6366 DSAStackTy &DSA) const {
6367 auto *VD = dyn_cast<VarDecl>(LCDecl);
6368 if (!VD) {
6369 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
6370 DeclRefExpr *Ref = buildDeclRefExpr(
6371 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
6372 const DSAStackTy::DSAVarData Data =
6373 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
6374 // If the loop control decl is explicitly marked as private, do not mark it
6375 // as captured again.
6376 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
6377 Captures.insert(std::make_pair(LCRef, Ref));
6378 return Ref;
6379 }
6380 return cast<DeclRefExpr>(LCRef);
6381 }
6382
6383 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
6384 if (LCDecl && !LCDecl->isInvalidDecl()) {
6385 QualType Type = LCDecl->getType().getNonReferenceType();
6386 VarDecl *PrivateVar = buildVarDecl(
6387 SemaRef, DefaultLoc, Type, LCDecl->getName(),
6388 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
6389 isa<VarDecl>(LCDecl)
6390 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
6391 : nullptr);
6392 if (PrivateVar->isInvalidDecl())
6393 return nullptr;
6394 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
6395 }
6396 return nullptr;
6397 }
6398
6399 /// Build initialization of the counter to be used for codegen.
6400 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
6401
6402 /// Build step of the counter be used for codegen.
6403 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
6404
6405 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
6406 Scope *S, Expr *Counter,
6407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
6408 Expr *Inc, OverloadedOperatorKind OOK) {
6409 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
6410 if (!Cnt)
6411 return nullptr;
6412 if (Inc) {
6413 assert((OOK == OO_Plus || OOK == OO_Minus) &&
6414 "Expected only + or - operations for depend clauses.");
6415 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
6416 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
6417 if (!Cnt)
6418 return nullptr;
6419 }
6420 ExprResult Diff;
6421 QualType VarType = LCDecl->getType().getNonReferenceType();
6422 if (VarType->isIntegerType() || VarType->isPointerType() ||
6423 SemaRef.getLangOpts().CPlusPlus) {
6424 // Upper - Lower
6425 Expr *Upper = TestIsLessOp.getValue()
6426 ? Cnt
6427 : tryBuildCapture(SemaRef, UB, Captures).get();
6428 Expr *Lower = TestIsLessOp.getValue()
6429 ? tryBuildCapture(SemaRef, LB, Captures).get()
6430 : Cnt;
6431 if (!Upper || !Lower)
6432 return nullptr;
6433
6434 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6435
6436 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
6437 // BuildBinOp already emitted error, this one is to point user to upper
6438 // and lower bound, and to tell what is passed to 'operator-'.
6439 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
6440 << Upper->getSourceRange() << Lower->getSourceRange();
6441 return nullptr;
6442 }
6443 }
6444
6445 if (!Diff.isUsable())
6446 return nullptr;
6447
6448 // Parentheses (for dumping/debugging purposes only).
6449 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6450 if (!Diff.isUsable())
6451 return nullptr;
6452
6453 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6454 if (!NewStep.isUsable())
6455 return nullptr;
6456 // (Upper - Lower) / Step
6457 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6458 if (!Diff.isUsable())
6459 return nullptr;
6460
6461 return Diff.get();
6462 }
6463 } // namespace
6464
6465 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
6466 assert(getLangOpts().OpenMP && "OpenMP is not active.");
6467 assert(Init && "Expected loop in canonical form.");
6468 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
6469 if (AssociatedLoops > 0 &&
6470 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
6471 DSAStack->loopStart();
6472 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
6473 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
6474 if (ValueDecl *D = ISC.getLoopDecl()) {
6475 auto *VD = dyn_cast<VarDecl>(D);
6476 DeclRefExpr *PrivateRef = nullptr;
6477 if (!VD) {
6478 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
6479 VD = Private;
6480 } else {
6481 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
6482 /*WithInit=*/false);
6483 VD = cast<VarDecl>(PrivateRef->getDecl());
6484 }
6485 }
6486 DSAStack->addLoopControlVariable(D, VD);
6487 const Decl *LD = DSAStack->getPossiblyLoopCunter();
6488 if (LD != D->getCanonicalDecl()) {
6489 DSAStack->resetPossibleLoopCounter();
6490 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
6491 MarkDeclarationsReferencedInExpr(
6492 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
6493 Var->getType().getNonLValueExprType(Context),
6494 ForLoc, /*RefersToCapture=*/true));
6495 }
6496 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
6497 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
6498 // Referenced in a Construct, C/C++]. The loop iteration variable in the
6499 // associated for-loop of a simd construct with just one associated
6500 // for-loop may be listed in a linear clause with a constant-linear-step
6501 // that is the increment of the associated for-loop. The loop iteration
6502 // variable(s) in the associated for-loop(s) of a for or parallel for
6503 // construct may be listed in a private or lastprivate clause.
6504 DSAStackTy::DSAVarData DVar =
6505 DSAStack->getTopDSA(D, /*FromParent=*/false);
6506 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
6507 // is declared in the loop and it is predetermined as a private.
6508 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
6509 OpenMPClauseKind PredeterminedCKind =
6510 isOpenMPSimdDirective(DKind)
6511 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
6512 : OMPC_private;
6513 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6514 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
6515 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
6516 DVar.CKind != OMPC_private))) ||
6517 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
6518 DKind == OMPD_master_taskloop ||
6519 DKind == OMPD_parallel_master_taskloop ||
6520 isOpenMPDistributeDirective(DKind)) &&
6521 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6522 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
6523 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
6524 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
6525 << getOpenMPClauseName(DVar.CKind)
6526 << getOpenMPDirectiveName(DKind)
6527 << getOpenMPClauseName(PredeterminedCKind);
6528 if (DVar.RefExpr == nullptr)
6529 DVar.CKind = PredeterminedCKind;
6530 reportOriginalDsa(*this, DSAStack, D, DVar,
6531 /*IsLoopIterVar=*/true);
6532 } else if (LoopDeclRefExpr) {
6533 // Make the loop iteration variable private (for worksharing
6534 // constructs), linear (for simd directives with the only one
6535 // associated loop) or lastprivate (for simd directives with several
6536 // collapsed or ordered loops).
6537 if (DVar.CKind == OMPC_unknown)
6538 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
6539 PrivateRef);
6540 }
6541 }
6542 }
6543 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
6544 }
6545 }
6546
6547 /// Called on a for stmt to check and extract its iteration space
6548 /// for further processing (such as collapsing).
6549 static bool checkOpenMPIterationSpace(
6550 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
6551 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
6552 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
6553 Expr *OrderedLoopCountExpr,
6554 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
6555 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
6556 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6557 // OpenMP [2.9.1, Canonical Loop Form]
6558 // for (init-expr; test-expr; incr-expr) structured-block
6559 // for (range-decl: range-expr) structured-block
6560 auto *For = dyn_cast_or_null<ForStmt>(S);
6561 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
6562 // Ranged for is supported only in OpenMP 5.0.
6563 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
6564 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
6565 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
6566 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
6567 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
6568 if (TotalNestedLoopCount > 1) {
6569 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
6570 SemaRef.Diag(DSA.getConstructLoc(),
6571 diag::note_omp_collapse_ordered_expr)
6572 << 2 << CollapseLoopCountExpr->getSourceRange()
6573 << OrderedLoopCountExpr->getSourceRange();
6574 else if (CollapseLoopCountExpr)
6575 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
6576 diag::note_omp_collapse_ordered_expr)
6577 << 0 << CollapseLoopCountExpr->getSourceRange();
6578 else
6579 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
6580 diag::note_omp_collapse_ordered_expr)
6581 << 1 << OrderedLoopCountExpr->getSourceRange();
6582 }
6583 return true;
6584 }
6585 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
6586 "No loop body.");
6587
6588 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
6589 For ? For->getForLoc() : CXXFor->getForLoc());
6590
6591 // Check init.
6592 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
6593 if (ISC.checkAndSetInit(Init))
6594 return true;
6595
6596 bool HasErrors = false;
6597
6598 // Check loop variable's type.
6599 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
6600 // OpenMP [2.6, Canonical Loop Form]
6601 // Var is one of the following:
6602 // A variable of signed or unsigned integer type.
6603 // For C++, a variable of a random access iterator type.
6604 // For C, a variable of a pointer type.
6605 QualType VarType = LCDecl->getType().getNonReferenceType();
6606 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
6607 !VarType->isPointerType() &&
6608 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
6609 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
6610 << SemaRef.getLangOpts().CPlusPlus;
6611 HasErrors = true;
6612 }
6613
6614 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
6615 // a Construct
6616 // The loop iteration variable(s) in the associated for-loop(s) of a for or
6617 // parallel for construct is (are) private.
6618 // The loop iteration variable in the associated for-loop of a simd
6619 // construct with just one associated for-loop is linear with a
6620 // constant-linear-step that is the increment of the associated for-loop.
6621 // Exclude loop var from the list of variables with implicitly defined data
6622 // sharing attributes.
6623 VarsWithImplicitDSA.erase(LCDecl);
6624
6625 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
6626
6627 // Check test-expr.
6628 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
6629
6630 // Check incr-expr.
6631 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
6632 }
6633
6634 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
6635 return HasErrors;
6636
6637 // Build the loop's iteration space representation.
6638 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
6639 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
6640 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
6641 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
6642 (isOpenMPWorksharingDirective(DKind) ||
6643 isOpenMPTaskLoopDirective(DKind) ||
6644 isOpenMPDistributeDirective(DKind)),
6645 Captures);
6646 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
6647 ISC.buildCounterVar(Captures, DSA);
6648 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
6649 ISC.buildPrivateCounterVar();
6650 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
6651 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
6652 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
6653 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
6654 ISC.getConditionSrcRange();
6655 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
6656 ISC.getIncrementSrcRange();
6657 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
6658 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
6659 ISC.isStrictTestOp();
6660 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
6661 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
6662 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
6663 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
6664 ISC.buildFinalCondition(DSA.getCurScope());
6665 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
6666 ISC.doesInitDependOnLC();
6667 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
6668 ISC.doesCondDependOnLC();
6669 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
6670 ISC.getLoopDependentIdx();
6671
6672 HasErrors |=
6673 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
6674 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
6675 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
6676 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
6677 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
6678 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
6679 if (!HasErrors && DSA.isOrderedRegion()) {
6680 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
6681 if (CurrentNestedLoopCount <
6682 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
6683 DSA.getOrderedRegionParam().second->setLoopNumIterations(
6684 CurrentNestedLoopCount,
6685 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
6686 DSA.getOrderedRegionParam().second->setLoopCounter(
6687 CurrentNestedLoopCount,
6688 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
6689 }
6690 }
6691 for (auto &Pair : DSA.getDoacrossDependClauses()) {
6692 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
6693 // Erroneous case - clause has some problems.
6694 continue;
6695 }
6696 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
6697 Pair.second.size() <= CurrentNestedLoopCount) {
6698 // Erroneous case - clause has some problems.
6699 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
6700 continue;
6701 }
6702 Expr *CntValue;
6703 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
6704 CntValue = ISC.buildOrderedLoopData(
6705 DSA.getCurScope(),
6706 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
6707 Pair.first->getDependencyLoc());
6708 else
6709 CntValue = ISC.buildOrderedLoopData(
6710 DSA.getCurScope(),
6711 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
6712 Pair.first->getDependencyLoc(),
6713 Pair.second[CurrentNestedLoopCount].first,
6714 Pair.second[CurrentNestedLoopCount].second);
6715 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
6716 }
6717 }
6718
6719 return HasErrors;
6720 }
6721
6722 /// Build 'VarRef = Start.
6723 static ExprResult
6724 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
6725 ExprResult Start, bool IsNonRectangularLB,
6726 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6727 // Build 'VarRef = Start.
6728 ExprResult NewStart = IsNonRectangularLB
6729 ? Start.get()
6730 : tryBuildCapture(SemaRef, Start.get(), Captures);
6731 if (!NewStart.isUsable())
6732 return ExprError();
6733 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
6734 VarRef.get()->getType())) {
6735 NewStart = SemaRef.PerformImplicitConversion(
6736 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
6737 /*AllowExplicit=*/true);
6738 if (!NewStart.isUsable())
6739 return ExprError();
6740 }
6741
6742 ExprResult Init =
6743 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
6744 return Init;
6745 }
6746
6747 /// Build 'VarRef = Start + Iter * Step'.
6748 static ExprResult buildCounterUpdate(
6749 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
6750 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
6751 bool IsNonRectangularLB,
6752 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
6753 // Add parentheses (for debugging purposes only).
6754 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
6755 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
6756 !Step.isUsable())
6757 return ExprError();
6758
6759 ExprResult NewStep = Step;
6760 if (Captures)
6761 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
6762 if (NewStep.isInvalid())
6763 return ExprError();
6764 ExprResult Update =
6765 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
6766 if (!Update.isUsable())
6767 return ExprError();
6768
6769 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
6770 // 'VarRef = Start (+|-) Iter * Step'.
6771 if (!Start.isUsable())
6772 return ExprError();
6773 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
6774 if (!NewStart.isUsable())
6775 return ExprError();
6776 if (Captures && !IsNonRectangularLB)
6777 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
6778 if (NewStart.isInvalid())
6779 return ExprError();
6780
6781 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
6782 ExprResult SavedUpdate = Update;
6783 ExprResult UpdateVal;
6784 if (VarRef.get()->getType()->isOverloadableType() ||
6785 NewStart.get()->getType()->isOverloadableType() ||
6786 Update.get()->getType()->isOverloadableType()) {
6787 Sema::TentativeAnalysisScope Trap(SemaRef);
6788
6789 Update =
6790 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
6791 if (Update.isUsable()) {
6792 UpdateVal =
6793 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
6794 VarRef.get(), SavedUpdate.get());
6795 if (UpdateVal.isUsable()) {
6796 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
6797 UpdateVal.get());
6798 }
6799 }
6800 }
6801
6802 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
6803 if (!Update.isUsable() || !UpdateVal.isUsable()) {
6804 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
6805 NewStart.get(), SavedUpdate.get());
6806 if (!Update.isUsable())
6807 return ExprError();
6808
6809 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
6810 VarRef.get()->getType())) {
6811 Update = SemaRef.PerformImplicitConversion(
6812 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
6813 if (!Update.isUsable())
6814 return ExprError();
6815 }
6816
6817 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
6818 }
6819 return Update;
6820 }
6821
6822 /// Convert integer expression \a E to make it have at least \a Bits
6823 /// bits.
6824 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
6825 if (E == nullptr)
6826 return ExprError();
6827 ASTContext &C = SemaRef.Context;
6828 QualType OldType = E->getType();
6829 unsigned HasBits = C.getTypeSize(OldType);
6830 if (HasBits >= Bits)
6831 return ExprResult(E);
6832 // OK to convert to signed, because new type has more bits than old.
6833 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
6834 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
6835 true);
6836 }
6837
6838 /// Check if the given expression \a E is a constant integer that fits
6839 /// into \a Bits bits.
6840 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
6841 if (E == nullptr)
6842 return false;
6843 llvm::APSInt Result;
6844 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
6845 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
6846 return false;
6847 }
6848
6849 /// Build preinits statement for the given declarations.
6850 static Stmt *buildPreInits(ASTContext &Context,
6851 MutableArrayRef<Decl *> PreInits) {
6852 if (!PreInits.empty()) {
6853 return new (Context) DeclStmt(
6854 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
6855 SourceLocation(), SourceLocation());
6856 }
6857 return nullptr;
6858 }
6859
6860 /// Build preinits statement for the given declarations.
6861 static Stmt *
6862 buildPreInits(ASTContext &Context,
6863 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6864 if (!Captures.empty()) {
6865 SmallVector<Decl *, 16> PreInits;
6866 for (const auto &Pair : Captures)
6867 PreInits.push_back(Pair.second->getDecl());
6868 return buildPreInits(Context, PreInits);
6869 }
6870 return nullptr;
6871 }
6872
6873 /// Build postupdate expression for the given list of postupdates expressions.
6874 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
6875 Expr *PostUpdate = nullptr;
6876 if (!PostUpdates.empty()) {
6877 for (Expr *E : PostUpdates) {
6878 Expr *ConvE = S.BuildCStyleCastExpr(
6879 E->getExprLoc(),
6880 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
6881 E->getExprLoc(), E)
6882 .get();
6883 PostUpdate = PostUpdate
6884 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
6885 PostUpdate, ConvE)
6886 .get()
6887 : ConvE;
6888 }
6889 }
6890 return PostUpdate;
6891 }
6892
6893 /// Called on a for stmt to check itself and nested loops (if any).
6894 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
6895 /// number of collapsed loops otherwise.
6896 static unsigned
6897 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
6898 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
6899 DSAStackTy &DSA,
6900 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
6901 OMPLoopDirective::HelperExprs &Built) {
6902 unsigned NestedLoopCount = 1;
6903 if (CollapseLoopCountExpr) {
6904 // Found 'collapse' clause - calculate collapse number.
6905 Expr::EvalResult Result;
6906 if (!CollapseLoopCountExpr->isValueDependent() &&
6907 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
6908 NestedLoopCount = Result.Val.getInt().getLimitedValue();
6909 } else {
6910 Built.clear(/*Size=*/1);
6911 return 1;
6912 }
6913 }
6914 unsigned OrderedLoopCount = 1;
6915 if (OrderedLoopCountExpr) {
6916 // Found 'ordered' clause - calculate collapse number.
6917 Expr::EvalResult EVResult;
6918 if (!OrderedLoopCountExpr->isValueDependent() &&
6919 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
6920 SemaRef.getASTContext())) {
6921 llvm::APSInt Result = EVResult.Val.getInt();
6922 if (Result.getLimitedValue() < NestedLoopCount) {
6923 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
6924 diag::err_omp_wrong_ordered_loop_count)
6925 << OrderedLoopCountExpr->getSourceRange();
6926 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
6927 diag::note_collapse_loop_count)
6928 << CollapseLoopCountExpr->getSourceRange();
6929 }
6930 OrderedLoopCount = Result.getLimitedValue();
6931 } else {
6932 Built.clear(/*Size=*/1);
6933 return 1;
6934 }
6935 }
6936 // This is helper routine for loop directives (e.g., 'for', 'simd',
6937 // 'for simd', etc.).
6938 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
6939 SmallVector<LoopIterationSpace, 4> IterSpaces(
6940 std::max(OrderedLoopCount, NestedLoopCount));
6941 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
6942 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
6943 if (checkOpenMPIterationSpace(
6944 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
6945 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
6946 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
6947 return 0;
6948 // Move on to the next nested for loop, or to the loop body.
6949 // OpenMP [2.8.1, simd construct, Restrictions]
6950 // All loops associated with the construct must be perfectly nested; that
6951 // is, there must be no intervening code nor any OpenMP directive between
6952 // any two loops.
6953 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
6954 CurStmt = For->getBody();
6955 } else {
6956 assert(isa<CXXForRangeStmt>(CurStmt) &&
6957 "Expected canonical for or range-based for loops.");
6958 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
6959 }
6960 CurStmt = CurStmt->IgnoreContainers();
6961 }
6962 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
6963 if (checkOpenMPIterationSpace(
6964 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
6965 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
6966 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
6967 return 0;
6968 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
6969 // Handle initialization of captured loop iterator variables.
6970 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
6971 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
6972 Captures[DRE] = DRE;
6973 }
6974 }
6975 // Move on to the next nested for loop, or to the loop body.
6976 // OpenMP [2.8.1, simd construct, Restrictions]
6977 // All loops associated with the construct must be perfectly nested; that
6978 // is, there must be no intervening code nor any OpenMP directive between
6979 // any two loops.
6980 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
6981 CurStmt = For->getBody();
6982 } else {
6983 assert(isa<CXXForRangeStmt>(CurStmt) &&
6984 "Expected canonical for or range-based for loops.");
6985 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
6986 }
6987 CurStmt = CurStmt->IgnoreContainers();
6988 }
6989
6990 Built.clear(/* size */ NestedLoopCount);
6991
6992 if (SemaRef.CurContext->isDependentContext())
6993 return NestedLoopCount;
6994
6995 // An example of what is generated for the following code:
6996 //
6997 // #pragma omp simd collapse(2) ordered(2)
6998 // for (i = 0; i < NI; ++i)
6999 // for (k = 0; k < NK; ++k)
7000 // for (j = J0; j < NJ; j+=2) {
7001 // <loop body>
7002 // }
7003 //
7004 // We generate the code below.
7005 // Note: the loop body may be outlined in CodeGen.
7006 // Note: some counters may be C++ classes, operator- is used to find number of
7007 // iterations and operator+= to calculate counter value.
7008 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
7009 // or i64 is currently supported).
7010 //
7011 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
7012 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
7013 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
7014 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
7015 // // similar updates for vars in clauses (e.g. 'linear')
7016 // <loop body (using local i and j)>
7017 // }
7018 // i = NI; // assign final values of counters
7019 // j = NJ;
7020 //
7021
7022 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
7023 // the iteration counts of the collapsed for loops.
7024 // Precondition tests if there is at least one iteration (all conditions are
7025 // true).
7026 auto PreCond = ExprResult(IterSpaces[0].PreCond);
7027 Expr *N0 = IterSpaces[0].NumIterations;
7028 ExprResult LastIteration32 =
7029 widenIterationCount(/*Bits=*/32,
7030 SemaRef
7031 .PerformImplicitConversion(
7032 N0->IgnoreImpCasts(), N0->getType(),
7033 Sema::AA_Converting, /*AllowExplicit=*/true)
7034 .get(),
7035 SemaRef);
7036 ExprResult LastIteration64 = widenIterationCount(
7037 /*Bits=*/64,
7038 SemaRef
7039 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
7040 Sema::AA_Converting,
7041 /*AllowExplicit=*/true)
7042 .get(),
7043 SemaRef);
7044
7045 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
7046 return NestedLoopCount;
7047
7048 ASTContext &C = SemaRef.Context;
7049 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
7050
7051 Scope *CurScope = DSA.getCurScope();
7052 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
7053 if (PreCond.isUsable()) {
7054 PreCond =
7055 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
7056 PreCond.get(), IterSpaces[Cnt].PreCond);
7057 }
7058 Expr *N = IterSpaces[Cnt].NumIterations;
7059 SourceLocation Loc = N->getExprLoc();
7060 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
7061 if (LastIteration32.isUsable())
7062 LastIteration32 = SemaRef.BuildBinOp(
7063 CurScope, Loc, BO_Mul, LastIteration32.get(),
7064 SemaRef
7065 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
7066 Sema::AA_Converting,
7067 /*AllowExplicit=*/true)
7068 .get());
7069 if (LastIteration64.isUsable())
7070 LastIteration64 = SemaRef.BuildBinOp(
7071 CurScope, Loc, BO_Mul, LastIteration64.get(),
7072 SemaRef
7073 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
7074 Sema::AA_Converting,
7075 /*AllowExplicit=*/true)
7076 .get());
7077 }
7078
7079 // Choose either the 32-bit or 64-bit version.
7080 ExprResult LastIteration = LastIteration64;
7081 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
7082 (LastIteration32.isUsable() &&
7083 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
7084 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
7085 fitsInto(
7086 /*Bits=*/32,
7087 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
7088 LastIteration64.get(), SemaRef))))
7089 LastIteration = LastIteration32;
7090 QualType VType = LastIteration.get()->getType();
7091 QualType RealVType = VType;
7092 QualType StrideVType = VType;
7093 if (isOpenMPTaskLoopDirective(DKind)) {
7094 VType =
7095 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
7096 StrideVType =
7097 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
7098 }
7099
7100 if (!LastIteration.isUsable())
7101 return 0;
7102
7103 // Save the number of iterations.
7104 ExprResult NumIterations = LastIteration;
7105 {
7106 LastIteration = SemaRef.BuildBinOp(
7107 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
7108 LastIteration.get(),
7109 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7110 if (!LastIteration.isUsable())
7111 return 0;
7112 }
7113
7114 // Calculate the last iteration number beforehand instead of doing this on
7115 // each iteration. Do not do this if the number of iterations may be kfold-ed.
7116 llvm::APSInt Result;
7117 bool IsConstant =
7118 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
7119 ExprResult CalcLastIteration;
7120 if (!IsConstant) {
7121 ExprResult SaveRef =
7122 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
7123 LastIteration = SaveRef;
7124
7125 // Prepare SaveRef + 1.
7126 NumIterations = SemaRef.BuildBinOp(
7127 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
7128 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7129 if (!NumIterations.isUsable())
7130 return 0;
7131 }
7132
7133 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
7134
7135 // Build variables passed into runtime, necessary for worksharing directives.
7136 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
7137 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
7138 isOpenMPDistributeDirective(DKind)) {
7139 // Lower bound variable, initialized with zero.
7140 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
7141 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
7142 SemaRef.AddInitializerToDecl(LBDecl,
7143 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7144 /*DirectInit*/ false);
7145
7146 // Upper bound variable, initialized with last iteration number.
7147 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
7148 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
7149 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
7150 /*DirectInit*/ false);
7151
7152 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
7153 // This will be used to implement clause 'lastprivate'.
7154 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
7155 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
7156 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
7157 SemaRef.AddInitializerToDecl(ILDecl,
7158 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7159 /*DirectInit*/ false);
7160
7161 // Stride variable returned by runtime (we initialize it to 1 by default).
7162 VarDecl *STDecl =
7163 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
7164 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
7165 SemaRef.AddInitializerToDecl(STDecl,
7166 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
7167 /*DirectInit*/ false);
7168
7169 // Build expression: UB = min(UB, LastIteration)
7170 // It is necessary for CodeGen of directives with static scheduling.
7171 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
7172 UB.get(), LastIteration.get());
7173 ExprResult CondOp = SemaRef.ActOnConditionalOp(
7174 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
7175 LastIteration.get(), UB.get());
7176 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
7177 CondOp.get());
7178 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
7179
7180 // If we have a combined directive that combines 'distribute', 'for' or
7181 // 'simd' we need to be able to access the bounds of the schedule of the
7182 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
7183 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
7184 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7185 // Lower bound variable, initialized with zero.
7186 VarDecl *CombLBDecl =
7187 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
7188 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
7189 SemaRef.AddInitializerToDecl(
7190 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7191 /*DirectInit*/ false);
7192
7193 // Upper bound variable, initialized with last iteration number.
7194 VarDecl *CombUBDecl =
7195 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
7196 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
7197 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
7198 /*DirectInit*/ false);
7199
7200 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
7201 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
7202 ExprResult CombCondOp =
7203 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
7204 LastIteration.get(), CombUB.get());
7205 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
7206 CombCondOp.get());
7207 CombEUB =
7208 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
7209
7210 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
7211 // We expect to have at least 2 more parameters than the 'parallel'
7212 // directive does - the lower and upper bounds of the previous schedule.
7213 assert(CD->getNumParams() >= 4 &&
7214 "Unexpected number of parameters in loop combined directive");
7215
7216 // Set the proper type for the bounds given what we learned from the
7217 // enclosed loops.
7218 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
7219 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
7220
7221 // Previous lower and upper bounds are obtained from the region
7222 // parameters.
7223 PrevLB =
7224 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
7225 PrevUB =
7226 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
7227 }
7228 }
7229
7230 // Build the iteration variable and its initialization before loop.
7231 ExprResult IV;
7232 ExprResult Init, CombInit;
7233 {
7234 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
7235 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
7236 Expr *RHS =
7237 (isOpenMPWorksharingDirective(DKind) ||
7238 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
7239 ? LB.get()
7240 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
7241 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
7242 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
7243
7244 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7245 Expr *CombRHS =
7246 (isOpenMPWorksharingDirective(DKind) ||
7247 isOpenMPTaskLoopDirective(DKind) ||
7248 isOpenMPDistributeDirective(DKind))
7249 ? CombLB.get()
7250 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
7251 CombInit =
7252 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
7253 CombInit =
7254 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
7255 }
7256 }
7257
7258 bool UseStrictCompare =
7259 RealVType->hasUnsignedIntegerRepresentation() &&
7260 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
7261 return LIS.IsStrictCompare;
7262 });
7263 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
7264 // unsigned IV)) for worksharing loops.
7265 SourceLocation CondLoc = AStmt->getBeginLoc();
7266 Expr *BoundUB = UB.get();
7267 if (UseStrictCompare) {
7268 BoundUB =
7269 SemaRef
7270 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
7271 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7272 .get();
7273 BoundUB =
7274 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
7275 }
7276 ExprResult Cond =
7277 (isOpenMPWorksharingDirective(DKind) ||
7278 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
7279 ? SemaRef.BuildBinOp(CurScope, CondLoc,
7280 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
7281 BoundUB)
7282 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7283 NumIterations.get());
7284 ExprResult CombDistCond;
7285 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7286 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7287 NumIterations.get());
7288 }
7289
7290 ExprResult CombCond;
7291 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7292 Expr *BoundCombUB = CombUB.get();
7293 if (UseStrictCompare) {
7294 BoundCombUB =
7295 SemaRef
7296 .BuildBinOp(
7297 CurScope, CondLoc, BO_Add, BoundCombUB,
7298 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7299 .get();
7300 BoundCombUB =
7301 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
7302 .get();
7303 }
7304 CombCond =
7305 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7306 IV.get(), BoundCombUB);
7307 }
7308 // Loop increment (IV = IV + 1)
7309 SourceLocation IncLoc = AStmt->getBeginLoc();
7310 ExprResult Inc =
7311 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
7312 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
7313 if (!Inc.isUsable())
7314 return 0;
7315 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
7316 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
7317 if (!Inc.isUsable())
7318 return 0;
7319
7320 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
7321 // Used for directives with static scheduling.
7322 // In combined construct, add combined version that use CombLB and CombUB
7323 // base variables for the update
7324 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
7325 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
7326 isOpenMPDistributeDirective(DKind)) {
7327 // LB + ST
7328 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
7329 if (!NextLB.isUsable())
7330 return 0;
7331 // LB = LB + ST
7332 NextLB =
7333 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
7334 NextLB =
7335 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
7336 if (!NextLB.isUsable())
7337 return 0;
7338 // UB + ST
7339 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
7340 if (!NextUB.isUsable())
7341 return 0;
7342 // UB = UB + ST
7343 NextUB =
7344 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
7345 NextUB =
7346 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
7347 if (!NextUB.isUsable())
7348 return 0;
7349 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7350 CombNextLB =
7351 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
7352 if (!NextLB.isUsable())
7353 return 0;
7354 // LB = LB + ST
7355 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
7356 CombNextLB.get());
7357 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
7358 /*DiscardedValue*/ false);
7359 if (!CombNextLB.isUsable())
7360 return 0;
7361 // UB + ST
7362 CombNextUB =
7363 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
7364 if (!CombNextUB.isUsable())
7365 return 0;
7366 // UB = UB + ST
7367 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
7368 CombNextUB.get());
7369 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
7370 /*DiscardedValue*/ false);
7371 if (!CombNextUB.isUsable())
7372 return 0;
7373 }
7374 }
7375
7376 // Create increment expression for distribute loop when combined in a same
7377 // directive with for as IV = IV + ST; ensure upper bound expression based
7378 // on PrevUB instead of NumIterations - used to implement 'for' when found
7379 // in combination with 'distribute', like in 'distribute parallel for'
7380 SourceLocation DistIncLoc = AStmt->getBeginLoc();
7381 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
7382 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7383 DistCond = SemaRef.BuildBinOp(
7384 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
7385 assert(DistCond.isUsable() && "distribute cond expr was not built");
7386
7387 DistInc =
7388 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
7389 assert(DistInc.isUsable() && "distribute inc expr was not built");
7390 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
7391 DistInc.get());
7392 DistInc =
7393 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
7394 assert(DistInc.isUsable() && "distribute inc expr was not built");
7395
7396 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
7397 // construct
7398 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
7399 ExprResult IsUBGreater =
7400 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
7401 ExprResult CondOp = SemaRef.ActOnConditionalOp(
7402 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
7403 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
7404 CondOp.get());
7405 PrevEUB =
7406 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
7407
7408 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
7409 // parallel for is in combination with a distribute directive with
7410 // schedule(static, 1)
7411 Expr *BoundPrevUB = PrevUB.get();
7412 if (UseStrictCompare) {
7413 BoundPrevUB =
7414 SemaRef
7415 .BuildBinOp(
7416 CurScope, CondLoc, BO_Add, BoundPrevUB,
7417 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7418 .get();
7419 BoundPrevUB =
7420 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
7421 .get();
7422 }
7423 ParForInDistCond =
7424 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7425 IV.get(), BoundPrevUB);
7426 }
7427
7428 // Build updates and final values of the loop counters.
7429 bool HasErrors = false;
7430 Built.Counters.resize(NestedLoopCount);
7431 Built.Inits.resize(NestedLoopCount);
7432 Built.Updates.resize(NestedLoopCount);
7433 Built.Finals.resize(NestedLoopCount);
7434 Built.DependentCounters.resize(NestedLoopCount);
7435 Built.DependentInits.resize(NestedLoopCount);
7436 Built.FinalsConditions.resize(NestedLoopCount);
7437 {
7438 // We implement the following algorithm for obtaining the
7439 // original loop iteration variable values based on the
7440 // value of the collapsed loop iteration variable IV.
7441 //
7442 // Let n+1 be the number of collapsed loops in the nest.
7443 // Iteration variables (I0, I1, .... In)
7444 // Iteration counts (N0, N1, ... Nn)
7445 //
7446 // Acc = IV;
7447 //
7448 // To compute Ik for loop k, 0 <= k <= n, generate:
7449 // Prod = N(k+1) * N(k+2) * ... * Nn;
7450 // Ik = Acc / Prod;
7451 // Acc -= Ik * Prod;
7452 //
7453 ExprResult Acc = IV;
7454 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
7455 LoopIterationSpace &IS = IterSpaces[Cnt];
7456 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
7457 ExprResult Iter;
7458
7459 // Compute prod
7460 ExprResult Prod =
7461 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
7462 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
7463 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
7464 IterSpaces[K].NumIterations);
7465
7466 // Iter = Acc / Prod
7467 // If there is at least one more inner loop to avoid
7468 // multiplication by 1.
7469 if (Cnt + 1 < NestedLoopCount)
7470 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
7471 Acc.get(), Prod.get());
7472 else
7473 Iter = Acc;
7474 if (!Iter.isUsable()) {
7475 HasErrors = true;
7476 break;
7477 }
7478
7479 // Update Acc:
7480 // Acc -= Iter * Prod
7481 // Check if there is at least one more inner loop to avoid
7482 // multiplication by 1.
7483 if (Cnt + 1 < NestedLoopCount)
7484 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
7485 Iter.get(), Prod.get());
7486 else
7487 Prod = Iter;
7488 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
7489 Acc.get(), Prod.get());
7490
7491 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
7492 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
7493 DeclRefExpr *CounterVar = buildDeclRefExpr(
7494 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
7495 /*RefersToCapture=*/true);
7496 ExprResult Init =
7497 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
7498 IS.CounterInit, IS.IsNonRectangularLB, Captures);
7499 if (!Init.isUsable()) {
7500 HasErrors = true;
7501 break;
7502 }
7503 ExprResult Update = buildCounterUpdate(
7504 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
7505 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
7506 if (!Update.isUsable()) {
7507 HasErrors = true;
7508 break;
7509 }
7510
7511 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
7512 ExprResult Final =
7513 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
7514 IS.CounterInit, IS.NumIterations, IS.CounterStep,
7515 IS.Subtract, IS.IsNonRectangularLB, &Captures);
7516 if (!Final.isUsable()) {
7517 HasErrors = true;
7518 break;
7519 }
7520
7521 if (!Update.isUsable() || !Final.isUsable()) {
7522 HasErrors = true;
7523 break;
7524 }
7525 // Save results
7526 Built.Counters[Cnt] = IS.CounterVar;
7527 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
7528 Built.Inits[Cnt] = Init.get();
7529 Built.Updates[Cnt] = Update.get();
7530 Built.Finals[Cnt] = Final.get();
7531 Built.DependentCounters[Cnt] = nullptr;
7532 Built.DependentInits[Cnt] = nullptr;
7533 Built.FinalsConditions[Cnt] = nullptr;
7534 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
7535 Built.DependentCounters[Cnt] =
7536 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
7537 Built.DependentInits[Cnt] =
7538 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
7539 Built.FinalsConditions[Cnt] = IS.FinalCondition;
7540 }
7541 }
7542 }
7543
7544 if (HasErrors)
7545 return 0;
7546
7547 // Save results
7548 Built.IterationVarRef = IV.get();
7549 Built.LastIteration = LastIteration.get();
7550 Built.NumIterations = NumIterations.get();
7551 Built.CalcLastIteration = SemaRef
7552 .ActOnFinishFullExpr(CalcLastIteration.get(),
7553 /*DiscardedValue=*/false)
7554 .get();
7555 Built.PreCond = PreCond.get();
7556 Built.PreInits = buildPreInits(C, Captures);
7557 Built.Cond = Cond.get();
7558 Built.Init = Init.get();
7559 Built.Inc = Inc.get();
7560 Built.LB = LB.get();
7561 Built.UB = UB.get();
7562 Built.IL = IL.get();
7563 Built.ST = ST.get();
7564 Built.EUB = EUB.get();
7565 Built.NLB = NextLB.get();
7566 Built.NUB = NextUB.get();
7567 Built.PrevLB = PrevLB.get();
7568 Built.PrevUB = PrevUB.get();
7569 Built.DistInc = DistInc.get();
7570 Built.PrevEUB = PrevEUB.get();
7571 Built.DistCombinedFields.LB = CombLB.get();
7572 Built.DistCombinedFields.UB = CombUB.get();
7573 Built.DistCombinedFields.EUB = CombEUB.get();
7574 Built.DistCombinedFields.Init = CombInit.get();
7575 Built.DistCombinedFields.Cond = CombCond.get();
7576 Built.DistCombinedFields.NLB = CombNextLB.get();
7577 Built.DistCombinedFields.NUB = CombNextUB.get();
7578 Built.DistCombinedFields.DistCond = CombDistCond.get();
7579 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
7580
7581 return NestedLoopCount;
7582 }
7583
7584 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
7585 auto CollapseClauses =
7586 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
7587 if (CollapseClauses.begin() != CollapseClauses.end())
7588 return (*CollapseClauses.begin())->getNumForLoops();
7589 return nullptr;
7590 }
7591
7592 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
7593 auto OrderedClauses =
7594 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
7595 if (OrderedClauses.begin() != OrderedClauses.end())
7596 return (*OrderedClauses.begin())->getNumForLoops();
7597 return nullptr;
7598 }
7599
7600 static bool checkSimdlenSafelenSpecified(Sema &S,
7601 const ArrayRef<OMPClause *> Clauses) {
7602 const OMPSafelenClause *Safelen = nullptr;
7603 const OMPSimdlenClause *Simdlen = nullptr;
7604
7605 for (const OMPClause *Clause : Clauses) {
7606 if (Clause->getClauseKind() == OMPC_safelen)
7607 Safelen = cast<OMPSafelenClause>(Clause);
7608 else if (Clause->getClauseKind() == OMPC_simdlen)
7609 Simdlen = cast<OMPSimdlenClause>(Clause);
7610 if (Safelen && Simdlen)
7611 break;
7612 }
7613
7614 if (Simdlen && Safelen) {
7615 const Expr *SimdlenLength = Simdlen->getSimdlen();
7616 const Expr *SafelenLength = Safelen->getSafelen();
7617 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
7618 SimdlenLength->isInstantiationDependent() ||
7619 SimdlenLength->containsUnexpandedParameterPack())
7620 return false;
7621 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
7622 SafelenLength->isInstantiationDependent() ||
7623 SafelenLength->containsUnexpandedParameterPack())
7624 return false;
7625 Expr::EvalResult SimdlenResult, SafelenResult;
7626 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
7627 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
7628 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
7629 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
7630 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
7631 // If both simdlen and safelen clauses are specified, the value of the
7632 // simdlen parameter must be less than or equal to the value of the safelen
7633 // parameter.
7634 if (SimdlenRes > SafelenRes) {
7635 S.Diag(SimdlenLength->getExprLoc(),
7636 diag::err_omp_wrong_simdlen_safelen_values)
7637 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
7638 return true;
7639 }
7640 }
7641 return false;
7642 }
7643
7644 StmtResult
7645 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
7646 SourceLocation StartLoc, SourceLocation EndLoc,
7647 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7648 if (!AStmt)
7649 return StmtError();
7650
7651 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7652 OMPLoopDirective::HelperExprs B;
7653 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7654 // define the nested loops number.
7655 unsigned NestedLoopCount = checkOpenMPLoop(
7656 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
7657 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
7658 if (NestedLoopCount == 0)
7659 return StmtError();
7660
7661 assert((CurContext->isDependentContext() || B.builtAll()) &&
7662 "omp simd loop exprs were not built");
7663
7664 if (!CurContext->isDependentContext()) {
7665 // Finalize the clauses that need pre-built expressions for CodeGen.
7666 for (OMPClause *C : Clauses) {
7667 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7668 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7669 B.NumIterations, *this, CurScope,
7670 DSAStack))
7671 return StmtError();
7672 }
7673 }
7674
7675 if (checkSimdlenSafelenSpecified(*this, Clauses))
7676 return StmtError();
7677
7678 setFunctionHasBranchProtectedScope();
7679 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
7680 Clauses, AStmt, B);
7681 }
7682
7683 StmtResult
7684 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
7685 SourceLocation StartLoc, SourceLocation EndLoc,
7686 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7687 if (!AStmt)
7688 return StmtError();
7689
7690 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7691 OMPLoopDirective::HelperExprs B;
7692 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7693 // define the nested loops number.
7694 unsigned NestedLoopCount = checkOpenMPLoop(
7695 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
7696 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
7697 if (NestedLoopCount == 0)
7698 return StmtError();
7699
7700 assert((CurContext->isDependentContext() || B.builtAll()) &&
7701 "omp for loop exprs were not built");
7702
7703 if (!CurContext->isDependentContext()) {
7704 // Finalize the clauses that need pre-built expressions for CodeGen.
7705 for (OMPClause *C : Clauses) {
7706 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7708 B.NumIterations, *this, CurScope,
7709 DSAStack))
7710 return StmtError();
7711 }
7712 }
7713
7714 setFunctionHasBranchProtectedScope();
7715 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
7716 Clauses, AStmt, B, DSAStack->isCancelRegion());
7717 }
7718
7719 StmtResult Sema::ActOnOpenMPForSimdDirective(
7720 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7721 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7722 if (!AStmt)
7723 return StmtError();
7724
7725 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7726 OMPLoopDirective::HelperExprs B;
7727 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7728 // define the nested loops number.
7729 unsigned NestedLoopCount =
7730 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
7731 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
7732 VarsWithImplicitDSA, B);
7733 if (NestedLoopCount == 0)
7734 return StmtError();
7735
7736 assert((CurContext->isDependentContext() || B.builtAll()) &&
7737 "omp for simd loop exprs were not built");
7738
7739 if (!CurContext->isDependentContext()) {
7740 // Finalize the clauses that need pre-built expressions for CodeGen.
7741 for (OMPClause *C : Clauses) {
7742 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7743 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7744 B.NumIterations, *this, CurScope,
7745 DSAStack))
7746 return StmtError();
7747 }
7748 }
7749
7750 if (checkSimdlenSafelenSpecified(*this, Clauses))
7751 return StmtError();
7752
7753 setFunctionHasBranchProtectedScope();
7754 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
7755 Clauses, AStmt, B);
7756 }
7757
7758 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
7759 Stmt *AStmt,
7760 SourceLocation StartLoc,
7761 SourceLocation EndLoc) {
7762 if (!AStmt)
7763 return StmtError();
7764
7765 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7766 auto BaseStmt = AStmt;
7767 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
7768 BaseStmt = CS->getCapturedStmt();
7769 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
7770 auto S = C->children();
7771 if (S.begin() == S.end())
7772 return StmtError();
7773 // All associated statements must be '#pragma omp section' except for
7774 // the first one.
7775 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
7776 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
7777 if (SectionStmt)
7778 Diag(SectionStmt->getBeginLoc(),
7779 diag::err_omp_sections_substmt_not_section);
7780 return StmtError();
7781 }
7782 cast<OMPSectionDirective>(SectionStmt)
7783 ->setHasCancel(DSAStack->isCancelRegion());
7784 }
7785 } else {
7786 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
7787 return StmtError();
7788 }
7789
7790 setFunctionHasBranchProtectedScope();
7791
7792 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7793 DSAStack->isCancelRegion());
7794 }
7795
7796 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
7797 SourceLocation StartLoc,
7798 SourceLocation EndLoc) {
7799 if (!AStmt)
7800 return StmtError();
7801
7802 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7803
7804 setFunctionHasBranchProtectedScope();
7805 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
7806
7807 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
7808 DSAStack->isCancelRegion());
7809 }
7810
7811 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
7812 Stmt *AStmt,
7813 SourceLocation StartLoc,
7814 SourceLocation EndLoc) {
7815 if (!AStmt)
7816 return StmtError();
7817
7818 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7819
7820 setFunctionHasBranchProtectedScope();
7821
7822 // OpenMP [2.7.3, single Construct, Restrictions]
7823 // The copyprivate clause must not be used with the nowait clause.
7824 const OMPClause *Nowait = nullptr;
7825 const OMPClause *Copyprivate = nullptr;
7826 for (const OMPClause *Clause : Clauses) {
7827 if (Clause->getClauseKind() == OMPC_nowait)
7828 Nowait = Clause;
7829 else if (Clause->getClauseKind() == OMPC_copyprivate)
7830 Copyprivate = Clause;
7831 if (Copyprivate && Nowait) {
7832 Diag(Copyprivate->getBeginLoc(),
7833 diag::err_omp_single_copyprivate_with_nowait);
7834 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
7835 return StmtError();
7836 }
7837 }
7838
7839 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7840 }
7841
7842 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
7843 SourceLocation StartLoc,
7844 SourceLocation EndLoc) {
7845 if (!AStmt)
7846 return StmtError();
7847
7848 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7849
7850 setFunctionHasBranchProtectedScope();
7851
7852 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
7853 }
7854
7855 StmtResult Sema::ActOnOpenMPCriticalDirective(
7856 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
7857 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
7858 if (!AStmt)
7859 return StmtError();
7860
7861 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7862
7863 bool ErrorFound = false;
7864 llvm::APSInt Hint;
7865 SourceLocation HintLoc;
7866 bool DependentHint = false;
7867 for (const OMPClause *C : Clauses) {
7868 if (C->getClauseKind() == OMPC_hint) {
7869 if (!DirName.getName()) {
7870 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
7871 ErrorFound = true;
7872 }
7873 Expr *E = cast<OMPHintClause>(C)->getHint();
7874 if (E->isTypeDependent() || E->isValueDependent() ||
7875 E->isInstantiationDependent()) {
7876 DependentHint = true;
7877 } else {
7878 Hint = E->EvaluateKnownConstInt(Context);
7879 HintLoc = C->getBeginLoc();
7880 }
7881 }
7882 }
7883 if (ErrorFound)
7884 return StmtError();
7885 const auto Pair = DSAStack->getCriticalWithHint(DirName);
7886 if (Pair.first && DirName.getName() && !DependentHint) {
7887 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
7888 Diag(StartLoc, diag::err_omp_critical_with_hint);
7889 if (HintLoc.isValid())
7890 Diag(HintLoc, diag::note_omp_critical_hint_here)
7891 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
7892 else
7893 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
7894 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
7895 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
7896 << 1
7897 << C->getHint()->EvaluateKnownConstInt(Context).toString(
7898 /*Radix=*/10, /*Signed=*/false);
7899 } else {
7900 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
7901 }
7902 }
7903 }
7904
7905 setFunctionHasBranchProtectedScope();
7906
7907 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
7908 Clauses, AStmt);
7909 if (!Pair.first && DirName.getName() && !DependentHint)
7910 DSAStack->addCriticalWithHint(Dir, Hint);
7911 return Dir;
7912 }
7913
7914 StmtResult Sema::ActOnOpenMPParallelForDirective(
7915 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7916 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7917 if (!AStmt)
7918 return StmtError();
7919
7920 auto *CS = cast<CapturedStmt>(AStmt);
7921 // 1.2.2 OpenMP Language Terminology
7922 // Structured block - An executable statement with a single entry at the
7923 // top and a single exit at the bottom.
7924 // The point of exit cannot be a branch out of the structured block.
7925 // longjmp() and throw() must not violate the entry/exit criteria.
7926 CS->getCapturedDecl()->setNothrow();
7927
7928 OMPLoopDirective::HelperExprs B;
7929 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7930 // define the nested loops number.
7931 unsigned NestedLoopCount =
7932 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
7933 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
7934 VarsWithImplicitDSA, B);
7935 if (NestedLoopCount == 0)
7936 return StmtError();
7937
7938 assert((CurContext->isDependentContext() || B.builtAll()) &&
7939 "omp parallel for loop exprs were not built");
7940
7941 if (!CurContext->isDependentContext()) {
7942 // Finalize the clauses that need pre-built expressions for CodeGen.
7943 for (OMPClause *C : Clauses) {
7944 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7945 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7946 B.NumIterations, *this, CurScope,
7947 DSAStack))
7948 return StmtError();
7949 }
7950 }
7951
7952 setFunctionHasBranchProtectedScope();
7953 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
7954 NestedLoopCount, Clauses, AStmt, B,
7955 DSAStack->isCancelRegion());
7956 }
7957
7958 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
7959 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7960 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7961 if (!AStmt)
7962 return StmtError();
7963
7964 auto *CS = cast<CapturedStmt>(AStmt);
7965 // 1.2.2 OpenMP Language Terminology
7966 // Structured block - An executable statement with a single entry at the
7967 // top and a single exit at the bottom.
7968 // The point of exit cannot be a branch out of the structured block.
7969 // longjmp() and throw() must not violate the entry/exit criteria.
7970 CS->getCapturedDecl()->setNothrow();
7971
7972 OMPLoopDirective::HelperExprs B;
7973 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7974 // define the nested loops number.
7975 unsigned NestedLoopCount =
7976 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
7977 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
7978 VarsWithImplicitDSA, B);
7979 if (NestedLoopCount == 0)
7980 return StmtError();
7981
7982 if (!CurContext->isDependentContext()) {
7983 // Finalize the clauses that need pre-built expressions for CodeGen.
7984 for (OMPClause *C : Clauses) {
7985 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7986 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7987 B.NumIterations, *this, CurScope,
7988 DSAStack))
7989 return StmtError();
7990 }
7991 }
7992
7993 if (checkSimdlenSafelenSpecified(*this, Clauses))
7994 return StmtError();
7995
7996 setFunctionHasBranchProtectedScope();
7997 return OMPParallelForSimdDirective::Create(
7998 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7999 }
8000
8001 StmtResult
8002 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
8003 Stmt *AStmt, SourceLocation StartLoc,
8004 SourceLocation EndLoc) {
8005 if (!AStmt)
8006 return StmtError();
8007
8008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8009 auto BaseStmt = AStmt;
8010 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8011 BaseStmt = CS->getCapturedStmt();
8012 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8013 auto S = C->children();
8014 if (S.begin() == S.end())
8015 return StmtError();
8016 // All associated statements must be '#pragma omp section' except for
8017 // the first one.
8018 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8019 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8020 if (SectionStmt)
8021 Diag(SectionStmt->getBeginLoc(),
8022 diag::err_omp_parallel_sections_substmt_not_section);
8023 return StmtError();
8024 }
8025 cast<OMPSectionDirective>(SectionStmt)
8026 ->setHasCancel(DSAStack->isCancelRegion());
8027 }
8028 } else {
8029 Diag(AStmt->getBeginLoc(),
8030 diag::err_omp_parallel_sections_not_compound_stmt);
8031 return StmtError();
8032 }
8033
8034 setFunctionHasBranchProtectedScope();
8035
8036 return OMPParallelSectionsDirective::Create(
8037 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
8038 }
8039
8040 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
8041 Stmt *AStmt, SourceLocation StartLoc,
8042 SourceLocation EndLoc) {
8043 if (!AStmt)
8044 return StmtError();
8045
8046 auto *CS = cast<CapturedStmt>(AStmt);
8047 // 1.2.2 OpenMP Language Terminology
8048 // Structured block - An executable statement with a single entry at the
8049 // top and a single exit at the bottom.
8050 // The point of exit cannot be a branch out of the structured block.
8051 // longjmp() and throw() must not violate the entry/exit criteria.
8052 CS->getCapturedDecl()->setNothrow();
8053
8054 setFunctionHasBranchProtectedScope();
8055
8056 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8057 DSAStack->isCancelRegion());
8058 }
8059
8060 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
8061 SourceLocation EndLoc) {
8062 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
8063 }
8064
8065 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
8066 SourceLocation EndLoc) {
8067 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
8068 }
8069
8070 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
8071 SourceLocation EndLoc) {
8072 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
8073 }
8074
8075 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
8076 Stmt *AStmt,
8077 SourceLocation StartLoc,
8078 SourceLocation EndLoc) {
8079 if (!AStmt)
8080 return StmtError();
8081
8082 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8083
8084 setFunctionHasBranchProtectedScope();
8085
8086 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
8087 AStmt,
8088 DSAStack->getTaskgroupReductionRef());
8089 }
8090
8091 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
8092 SourceLocation StartLoc,
8093 SourceLocation EndLoc) {
8094 assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
8095 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
8096 }
8097
8098 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
8099 Stmt *AStmt,
8100 SourceLocation StartLoc,
8101 SourceLocation EndLoc) {
8102 const OMPClause *DependFound = nullptr;
8103 const OMPClause *DependSourceClause = nullptr;
8104 const OMPClause *DependSinkClause = nullptr;
8105 bool ErrorFound = false;
8106 const OMPThreadsClause *TC = nullptr;
8107 const OMPSIMDClause *SC = nullptr;
8108 for (const OMPClause *C : Clauses) {
8109 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
8110 DependFound = C;
8111 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
8112 if (DependSourceClause) {
8113 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
8114 << getOpenMPDirectiveName(OMPD_ordered)
8115 << getOpenMPClauseName(OMPC_depend) << 2;
8116 ErrorFound = true;
8117 } else {
8118 DependSourceClause = C;
8119 }
8120 if (DependSinkClause) {
8121 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8122 << 0;
8123 ErrorFound = true;
8124 }
8125 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
8126 if (DependSourceClause) {
8127 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8128 << 1;
8129 ErrorFound = true;
8130 }
8131 DependSinkClause = C;
8132 }
8133 } else if (C->getClauseKind() == OMPC_threads) {
8134 TC = cast<OMPThreadsClause>(C);
8135 } else if (C->getClauseKind() == OMPC_simd) {
8136 SC = cast<OMPSIMDClause>(C);
8137 }
8138 }
8139 if (!ErrorFound && !SC &&
8140 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
8141 // OpenMP [2.8.1,simd Construct, Restrictions]
8142 // An ordered construct with the simd clause is the only OpenMP construct
8143 // that can appear in the simd region.
8144 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
8145 ErrorFound = true;
8146 } else if (DependFound && (TC || SC)) {
8147 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
8148 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
8149 ErrorFound = true;
8150 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
8151 Diag(DependFound->getBeginLoc(),
8152 diag::err_omp_ordered_directive_without_param);
8153 ErrorFound = true;
8154 } else if (TC || Clauses.empty()) {
8155 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
8156 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
8157 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
8158 << (TC != nullptr);
8159 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
8160 ErrorFound = true;
8161 }
8162 }
8163 if ((!AStmt && !DependFound) || ErrorFound)
8164 return StmtError();
8165
8166 if (AStmt) {
8167 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8168
8169 setFunctionHasBranchProtectedScope();
8170 }
8171
8172 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8173 }
8174
8175 namespace {
8176 /// Helper class for checking expression in 'omp atomic [update]'
8177 /// construct.
8178 class OpenMPAtomicUpdateChecker {
8179 /// Error results for atomic update expressions.
8180 enum ExprAnalysisErrorCode {
8181 /// A statement is not an expression statement.
8182 NotAnExpression,
8183 /// Expression is not builtin binary or unary operation.
8184 NotABinaryOrUnaryExpression,
8185 /// Unary operation is not post-/pre- increment/decrement operation.
8186 NotAnUnaryIncDecExpression,
8187 /// An expression is not of scalar type.
8188 NotAScalarType,
8189 /// A binary operation is not an assignment operation.
8190 NotAnAssignmentOp,
8191 /// RHS part of the binary operation is not a binary expression.
8192 NotABinaryExpression,
8193 /// RHS part is not additive/multiplicative/shift/biwise binary
8194 /// expression.
8195 NotABinaryOperator,
8196 /// RHS binary operation does not have reference to the updated LHS
8197 /// part.
8198 NotAnUpdateExpression,
8199 /// No errors is found.
8200 NoError
8201 };
8202 /// Reference to Sema.
8203 Sema &SemaRef;
8204 /// A location for note diagnostics (when error is found).
8205 SourceLocation NoteLoc;
8206 /// 'x' lvalue part of the source atomic expression.
8207 Expr *X;
8208 /// 'expr' rvalue part of the source atomic expression.
8209 Expr *E;
8210 /// Helper expression of the form
8211 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8212 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8213 Expr *UpdateExpr;
8214 /// Is 'x' a LHS in a RHS part of full update expression. It is
8215 /// important for non-associative operations.
8216 bool IsXLHSInRHSPart;
8217 BinaryOperatorKind Op;
8218 SourceLocation OpLoc;
8219 /// true if the source expression is a postfix unary operation, false
8220 /// if it is a prefix unary operation.
8221 bool IsPostfixUpdate;
8222
8223 public:
8224 OpenMPAtomicUpdateChecker(Sema &SemaRef)
8225 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
8226 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
8227 /// Check specified statement that it is suitable for 'atomic update'
8228 /// constructs and extract 'x', 'expr' and Operation from the original
8229 /// expression. If DiagId and NoteId == 0, then only check is performed
8230 /// without error notification.
8231 /// \param DiagId Diagnostic which should be emitted if error is found.
8232 /// \param NoteId Diagnostic note for the main error message.
8233 /// \return true if statement is not an update expression, false otherwise.
8234 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
8235 /// Return the 'x' lvalue part of the source atomic expression.
8236 Expr *getX() const { return X; }
8237 /// Return the 'expr' rvalue part of the source atomic expression.
8238 Expr *getExpr() const { return E; }
8239 /// Return the update expression used in calculation of the updated
8240 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8241 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8242 Expr *getUpdateExpr() const { return UpdateExpr; }
8243 /// Return true if 'x' is LHS in RHS part of full update expression,
8244 /// false otherwise.
8245 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
8246
8247 /// true if the source expression is a postfix unary operation, false
8248 /// if it is a prefix unary operation.
8249 bool isPostfixUpdate() const { return IsPostfixUpdate; }
8250
8251 private:
8252 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
8253 unsigned NoteId = 0);
8254 };
8255 } // namespace
8256
8257 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
8258 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
8259 ExprAnalysisErrorCode ErrorFound = NoError;
8260 SourceLocation ErrorLoc, NoteLoc;
8261 SourceRange ErrorRange, NoteRange;
8262 // Allowed constructs are:
8263 // x = x binop expr;
8264 // x = expr binop x;
8265 if (AtomicBinOp->getOpcode() == BO_Assign) {
8266 X = AtomicBinOp->getLHS();
8267 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
8268 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
8269 if (AtomicInnerBinOp->isMultiplicativeOp() ||
8270 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
8271 AtomicInnerBinOp->isBitwiseOp()) {
8272 Op = AtomicInnerBinOp->getOpcode();
8273 OpLoc = AtomicInnerBinOp->getOperatorLoc();
8274 Expr *LHS = AtomicInnerBinOp->getLHS();
8275 Expr *RHS = AtomicInnerBinOp->getRHS();
8276 llvm::FoldingSetNodeID XId, LHSId, RHSId;
8277 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
8278 /*Canonical=*/true);
8279 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
8280 /*Canonical=*/true);
8281 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
8282 /*Canonical=*/true);
8283 if (XId == LHSId) {
8284 E = RHS;
8285 IsXLHSInRHSPart = true;
8286 } else if (XId == RHSId) {
8287 E = LHS;
8288 IsXLHSInRHSPart = false;
8289 } else {
8290 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8291 ErrorRange = AtomicInnerBinOp->getSourceRange();
8292 NoteLoc = X->getExprLoc();
8293 NoteRange = X->getSourceRange();
8294 ErrorFound = NotAnUpdateExpression;
8295 }
8296 } else {
8297 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8298 ErrorRange = AtomicInnerBinOp->getSourceRange();
8299 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
8300 NoteRange = SourceRange(NoteLoc, NoteLoc);
8301 ErrorFound = NotABinaryOperator;
8302 }
8303 } else {
8304 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
8305 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
8306 ErrorFound = NotABinaryExpression;
8307 }
8308 } else {
8309 ErrorLoc = AtomicBinOp->getExprLoc();
8310 ErrorRange = AtomicBinOp->getSourceRange();
8311 NoteLoc = AtomicBinOp->getOperatorLoc();
8312 NoteRange = SourceRange(NoteLoc, NoteLoc);
8313 ErrorFound = NotAnAssignmentOp;
8314 }
8315 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8316 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8317 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8318 return true;
8319 }
8320 if (SemaRef.CurContext->isDependentContext())
8321 E = X = UpdateExpr = nullptr;
8322 return ErrorFound != NoError;
8323 }
8324
8325 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
8326 unsigned NoteId) {
8327 ExprAnalysisErrorCode ErrorFound = NoError;
8328 SourceLocation ErrorLoc, NoteLoc;
8329 SourceRange ErrorRange, NoteRange;
8330 // Allowed constructs are:
8331 // x++;
8332 // x--;
8333 // ++x;
8334 // --x;
8335 // x binop= expr;
8336 // x = x binop expr;
8337 // x = expr binop x;
8338 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
8339 AtomicBody = AtomicBody->IgnoreParenImpCasts();
8340 if (AtomicBody->getType()->isScalarType() ||
8341 AtomicBody->isInstantiationDependent()) {
8342 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
8343 AtomicBody->IgnoreParenImpCasts())) {
8344 // Check for Compound Assignment Operation
8345 Op = BinaryOperator::getOpForCompoundAssignment(
8346 AtomicCompAssignOp->getOpcode());
8347 OpLoc = AtomicCompAssignOp->getOperatorLoc();
8348 E = AtomicCompAssignOp->getRHS();
8349 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
8350 IsXLHSInRHSPart = true;
8351 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
8352 AtomicBody->IgnoreParenImpCasts())) {
8353 // Check for Binary Operation
8354 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
8355 return true;
8356 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
8357 AtomicBody->IgnoreParenImpCasts())) {
8358 // Check for Unary Operation
8359 if (AtomicUnaryOp->isIncrementDecrementOp()) {
8360 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
8361 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
8362 OpLoc = AtomicUnaryOp->getOperatorLoc();
8363 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
8364 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
8365 IsXLHSInRHSPart = true;
8366 } else {
8367 ErrorFound = NotAnUnaryIncDecExpression;
8368 ErrorLoc = AtomicUnaryOp->getExprLoc();
8369 ErrorRange = AtomicUnaryOp->getSourceRange();
8370 NoteLoc = AtomicUnaryOp->getOperatorLoc();
8371 NoteRange = SourceRange(NoteLoc, NoteLoc);
8372 }
8373 } else if (!AtomicBody->isInstantiationDependent()) {
8374 ErrorFound = NotABinaryOrUnaryExpression;
8375 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
8376 NoteRange = ErrorRange = AtomicBody->getSourceRange();
8377 }
8378 } else {
8379 ErrorFound = NotAScalarType;
8380 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
8381 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8382 }
8383 } else {
8384 ErrorFound = NotAnExpression;
8385 NoteLoc = ErrorLoc = S->getBeginLoc();
8386 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8387 }
8388 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8389 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8390 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8391 return true;
8392 }
8393 if (SemaRef.CurContext->isDependentContext())
8394 E = X = UpdateExpr = nullptr;
8395 if (ErrorFound == NoError && E && X) {
8396 // Build an update expression of form 'OpaqueValueExpr(x) binop
8397 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
8398 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
8399 auto *OVEX = new (SemaRef.getASTContext())
8400 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
8401 auto *OVEExpr = new (SemaRef.getASTContext())
8402 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
8403 ExprResult Update =
8404 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
8405 IsXLHSInRHSPart ? OVEExpr : OVEX);
8406 if (Update.isInvalid())
8407 return true;
8408 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
8409 Sema::AA_Casting);
8410 if (Update.isInvalid())
8411 return true;
8412 UpdateExpr = Update.get();
8413 }
8414 return ErrorFound != NoError;
8415 }
8416
8417 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
8418 Stmt *AStmt,
8419 SourceLocation StartLoc,
8420 SourceLocation EndLoc) {
8421 if (!AStmt)
8422 return StmtError();
8423
8424 auto *CS = cast<CapturedStmt>(AStmt);
8425 // 1.2.2 OpenMP Language Terminology
8426 // Structured block - An executable statement with a single entry at the
8427 // top and a single exit at the bottom.
8428 // The point of exit cannot be a branch out of the structured block.
8429 // longjmp() and throw() must not violate the entry/exit criteria.
8430 OpenMPClauseKind AtomicKind = OMPC_unknown;
8431 SourceLocation AtomicKindLoc;
8432 for (const OMPClause *C : Clauses) {
8433 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
8434 C->getClauseKind() == OMPC_update ||
8435 C->getClauseKind() == OMPC_capture) {
8436 if (AtomicKind != OMPC_unknown) {
8437 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
8438 << SourceRange(C->getBeginLoc(), C->getEndLoc());
8439 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
8440 << getOpenMPClauseName(AtomicKind);
8441 } else {
8442 AtomicKind = C->getClauseKind();
8443 AtomicKindLoc = C->getBeginLoc();
8444 }
8445 }
8446 }
8447
8448 Stmt *Body = CS->getCapturedStmt();
8449 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
8450 Body = EWC->getSubExpr();
8451
8452 Expr *X = nullptr;
8453 Expr *V = nullptr;
8454 Expr *E = nullptr;
8455 Expr *UE = nullptr;
8456 bool IsXLHSInRHSPart = false;
8457 bool IsPostfixUpdate = false;
8458 // OpenMP [2.12.6, atomic Construct]
8459 // In the next expressions:
8460 // * x and v (as applicable) are both l-value expressions with scalar type.
8461 // * During the execution of an atomic region, multiple syntactic
8462 // occurrences of x must designate the same storage location.
8463 // * Neither of v and expr (as applicable) may access the storage location
8464 // designated by x.
8465 // * Neither of x and expr (as applicable) may access the storage location
8466 // designated by v.
8467 // * expr is an expression with scalar type.
8468 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
8469 // * binop, binop=, ++, and -- are not overloaded operators.
8470 // * The expression x binop expr must be numerically equivalent to x binop
8471 // (expr). This requirement is satisfied if the operators in expr have
8472 // precedence greater than binop, or by using parentheses around expr or
8473 // subexpressions of expr.
8474 // * The expression expr binop x must be numerically equivalent to (expr)
8475 // binop x. This requirement is satisfied if the operators in expr have
8476 // precedence equal to or greater than binop, or by using parentheses around
8477 // expr or subexpressions of expr.
8478 // * For forms that allow multiple occurrences of x, the number of times
8479 // that x is evaluated is unspecified.
8480 if (AtomicKind == OMPC_read) {
8481 enum {
8482 NotAnExpression,
8483 NotAnAssignmentOp,
8484 NotAScalarType,
8485 NotAnLValue,
8486 NoError
8487 } ErrorFound = NoError;
8488 SourceLocation ErrorLoc, NoteLoc;
8489 SourceRange ErrorRange, NoteRange;
8490 // If clause is read:
8491 // v = x;
8492 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8493 const auto *AtomicBinOp =
8494 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8495 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
8496 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
8497 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
8498 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
8499 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
8500 if (!X->isLValue() || !V->isLValue()) {
8501 const Expr *NotLValueExpr = X->isLValue() ? V : X;
8502 ErrorFound = NotAnLValue;
8503 ErrorLoc = AtomicBinOp->getExprLoc();
8504 ErrorRange = AtomicBinOp->getSourceRange();
8505 NoteLoc = NotLValueExpr->getExprLoc();
8506 NoteRange = NotLValueExpr->getSourceRange();
8507 }
8508 } else if (!X->isInstantiationDependent() ||
8509 !V->isInstantiationDependent()) {
8510 const Expr *NotScalarExpr =
8511 (X->isInstantiationDependent() || X->getType()->isScalarType())
8512 ? V
8513 : X;
8514 ErrorFound = NotAScalarType;
8515 ErrorLoc = AtomicBinOp->getExprLoc();
8516 ErrorRange = AtomicBinOp->getSourceRange();
8517 NoteLoc = NotScalarExpr->getExprLoc();
8518 NoteRange = NotScalarExpr->getSourceRange();
8519 }
8520 } else if (!AtomicBody->isInstantiationDependent()) {
8521 ErrorFound = NotAnAssignmentOp;
8522 ErrorLoc = AtomicBody->getExprLoc();
8523 ErrorRange = AtomicBody->getSourceRange();
8524 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8525 : AtomicBody->getExprLoc();
8526 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8527 : AtomicBody->getSourceRange();
8528 }
8529 } else {
8530 ErrorFound = NotAnExpression;
8531 NoteLoc = ErrorLoc = Body->getBeginLoc();
8532 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8533 }
8534 if (ErrorFound != NoError) {
8535 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
8536 << ErrorRange;
8537 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
8538 << NoteRange;
8539 return StmtError();
8540 }
8541 if (CurContext->isDependentContext())
8542 V = X = nullptr;
8543 } else if (AtomicKind == OMPC_write) {
8544 enum {
8545 NotAnExpression,
8546 NotAnAssignmentOp,
8547 NotAScalarType,
8548 NotAnLValue,
8549 NoError
8550 } ErrorFound = NoError;
8551 SourceLocation ErrorLoc, NoteLoc;
8552 SourceRange ErrorRange, NoteRange;
8553 // If clause is write:
8554 // x = expr;
8555 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8556 const auto *AtomicBinOp =
8557 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8558 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
8559 X = AtomicBinOp->getLHS();
8560 E = AtomicBinOp->getRHS();
8561 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
8562 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
8563 if (!X->isLValue()) {
8564 ErrorFound = NotAnLValue;
8565 ErrorLoc = AtomicBinOp->getExprLoc();
8566 ErrorRange = AtomicBinOp->getSourceRange();
8567 NoteLoc = X->getExprLoc();
8568 NoteRange = X->getSourceRange();
8569 }
8570 } else if (!X->isInstantiationDependent() ||
8571 !E->isInstantiationDependent()) {
8572 const Expr *NotScalarExpr =
8573 (X->isInstantiationDependent() || X->getType()->isScalarType())
8574 ? E
8575 : X;
8576 ErrorFound = NotAScalarType;
8577 ErrorLoc = AtomicBinOp->getExprLoc();
8578 ErrorRange = AtomicBinOp->getSourceRange();
8579 NoteLoc = NotScalarExpr->getExprLoc();
8580 NoteRange = NotScalarExpr->getSourceRange();
8581 }
8582 } else if (!AtomicBody->isInstantiationDependent()) {
8583 ErrorFound = NotAnAssignmentOp;
8584 ErrorLoc = AtomicBody->getExprLoc();
8585 ErrorRange = AtomicBody->getSourceRange();
8586 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8587 : AtomicBody->getExprLoc();
8588 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8589 : AtomicBody->getSourceRange();
8590 }
8591 } else {
8592 ErrorFound = NotAnExpression;
8593 NoteLoc = ErrorLoc = Body->getBeginLoc();
8594 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8595 }
8596 if (ErrorFound != NoError) {
8597 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
8598 << ErrorRange;
8599 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
8600 << NoteRange;
8601 return StmtError();
8602 }
8603 if (CurContext->isDependentContext())
8604 E = X = nullptr;
8605 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
8606 // If clause is update:
8607 // x++;
8608 // x--;
8609 // ++x;
8610 // --x;
8611 // x binop= expr;
8612 // x = x binop expr;
8613 // x = expr binop x;
8614 OpenMPAtomicUpdateChecker Checker(*this);
8615 if (Checker.checkStatement(
8616 Body, (AtomicKind == OMPC_update)
8617 ? diag::err_omp_atomic_update_not_expression_statement
8618 : diag::err_omp_atomic_not_expression_statement,
8619 diag::note_omp_atomic_update))
8620 return StmtError();
8621 if (!CurContext->isDependentContext()) {
8622 E = Checker.getExpr();
8623 X = Checker.getX();
8624 UE = Checker.getUpdateExpr();
8625 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
8626 }
8627 } else if (AtomicKind == OMPC_capture) {
8628 enum {
8629 NotAnAssignmentOp,
8630 NotACompoundStatement,
8631 NotTwoSubstatements,
8632 NotASpecificExpression,
8633 NoError
8634 } ErrorFound = NoError;
8635 SourceLocation ErrorLoc, NoteLoc;
8636 SourceRange ErrorRange, NoteRange;
8637 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8638 // If clause is a capture:
8639 // v = x++;
8640 // v = x--;
8641 // v = ++x;
8642 // v = --x;
8643 // v = x binop= expr;
8644 // v = x = x binop expr;
8645 // v = x = expr binop x;
8646 const auto *AtomicBinOp =
8647 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8648 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
8649 V = AtomicBinOp->getLHS();
8650 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
8651 OpenMPAtomicUpdateChecker Checker(*this);
8652 if (Checker.checkStatement(
8653 Body, diag::err_omp_atomic_capture_not_expression_statement,
8654 diag::note_omp_atomic_update))
8655 return StmtError();
8656 E = Checker.getExpr();
8657 X = Checker.getX();
8658 UE = Checker.getUpdateExpr();
8659 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
8660 IsPostfixUpdate = Checker.isPostfixUpdate();
8661 } else if (!AtomicBody->isInstantiationDependent()) {
8662 ErrorLoc = AtomicBody->getExprLoc();
8663 ErrorRange = AtomicBody->getSourceRange();
8664 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8665 : AtomicBody->getExprLoc();
8666 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8667 : AtomicBody->getSourceRange();
8668 ErrorFound = NotAnAssignmentOp;
8669 }
8670 if (ErrorFound != NoError) {
8671 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
8672 << ErrorRange;
8673 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
8674 return StmtError();
8675 }
8676 if (CurContext->isDependentContext())
8677 UE = V = E = X = nullptr;
8678 } else {
8679 // If clause is a capture:
8680 // { v = x; x = expr; }
8681 // { v = x; x++; }
8682 // { v = x; x--; }
8683 // { v = x; ++x; }
8684 // { v = x; --x; }
8685 // { v = x; x binop= expr; }
8686 // { v = x; x = x binop expr; }
8687 // { v = x; x = expr binop x; }
8688 // { x++; v = x; }
8689 // { x--; v = x; }
8690 // { ++x; v = x; }
8691 // { --x; v = x; }
8692 // { x binop= expr; v = x; }
8693 // { x = x binop expr; v = x; }
8694 // { x = expr binop x; v = x; }
8695 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
8696 // Check that this is { expr1; expr2; }
8697 if (CS->size() == 2) {
8698 Stmt *First = CS->body_front();
8699 Stmt *Second = CS->body_back();
8700 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
8701 First = EWC->getSubExpr()->IgnoreParenImpCasts();
8702 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
8703 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
8704 // Need to find what subexpression is 'v' and what is 'x'.
8705 OpenMPAtomicUpdateChecker Checker(*this);
8706 bool IsUpdateExprFound = !Checker.checkStatement(Second);
8707 BinaryOperator *BinOp = nullptr;
8708 if (IsUpdateExprFound) {
8709 BinOp = dyn_cast<BinaryOperator>(First);
8710 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
8711 }
8712 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
8713 // { v = x; x++; }
8714 // { v = x; x--; }
8715 // { v = x; ++x; }
8716 // { v = x; --x; }
8717 // { v = x; x binop= expr; }
8718 // { v = x; x = x binop expr; }
8719 // { v = x; x = expr binop x; }
8720 // Check that the first expression has form v = x.
8721 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
8722 llvm::FoldingSetNodeID XId, PossibleXId;
8723 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
8724 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
8725 IsUpdateExprFound = XId == PossibleXId;
8726 if (IsUpdateExprFound) {
8727 V = BinOp->getLHS();
8728 X = Checker.getX();
8729 E = Checker.getExpr();
8730 UE = Checker.getUpdateExpr();
8731 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
8732 IsPostfixUpdate = true;
8733 }
8734 }
8735 if (!IsUpdateExprFound) {
8736 IsUpdateExprFound = !Checker.checkStatement(First);
8737 BinOp = nullptr;
8738 if (IsUpdateExprFound) {
8739 BinOp = dyn_cast<BinaryOperator>(Second);
8740 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
8741 }
8742 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
8743 // { x++; v = x; }
8744 // { x--; v = x; }
8745 // { ++x; v = x; }
8746 // { --x; v = x; }
8747 // { x binop= expr; v = x; }
8748 // { x = x binop expr; v = x; }
8749 // { x = expr binop x; v = x; }
8750 // Check that the second expression has form v = x.
8751 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
8752 llvm::FoldingSetNodeID XId, PossibleXId;
8753 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
8754 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
8755 IsUpdateExprFound = XId == PossibleXId;
8756 if (IsUpdateExprFound) {
8757 V = BinOp->getLHS();
8758 X = Checker.getX();
8759 E = Checker.getExpr();
8760 UE = Checker.getUpdateExpr();
8761 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
8762 IsPostfixUpdate = false;
8763 }
8764 }
8765 }
8766 if (!IsUpdateExprFound) {
8767 // { v = x; x = expr; }
8768 auto *FirstExpr = dyn_cast<Expr>(First);
8769 auto *SecondExpr = dyn_cast<Expr>(Second);
8770 if (!FirstExpr || !SecondExpr ||
8771 !(FirstExpr->isInstantiationDependent() ||
8772 SecondExpr->isInstantiationDependent())) {
8773 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
8774 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
8775 ErrorFound = NotAnAssignmentOp;
8776 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
8777 : First->getBeginLoc();
8778 NoteRange = ErrorRange = FirstBinOp
8779 ? FirstBinOp->getSourceRange()
8780 : SourceRange(ErrorLoc, ErrorLoc);
8781 } else {
8782 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
8783 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
8784 ErrorFound = NotAnAssignmentOp;
8785 NoteLoc = ErrorLoc = SecondBinOp
8786 ? SecondBinOp->getOperatorLoc()
8787 : Second->getBeginLoc();
8788 NoteRange = ErrorRange =
8789 SecondBinOp ? SecondBinOp->getSourceRange()
8790 : SourceRange(ErrorLoc, ErrorLoc);
8791 } else {
8792 Expr *PossibleXRHSInFirst =
8793 FirstBinOp->getRHS()->IgnoreParenImpCasts();
8794 Expr *PossibleXLHSInSecond =
8795 SecondBinOp->getLHS()->IgnoreParenImpCasts();
8796 llvm::FoldingSetNodeID X1Id, X2Id;
8797 PossibleXRHSInFirst->Profile(X1Id, Context,
8798 /*Canonical=*/true);
8799 PossibleXLHSInSecond->Profile(X2Id, Context,
8800 /*Canonical=*/true);
8801 IsUpdateExprFound = X1Id == X2Id;
8802 if (IsUpdateExprFound) {
8803 V = FirstBinOp->getLHS();
8804 X = SecondBinOp->getLHS();
8805 E = SecondBinOp->getRHS();
8806 UE = nullptr;
8807 IsXLHSInRHSPart = false;
8808 IsPostfixUpdate = true;
8809 } else {
8810 ErrorFound = NotASpecificExpression;
8811 ErrorLoc = FirstBinOp->getExprLoc();
8812 ErrorRange = FirstBinOp->getSourceRange();
8813 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
8814 NoteRange = SecondBinOp->getRHS()->getSourceRange();
8815 }
8816 }
8817 }
8818 }
8819 }
8820 } else {
8821 NoteLoc = ErrorLoc = Body->getBeginLoc();
8822 NoteRange = ErrorRange =
8823 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
8824 ErrorFound = NotTwoSubstatements;
8825 }
8826 } else {
8827 NoteLoc = ErrorLoc = Body->getBeginLoc();
8828 NoteRange = ErrorRange =
8829 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
8830 ErrorFound = NotACompoundStatement;
8831 }
8832 if (ErrorFound != NoError) {
8833 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
8834 << ErrorRange;
8835 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
8836 return StmtError();
8837 }
8838 if (CurContext->isDependentContext())
8839 UE = V = E = X = nullptr;
8840 }
8841 }
8842
8843 setFunctionHasBranchProtectedScope();
8844
8845 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8846 X, V, E, UE, IsXLHSInRHSPart,
8847 IsPostfixUpdate);
8848 }
8849
8850 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
8851 Stmt *AStmt,
8852 SourceLocation StartLoc,
8853 SourceLocation EndLoc) {
8854 if (!AStmt)
8855 return StmtError();
8856
8857 auto *CS = cast<CapturedStmt>(AStmt);
8858 // 1.2.2 OpenMP Language Terminology
8859 // Structured block - An executable statement with a single entry at the
8860 // top and a single exit at the bottom.
8861 // The point of exit cannot be a branch out of the structured block.
8862 // longjmp() and throw() must not violate the entry/exit criteria.
8863 CS->getCapturedDecl()->setNothrow();
8864 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
8865 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8866 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8867 // 1.2.2 OpenMP Language Terminology
8868 // Structured block - An executable statement with a single entry at the
8869 // top and a single exit at the bottom.
8870 // The point of exit cannot be a branch out of the structured block.
8871 // longjmp() and throw() must not violate the entry/exit criteria.
8872 CS->getCapturedDecl()->setNothrow();
8873 }
8874
8875 // OpenMP [2.16, Nesting of Regions]
8876 // If specified, a teams construct must be contained within a target
8877 // construct. That target construct must contain no statements or directives
8878 // outside of the teams construct.
8879 if (DSAStack->hasInnerTeamsRegion()) {
8880 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
8881 bool OMPTeamsFound = true;
8882 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
8883 auto I = CS->body_begin();
8884 while (I != CS->body_end()) {
8885 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
8886 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
8887 OMPTeamsFound) {
8888
8889 OMPTeamsFound = false;
8890 break;
8891 }
8892 ++I;
8893 }
8894 assert(I != CS->body_end() && "Not found statement");
8895 S = *I;
8896 } else {
8897 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
8898 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
8899 }
8900 if (!OMPTeamsFound) {
8901 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
8902 Diag(DSAStack->getInnerTeamsRegionLoc(),
8903 diag::note_omp_nested_teams_construct_here);
8904 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
8905 << isa<OMPExecutableDirective>(S);
8906 return StmtError();
8907 }
8908 }
8909
8910 setFunctionHasBranchProtectedScope();
8911
8912 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8913 }
8914
8915 StmtResult
8916 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
8917 Stmt *AStmt, SourceLocation StartLoc,
8918 SourceLocation EndLoc) {
8919 if (!AStmt)
8920 return StmtError();
8921
8922 auto *CS = cast<CapturedStmt>(AStmt);
8923 // 1.2.2 OpenMP Language Terminology
8924 // Structured block - An executable statement with a single entry at the
8925 // top and a single exit at the bottom.
8926 // The point of exit cannot be a branch out of the structured block.
8927 // longjmp() and throw() must not violate the entry/exit criteria.
8928 CS->getCapturedDecl()->setNothrow();
8929 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
8930 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8931 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8932 // 1.2.2 OpenMP Language Terminology
8933 // Structured block - An executable statement with a single entry at the
8934 // top and a single exit at the bottom.
8935 // The point of exit cannot be a branch out of the structured block.
8936 // longjmp() and throw() must not violate the entry/exit criteria.
8937 CS->getCapturedDecl()->setNothrow();
8938 }
8939
8940 setFunctionHasBranchProtectedScope();
8941
8942 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
8943 AStmt);
8944 }
8945
8946 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
8947 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8948 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8949 if (!AStmt)
8950 return StmtError();
8951
8952 auto *CS = cast<CapturedStmt>(AStmt);
8953 // 1.2.2 OpenMP Language Terminology
8954 // Structured block - An executable statement with a single entry at the
8955 // top and a single exit at the bottom.
8956 // The point of exit cannot be a branch out of the structured block.
8957 // longjmp() and throw() must not violate the entry/exit criteria.
8958 CS->getCapturedDecl()->setNothrow();
8959 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
8960 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8961 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8962 // 1.2.2 OpenMP Language Terminology
8963 // Structured block - An executable statement with a single entry at the
8964 // top and a single exit at the bottom.
8965 // The point of exit cannot be a branch out of the structured block.
8966 // longjmp() and throw() must not violate the entry/exit criteria.
8967 CS->getCapturedDecl()->setNothrow();
8968 }
8969
8970 OMPLoopDirective::HelperExprs B;
8971 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8972 // define the nested loops number.
8973 unsigned NestedLoopCount =
8974 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
8975 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
8976 VarsWithImplicitDSA, B);
8977 if (NestedLoopCount == 0)
8978 return StmtError();
8979
8980 assert((CurContext->isDependentContext() || B.builtAll()) &&
8981 "omp target parallel for loop exprs were not built");
8982
8983 if (!CurContext->isDependentContext()) {
8984 // Finalize the clauses that need pre-built expressions for CodeGen.
8985 for (OMPClause *C : Clauses) {
8986 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8987 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8988 B.NumIterations, *this, CurScope,
8989 DSAStack))
8990 return StmtError();
8991 }
8992 }
8993
8994 setFunctionHasBranchProtectedScope();
8995 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
8996 NestedLoopCount, Clauses, AStmt,
8997 B, DSAStack->isCancelRegion());
8998 }
8999
9000 /// Check for existence of a map clause in the list of clauses.
9001 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
9002 const OpenMPClauseKind K) {
9003 return llvm::any_of(
9004 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
9005 }
9006
9007 template <typename... Params>
9008 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
9009 const Params... ClauseTypes) {
9010 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
9011 }
9012
9013 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
9014 Stmt *AStmt,
9015 SourceLocation StartLoc,
9016 SourceLocation EndLoc) {
9017 if (!AStmt)
9018 return StmtError();
9019
9020 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9021
9022 // OpenMP [2.10.1, Restrictions, p. 97]
9023 // At least one map clause must appear on the directive.
9024 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
9025 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9026 << "'map' or 'use_device_ptr'"
9027 << getOpenMPDirectiveName(OMPD_target_data);
9028 return StmtError();
9029 }
9030
9031 setFunctionHasBranchProtectedScope();
9032
9033 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9034 AStmt);
9035 }
9036
9037 StmtResult
9038 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
9039 SourceLocation StartLoc,
9040 SourceLocation EndLoc, Stmt *AStmt) {
9041 if (!AStmt)
9042 return StmtError();
9043
9044 auto *CS = cast<CapturedStmt>(AStmt);
9045 // 1.2.2 OpenMP Language Terminology
9046 // Structured block - An executable statement with a single entry at the
9047 // top and a single exit at the bottom.
9048 // The point of exit cannot be a branch out of the structured block.
9049 // longjmp() and throw() must not violate the entry/exit criteria.
9050 CS->getCapturedDecl()->setNothrow();
9051 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
9052 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9053 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9054 // 1.2.2 OpenMP Language Terminology
9055 // Structured block - An executable statement with a single entry at the
9056 // top and a single exit at the bottom.
9057 // The point of exit cannot be a branch out of the structured block.
9058 // longjmp() and throw() must not violate the entry/exit criteria.
9059 CS->getCapturedDecl()->setNothrow();
9060 }
9061
9062 // OpenMP [2.10.2, Restrictions, p. 99]
9063 // At least one map clause must appear on the directive.
9064 if (!hasClauses(Clauses, OMPC_map)) {
9065 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9066 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
9067 return StmtError();
9068 }
9069
9070 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9071 AStmt);
9072 }
9073
9074 StmtResult
9075 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
9076 SourceLocation StartLoc,
9077 SourceLocation EndLoc, Stmt *AStmt) {
9078 if (!AStmt)
9079 return StmtError();
9080
9081 auto *CS = cast<CapturedStmt>(AStmt);
9082 // 1.2.2 OpenMP Language Terminology
9083 // Structured block - An executable statement with a single entry at the
9084 // top and a single exit at the bottom.
9085 // The point of exit cannot be a branch out of the structured block.
9086 // longjmp() and throw() must not violate the entry/exit criteria.
9087 CS->getCapturedDecl()->setNothrow();
9088 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
9089 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9090 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9091 // 1.2.2 OpenMP Language Terminology
9092 // Structured block - An executable statement with a single entry at the
9093 // top and a single exit at the bottom.
9094 // The point of exit cannot be a branch out of the structured block.
9095 // longjmp() and throw() must not violate the entry/exit criteria.
9096 CS->getCapturedDecl()->setNothrow();
9097 }
9098
9099 // OpenMP [2.10.3, Restrictions, p. 102]
9100 // At least one map clause must appear on the directive.
9101 if (!hasClauses(Clauses, OMPC_map)) {
9102 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9103 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
9104 return StmtError();
9105 }
9106
9107 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9108 AStmt);
9109 }
9110
9111 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
9112 SourceLocation StartLoc,
9113 SourceLocation EndLoc,
9114 Stmt *AStmt) {
9115 if (!AStmt)
9116 return StmtError();
9117
9118 auto *CS = cast<CapturedStmt>(AStmt);
9119 // 1.2.2 OpenMP Language Terminology
9120 // Structured block - An executable statement with a single entry at the
9121 // top and a single exit at the bottom.
9122 // The point of exit cannot be a branch out of the structured block.
9123 // longjmp() and throw() must not violate the entry/exit criteria.
9124 CS->getCapturedDecl()->setNothrow();
9125 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
9126 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9127 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9128 // 1.2.2 OpenMP Language Terminology
9129 // Structured block - An executable statement with a single entry at the
9130 // top and a single exit at the bottom.
9131 // The point of exit cannot be a branch out of the structured block.
9132 // longjmp() and throw() must not violate the entry/exit criteria.
9133 CS->getCapturedDecl()->setNothrow();
9134 }
9135
9136 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
9137 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
9138 return StmtError();
9139 }
9140 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
9141 AStmt);
9142 }
9143
9144 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
9145 Stmt *AStmt, SourceLocation StartLoc,
9146 SourceLocation EndLoc) {
9147 if (!AStmt)
9148 return StmtError();
9149
9150 auto *CS = cast<CapturedStmt>(AStmt);
9151 // 1.2.2 OpenMP Language Terminology
9152 // Structured block - An executable statement with a single entry at the
9153 // top and a single exit at the bottom.
9154 // The point of exit cannot be a branch out of the structured block.
9155 // longjmp() and throw() must not violate the entry/exit criteria.
9156 CS->getCapturedDecl()->setNothrow();
9157
9158 setFunctionHasBranchProtectedScope();
9159
9160 DSAStack->setParentTeamsRegionLoc(StartLoc);
9161
9162 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9163 }
9164
9165 StmtResult
9166 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
9167 SourceLocation EndLoc,
9168 OpenMPDirectiveKind CancelRegion) {
9169 if (DSAStack->isParentNowaitRegion()) {
9170 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
9171 return StmtError();
9172 }
9173 if (DSAStack->isParentOrderedRegion()) {
9174 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
9175 return StmtError();
9176 }
9177 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
9178 CancelRegion);
9179 }
9180
9181 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
9182 SourceLocation StartLoc,
9183 SourceLocation EndLoc,
9184 OpenMPDirectiveKind CancelRegion) {
9185 if (DSAStack->isParentNowaitRegion()) {
9186 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
9187 return StmtError();
9188 }
9189 if (DSAStack->isParentOrderedRegion()) {
9190 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
9191 return StmtError();
9192 }
9193 DSAStack->setParentCancelRegion(/*Cancel=*/true);
9194 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
9195 CancelRegion);
9196 }
9197
9198 static bool checkGrainsizeNumTasksClauses(Sema &S,
9199 ArrayRef<OMPClause *> Clauses) {
9200 const OMPClause *PrevClause = nullptr;
9201 bool ErrorFound = false;
9202 for (const OMPClause *C : Clauses) {
9203 if (C->getClauseKind() == OMPC_grainsize ||
9204 C->getClauseKind() == OMPC_num_tasks) {
9205 if (!PrevClause)
9206 PrevClause = C;
9207 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9208 S.Diag(C->getBeginLoc(),
9209 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
9210 << getOpenMPClauseName(C->getClauseKind())
9211 << getOpenMPClauseName(PrevClause->getClauseKind());
9212 S.Diag(PrevClause->getBeginLoc(),
9213 diag::note_omp_previous_grainsize_num_tasks)
9214 << getOpenMPClauseName(PrevClause->getClauseKind());
9215 ErrorFound = true;
9216 }
9217 }
9218 }
9219 return ErrorFound;
9220 }
9221
9222 static bool checkReductionClauseWithNogroup(Sema &S,
9223 ArrayRef<OMPClause *> Clauses) {
9224 const OMPClause *ReductionClause = nullptr;
9225 const OMPClause *NogroupClause = nullptr;
9226 for (const OMPClause *C : Clauses) {
9227 if (C->getClauseKind() == OMPC_reduction) {
9228 ReductionClause = C;
9229 if (NogroupClause)
9230 break;
9231 continue;
9232 }
9233 if (C->getClauseKind() == OMPC_nogroup) {
9234 NogroupClause = C;
9235 if (ReductionClause)
9236 break;
9237 continue;
9238 }
9239 }
9240 if (ReductionClause && NogroupClause) {
9241 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
9242 << SourceRange(NogroupClause->getBeginLoc(),
9243 NogroupClause->getEndLoc());
9244 return true;
9245 }
9246 return false;
9247 }
9248
9249 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
9250 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9251 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9252 if (!AStmt)
9253 return StmtError();
9254
9255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9256 OMPLoopDirective::HelperExprs B;
9257 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9258 // define the nested loops number.
9259 unsigned NestedLoopCount =
9260 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
9261 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9262 VarsWithImplicitDSA, B);
9263 if (NestedLoopCount == 0)
9264 return StmtError();
9265
9266 assert((CurContext->isDependentContext() || B.builtAll()) &&
9267 "omp for loop exprs were not built");
9268
9269 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9270 // The grainsize clause and num_tasks clause are mutually exclusive and may
9271 // not appear on the same taskloop directive.
9272 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9273 return StmtError();
9274 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9275 // If a reduction clause is present on the taskloop directive, the nogroup
9276 // clause must not be specified.
9277 if (checkReductionClauseWithNogroup(*this, Clauses))
9278 return StmtError();
9279
9280 setFunctionHasBranchProtectedScope();
9281 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9282 NestedLoopCount, Clauses, AStmt, B);
9283 }
9284
9285 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
9286 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9287 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9288 if (!AStmt)
9289 return StmtError();
9290
9291 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9292 OMPLoopDirective::HelperExprs B;
9293 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9294 // define the nested loops number.
9295 unsigned NestedLoopCount =
9296 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
9297 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9298 VarsWithImplicitDSA, B);
9299 if (NestedLoopCount == 0)
9300 return StmtError();
9301
9302 assert((CurContext->isDependentContext() || B.builtAll()) &&
9303 "omp for loop exprs were not built");
9304
9305 if (!CurContext->isDependentContext()) {
9306 // Finalize the clauses that need pre-built expressions for CodeGen.
9307 for (OMPClause *C : Clauses) {
9308 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9309 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9310 B.NumIterations, *this, CurScope,
9311 DSAStack))
9312 return StmtError();
9313 }
9314 }
9315
9316 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9317 // The grainsize clause and num_tasks clause are mutually exclusive and may
9318 // not appear on the same taskloop directive.
9319 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9320 return StmtError();
9321 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9322 // If a reduction clause is present on the taskloop directive, the nogroup
9323 // clause must not be specified.
9324 if (checkReductionClauseWithNogroup(*this, Clauses))
9325 return StmtError();
9326 if (checkSimdlenSafelenSpecified(*this, Clauses))
9327 return StmtError();
9328
9329 setFunctionHasBranchProtectedScope();
9330 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
9331 NestedLoopCount, Clauses, AStmt, B);
9332 }
9333
9334 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
9335 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9336 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9337 if (!AStmt)
9338 return StmtError();
9339
9340 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9341 OMPLoopDirective::HelperExprs B;
9342 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9343 // define the nested loops number.
9344 unsigned NestedLoopCount =
9345 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
9346 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9347 VarsWithImplicitDSA, B);
9348 if (NestedLoopCount == 0)
9349 return StmtError();
9350
9351 assert((CurContext->isDependentContext() || B.builtAll()) &&
9352 "omp for loop exprs were not built");
9353
9354 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9355 // The grainsize clause and num_tasks clause are mutually exclusive and may
9356 // not appear on the same taskloop directive.
9357 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9358 return StmtError();
9359 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9360 // If a reduction clause is present on the taskloop directive, the nogroup
9361 // clause must not be specified.
9362 if (checkReductionClauseWithNogroup(*this, Clauses))
9363 return StmtError();
9364
9365 setFunctionHasBranchProtectedScope();
9366 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9367 NestedLoopCount, Clauses, AStmt, B);
9368 }
9369
9370 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
9371 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9372 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9373 if (!AStmt)
9374 return StmtError();
9375
9376 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9377 OMPLoopDirective::HelperExprs B;
9378 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9379 // define the nested loops number.
9380 unsigned NestedLoopCount =
9381 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
9382 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9383 VarsWithImplicitDSA, B);
9384 if (NestedLoopCount == 0)
9385 return StmtError();
9386
9387 assert((CurContext->isDependentContext() || B.builtAll()) &&
9388 "omp for loop exprs were not built");
9389
9390 if (!CurContext->isDependentContext()) {
9391 // Finalize the clauses that need pre-built expressions for CodeGen.
9392 for (OMPClause *C : Clauses) {
9393 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9394 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9395 B.NumIterations, *this, CurScope,
9396 DSAStack))
9397 return StmtError();
9398 }
9399 }
9400
9401 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9402 // The grainsize clause and num_tasks clause are mutually exclusive and may
9403 // not appear on the same taskloop directive.
9404 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9405 return StmtError();
9406 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9407 // If a reduction clause is present on the taskloop directive, the nogroup
9408 // clause must not be specified.
9409 if (checkReductionClauseWithNogroup(*this, Clauses))
9410 return StmtError();
9411 if (checkSimdlenSafelenSpecified(*this, Clauses))
9412 return StmtError();
9413
9414 setFunctionHasBranchProtectedScope();
9415 return OMPMasterTaskLoopSimdDirective::Create(
9416 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9417 }
9418
9419 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
9420 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9421 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9422 if (!AStmt)
9423 return StmtError();
9424
9425 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9426 auto *CS = cast<CapturedStmt>(AStmt);
9427 // 1.2.2 OpenMP Language Terminology
9428 // Structured block - An executable statement with a single entry at the
9429 // top and a single exit at the bottom.
9430 // The point of exit cannot be a branch out of the structured block.
9431 // longjmp() and throw() must not violate the entry/exit criteria.
9432 CS->getCapturedDecl()->setNothrow();
9433 for (int ThisCaptureLevel =
9434 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
9435 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9436 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9437 // 1.2.2 OpenMP Language Terminology
9438 // Structured block - An executable statement with a single entry at the
9439 // top and a single exit at the bottom.
9440 // The point of exit cannot be a branch out of the structured block.
9441 // longjmp() and throw() must not violate the entry/exit criteria.
9442 CS->getCapturedDecl()->setNothrow();
9443 }
9444
9445 OMPLoopDirective::HelperExprs B;
9446 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9447 // define the nested loops number.
9448 unsigned NestedLoopCount = checkOpenMPLoop(
9449 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
9450 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
9451 VarsWithImplicitDSA, B);
9452 if (NestedLoopCount == 0)
9453 return StmtError();
9454
9455 assert((CurContext->isDependentContext() || B.builtAll()) &&
9456 "omp for loop exprs were not built");
9457
9458 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9459 // The grainsize clause and num_tasks clause are mutually exclusive and may
9460 // not appear on the same taskloop directive.
9461 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9462 return StmtError();
9463 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9464 // If a reduction clause is present on the taskloop directive, the nogroup
9465 // clause must not be specified.
9466 if (checkReductionClauseWithNogroup(*this, Clauses))
9467 return StmtError();
9468
9469 setFunctionHasBranchProtectedScope();
9470 return OMPParallelMasterTaskLoopDirective::Create(
9471 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9472 }
9473
9474 StmtResult Sema::ActOnOpenMPDistributeDirective(
9475 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9476 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9477 if (!AStmt)
9478 return StmtError();
9479
9480 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9481 OMPLoopDirective::HelperExprs B;
9482 // In presence of clause 'collapse' with number of loops, it will
9483 // define the nested loops number.
9484 unsigned NestedLoopCount =
9485 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
9486 nullptr /*ordered not a clause on distribute*/, AStmt,
9487 *this, *DSAStack, VarsWithImplicitDSA, B);
9488 if (NestedLoopCount == 0)
9489 return StmtError();
9490
9491 assert((CurContext->isDependentContext() || B.builtAll()) &&
9492 "omp for loop exprs were not built");
9493
9494 setFunctionHasBranchProtectedScope();
9495 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
9496 NestedLoopCount, Clauses, AStmt, B);
9497 }
9498
9499 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
9500 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9501 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9502 if (!AStmt)
9503 return StmtError();
9504
9505 auto *CS = cast<CapturedStmt>(AStmt);
9506 // 1.2.2 OpenMP Language Terminology
9507 // Structured block - An executable statement with a single entry at the
9508 // top and a single exit at the bottom.
9509 // The point of exit cannot be a branch out of the structured block.
9510 // longjmp() and throw() must not violate the entry/exit criteria.
9511 CS->getCapturedDecl()->setNothrow();
9512 for (int ThisCaptureLevel =
9513 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
9514 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9515 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9516 // 1.2.2 OpenMP Language Terminology
9517 // Structured block - An executable statement with a single entry at the
9518 // top and a single exit at the bottom.
9519 // The point of exit cannot be a branch out of the structured block.
9520 // longjmp() and throw() must not violate the entry/exit criteria.
9521 CS->getCapturedDecl()->setNothrow();
9522 }
9523
9524 OMPLoopDirective::HelperExprs B;
9525 // In presence of clause 'collapse' with number of loops, it will
9526 // define the nested loops number.
9527 unsigned NestedLoopCount = checkOpenMPLoop(
9528 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
9529 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
9530 VarsWithImplicitDSA, B);
9531 if (NestedLoopCount == 0)
9532 return StmtError();
9533
9534 assert((CurContext->isDependentContext() || B.builtAll()) &&
9535 "omp for loop exprs were not built");
9536
9537 setFunctionHasBranchProtectedScope();
9538 return OMPDistributeParallelForDirective::Create(
9539 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9540 DSAStack->isCancelRegion());
9541 }
9542
9543 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
9544 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9545 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9546 if (!AStmt)
9547 return StmtError();
9548
9549 auto *CS = cast<CapturedStmt>(AStmt);
9550 // 1.2.2 OpenMP Language Terminology
9551 // Structured block - An executable statement with a single entry at the
9552 // top and a single exit at the bottom.
9553 // The point of exit cannot be a branch out of the structured block.
9554 // longjmp() and throw() must not violate the entry/exit criteria.
9555 CS->getCapturedDecl()->setNothrow();
9556 for (int ThisCaptureLevel =
9557 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
9558 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9559 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9560 // 1.2.2 OpenMP Language Terminology
9561 // Structured block - An executable statement with a single entry at the
9562 // top and a single exit at the bottom.
9563 // The point of exit cannot be a branch out of the structured block.
9564 // longjmp() and throw() must not violate the entry/exit criteria.
9565 CS->getCapturedDecl()->setNothrow();
9566 }
9567
9568 OMPLoopDirective::HelperExprs B;
9569 // In presence of clause 'collapse' with number of loops, it will
9570 // define the nested loops number.
9571 unsigned NestedLoopCount = checkOpenMPLoop(
9572 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
9573 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
9574 VarsWithImplicitDSA, B);
9575 if (NestedLoopCount == 0)
9576 return StmtError();
9577
9578 assert((CurContext->isDependentContext() || B.builtAll()) &&
9579 "omp for loop exprs were not built");
9580
9581 if (!CurContext->isDependentContext()) {
9582 // Finalize the clauses that need pre-built expressions for CodeGen.
9583 for (OMPClause *C : Clauses) {
9584 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9585 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9586 B.NumIterations, *this, CurScope,
9587 DSAStack))
9588 return StmtError();
9589 }
9590 }
9591
9592 if (checkSimdlenSafelenSpecified(*this, Clauses))
9593 return StmtError();
9594
9595 setFunctionHasBranchProtectedScope();
9596 return OMPDistributeParallelForSimdDirective::Create(
9597 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9598 }
9599
9600 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
9601 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9602 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9603 if (!AStmt)
9604 return StmtError();
9605
9606 auto *CS = cast<CapturedStmt>(AStmt);
9607 // 1.2.2 OpenMP Language Terminology
9608 // Structured block - An executable statement with a single entry at the
9609 // top and a single exit at the bottom.
9610 // The point of exit cannot be a branch out of the structured block.
9611 // longjmp() and throw() must not violate the entry/exit criteria.
9612 CS->getCapturedDecl()->setNothrow();
9613 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
9614 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9615 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9616 // 1.2.2 OpenMP Language Terminology
9617 // Structured block - An executable statement with a single entry at the
9618 // top and a single exit at the bottom.
9619 // The point of exit cannot be a branch out of the structured block.
9620 // longjmp() and throw() must not violate the entry/exit criteria.
9621 CS->getCapturedDecl()->setNothrow();
9622 }
9623
9624 OMPLoopDirective::HelperExprs B;
9625 // In presence of clause 'collapse' with number of loops, it will
9626 // define the nested loops number.
9627 unsigned NestedLoopCount =
9628 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
9629 nullptr /*ordered not a clause on distribute*/, CS, *this,
9630 *DSAStack, VarsWithImplicitDSA, B);
9631 if (NestedLoopCount == 0)
9632 return StmtError();
9633
9634 assert((CurContext->isDependentContext() || B.builtAll()) &&
9635 "omp for loop exprs were not built");
9636
9637 if (!CurContext->isDependentContext()) {
9638 // Finalize the clauses that need pre-built expressions for CodeGen.
9639 for (OMPClause *C : Clauses) {
9640 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9641 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9642 B.NumIterations, *this, CurScope,
9643 DSAStack))
9644 return StmtError();
9645 }
9646 }
9647
9648 if (checkSimdlenSafelenSpecified(*this, Clauses))
9649 return StmtError();
9650
9651 setFunctionHasBranchProtectedScope();
9652 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
9653 NestedLoopCount, Clauses, AStmt, B);
9654 }
9655
9656 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
9657 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9658 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9659 if (!AStmt)
9660 return StmtError();
9661
9662 auto *CS = cast<CapturedStmt>(AStmt);
9663 // 1.2.2 OpenMP Language Terminology
9664 // Structured block - An executable statement with a single entry at the
9665 // top and a single exit at the bottom.
9666 // The point of exit cannot be a branch out of the structured block.
9667 // longjmp() and throw() must not violate the entry/exit criteria.
9668 CS->getCapturedDecl()->setNothrow();
9669 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
9670 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9671 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9672 // 1.2.2 OpenMP Language Terminology
9673 // Structured block - An executable statement with a single entry at the
9674 // top and a single exit at the bottom.
9675 // The point of exit cannot be a branch out of the structured block.
9676 // longjmp() and throw() must not violate the entry/exit criteria.
9677 CS->getCapturedDecl()->setNothrow();
9678 }
9679
9680 OMPLoopDirective::HelperExprs B;
9681 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9682 // define the nested loops number.
9683 unsigned NestedLoopCount = checkOpenMPLoop(
9684 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
9685 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
9686 VarsWithImplicitDSA, B);
9687 if (NestedLoopCount == 0)
9688 return StmtError();
9689
9690 assert((CurContext->isDependentContext() || B.builtAll()) &&
9691 "omp target parallel for simd loop exprs were not built");
9692
9693 if (!CurContext->isDependentContext()) {
9694 // Finalize the clauses that need pre-built expressions for CodeGen.
9695 for (OMPClause *C : Clauses) {
9696 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9697 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9698 B.NumIterations, *this, CurScope,
9699 DSAStack))
9700 return StmtError();
9701 }
9702 }
9703 if (checkSimdlenSafelenSpecified(*this, Clauses))
9704 return StmtError();
9705
9706 setFunctionHasBranchProtectedScope();
9707 return OMPTargetParallelForSimdDirective::Create(
9708 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9709 }
9710
9711 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
9712 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9713 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9714 if (!AStmt)
9715 return StmtError();
9716
9717 auto *CS = cast<CapturedStmt>(AStmt);
9718 // 1.2.2 OpenMP Language Terminology
9719 // Structured block - An executable statement with a single entry at the
9720 // top and a single exit at the bottom.
9721 // The point of exit cannot be a branch out of the structured block.
9722 // longjmp() and throw() must not violate the entry/exit criteria.
9723 CS->getCapturedDecl()->setNothrow();
9724 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
9725 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9726 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9727 // 1.2.2 OpenMP Language Terminology
9728 // Structured block - An executable statement with a single entry at the
9729 // top and a single exit at the bottom.
9730 // The point of exit cannot be a branch out of the structured block.
9731 // longjmp() and throw() must not violate the entry/exit criteria.
9732 CS->getCapturedDecl()->setNothrow();
9733 }
9734
9735 OMPLoopDirective::HelperExprs B;
9736 // In presence of clause 'collapse' with number of loops, it will define the
9737 // nested loops number.
9738 unsigned NestedLoopCount =
9739 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
9740 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
9741 VarsWithImplicitDSA, B);
9742 if (NestedLoopCount == 0)
9743 return StmtError();
9744
9745 assert((CurContext->isDependentContext() || B.builtAll()) &&
9746 "omp target simd loop exprs were not built");
9747
9748 if (!CurContext->isDependentContext()) {
9749 // Finalize the clauses that need pre-built expressions for CodeGen.
9750 for (OMPClause *C : Clauses) {
9751 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9752 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9753 B.NumIterations, *this, CurScope,
9754 DSAStack))
9755 return StmtError();
9756 }
9757 }
9758
9759 if (checkSimdlenSafelenSpecified(*this, Clauses))
9760 return StmtError();
9761
9762 setFunctionHasBranchProtectedScope();
9763 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
9764 NestedLoopCount, Clauses, AStmt, B);
9765 }
9766
9767 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
9768 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9769 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9770 if (!AStmt)
9771 return StmtError();
9772
9773 auto *CS = cast<CapturedStmt>(AStmt);
9774 // 1.2.2 OpenMP Language Terminology
9775 // Structured block - An executable statement with a single entry at the
9776 // top and a single exit at the bottom.
9777 // The point of exit cannot be a branch out of the structured block.
9778 // longjmp() and throw() must not violate the entry/exit criteria.
9779 CS->getCapturedDecl()->setNothrow();
9780 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
9781 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9782 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9783 // 1.2.2 OpenMP Language Terminology
9784 // Structured block - An executable statement with a single entry at the
9785 // top and a single exit at the bottom.
9786 // The point of exit cannot be a branch out of the structured block.
9787 // longjmp() and throw() must not violate the entry/exit criteria.
9788 CS->getCapturedDecl()->setNothrow();
9789 }
9790
9791 OMPLoopDirective::HelperExprs B;
9792 // In presence of clause 'collapse' with number of loops, it will
9793 // define the nested loops number.
9794 unsigned NestedLoopCount =
9795 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
9796 nullptr /*ordered not a clause on distribute*/, CS, *this,
9797 *DSAStack, VarsWithImplicitDSA, B);
9798 if (NestedLoopCount == 0)
9799 return StmtError();
9800
9801 assert((CurContext->isDependentContext() || B.builtAll()) &&
9802 "omp teams distribute loop exprs were not built");
9803
9804 setFunctionHasBranchProtectedScope();
9805
9806 DSAStack->setParentTeamsRegionLoc(StartLoc);
9807
9808 return OMPTeamsDistributeDirective::Create(
9809 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9810 }
9811
9812 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
9813 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9814 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9815 if (!AStmt)
9816 return StmtError();
9817
9818 auto *CS = cast<CapturedStmt>(AStmt);
9819 // 1.2.2 OpenMP Language Terminology
9820 // Structured block - An executable statement with a single entry at the
9821 // top and a single exit at the bottom.
9822 // The point of exit cannot be a branch out of the structured block.
9823 // longjmp() and throw() must not violate the entry/exit criteria.
9824 CS->getCapturedDecl()->setNothrow();
9825 for (int ThisCaptureLevel =
9826 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
9827 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9828 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9829 // 1.2.2 OpenMP Language Terminology
9830 // Structured block - An executable statement with a single entry at the
9831 // top and a single exit at the bottom.
9832 // The point of exit cannot be a branch out of the structured block.
9833 // longjmp() and throw() must not violate the entry/exit criteria.
9834 CS->getCapturedDecl()->setNothrow();
9835 }
9836
9837
9838 OMPLoopDirective::HelperExprs B;
9839 // In presence of clause 'collapse' with number of loops, it will
9840 // define the nested loops number.
9841 unsigned NestedLoopCount = checkOpenMPLoop(
9842 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
9843 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
9844 VarsWithImplicitDSA, B);
9845
9846 if (NestedLoopCount == 0)
9847 return StmtError();
9848
9849 assert((CurContext->isDependentContext() || B.builtAll()) &&
9850 "omp teams distribute simd loop exprs were not built");
9851
9852 if (!CurContext->isDependentContext()) {
9853 // Finalize the clauses that need pre-built expressions for CodeGen.
9854 for (OMPClause *C : Clauses) {
9855 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9856 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9857 B.NumIterations, *this, CurScope,
9858 DSAStack))
9859 return StmtError();
9860 }
9861 }
9862
9863 if (checkSimdlenSafelenSpecified(*this, Clauses))
9864 return StmtError();
9865
9866 setFunctionHasBranchProtectedScope();
9867
9868 DSAStack->setParentTeamsRegionLoc(StartLoc);
9869
9870 return OMPTeamsDistributeSimdDirective::Create(
9871 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9872 }
9873
9874 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
9875 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9876 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9877 if (!AStmt)
9878 return StmtError();
9879
9880 auto *CS = cast<CapturedStmt>(AStmt);
9881 // 1.2.2 OpenMP Language Terminology
9882 // Structured block - An executable statement with a single entry at the
9883 // top and a single exit at the bottom.
9884 // The point of exit cannot be a branch out of the structured block.
9885 // longjmp() and throw() must not violate the entry/exit criteria.
9886 CS->getCapturedDecl()->setNothrow();
9887
9888 for (int ThisCaptureLevel =
9889 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
9890 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9891 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9892 // 1.2.2 OpenMP Language Terminology
9893 // Structured block - An executable statement with a single entry at the
9894 // top and a single exit at the bottom.
9895 // The point of exit cannot be a branch out of the structured block.
9896 // longjmp() and throw() must not violate the entry/exit criteria.
9897 CS->getCapturedDecl()->setNothrow();
9898 }
9899
9900 OMPLoopDirective::HelperExprs B;
9901 // In presence of clause 'collapse' with number of loops, it will
9902 // define the nested loops number.
9903 unsigned NestedLoopCount = checkOpenMPLoop(
9904 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
9905 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
9906 VarsWithImplicitDSA, B);
9907
9908 if (NestedLoopCount == 0)
9909 return StmtError();
9910
9911 assert((CurContext->isDependentContext() || B.builtAll()) &&
9912 "omp for loop exprs were not built");
9913
9914 if (!CurContext->isDependentContext()) {
9915 // Finalize the clauses that need pre-built expressions for CodeGen.
9916 for (OMPClause *C : Clauses) {
9917 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9918 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9919 B.NumIterations, *this, CurScope,
9920 DSAStack))
9921 return StmtError();
9922 }
9923 }
9924
9925 if (checkSimdlenSafelenSpecified(*this, Clauses))
9926 return StmtError();
9927
9928 setFunctionHasBranchProtectedScope();
9929
9930 DSAStack->setParentTeamsRegionLoc(StartLoc);
9931
9932 return OMPTeamsDistributeParallelForSimdDirective::Create(
9933 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9934 }
9935
9936 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
9937 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9938 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9939 if (!AStmt)
9940 return StmtError();
9941
9942 auto *CS = cast<CapturedStmt>(AStmt);
9943 // 1.2.2 OpenMP Language Terminology
9944 // Structured block - An executable statement with a single entry at the
9945 // top and a single exit at the bottom.
9946 // The point of exit cannot be a branch out of the structured block.
9947 // longjmp() and throw() must not violate the entry/exit criteria.
9948 CS->getCapturedDecl()->setNothrow();
9949
9950 for (int ThisCaptureLevel =
9951 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
9952 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9953 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9954 // 1.2.2 OpenMP Language Terminology
9955 // Structured block - An executable statement with a single entry at the
9956 // top and a single exit at the bottom.
9957 // The point of exit cannot be a branch out of the structured block.
9958 // longjmp() and throw() must not violate the entry/exit criteria.
9959 CS->getCapturedDecl()->setNothrow();
9960 }
9961
9962 OMPLoopDirective::HelperExprs B;
9963 // In presence of clause 'collapse' with number of loops, it will
9964 // define the nested loops number.
9965 unsigned NestedLoopCount = checkOpenMPLoop(
9966 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
9967 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
9968 VarsWithImplicitDSA, B);
9969
9970 if (NestedLoopCount == 0)
9971 return StmtError();
9972
9973 assert((CurContext->isDependentContext() || B.builtAll()) &&
9974 "omp for loop exprs were not built");
9975
9976 setFunctionHasBranchProtectedScope();
9977
9978 DSAStack->setParentTeamsRegionLoc(StartLoc);
9979
9980 return OMPTeamsDistributeParallelForDirective::Create(
9981 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9982 DSAStack->isCancelRegion());
9983 }
9984
9985 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
9986 Stmt *AStmt,
9987 SourceLocation StartLoc,
9988 SourceLocation EndLoc) {
9989 if (!AStmt)
9990 return StmtError();
9991
9992 auto *CS = cast<CapturedStmt>(AStmt);
9993 // 1.2.2 OpenMP Language Terminology
9994 // Structured block - An executable statement with a single entry at the
9995 // top and a single exit at the bottom.
9996 // The point of exit cannot be a branch out of the structured block.
9997 // longjmp() and throw() must not violate the entry/exit criteria.
9998 CS->getCapturedDecl()->setNothrow();
9999
10000 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
10001 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10002 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10003 // 1.2.2 OpenMP Language Terminology
10004 // Structured block - An executable statement with a single entry at the
10005 // top and a single exit at the bottom.
10006 // The point of exit cannot be a branch out of the structured block.
10007 // longjmp() and throw() must not violate the entry/exit criteria.
10008 CS->getCapturedDecl()->setNothrow();
10009 }
10010 setFunctionHasBranchProtectedScope();
10011
10012 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
10013 AStmt);
10014 }
10015
10016 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
10017 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10018 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10019 if (!AStmt)
10020 return StmtError();
10021
10022 auto *CS = cast<CapturedStmt>(AStmt);
10023 // 1.2.2 OpenMP Language Terminology
10024 // Structured block - An executable statement with a single entry at the
10025 // top and a single exit at the bottom.
10026 // The point of exit cannot be a branch out of the structured block.
10027 // longjmp() and throw() must not violate the entry/exit criteria.
10028 CS->getCapturedDecl()->setNothrow();
10029 for (int ThisCaptureLevel =
10030 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
10031 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10032 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10033 // 1.2.2 OpenMP Language Terminology
10034 // Structured block - An executable statement with a single entry at the
10035 // top and a single exit at the bottom.
10036 // The point of exit cannot be a branch out of the structured block.
10037 // longjmp() and throw() must not violate the entry/exit criteria.
10038 CS->getCapturedDecl()->setNothrow();
10039 }
10040
10041 OMPLoopDirective::HelperExprs B;
10042 // In presence of clause 'collapse' with number of loops, it will
10043 // define the nested loops number.
10044 unsigned NestedLoopCount = checkOpenMPLoop(
10045 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
10046 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10047 VarsWithImplicitDSA, B);
10048 if (NestedLoopCount == 0)
10049 return StmtError();
10050
10051 assert((CurContext->isDependentContext() || B.builtAll()) &&
10052 "omp target teams distribute loop exprs were not built");
10053
10054 setFunctionHasBranchProtectedScope();
10055 return OMPTargetTeamsDistributeDirective::Create(
10056 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10057 }
10058
10059 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
10060 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10061 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10062 if (!AStmt)
10063 return StmtError();
10064
10065 auto *CS = cast<CapturedStmt>(AStmt);
10066 // 1.2.2 OpenMP Language Terminology
10067 // Structured block - An executable statement with a single entry at the
10068 // top and a single exit at the bottom.
10069 // The point of exit cannot be a branch out of the structured block.
10070 // longjmp() and throw() must not violate the entry/exit criteria.
10071 CS->getCapturedDecl()->setNothrow();
10072 for (int ThisCaptureLevel =
10073 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
10074 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10075 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10076 // 1.2.2 OpenMP Language Terminology
10077 // Structured block - An executable statement with a single entry at the
10078 // top and a single exit at the bottom.
10079 // The point of exit cannot be a branch out of the structured block.
10080 // longjmp() and throw() must not violate the entry/exit criteria.
10081 CS->getCapturedDecl()->setNothrow();
10082 }
10083
10084 OMPLoopDirective::HelperExprs B;
10085 // In presence of clause 'collapse' with number of loops, it will
10086 // define the nested loops number.
10087 unsigned NestedLoopCount = checkOpenMPLoop(
10088 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10089 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10090 VarsWithImplicitDSA, B);
10091 if (NestedLoopCount == 0)
10092 return StmtError();
10093
10094 assert((CurContext->isDependentContext() || B.builtAll()) &&
10095 "omp target teams distribute parallel for loop exprs were not built");
10096
10097 if (!CurContext->isDependentContext()) {
10098 // Finalize the clauses that need pre-built expressions for CodeGen.
10099 for (OMPClause *C : Clauses) {
10100 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10101 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10102 B.NumIterations, *this, CurScope,
10103 DSAStack))
10104 return StmtError();
10105 }
10106 }
10107
10108 setFunctionHasBranchProtectedScope();
10109 return OMPTargetTeamsDistributeParallelForDirective::Create(
10110 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10111 DSAStack->isCancelRegion());
10112 }
10113
10114 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
10115 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10116 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10117 if (!AStmt)
10118 return StmtError();
10119
10120 auto *CS = cast<CapturedStmt>(AStmt);
10121 // 1.2.2 OpenMP Language Terminology
10122 // Structured block - An executable statement with a single entry at the
10123 // top and a single exit at the bottom.
10124 // The point of exit cannot be a branch out of the structured block.
10125 // longjmp() and throw() must not violate the entry/exit criteria.
10126 CS->getCapturedDecl()->setNothrow();
10127 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
10128 OMPD_target_teams_distribute_parallel_for_simd);
10129 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10130 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10131 // 1.2.2 OpenMP Language Terminology
10132 // Structured block - An executable statement with a single entry at the
10133 // top and a single exit at the bottom.
10134 // The point of exit cannot be a branch out of the structured block.
10135 // longjmp() and throw() must not violate the entry/exit criteria.
10136 CS->getCapturedDecl()->setNothrow();
10137 }
10138
10139 OMPLoopDirective::HelperExprs B;
10140 // In presence of clause 'collapse' with number of loops, it will
10141 // define the nested loops number.
10142 unsigned NestedLoopCount =
10143 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
10144 getCollapseNumberExpr(Clauses),
10145 nullptr /*ordered not a clause on distribute*/, CS, *this,
10146 *DSAStack, VarsWithImplicitDSA, B);
10147 if (NestedLoopCount == 0)
10148 return StmtError();
10149
10150 assert((CurContext->isDependentContext() || B.builtAll()) &&
10151 "omp target teams distribute parallel for simd loop exprs were not "
10152 "built");
10153
10154 if (!CurContext->isDependentContext()) {
10155 // Finalize the clauses that need pre-built expressions for CodeGen.
10156 for (OMPClause *C : Clauses) {
10157 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10158 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10159 B.NumIterations, *this, CurScope,
10160 DSAStack))
10161 return StmtError();
10162 }
10163 }
10164
10165 if (checkSimdlenSafelenSpecified(*this, Clauses))
10166 return StmtError();
10167
10168 setFunctionHasBranchProtectedScope();
10169 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
10170 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10171 }
10172
10173 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
10174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10175 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10176 if (!AStmt)
10177 return StmtError();
10178
10179 auto *CS = cast<CapturedStmt>(AStmt);
10180 // 1.2.2 OpenMP Language Terminology
10181 // Structured block - An executable statement with a single entry at the
10182 // top and a single exit at the bottom.
10183 // The point of exit cannot be a branch out of the structured block.
10184 // longjmp() and throw() must not violate the entry/exit criteria.
10185 CS->getCapturedDecl()->setNothrow();
10186 for (int ThisCaptureLevel =
10187 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
10188 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10189 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10190 // 1.2.2 OpenMP Language Terminology
10191 // Structured block - An executable statement with a single entry at the
10192 // top and a single exit at the bottom.
10193 // The point of exit cannot be a branch out of the structured block.
10194 // longjmp() and throw() must not violate the entry/exit criteria.
10195 CS->getCapturedDecl()->setNothrow();
10196 }
10197
10198 OMPLoopDirective::HelperExprs B;
10199 // In presence of clause 'collapse' with number of loops, it will
10200 // define the nested loops number.
10201 unsigned NestedLoopCount = checkOpenMPLoop(
10202 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
10203 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10204 VarsWithImplicitDSA, B);
10205 if (NestedLoopCount == 0)
10206 return StmtError();
10207
10208 assert((CurContext->isDependentContext() || B.builtAll()) &&
10209 "omp target teams distribute simd loop exprs were not built");
10210
10211 if (!CurContext->isDependentContext()) {
10212 // Finalize the clauses that need pre-built expressions for CodeGen.
10213 for (OMPClause *C : Clauses) {
10214 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10215 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10216 B.NumIterations, *this, CurScope,
10217 DSAStack))
10218 return StmtError();
10219 }
10220 }
10221
10222 if (checkSimdlenSafelenSpecified(*this, Clauses))
10223 return StmtError();
10224
10225 setFunctionHasBranchProtectedScope();
10226 return OMPTargetTeamsDistributeSimdDirective::Create(
10227 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10228 }
10229
10230 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
10231 SourceLocation StartLoc,
10232 SourceLocation LParenLoc,
10233 SourceLocation EndLoc) {
10234 OMPClause *Res = nullptr;
10235 switch (Kind) {
10236 case OMPC_final:
10237 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
10238 break;
10239 case OMPC_num_threads:
10240 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
10241 break;
10242 case OMPC_safelen:
10243 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
10244 break;
10245 case OMPC_simdlen:
10246 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
10247 break;
10248 case OMPC_allocator:
10249 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
10250 break;
10251 case OMPC_collapse:
10252 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
10253 break;
10254 case OMPC_ordered:
10255 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
10256 break;
10257 case OMPC_device:
10258 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
10259 break;
10260 case OMPC_num_teams:
10261 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
10262 break;
10263 case OMPC_thread_limit:
10264 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
10265 break;
10266 case OMPC_priority:
10267 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
10268 break;
10269 case OMPC_grainsize:
10270 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
10271 break;
10272 case OMPC_num_tasks:
10273 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
10274 break;
10275 case OMPC_hint:
10276 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
10277 break;
10278 case OMPC_if:
10279 case OMPC_default:
10280 case OMPC_proc_bind:
10281 case OMPC_schedule:
10282 case OMPC_private:
10283 case OMPC_firstprivate:
10284 case OMPC_lastprivate:
10285 case OMPC_shared:
10286 case OMPC_reduction:
10287 case OMPC_task_reduction:
10288 case OMPC_in_reduction:
10289 case OMPC_linear:
10290 case OMPC_aligned:
10291 case OMPC_copyin:
10292 case OMPC_copyprivate:
10293 case OMPC_nowait:
10294 case OMPC_untied:
10295 case OMPC_mergeable:
10296 case OMPC_threadprivate:
10297 case OMPC_allocate:
10298 case OMPC_flush:
10299 case OMPC_read:
10300 case OMPC_write:
10301 case OMPC_update:
10302 case OMPC_capture:
10303 case OMPC_seq_cst:
10304 case OMPC_depend:
10305 case OMPC_threads:
10306 case OMPC_simd:
10307 case OMPC_map:
10308 case OMPC_nogroup:
10309 case OMPC_dist_schedule:
10310 case OMPC_defaultmap:
10311 case OMPC_unknown:
10312 case OMPC_uniform:
10313 case OMPC_to:
10314 case OMPC_from:
10315 case OMPC_use_device_ptr:
10316 case OMPC_is_device_ptr:
10317 case OMPC_unified_address:
10318 case OMPC_unified_shared_memory:
10319 case OMPC_reverse_offload:
10320 case OMPC_dynamic_allocators:
10321 case OMPC_atomic_default_mem_order:
10322 case OMPC_device_type:
10323 case OMPC_match:
10324 llvm_unreachable("Clause is not allowed.");
10325 }
10326 return Res;
10327 }
10328
10329 // An OpenMP directive such as 'target parallel' has two captured regions:
10330 // for the 'target' and 'parallel' respectively. This function returns
10331 // the region in which to capture expressions associated with a clause.
10332 // A return value of OMPD_unknown signifies that the expression should not
10333 // be captured.
10334 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
10335 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
10336 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
10337 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
10338 switch (CKind) {
10339 case OMPC_if:
10340 switch (DKind) {
10341 case OMPD_target_parallel:
10342 case OMPD_target_parallel_for:
10343 case OMPD_target_parallel_for_simd:
10344 // If this clause applies to the nested 'parallel' region, capture within
10345 // the 'target' region, otherwise do not capture.
10346 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10347 CaptureRegion = OMPD_target;
10348 break;
10349 case OMPD_target_teams_distribute_parallel_for:
10350 case OMPD_target_teams_distribute_parallel_for_simd:
10351 // If this clause applies to the nested 'parallel' region, capture within
10352 // the 'teams' region, otherwise do not capture.
10353 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10354 CaptureRegion = OMPD_teams;
10355 break;
10356 case OMPD_teams_distribute_parallel_for:
10357 case OMPD_teams_distribute_parallel_for_simd:
10358 CaptureRegion = OMPD_teams;
10359 break;
10360 case OMPD_target_update:
10361 case OMPD_target_enter_data:
10362 case OMPD_target_exit_data:
10363 CaptureRegion = OMPD_task;
10364 break;
10365 case OMPD_parallel_master_taskloop:
10366 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
10367 CaptureRegion = OMPD_parallel;
10368 break;
10369 case OMPD_cancel:
10370 case OMPD_parallel:
10371 case OMPD_parallel_sections:
10372 case OMPD_parallel_for:
10373 case OMPD_parallel_for_simd:
10374 case OMPD_target:
10375 case OMPD_target_simd:
10376 case OMPD_target_teams:
10377 case OMPD_target_teams_distribute:
10378 case OMPD_target_teams_distribute_simd:
10379 case OMPD_distribute_parallel_for:
10380 case OMPD_distribute_parallel_for_simd:
10381 case OMPD_task:
10382 case OMPD_taskloop:
10383 case OMPD_taskloop_simd:
10384 case OMPD_master_taskloop:
10385 case OMPD_master_taskloop_simd:
10386 case OMPD_target_data:
10387 // Do not capture if-clause expressions.
10388 break;
10389 case OMPD_threadprivate:
10390 case OMPD_allocate:
10391 case OMPD_taskyield:
10392 case OMPD_barrier:
10393 case OMPD_taskwait:
10394 case OMPD_cancellation_point:
10395 case OMPD_flush:
10396 case OMPD_declare_reduction:
10397 case OMPD_declare_mapper:
10398 case OMPD_declare_simd:
10399 case OMPD_declare_variant:
10400 case OMPD_declare_target:
10401 case OMPD_end_declare_target:
10402 case OMPD_teams:
10403 case OMPD_simd:
10404 case OMPD_for:
10405 case OMPD_for_simd:
10406 case OMPD_sections:
10407 case OMPD_section:
10408 case OMPD_single:
10409 case OMPD_master:
10410 case OMPD_critical:
10411 case OMPD_taskgroup:
10412 case OMPD_distribute:
10413 case OMPD_ordered:
10414 case OMPD_atomic:
10415 case OMPD_distribute_simd:
10416 case OMPD_teams_distribute:
10417 case OMPD_teams_distribute_simd:
10418 case OMPD_requires:
10419 llvm_unreachable("Unexpected OpenMP directive with if-clause");
10420 case OMPD_unknown:
10421 llvm_unreachable("Unknown OpenMP directive");
10422 }
10423 break;
10424 case OMPC_num_threads:
10425 switch (DKind) {
10426 case OMPD_target_parallel:
10427 case OMPD_target_parallel_for:
10428 case OMPD_target_parallel_for_simd:
10429 CaptureRegion = OMPD_target;
10430 break;
10431 case OMPD_teams_distribute_parallel_for:
10432 case OMPD_teams_distribute_parallel_for_simd:
10433 case OMPD_target_teams_distribute_parallel_for:
10434 case OMPD_target_teams_distribute_parallel_for_simd:
10435 CaptureRegion = OMPD_teams;
10436 break;
10437 case OMPD_parallel:
10438 case OMPD_parallel_sections:
10439 case OMPD_parallel_for:
10440 case OMPD_parallel_for_simd:
10441 case OMPD_distribute_parallel_for:
10442 case OMPD_distribute_parallel_for_simd:
10443 case OMPD_parallel_master_taskloop:
10444 // Do not capture num_threads-clause expressions.
10445 break;
10446 case OMPD_target_data:
10447 case OMPD_target_enter_data:
10448 case OMPD_target_exit_data:
10449 case OMPD_target_update:
10450 case OMPD_target:
10451 case OMPD_target_simd:
10452 case OMPD_target_teams:
10453 case OMPD_target_teams_distribute:
10454 case OMPD_target_teams_distribute_simd:
10455 case OMPD_cancel:
10456 case OMPD_task:
10457 case OMPD_taskloop:
10458 case OMPD_taskloop_simd:
10459 case OMPD_master_taskloop:
10460 case OMPD_master_taskloop_simd:
10461 case OMPD_threadprivate:
10462 case OMPD_allocate:
10463 case OMPD_taskyield:
10464 case OMPD_barrier:
10465 case OMPD_taskwait:
10466 case OMPD_cancellation_point:
10467 case OMPD_flush:
10468 case OMPD_declare_reduction:
10469 case OMPD_declare_mapper:
10470 case OMPD_declare_simd:
10471 case OMPD_declare_variant:
10472 case OMPD_declare_target:
10473 case OMPD_end_declare_target:
10474 case OMPD_teams:
10475 case OMPD_simd:
10476 case OMPD_for:
10477 case OMPD_for_simd:
10478 case OMPD_sections:
10479 case OMPD_section:
10480 case OMPD_single:
10481 case OMPD_master:
10482 case OMPD_critical:
10483 case OMPD_taskgroup:
10484 case OMPD_distribute:
10485 case OMPD_ordered:
10486 case OMPD_atomic:
10487 case OMPD_distribute_simd:
10488 case OMPD_teams_distribute:
10489 case OMPD_teams_distribute_simd:
10490 case OMPD_requires:
10491 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
10492 case OMPD_unknown:
10493 llvm_unreachable("Unknown OpenMP directive");
10494 }
10495 break;
10496 case OMPC_num_teams:
10497 switch (DKind) {
10498 case OMPD_target_teams:
10499 case OMPD_target_teams_distribute:
10500 case OMPD_target_teams_distribute_simd:
10501 case OMPD_target_teams_distribute_parallel_for:
10502 case OMPD_target_teams_distribute_parallel_for_simd:
10503 CaptureRegion = OMPD_target;
10504 break;
10505 case OMPD_teams_distribute_parallel_for:
10506 case OMPD_teams_distribute_parallel_for_simd:
10507 case OMPD_teams:
10508 case OMPD_teams_distribute:
10509 case OMPD_teams_distribute_simd:
10510 // Do not capture num_teams-clause expressions.
10511 break;
10512 case OMPD_distribute_parallel_for:
10513 case OMPD_distribute_parallel_for_simd:
10514 case OMPD_task:
10515 case OMPD_taskloop:
10516 case OMPD_taskloop_simd:
10517 case OMPD_master_taskloop:
10518 case OMPD_master_taskloop_simd:
10519 case OMPD_parallel_master_taskloop:
10520 case OMPD_target_data:
10521 case OMPD_target_enter_data:
10522 case OMPD_target_exit_data:
10523 case OMPD_target_update:
10524 case OMPD_cancel:
10525 case OMPD_parallel:
10526 case OMPD_parallel_sections:
10527 case OMPD_parallel_for:
10528 case OMPD_parallel_for_simd:
10529 case OMPD_target:
10530 case OMPD_target_simd:
10531 case OMPD_target_parallel:
10532 case OMPD_target_parallel_for:
10533 case OMPD_target_parallel_for_simd:
10534 case OMPD_threadprivate:
10535 case OMPD_allocate:
10536 case OMPD_taskyield:
10537 case OMPD_barrier:
10538 case OMPD_taskwait:
10539 case OMPD_cancellation_point:
10540 case OMPD_flush:
10541 case OMPD_declare_reduction:
10542 case OMPD_declare_mapper:
10543 case OMPD_declare_simd:
10544 case OMPD_declare_variant:
10545 case OMPD_declare_target:
10546 case OMPD_end_declare_target:
10547 case OMPD_simd:
10548 case OMPD_for:
10549 case OMPD_for_simd:
10550 case OMPD_sections:
10551 case OMPD_section:
10552 case OMPD_single:
10553 case OMPD_master:
10554 case OMPD_critical:
10555 case OMPD_taskgroup:
10556 case OMPD_distribute:
10557 case OMPD_ordered:
10558 case OMPD_atomic:
10559 case OMPD_distribute_simd:
10560 case OMPD_requires:
10561 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
10562 case OMPD_unknown:
10563 llvm_unreachable("Unknown OpenMP directive");
10564 }
10565 break;
10566 case OMPC_thread_limit:
10567 switch (DKind) {
10568 case OMPD_target_teams:
10569 case OMPD_target_teams_distribute:
10570 case OMPD_target_teams_distribute_simd:
10571 case OMPD_target_teams_distribute_parallel_for:
10572 case OMPD_target_teams_distribute_parallel_for_simd:
10573 CaptureRegion = OMPD_target;
10574 break;
10575 case OMPD_teams_distribute_parallel_for:
10576 case OMPD_teams_distribute_parallel_for_simd:
10577 case OMPD_teams:
10578 case OMPD_teams_distribute:
10579 case OMPD_teams_distribute_simd:
10580 // Do not capture thread_limit-clause expressions.
10581 break;
10582 case OMPD_distribute_parallel_for:
10583 case OMPD_distribute_parallel_for_simd:
10584 case OMPD_task:
10585 case OMPD_taskloop:
10586 case OMPD_taskloop_simd:
10587 case OMPD_master_taskloop:
10588 case OMPD_master_taskloop_simd:
10589 case OMPD_parallel_master_taskloop:
10590 case OMPD_target_data:
10591 case OMPD_target_enter_data:
10592 case OMPD_target_exit_data:
10593 case OMPD_target_update:
10594 case OMPD_cancel:
10595 case OMPD_parallel:
10596 case OMPD_parallel_sections:
10597 case OMPD_parallel_for:
10598 case OMPD_parallel_for_simd:
10599 case OMPD_target:
10600 case OMPD_target_simd:
10601 case OMPD_target_parallel:
10602 case OMPD_target_parallel_for:
10603 case OMPD_target_parallel_for_simd:
10604 case OMPD_threadprivate:
10605 case OMPD_allocate:
10606 case OMPD_taskyield:
10607 case OMPD_barrier:
10608 case OMPD_taskwait:
10609 case OMPD_cancellation_point:
10610 case OMPD_flush:
10611 case OMPD_declare_reduction:
10612 case OMPD_declare_mapper:
10613 case OMPD_declare_simd:
10614 case OMPD_declare_variant:
10615 case OMPD_declare_target:
10616 case OMPD_end_declare_target:
10617 case OMPD_simd:
10618 case OMPD_for:
10619 case OMPD_for_simd:
10620 case OMPD_sections:
10621 case OMPD_section:
10622 case OMPD_single:
10623 case OMPD_master:
10624 case OMPD_critical:
10625 case OMPD_taskgroup:
10626 case OMPD_distribute:
10627 case OMPD_ordered:
10628 case OMPD_atomic:
10629 case OMPD_distribute_simd:
10630 case OMPD_requires:
10631 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
10632 case OMPD_unknown:
10633 llvm_unreachable("Unknown OpenMP directive");
10634 }
10635 break;
10636 case OMPC_schedule:
10637 switch (DKind) {
10638 case OMPD_parallel_for:
10639 case OMPD_parallel_for_simd:
10640 case OMPD_distribute_parallel_for:
10641 case OMPD_distribute_parallel_for_simd:
10642 case OMPD_teams_distribute_parallel_for:
10643 case OMPD_teams_distribute_parallel_for_simd:
10644 case OMPD_target_parallel_for:
10645 case OMPD_target_parallel_for_simd:
10646 case OMPD_target_teams_distribute_parallel_for:
10647 case OMPD_target_teams_distribute_parallel_for_simd:
10648 CaptureRegion = OMPD_parallel;
10649 break;
10650 case OMPD_for:
10651 case OMPD_for_simd:
10652 // Do not capture schedule-clause expressions.
10653 break;
10654 case OMPD_task:
10655 case OMPD_taskloop:
10656 case OMPD_taskloop_simd:
10657 case OMPD_master_taskloop:
10658 case OMPD_master_taskloop_simd:
10659 case OMPD_parallel_master_taskloop:
10660 case OMPD_target_data:
10661 case OMPD_target_enter_data:
10662 case OMPD_target_exit_data:
10663 case OMPD_target_update:
10664 case OMPD_teams:
10665 case OMPD_teams_distribute:
10666 case OMPD_teams_distribute_simd:
10667 case OMPD_target_teams_distribute:
10668 case OMPD_target_teams_distribute_simd:
10669 case OMPD_target:
10670 case OMPD_target_simd:
10671 case OMPD_target_parallel:
10672 case OMPD_cancel:
10673 case OMPD_parallel:
10674 case OMPD_parallel_sections:
10675 case OMPD_threadprivate:
10676 case OMPD_allocate:
10677 case OMPD_taskyield:
10678 case OMPD_barrier:
10679 case OMPD_taskwait:
10680 case OMPD_cancellation_point:
10681 case OMPD_flush:
10682 case OMPD_declare_reduction:
10683 case OMPD_declare_mapper:
10684 case OMPD_declare_simd:
10685 case OMPD_declare_variant:
10686 case OMPD_declare_target:
10687 case OMPD_end_declare_target:
10688 case OMPD_simd:
10689 case OMPD_sections:
10690 case OMPD_section:
10691 case OMPD_single:
10692 case OMPD_master:
10693 case OMPD_critical:
10694 case OMPD_taskgroup:
10695 case OMPD_distribute:
10696 case OMPD_ordered:
10697 case OMPD_atomic:
10698 case OMPD_distribute_simd:
10699 case OMPD_target_teams:
10700 case OMPD_requires:
10701 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
10702 case OMPD_unknown:
10703 llvm_unreachable("Unknown OpenMP directive");
10704 }
10705 break;
10706 case OMPC_dist_schedule:
10707 switch (DKind) {
10708 case OMPD_teams_distribute_parallel_for:
10709 case OMPD_teams_distribute_parallel_for_simd:
10710 case OMPD_teams_distribute:
10711 case OMPD_teams_distribute_simd:
10712 case OMPD_target_teams_distribute_parallel_for:
10713 case OMPD_target_teams_distribute_parallel_for_simd:
10714 case OMPD_target_teams_distribute:
10715 case OMPD_target_teams_distribute_simd:
10716 CaptureRegion = OMPD_teams;
10717 break;
10718 case OMPD_distribute_parallel_for:
10719 case OMPD_distribute_parallel_for_simd:
10720 case OMPD_distribute:
10721 case OMPD_distribute_simd:
10722 // Do not capture thread_limit-clause expressions.
10723 break;
10724 case OMPD_parallel_for:
10725 case OMPD_parallel_for_simd:
10726 case OMPD_target_parallel_for_simd:
10727 case OMPD_target_parallel_for:
10728 case OMPD_task:
10729 case OMPD_taskloop:
10730 case OMPD_taskloop_simd:
10731 case OMPD_master_taskloop:
10732 case OMPD_master_taskloop_simd:
10733 case OMPD_parallel_master_taskloop:
10734 case OMPD_target_data:
10735 case OMPD_target_enter_data:
10736 case OMPD_target_exit_data:
10737 case OMPD_target_update:
10738 case OMPD_teams:
10739 case OMPD_target:
10740 case OMPD_target_simd:
10741 case OMPD_target_parallel:
10742 case OMPD_cancel:
10743 case OMPD_parallel:
10744 case OMPD_parallel_sections:
10745 case OMPD_threadprivate:
10746 case OMPD_allocate:
10747 case OMPD_taskyield:
10748 case OMPD_barrier:
10749 case OMPD_taskwait:
10750 case OMPD_cancellation_point:
10751 case OMPD_flush:
10752 case OMPD_declare_reduction:
10753 case OMPD_declare_mapper:
10754 case OMPD_declare_simd:
10755 case OMPD_declare_variant:
10756 case OMPD_declare_target:
10757 case OMPD_end_declare_target:
10758 case OMPD_simd:
10759 case OMPD_for:
10760 case OMPD_for_simd:
10761 case OMPD_sections:
10762 case OMPD_section:
10763 case OMPD_single:
10764 case OMPD_master:
10765 case OMPD_critical:
10766 case OMPD_taskgroup:
10767 case OMPD_ordered:
10768 case OMPD_atomic:
10769 case OMPD_target_teams:
10770 case OMPD_requires:
10771 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
10772 case OMPD_unknown:
10773 llvm_unreachable("Unknown OpenMP directive");
10774 }
10775 break;
10776 case OMPC_device:
10777 switch (DKind) {
10778 case OMPD_target_update:
10779 case OMPD_target_enter_data:
10780 case OMPD_target_exit_data:
10781 case OMPD_target:
10782 case OMPD_target_simd:
10783 case OMPD_target_teams:
10784 case OMPD_target_parallel:
10785 case OMPD_target_teams_distribute:
10786 case OMPD_target_teams_distribute_simd:
10787 case OMPD_target_parallel_for:
10788 case OMPD_target_parallel_for_simd:
10789 case OMPD_target_teams_distribute_parallel_for:
10790 case OMPD_target_teams_distribute_parallel_for_simd:
10791 CaptureRegion = OMPD_task;
10792 break;
10793 case OMPD_target_data:
10794 // Do not capture device-clause expressions.
10795 break;
10796 case OMPD_teams_distribute_parallel_for:
10797 case OMPD_teams_distribute_parallel_for_simd:
10798 case OMPD_teams:
10799 case OMPD_teams_distribute:
10800 case OMPD_teams_distribute_simd:
10801 case OMPD_distribute_parallel_for:
10802 case OMPD_distribute_parallel_for_simd:
10803 case OMPD_task:
10804 case OMPD_taskloop:
10805 case OMPD_taskloop_simd:
10806 case OMPD_master_taskloop:
10807 case OMPD_master_taskloop_simd:
10808 case OMPD_parallel_master_taskloop:
10809 case OMPD_cancel:
10810 case OMPD_parallel:
10811 case OMPD_parallel_sections:
10812 case OMPD_parallel_for:
10813 case OMPD_parallel_for_simd:
10814 case OMPD_threadprivate:
10815 case OMPD_allocate:
10816 case OMPD_taskyield:
10817 case OMPD_barrier:
10818 case OMPD_taskwait:
10819 case OMPD_cancellation_point:
10820 case OMPD_flush:
10821 case OMPD_declare_reduction:
10822 case OMPD_declare_mapper:
10823 case OMPD_declare_simd:
10824 case OMPD_declare_variant:
10825 case OMPD_declare_target:
10826 case OMPD_end_declare_target:
10827 case OMPD_simd:
10828 case OMPD_for:
10829 case OMPD_for_simd:
10830 case OMPD_sections:
10831 case OMPD_section:
10832 case OMPD_single:
10833 case OMPD_master:
10834 case OMPD_critical:
10835 case OMPD_taskgroup:
10836 case OMPD_distribute:
10837 case OMPD_ordered:
10838 case OMPD_atomic:
10839 case OMPD_distribute_simd:
10840 case OMPD_requires:
10841 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
10842 case OMPD_unknown:
10843 llvm_unreachable("Unknown OpenMP directive");
10844 }
10845 break;
10846 case OMPC_grainsize:
10847 case OMPC_num_tasks:
10848 case OMPC_final:
10849 case OMPC_priority:
10850 switch (DKind) {
10851 case OMPD_task:
10852 case OMPD_taskloop:
10853 case OMPD_taskloop_simd:
10854 case OMPD_master_taskloop:
10855 case OMPD_master_taskloop_simd:
10856 break;
10857 case OMPD_parallel_master_taskloop:
10858 CaptureRegion = OMPD_parallel;
10859 break;
10860 case OMPD_target_update:
10861 case OMPD_target_enter_data:
10862 case OMPD_target_exit_data:
10863 case OMPD_target:
10864 case OMPD_target_simd:
10865 case OMPD_target_teams:
10866 case OMPD_target_parallel:
10867 case OMPD_target_teams_distribute:
10868 case OMPD_target_teams_distribute_simd:
10869 case OMPD_target_parallel_for:
10870 case OMPD_target_parallel_for_simd:
10871 case OMPD_target_teams_distribute_parallel_for:
10872 case OMPD_target_teams_distribute_parallel_for_simd:
10873 case OMPD_target_data:
10874 case OMPD_teams_distribute_parallel_for:
10875 case OMPD_teams_distribute_parallel_for_simd:
10876 case OMPD_teams:
10877 case OMPD_teams_distribute:
10878 case OMPD_teams_distribute_simd:
10879 case OMPD_distribute_parallel_for:
10880 case OMPD_distribute_parallel_for_simd:
10881 case OMPD_cancel:
10882 case OMPD_parallel:
10883 case OMPD_parallel_sections:
10884 case OMPD_parallel_for:
10885 case OMPD_parallel_for_simd:
10886 case OMPD_threadprivate:
10887 case OMPD_allocate:
10888 case OMPD_taskyield:
10889 case OMPD_barrier:
10890 case OMPD_taskwait:
10891 case OMPD_cancellation_point:
10892 case OMPD_flush:
10893 case OMPD_declare_reduction:
10894 case OMPD_declare_mapper:
10895 case OMPD_declare_simd:
10896 case OMPD_declare_variant:
10897 case OMPD_declare_target:
10898 case OMPD_end_declare_target:
10899 case OMPD_simd:
10900 case OMPD_for:
10901 case OMPD_for_simd:
10902 case OMPD_sections:
10903 case OMPD_section:
10904 case OMPD_single:
10905 case OMPD_master:
10906 case OMPD_critical:
10907 case OMPD_taskgroup:
10908 case OMPD_distribute:
10909 case OMPD_ordered:
10910 case OMPD_atomic:
10911 case OMPD_distribute_simd:
10912 case OMPD_requires:
10913 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
10914 case OMPD_unknown:
10915 llvm_unreachable("Unknown OpenMP directive");
10916 }
10917 break;
10918 case OMPC_firstprivate:
10919 case OMPC_lastprivate:
10920 case OMPC_reduction:
10921 case OMPC_task_reduction:
10922 case OMPC_in_reduction:
10923 case OMPC_linear:
10924 case OMPC_default:
10925 case OMPC_proc_bind:
10926 case OMPC_safelen:
10927 case OMPC_simdlen:
10928 case OMPC_allocator:
10929 case OMPC_collapse:
10930 case OMPC_private:
10931 case OMPC_shared:
10932 case OMPC_aligned:
10933 case OMPC_copyin:
10934 case OMPC_copyprivate:
10935 case OMPC_ordered:
10936 case OMPC_nowait:
10937 case OMPC_untied:
10938 case OMPC_mergeable:
10939 case OMPC_threadprivate:
10940 case OMPC_allocate:
10941 case OMPC_flush:
10942 case OMPC_read:
10943 case OMPC_write:
10944 case OMPC_update:
10945 case OMPC_capture:
10946 case OMPC_seq_cst:
10947 case OMPC_depend:
10948 case OMPC_threads:
10949 case OMPC_simd:
10950 case OMPC_map:
10951 case OMPC_nogroup:
10952 case OMPC_hint:
10953 case OMPC_defaultmap:
10954 case OMPC_unknown:
10955 case OMPC_uniform:
10956 case OMPC_to:
10957 case OMPC_from:
10958 case OMPC_use_device_ptr:
10959 case OMPC_is_device_ptr:
10960 case OMPC_unified_address:
10961 case OMPC_unified_shared_memory:
10962 case OMPC_reverse_offload:
10963 case OMPC_dynamic_allocators:
10964 case OMPC_atomic_default_mem_order:
10965 case OMPC_device_type:
10966 case OMPC_match:
10967 llvm_unreachable("Unexpected OpenMP clause.");
10968 }
10969 return CaptureRegion;
10970 }
10971
10972 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
10973 Expr *Condition, SourceLocation StartLoc,
10974 SourceLocation LParenLoc,
10975 SourceLocation NameModifierLoc,
10976 SourceLocation ColonLoc,
10977 SourceLocation EndLoc) {
10978 Expr *ValExpr = Condition;
10979 Stmt *HelperValStmt = nullptr;
10980 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
10981 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
10982 !Condition->isInstantiationDependent() &&
10983 !Condition->containsUnexpandedParameterPack()) {
10984 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
10985 if (Val.isInvalid())
10986 return nullptr;
10987
10988 ValExpr = Val.get();
10989
10990 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
10991 CaptureRegion =
10992 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
10993 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
10994 ValExpr = MakeFullExpr(ValExpr).get();
10995 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
10996 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
10997 HelperValStmt = buildPreInits(Context, Captures);
10998 }
10999 }
11000
11001 return new (Context)
11002 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
11003 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
11004 }
11005
11006 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
11007 SourceLocation StartLoc,
11008 SourceLocation LParenLoc,
11009 SourceLocation EndLoc) {
11010 Expr *ValExpr = Condition;
11011 Stmt *HelperValStmt = nullptr;
11012 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11013 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
11014 !Condition->isInstantiationDependent() &&
11015 !Condition->containsUnexpandedParameterPack()) {
11016 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
11017 if (Val.isInvalid())
11018 return nullptr;
11019
11020 ValExpr = MakeFullExpr(Val.get()).get();
11021
11022 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11023 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final);
11024 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11025 ValExpr = MakeFullExpr(ValExpr).get();
11026 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11027 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11028 HelperValStmt = buildPreInits(Context, Captures);
11029 }
11030 }
11031
11032 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
11033 StartLoc, LParenLoc, EndLoc);
11034 }
11035
11036 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
11037 Expr *Op) {
11038 if (!Op)
11039 return ExprError();
11040
11041 class IntConvertDiagnoser : public ICEConvertDiagnoser {
11042 public:
11043 IntConvertDiagnoser()
11044 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
11045 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
11046 QualType T) override {
11047 return S.Diag(Loc, diag::err_omp_not_integral) << T;
11048 }
11049 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
11050 QualType T) override {
11051 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
11052 }
11053 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
11054 QualType T,
11055 QualType ConvTy) override {
11056 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
11057 }
11058 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
11059 QualType ConvTy) override {
11060 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
11061 << ConvTy->isEnumeralType() << ConvTy;
11062 }
11063 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
11064 QualType T) override {
11065 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
11066 }
11067 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
11068 QualType ConvTy) override {
11069 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
11070 << ConvTy->isEnumeralType() << ConvTy;
11071 }
11072 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
11073 QualType) override {
11074 llvm_unreachable("conversion functions are permitted");
11075 }
11076 } ConvertDiagnoser;
11077 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
11078 }
11079
11080 static bool
11081 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
11082 bool StrictlyPositive, bool BuildCapture = false,
11083 OpenMPDirectiveKind DKind = OMPD_unknown,
11084 OpenMPDirectiveKind *CaptureRegion = nullptr,
11085 Stmt **HelperValStmt = nullptr) {
11086 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
11087 !ValExpr->isInstantiationDependent()) {
11088 SourceLocation Loc = ValExpr->getExprLoc();
11089 ExprResult Value =
11090 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
11091 if (Value.isInvalid())
11092 return false;
11093
11094 ValExpr = Value.get();
11095 // The expression must evaluate to a non-negative integer value.
11096 llvm::APSInt Result;
11097 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
11098 Result.isSigned() &&
11099 !((!StrictlyPositive && Result.isNonNegative()) ||
11100 (StrictlyPositive && Result.isStrictlyPositive()))) {
11101 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
11102 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11103 << ValExpr->getSourceRange();
11104 return false;
11105 }
11106 if (!BuildCapture)
11107 return true;
11108 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind);
11109 if (*CaptureRegion != OMPD_unknown &&
11110 !SemaRef.CurContext->isDependentContext()) {
11111 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
11112 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11113 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
11114 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
11115 }
11116 }
11117 return true;
11118 }
11119
11120 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
11121 SourceLocation StartLoc,
11122 SourceLocation LParenLoc,
11123 SourceLocation EndLoc) {
11124 Expr *ValExpr = NumThreads;
11125 Stmt *HelperValStmt = nullptr;
11126
11127 // OpenMP [2.5, Restrictions]
11128 // The num_threads expression must evaluate to a positive integer value.
11129 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
11130 /*StrictlyPositive=*/true))
11131 return nullptr;
11132
11133 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11134 OpenMPDirectiveKind CaptureRegion =
11135 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
11136 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11137 ValExpr = MakeFullExpr(ValExpr).get();
11138 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11139 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11140 HelperValStmt = buildPreInits(Context, Captures);
11141 }
11142
11143 return new (Context) OMPNumThreadsClause(
11144 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
11145 }
11146
11147 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
11148 OpenMPClauseKind CKind,
11149 bool StrictlyPositive) {
11150 if (!E)
11151 return ExprError();
11152 if (E->isValueDependent() || E->isTypeDependent() ||
11153 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
11154 return E;
11155 llvm::APSInt Result;
11156 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
11157 if (ICE.isInvalid())
11158 return ExprError();
11159 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
11160 (!StrictlyPositive && !Result.isNonNegative())) {
11161 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
11162 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11163 << E->getSourceRange();
11164 return ExprError();
11165 }
11166 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
11167 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
11168 << E->getSourceRange();
11169 return ExprError();
11170 }
11171 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
11172 DSAStack->setAssociatedLoops(Result.getExtValue());
11173 else if (CKind == OMPC_ordered)
11174 DSAStack->setAssociatedLoops(Result.getExtValue());
11175 return ICE;
11176 }
11177
11178 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
11179 SourceLocation LParenLoc,
11180 SourceLocation EndLoc) {
11181 // OpenMP [2.8.1, simd construct, Description]
11182 // The parameter of the safelen clause must be a constant
11183 // positive integer expression.
11184 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
11185 if (Safelen.isInvalid())
11186 return nullptr;
11187 return new (Context)
11188 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
11189 }
11190
11191 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
11192 SourceLocation LParenLoc,
11193 SourceLocation EndLoc) {
11194 // OpenMP [2.8.1, simd construct, Description]
11195 // The parameter of the simdlen clause must be a constant
11196 // positive integer expression.
11197 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
11198 if (Simdlen.isInvalid())
11199 return nullptr;
11200 return new (Context)
11201 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
11202 }
11203
11204 /// Tries to find omp_allocator_handle_t type.
11205 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
11206 DSAStackTy *Stack) {
11207 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
11208 if (!OMPAllocatorHandleT.isNull())
11209 return true;
11210 // Build the predefined allocator expressions.
11211 bool ErrorFound = false;
11212 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
11213 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
11214 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
11215 StringRef Allocator =
11216 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
11217 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
11218 auto *VD = dyn_cast_or_null<ValueDecl>(
11219 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
11220 if (!VD) {
11221 ErrorFound = true;
11222 break;
11223 }
11224 QualType AllocatorType =
11225 VD->getType().getNonLValueExprType(S.getASTContext());
11226 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
11227 if (!Res.isUsable()) {
11228 ErrorFound = true;
11229 break;
11230 }
11231 if (OMPAllocatorHandleT.isNull())
11232 OMPAllocatorHandleT = AllocatorType;
11233 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
11234 ErrorFound = true;
11235 break;
11236 }
11237 Stack->setAllocator(AllocatorKind, Res.get());
11238 }
11239 if (ErrorFound) {
11240 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
11241 return false;
11242 }
11243 OMPAllocatorHandleT.addConst();
11244 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
11245 return true;
11246 }
11247
11248 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
11249 SourceLocation LParenLoc,
11250 SourceLocation EndLoc) {
11251 // OpenMP [2.11.3, allocate Directive, Description]
11252 // allocator is an expression of omp_allocator_handle_t type.
11253 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
11254 return nullptr;
11255
11256 ExprResult Allocator = DefaultLvalueConversion(A);
11257 if (Allocator.isInvalid())
11258 return nullptr;
11259 Allocator = PerformImplicitConversion(Allocator.get(),
11260 DSAStack->getOMPAllocatorHandleT(),
11261 Sema::AA_Initializing,
11262 /*AllowExplicit=*/true);
11263 if (Allocator.isInvalid())
11264 return nullptr;
11265 return new (Context)
11266 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
11267 }
11268
11269 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
11270 SourceLocation StartLoc,
11271 SourceLocation LParenLoc,
11272 SourceLocation EndLoc) {
11273 // OpenMP [2.7.1, loop construct, Description]
11274 // OpenMP [2.8.1, simd construct, Description]
11275 // OpenMP [2.9.6, distribute construct, Description]
11276 // The parameter of the collapse clause must be a constant
11277 // positive integer expression.
11278 ExprResult NumForLoopsResult =
11279 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
11280 if (NumForLoopsResult.isInvalid())
11281 return nullptr;
11282 return new (Context)
11283 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
11284 }
11285
11286 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
11287 SourceLocation EndLoc,
11288 SourceLocation LParenLoc,
11289 Expr *NumForLoops) {
11290 // OpenMP [2.7.1, loop construct, Description]
11291 // OpenMP [2.8.1, simd construct, Description]
11292 // OpenMP [2.9.6, distribute construct, Description]
11293 // The parameter of the ordered clause must be a constant
11294 // positive integer expression if any.
11295 if (NumForLoops && LParenLoc.isValid()) {
11296 ExprResult NumForLoopsResult =
11297 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
11298 if (NumForLoopsResult.isInvalid())
11299 return nullptr;
11300 NumForLoops = NumForLoopsResult.get();
11301 } else {
11302 NumForLoops = nullptr;
11303 }
11304 auto *Clause = OMPOrderedClause::Create(
11305 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
11306 StartLoc, LParenLoc, EndLoc);
11307 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
11308 return Clause;
11309 }
11310
11311 OMPClause *Sema::ActOnOpenMPSimpleClause(
11312 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
11313 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
11314 OMPClause *Res = nullptr;
11315 switch (Kind) {
11316 case OMPC_default:
11317 Res =
11318 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
11319 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11320 break;
11321 case OMPC_proc_bind:
11322 Res = ActOnOpenMPProcBindClause(
11323 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
11324 LParenLoc, EndLoc);
11325 break;
11326 case OMPC_atomic_default_mem_order:
11327 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
11328 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
11329 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11330 break;
11331 case OMPC_if:
11332 case OMPC_final:
11333 case OMPC_num_threads:
11334 case OMPC_safelen:
11335 case OMPC_simdlen:
11336 case OMPC_allocator:
11337 case OMPC_collapse:
11338 case OMPC_schedule:
11339 case OMPC_private:
11340 case OMPC_firstprivate:
11341 case OMPC_lastprivate:
11342 case OMPC_shared:
11343 case OMPC_reduction:
11344 case OMPC_task_reduction:
11345 case OMPC_in_reduction:
11346 case OMPC_linear:
11347 case OMPC_aligned:
11348 case OMPC_copyin:
11349 case OMPC_copyprivate:
11350 case OMPC_ordered:
11351 case OMPC_nowait:
11352 case OMPC_untied:
11353 case OMPC_mergeable:
11354 case OMPC_threadprivate:
11355 case OMPC_allocate:
11356 case OMPC_flush:
11357 case OMPC_read:
11358 case OMPC_write:
11359 case OMPC_update:
11360 case OMPC_capture:
11361 case OMPC_seq_cst:
11362 case OMPC_depend:
11363 case OMPC_device:
11364 case OMPC_threads:
11365 case OMPC_simd:
11366 case OMPC_map:
11367 case OMPC_num_teams:
11368 case OMPC_thread_limit:
11369 case OMPC_priority:
11370 case OMPC_grainsize:
11371 case OMPC_nogroup:
11372 case OMPC_num_tasks:
11373 case OMPC_hint:
11374 case OMPC_dist_schedule:
11375 case OMPC_defaultmap:
11376 case OMPC_unknown:
11377 case OMPC_uniform:
11378 case OMPC_to:
11379 case OMPC_from:
11380 case OMPC_use_device_ptr:
11381 case OMPC_is_device_ptr:
11382 case OMPC_unified_address:
11383 case OMPC_unified_shared_memory:
11384 case OMPC_reverse_offload:
11385 case OMPC_dynamic_allocators:
11386 case OMPC_device_type:
11387 case OMPC_match:
11388 llvm_unreachable("Clause is not allowed.");
11389 }
11390 return Res;
11391 }
11392
11393 static std::string
11394 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
11395 ArrayRef<unsigned> Exclude = llvm::None) {
11396 SmallString<256> Buffer;
11397 llvm::raw_svector_ostream Out(Buffer);
11398 unsigned Bound = Last >= 2 ? Last - 2 : 0;
11399 unsigned Skipped = Exclude.size();
11400 auto S = Exclude.begin(), E = Exclude.end();
11401 for (unsigned I = First; I < Last; ++I) {
11402 if (std::find(S, E, I) != E) {
11403 --Skipped;
11404 continue;
11405 }
11406 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
11407 if (I == Bound - Skipped)
11408 Out << " or ";
11409 else if (I != Bound + 1 - Skipped)
11410 Out << ", ";
11411 }
11412 return Out.str();
11413 }
11414
11415 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
11416 SourceLocation KindKwLoc,
11417 SourceLocation StartLoc,
11418 SourceLocation LParenLoc,
11419 SourceLocation EndLoc) {
11420 if (Kind == OMPC_DEFAULT_unknown) {
11421 static_assert(OMPC_DEFAULT_unknown > 0,
11422 "OMPC_DEFAULT_unknown not greater than 0");
11423 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11424 << getListOfPossibleValues(OMPC_default, /*First=*/0,
11425 /*Last=*/OMPC_DEFAULT_unknown)
11426 << getOpenMPClauseName(OMPC_default);
11427 return nullptr;
11428 }
11429 switch (Kind) {
11430 case OMPC_DEFAULT_none:
11431 DSAStack->setDefaultDSANone(KindKwLoc);
11432 break;
11433 case OMPC_DEFAULT_shared:
11434 DSAStack->setDefaultDSAShared(KindKwLoc);
11435 break;
11436 case OMPC_DEFAULT_unknown:
11437 llvm_unreachable("Clause kind is not allowed.");
11438 break;
11439 }
11440 return new (Context)
11441 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
11442 }
11443
11444 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
11445 SourceLocation KindKwLoc,
11446 SourceLocation StartLoc,
11447 SourceLocation LParenLoc,
11448 SourceLocation EndLoc) {
11449 if (Kind == OMPC_PROC_BIND_unknown) {
11450 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11451 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
11452 /*Last=*/OMPC_PROC_BIND_unknown)
11453 << getOpenMPClauseName(OMPC_proc_bind);
11454 return nullptr;
11455 }
11456 return new (Context)
11457 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
11458 }
11459
11460 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
11461 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
11462 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
11463 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
11464 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11465 << getListOfPossibleValues(
11466 OMPC_atomic_default_mem_order, /*First=*/0,
11467 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
11468 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
11469 return nullptr;
11470 }
11471 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
11472 LParenLoc, EndLoc);
11473 }
11474
11475 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
11476 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
11477 SourceLocation StartLoc, SourceLocation LParenLoc,
11478 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
11479 SourceLocation EndLoc) {
11480 OMPClause *Res = nullptr;
11481 switch (Kind) {
11482 case OMPC_schedule:
11483 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
11484 assert(Argument.size() == NumberOfElements &&
11485 ArgumentLoc.size() == NumberOfElements);
11486 Res = ActOnOpenMPScheduleClause(
11487 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
11488 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
11489 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
11490 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
11491 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
11492 break;
11493 case OMPC_if:
11494 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
11495 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
11496 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
11497 DelimLoc, EndLoc);
11498 break;
11499 case OMPC_dist_schedule:
11500 Res = ActOnOpenMPDistScheduleClause(
11501 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
11502 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
11503 break;
11504 case OMPC_defaultmap:
11505 enum { Modifier, DefaultmapKind };
11506 Res = ActOnOpenMPDefaultmapClause(
11507 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
11508 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
11509 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
11510 EndLoc);
11511 break;
11512 case OMPC_final:
11513 case OMPC_num_threads:
11514 case OMPC_safelen:
11515 case OMPC_simdlen:
11516 case OMPC_allocator:
11517 case OMPC_collapse:
11518 case OMPC_default:
11519 case OMPC_proc_bind:
11520 case OMPC_private:
11521 case OMPC_firstprivate:
11522 case OMPC_lastprivate:
11523 case OMPC_shared:
11524 case OMPC_reduction:
11525 case OMPC_task_reduction:
11526 case OMPC_in_reduction:
11527 case OMPC_linear:
11528 case OMPC_aligned:
11529 case OMPC_copyin:
11530 case OMPC_copyprivate:
11531 case OMPC_ordered:
11532 case OMPC_nowait:
11533 case OMPC_untied:
11534 case OMPC_mergeable:
11535 case OMPC_threadprivate:
11536 case OMPC_allocate:
11537 case OMPC_flush:
11538 case OMPC_read:
11539 case OMPC_write:
11540 case OMPC_update:
11541 case OMPC_capture:
11542 case OMPC_seq_cst:
11543 case OMPC_depend:
11544 case OMPC_device:
11545 case OMPC_threads:
11546 case OMPC_simd:
11547 case OMPC_map:
11548 case OMPC_num_teams:
11549 case OMPC_thread_limit:
11550 case OMPC_priority:
11551 case OMPC_grainsize:
11552 case OMPC_nogroup:
11553 case OMPC_num_tasks:
11554 case OMPC_hint:
11555 case OMPC_unknown:
11556 case OMPC_uniform:
11557 case OMPC_to:
11558 case OMPC_from:
11559 case OMPC_use_device_ptr:
11560 case OMPC_is_device_ptr:
11561 case OMPC_unified_address:
11562 case OMPC_unified_shared_memory:
11563 case OMPC_reverse_offload:
11564 case OMPC_dynamic_allocators:
11565 case OMPC_atomic_default_mem_order:
11566 case OMPC_device_type:
11567 case OMPC_match:
11568 llvm_unreachable("Clause is not allowed.");
11569 }
11570 return Res;
11571 }
11572
11573 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
11574 OpenMPScheduleClauseModifier M2,
11575 SourceLocation M1Loc, SourceLocation M2Loc) {
11576 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
11577 SmallVector<unsigned, 2> Excluded;
11578 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
11579 Excluded.push_back(M2);
11580 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
11581 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
11582 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
11583 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
11584 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
11585 << getListOfPossibleValues(OMPC_schedule,
11586 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
11587 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
11588 Excluded)
11589 << getOpenMPClauseName(OMPC_schedule);
11590 return true;
11591 }
11592 return false;
11593 }
11594
11595 OMPClause *Sema::ActOnOpenMPScheduleClause(
11596 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
11597 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
11598 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
11599 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
11600 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
11601 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
11602 return nullptr;
11603 // OpenMP, 2.7.1, Loop Construct, Restrictions
11604 // Either the monotonic modifier or the nonmonotonic modifier can be specified
11605 // but not both.
11606 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
11607 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
11608 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
11609 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
11610 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
11611 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
11612 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
11613 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
11614 return nullptr;
11615 }
11616 if (Kind == OMPC_SCHEDULE_unknown) {
11617 std::string Values;
11618 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
11619 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
11620 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
11621 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
11622 Exclude);
11623 } else {
11624 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
11625 /*Last=*/OMPC_SCHEDULE_unknown);
11626 }
11627 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
11628 << Values << getOpenMPClauseName(OMPC_schedule);
11629 return nullptr;
11630 }
11631 // OpenMP, 2.7.1, Loop Construct, Restrictions
11632 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
11633 // schedule(guided).
11634 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
11635 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
11636 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
11637 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
11638 diag::err_omp_schedule_nonmonotonic_static);
11639 return nullptr;
11640 }
11641 Expr *ValExpr = ChunkSize;
11642 Stmt *HelperValStmt = nullptr;
11643 if (ChunkSize) {
11644 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
11645 !ChunkSize->isInstantiationDependent() &&
11646 !ChunkSize->containsUnexpandedParameterPack()) {
11647 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
11648 ExprResult Val =
11649 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
11650 if (Val.isInvalid())
11651 return nullptr;
11652
11653 ValExpr = Val.get();
11654
11655 // OpenMP [2.7.1, Restrictions]
11656 // chunk_size must be a loop invariant integer expression with a positive
11657 // value.
11658 llvm::APSInt Result;
11659 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
11660 if (Result.isSigned() && !Result.isStrictlyPositive()) {
11661 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
11662 << "schedule" << 1 << ChunkSize->getSourceRange();
11663 return nullptr;
11664 }
11665 } else if (getOpenMPCaptureRegionForClause(
11666 DSAStack->getCurrentDirective(), OMPC_schedule) !=
11667 OMPD_unknown &&
11668 !CurContext->isDependentContext()) {
11669 ValExpr = MakeFullExpr(ValExpr).get();
11670 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11671 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11672 HelperValStmt = buildPreInits(Context, Captures);
11673 }
11674 }
11675 }
11676
11677 return new (Context)
11678 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
11679 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
11680 }
11681
11682 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
11683 SourceLocation StartLoc,
11684 SourceLocation EndLoc) {
11685 OMPClause *Res = nullptr;
11686 switch (Kind) {
11687 case OMPC_ordered:
11688 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
11689 break;
11690 case OMPC_nowait:
11691 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
11692 break;
11693 case OMPC_untied:
11694 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
11695 break;
11696 case OMPC_mergeable:
11697 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
11698 break;
11699 case OMPC_read:
11700 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
11701 break;
11702 case OMPC_write:
11703 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
11704 break;
11705 case OMPC_update:
11706 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
11707 break;
11708 case OMPC_capture:
11709 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
11710 break;
11711 case OMPC_seq_cst:
11712 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
11713 break;
11714 case OMPC_threads:
11715 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
11716 break;
11717 case OMPC_simd:
11718 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
11719 break;
11720 case OMPC_nogroup:
11721 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
11722 break;
11723 case OMPC_unified_address:
11724 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
11725 break;
11726 case OMPC_unified_shared_memory:
11727 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
11728 break;
11729 case OMPC_reverse_offload:
11730 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
11731 break;
11732 case OMPC_dynamic_allocators:
11733 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
11734 break;
11735 case OMPC_if:
11736 case OMPC_final:
11737 case OMPC_num_threads:
11738 case OMPC_safelen:
11739 case OMPC_simdlen:
11740 case OMPC_allocator:
11741 case OMPC_collapse:
11742 case OMPC_schedule:
11743 case OMPC_private:
11744 case OMPC_firstprivate:
11745 case OMPC_lastprivate:
11746 case OMPC_shared:
11747 case OMPC_reduction:
11748 case OMPC_task_reduction:
11749 case OMPC_in_reduction:
11750 case OMPC_linear:
11751 case OMPC_aligned:
11752 case OMPC_copyin:
11753 case OMPC_copyprivate:
11754 case OMPC_default:
11755 case OMPC_proc_bind:
11756 case OMPC_threadprivate:
11757 case OMPC_allocate:
11758 case OMPC_flush:
11759 case OMPC_depend:
11760 case OMPC_device:
11761 case OMPC_map:
11762 case OMPC_num_teams:
11763 case OMPC_thread_limit:
11764 case OMPC_priority:
11765 case OMPC_grainsize:
11766 case OMPC_num_tasks:
11767 case OMPC_hint:
11768 case OMPC_dist_schedule:
11769 case OMPC_defaultmap:
11770 case OMPC_unknown:
11771 case OMPC_uniform:
11772 case OMPC_to:
11773 case OMPC_from:
11774 case OMPC_use_device_ptr:
11775 case OMPC_is_device_ptr:
11776 case OMPC_atomic_default_mem_order:
11777 case OMPC_device_type:
11778 case OMPC_match:
11779 llvm_unreachable("Clause is not allowed.");
11780 }
11781 return Res;
11782 }
11783
11784 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
11785 SourceLocation EndLoc) {
11786 DSAStack->setNowaitRegion();
11787 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
11788 }
11789
11790 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
11791 SourceLocation EndLoc) {
11792 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
11793 }
11794
11795 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
11796 SourceLocation EndLoc) {
11797 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
11798 }
11799
11800 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
11801 SourceLocation EndLoc) {
11802 return new (Context) OMPReadClause(StartLoc, EndLoc);
11803 }
11804
11805 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
11806 SourceLocation EndLoc) {
11807 return new (Context) OMPWriteClause(StartLoc, EndLoc);
11808 }
11809
11810 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
11811 SourceLocation EndLoc) {
11812 return new (Context) OMPUpdateClause(StartLoc, EndLoc);
11813 }
11814
11815 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
11816 SourceLocation EndLoc) {
11817 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
11818 }
11819
11820 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
11821 SourceLocation EndLoc) {
11822 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
11823 }
11824
11825 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
11826 SourceLocation EndLoc) {
11827 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
11828 }
11829
11830 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
11831 SourceLocation EndLoc) {
11832 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
11833 }
11834
11835 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
11836 SourceLocation EndLoc) {
11837 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
11838 }
11839
11840 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
11841 SourceLocation EndLoc) {
11842 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
11843 }
11844
11845 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
11846 SourceLocation EndLoc) {
11847 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
11848 }
11849
11850 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
11851 SourceLocation EndLoc) {
11852 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
11853 }
11854
11855 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
11856 SourceLocation EndLoc) {
11857 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
11858 }
11859
11860 OMPClause *Sema::ActOnOpenMPVarListClause(
11861 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
11862 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
11863 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
11864 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind,
11865 OpenMPLinearClauseKind LinKind,
11866 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
11867 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType,
11868 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) {
11869 SourceLocation StartLoc = Locs.StartLoc;
11870 SourceLocation LParenLoc = Locs.LParenLoc;
11871 SourceLocation EndLoc = Locs.EndLoc;
11872 OMPClause *Res = nullptr;
11873 switch (Kind) {
11874 case OMPC_private:
11875 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11876 break;
11877 case OMPC_firstprivate:
11878 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11879 break;
11880 case OMPC_lastprivate:
11881 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11882 break;
11883 case OMPC_shared:
11884 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
11885 break;
11886 case OMPC_reduction:
11887 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
11888 EndLoc, ReductionOrMapperIdScopeSpec,
11889 ReductionOrMapperId);
11890 break;
11891 case OMPC_task_reduction:
11892 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
11893 EndLoc, ReductionOrMapperIdScopeSpec,
11894 ReductionOrMapperId);
11895 break;
11896 case OMPC_in_reduction:
11897 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
11898 EndLoc, ReductionOrMapperIdScopeSpec,
11899 ReductionOrMapperId);
11900 break;
11901 case OMPC_linear:
11902 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
11903 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
11904 break;
11905 case OMPC_aligned:
11906 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
11907 ColonLoc, EndLoc);
11908 break;
11909 case OMPC_copyin:
11910 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
11911 break;
11912 case OMPC_copyprivate:
11913 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11914 break;
11915 case OMPC_flush:
11916 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
11917 break;
11918 case OMPC_depend:
11919 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
11920 StartLoc, LParenLoc, EndLoc);
11921 break;
11922 case OMPC_map:
11923 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc,
11924 ReductionOrMapperIdScopeSpec,
11925 ReductionOrMapperId, MapType, IsMapTypeImplicit,
11926 DepLinMapLoc, ColonLoc, VarList, Locs);
11927 break;
11928 case OMPC_to:
11929 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
11930 ReductionOrMapperId, Locs);
11931 break;
11932 case OMPC_from:
11933 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
11934 ReductionOrMapperId, Locs);
11935 break;
11936 case OMPC_use_device_ptr:
11937 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
11938 break;
11939 case OMPC_is_device_ptr:
11940 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
11941 break;
11942 case OMPC_allocate:
11943 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
11944 ColonLoc, EndLoc);
11945 break;
11946 case OMPC_if:
11947 case OMPC_final:
11948 case OMPC_num_threads:
11949 case OMPC_safelen:
11950 case OMPC_simdlen:
11951 case OMPC_allocator:
11952 case OMPC_collapse:
11953 case OMPC_default:
11954 case OMPC_proc_bind:
11955 case OMPC_schedule:
11956 case OMPC_ordered:
11957 case OMPC_nowait:
11958 case OMPC_untied:
11959 case OMPC_mergeable:
11960 case OMPC_threadprivate:
11961 case OMPC_read:
11962 case OMPC_write:
11963 case OMPC_update:
11964 case OMPC_capture:
11965 case OMPC_seq_cst:
11966 case OMPC_device:
11967 case OMPC_threads:
11968 case OMPC_simd:
11969 case OMPC_num_teams:
11970 case OMPC_thread_limit:
11971 case OMPC_priority:
11972 case OMPC_grainsize:
11973 case OMPC_nogroup:
11974 case OMPC_num_tasks:
11975 case OMPC_hint:
11976 case OMPC_dist_schedule:
11977 case OMPC_defaultmap:
11978 case OMPC_unknown:
11979 case OMPC_uniform:
11980 case OMPC_unified_address:
11981 case OMPC_unified_shared_memory:
11982 case OMPC_reverse_offload:
11983 case OMPC_dynamic_allocators:
11984 case OMPC_atomic_default_mem_order:
11985 case OMPC_device_type:
11986 case OMPC_match:
11987 llvm_unreachable("Clause is not allowed.");
11988 }
11989 return Res;
11990 }
11991
11992 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
11993 ExprObjectKind OK, SourceLocation Loc) {
11994 ExprResult Res = BuildDeclRefExpr(
11995 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
11996 if (!Res.isUsable())
11997 return ExprError();
11998 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
11999 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
12000 if (!Res.isUsable())
12001 return ExprError();
12002 }
12003 if (VK != VK_LValue && Res.get()->isGLValue()) {
12004 Res = DefaultLvalueConversion(Res.get());
12005 if (!Res.isUsable())
12006 return ExprError();
12007 }
12008 return Res;
12009 }
12010
12011 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
12012 SourceLocation StartLoc,
12013 SourceLocation LParenLoc,
12014 SourceLocation EndLoc) {
12015 SmallVector<Expr *, 8> Vars;
12016 SmallVector<Expr *, 8> PrivateCopies;
12017 for (Expr *RefExpr : VarList) {
12018 assert(RefExpr && "NULL expr in OpenMP private clause.");
12019 SourceLocation ELoc;
12020 SourceRange ERange;
12021 Expr *SimpleRefExpr = RefExpr;
12022 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12023 if (Res.second) {
12024 // It will be analyzed later.
12025 Vars.push_back(RefExpr);
12026 PrivateCopies.push_back(nullptr);
12027 }
12028 ValueDecl *D = Res.first;
12029 if (!D)
12030 continue;
12031
12032 QualType Type = D->getType();
12033 auto *VD = dyn_cast<VarDecl>(D);
12034
12035 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
12036 // A variable that appears in a private clause must not have an incomplete
12037 // type or a reference type.
12038 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
12039 continue;
12040 Type = Type.getNonReferenceType();
12041
12042 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12043 // A variable that is privatized must not have a const-qualified type
12044 // unless it is of class type with a mutable member. This restriction does
12045 // not apply to the firstprivate clause.
12046 //
12047 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
12048 // A variable that appears in a private clause must not have a
12049 // const-qualified type unless it is of class type with a mutable member.
12050 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
12051 continue;
12052
12053 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12054 // in a Construct]
12055 // Variables with the predetermined data-sharing attributes may not be
12056 // listed in data-sharing attributes clauses, except for the cases
12057 // listed below. For these exceptions only, listing a predetermined
12058 // variable in a data-sharing attribute clause is allowed and overrides
12059 // the variable's predetermined data-sharing attributes.
12060 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
12061 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
12062 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12063 << getOpenMPClauseName(OMPC_private);
12064 reportOriginalDsa(*this, DSAStack, D, DVar);
12065 continue;
12066 }
12067
12068 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
12069 // Variably modified types are not supported for tasks.
12070 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
12071 isOpenMPTaskingDirective(CurrDir)) {
12072 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12073 << getOpenMPClauseName(OMPC_private) << Type
12074 << getOpenMPDirectiveName(CurrDir);
12075 bool IsDecl =
12076 !VD ||
12077 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12078 Diag(D->getLocation(),
12079 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12080 << D;
12081 continue;
12082 }
12083
12084 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12085 // A list item cannot appear in both a map clause and a data-sharing
12086 // attribute clause on the same construct
12087 //
12088 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
12089 // A list item cannot appear in both a map clause and a data-sharing
12090 // attribute clause on the same construct unless the construct is a
12091 // combined construct.
12092 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
12093 CurrDir == OMPD_target) {
12094 OpenMPClauseKind ConflictKind;
12095 if (DSAStack->checkMappableExprComponentListsForDecl(
12096 VD, /*CurrentRegionOnly=*/true,
12097 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
12098 OpenMPClauseKind WhereFoundClauseKind) -> bool {
12099 ConflictKind = WhereFoundClauseKind;
12100 return true;
12101 })) {
12102 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12103 << getOpenMPClauseName(OMPC_private)
12104 << getOpenMPClauseName(ConflictKind)
12105 << getOpenMPDirectiveName(CurrDir);
12106 reportOriginalDsa(*this, DSAStack, D, DVar);
12107 continue;
12108 }
12109 }
12110
12111 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
12112 // A variable of class type (or array thereof) that appears in a private
12113 // clause requires an accessible, unambiguous default constructor for the
12114 // class type.
12115 // Generate helper private variable and initialize it with the default
12116 // value. The address of the original variable is replaced by the address of
12117 // the new private variable in CodeGen. This new variable is not added to
12118 // IdResolver, so the code in the OpenMP region uses original variable for
12119 // proper diagnostics.
12120 Type = Type.getUnqualifiedType();
12121 VarDecl *VDPrivate =
12122 buildVarDecl(*this, ELoc, Type, D->getName(),
12123 D->hasAttrs() ? &D->getAttrs() : nullptr,
12124 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
12125 ActOnUninitializedDecl(VDPrivate);
12126 if (VDPrivate->isInvalidDecl())
12127 continue;
12128 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
12129 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
12130
12131 DeclRefExpr *Ref = nullptr;
12132 if (!VD && !CurContext->isDependentContext())
12133 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
12134 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
12135 Vars.push_back((VD || CurContext->isDependentContext())
12136 ? RefExpr->IgnoreParens()
12137 : Ref);
12138 PrivateCopies.push_back(VDPrivateRefExpr);
12139 }
12140
12141 if (Vars.empty())
12142 return nullptr;
12143
12144 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
12145 PrivateCopies);
12146 }
12147
12148 namespace {
12149 class DiagsUninitializedSeveretyRAII {
12150 private:
12151 DiagnosticsEngine &Diags;
12152 SourceLocation SavedLoc;
12153 bool IsIgnored = false;
12154
12155 public:
12156 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
12157 bool IsIgnored)
12158 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
12159 if (!IsIgnored) {
12160 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
12161 /*Map*/ diag::Severity::Ignored, Loc);
12162 }
12163 }
12164 ~DiagsUninitializedSeveretyRAII() {
12165 if (!IsIgnored)
12166 Diags.popMappings(SavedLoc);
12167 }
12168 };
12169 }
12170
12171 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
12172 SourceLocation StartLoc,
12173 SourceLocation LParenLoc,
12174 SourceLocation EndLoc) {
12175 SmallVector<Expr *, 8> Vars;
12176 SmallVector<Expr *, 8> PrivateCopies;
12177 SmallVector<Expr *, 8> Inits;
12178 SmallVector<Decl *, 4> ExprCaptures;
12179 bool IsImplicitClause =
12180 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
12181 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
12182
12183 for (Expr *RefExpr : VarList) {
12184 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
12185 SourceLocation ELoc;
12186 SourceRange ERange;
12187 Expr *SimpleRefExpr = RefExpr;
12188 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12189 if (Res.second) {
12190 // It will be analyzed later.
12191 Vars.push_back(RefExpr);
12192 PrivateCopies.push_back(nullptr);
12193 Inits.push_back(nullptr);
12194 }
12195 ValueDecl *D = Res.first;
12196 if (!D)
12197 continue;
12198
12199 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
12200 QualType Type = D->getType();
12201 auto *VD = dyn_cast<VarDecl>(D);
12202
12203 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
12204 // A variable that appears in a private clause must not have an incomplete
12205 // type or a reference type.
12206 if (RequireCompleteType(ELoc, Type,
12207 diag::err_omp_firstprivate_incomplete_type))
12208 continue;
12209 Type = Type.getNonReferenceType();
12210
12211 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
12212 // A variable of class type (or array thereof) that appears in a private
12213 // clause requires an accessible, unambiguous copy constructor for the
12214 // class type.
12215 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
12216
12217 // If an implicit firstprivate variable found it was checked already.
12218 DSAStackTy::DSAVarData TopDVar;
12219 if (!IsImplicitClause) {
12220 DSAStackTy::DSAVarData DVar =
12221 DSAStack->getTopDSA(D, /*FromParent=*/false);
12222 TopDVar = DVar;
12223 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
12224 bool IsConstant = ElemType.isConstant(Context);
12225 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
12226 // A list item that specifies a given variable may not appear in more
12227 // than one clause on the same directive, except that a variable may be
12228 // specified in both firstprivate and lastprivate clauses.
12229 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
12230 // A list item may appear in a firstprivate or lastprivate clause but not
12231 // both.
12232 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
12233 (isOpenMPDistributeDirective(CurrDir) ||
12234 DVar.CKind != OMPC_lastprivate) &&
12235 DVar.RefExpr) {
12236 Diag(ELoc, diag::err_omp_wrong_dsa)
12237 << getOpenMPClauseName(DVar.CKind)
12238 << getOpenMPClauseName(OMPC_firstprivate);
12239 reportOriginalDsa(*this, DSAStack, D, DVar);
12240 continue;
12241 }
12242
12243 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12244 // in a Construct]
12245 // Variables with the predetermined data-sharing attributes may not be
12246 // listed in data-sharing attributes clauses, except for the cases
12247 // listed below. For these exceptions only, listing a predetermined
12248 // variable in a data-sharing attribute clause is allowed and overrides
12249 // the variable's predetermined data-sharing attributes.
12250 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12251 // in a Construct, C/C++, p.2]
12252 // Variables with const-qualified type having no mutable member may be
12253 // listed in a firstprivate clause, even if they are static data members.
12254 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
12255 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
12256 Diag(ELoc, diag::err_omp_wrong_dsa)
12257 << getOpenMPClauseName(DVar.CKind)
12258 << getOpenMPClauseName(OMPC_firstprivate);
12259 reportOriginalDsa(*this, DSAStack, D, DVar);
12260 continue;
12261 }
12262
12263 // OpenMP [2.9.3.4, Restrictions, p.2]
12264 // A list item that is private within a parallel region must not appear
12265 // in a firstprivate clause on a worksharing construct if any of the
12266 // worksharing regions arising from the worksharing construct ever bind
12267 // to any of the parallel regions arising from the parallel construct.
12268 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
12269 // A list item that is private within a teams region must not appear in a
12270 // firstprivate clause on a distribute construct if any of the distribute
12271 // regions arising from the distribute construct ever bind to any of the
12272 // teams regions arising from the teams construct.
12273 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
12274 // A list item that appears in a reduction clause of a teams construct
12275 // must not appear in a firstprivate clause on a distribute construct if
12276 // any of the distribute regions arising from the distribute construct
12277 // ever bind to any of the teams regions arising from the teams construct.
12278 if ((isOpenMPWorksharingDirective(CurrDir) ||
12279 isOpenMPDistributeDirective(CurrDir)) &&
12280 !isOpenMPParallelDirective(CurrDir) &&
12281 !isOpenMPTeamsDirective(CurrDir)) {
12282 DVar = DSAStack->getImplicitDSA(D, true);
12283 if (DVar.CKind != OMPC_shared &&
12284 (isOpenMPParallelDirective(DVar.DKind) ||
12285 isOpenMPTeamsDirective(DVar.DKind) ||
12286 DVar.DKind == OMPD_unknown)) {
12287 Diag(ELoc, diag::err_omp_required_access)
12288 << getOpenMPClauseName(OMPC_firstprivate)
12289 << getOpenMPClauseName(OMPC_shared);
12290 reportOriginalDsa(*this, DSAStack, D, DVar);
12291 continue;
12292 }
12293 }
12294 // OpenMP [2.9.3.4, Restrictions, p.3]
12295 // A list item that appears in a reduction clause of a parallel construct
12296 // must not appear in a firstprivate clause on a worksharing or task
12297 // construct if any of the worksharing or task regions arising from the
12298 // worksharing or task construct ever bind to any of the parallel regions
12299 // arising from the parallel construct.
12300 // OpenMP [2.9.3.4, Restrictions, p.4]
12301 // A list item that appears in a reduction clause in worksharing
12302 // construct must not appear in a firstprivate clause in a task construct
12303 // encountered during execution of any of the worksharing regions arising
12304 // from the worksharing construct.
12305 if (isOpenMPTaskingDirective(CurrDir)) {
12306 DVar = DSAStack->hasInnermostDSA(
12307 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
12308 [](OpenMPDirectiveKind K) {
12309 return isOpenMPParallelDirective(K) ||
12310 isOpenMPWorksharingDirective(K) ||
12311 isOpenMPTeamsDirective(K);
12312 },
12313 /*FromParent=*/true);
12314 if (DVar.CKind == OMPC_reduction &&
12315 (isOpenMPParallelDirective(DVar.DKind) ||
12316 isOpenMPWorksharingDirective(DVar.DKind) ||
12317 isOpenMPTeamsDirective(DVar.DKind))) {
12318 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
12319 << getOpenMPDirectiveName(DVar.DKind);
12320 reportOriginalDsa(*this, DSAStack, D, DVar);
12321 continue;
12322 }
12323 }
12324
12325 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12326 // A list item cannot appear in both a map clause and a data-sharing
12327 // attribute clause on the same construct
12328 //
12329 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
12330 // A list item cannot appear in both a map clause and a data-sharing
12331 // attribute clause on the same construct unless the construct is a
12332 // combined construct.
12333 if ((LangOpts.OpenMP <= 45 &&
12334 isOpenMPTargetExecutionDirective(CurrDir)) ||
12335 CurrDir == OMPD_target) {
12336 OpenMPClauseKind ConflictKind;
12337 if (DSAStack->checkMappableExprComponentListsForDecl(
12338 VD, /*CurrentRegionOnly=*/true,
12339 [&ConflictKind](
12340 OMPClauseMappableExprCommon::MappableExprComponentListRef,
12341 OpenMPClauseKind WhereFoundClauseKind) {
12342 ConflictKind = WhereFoundClauseKind;
12343 return true;
12344 })) {
12345 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12346 << getOpenMPClauseName(OMPC_firstprivate)
12347 << getOpenMPClauseName(ConflictKind)
12348 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12349 reportOriginalDsa(*this, DSAStack, D, DVar);
12350 continue;
12351 }
12352 }
12353 }
12354
12355 // Variably modified types are not supported for tasks.
12356 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
12357 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
12358 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12359 << getOpenMPClauseName(OMPC_firstprivate) << Type
12360 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12361 bool IsDecl =
12362 !VD ||
12363 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12364 Diag(D->getLocation(),
12365 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12366 << D;
12367 continue;
12368 }
12369
12370 Type = Type.getUnqualifiedType();
12371 VarDecl *VDPrivate =
12372 buildVarDecl(*this, ELoc, Type, D->getName(),
12373 D->hasAttrs() ? &D->getAttrs() : nullptr,
12374 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
12375 // Generate helper private variable and initialize it with the value of the
12376 // original variable. The address of the original variable is replaced by
12377 // the address of the new private variable in the CodeGen. This new variable
12378 // is not added to IdResolver, so the code in the OpenMP region uses
12379 // original variable for proper diagnostics and variable capturing.
12380 Expr *VDInitRefExpr = nullptr;
12381 // For arrays generate initializer for single element and replace it by the
12382 // original array element in CodeGen.
12383 if (Type->isArrayType()) {
12384 VarDecl *VDInit =
12385 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
12386 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
12387 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
12388 ElemType = ElemType.getUnqualifiedType();
12389 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
12390 ".firstprivate.temp");
12391 InitializedEntity Entity =
12392 InitializedEntity::InitializeVariable(VDInitTemp);
12393 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
12394
12395 InitializationSequence InitSeq(*this, Entity, Kind, Init);
12396 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
12397 if (Result.isInvalid())
12398 VDPrivate->setInvalidDecl();
12399 else
12400 VDPrivate->setInit(Result.getAs<Expr>());
12401 // Remove temp variable declaration.
12402 Context.Deallocate(VDInitTemp);
12403 } else {
12404 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
12405 ".firstprivate.temp");
12406 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
12407 RefExpr->getExprLoc());
12408 AddInitializerToDecl(VDPrivate,
12409 DefaultLvalueConversion(VDInitRefExpr).get(),
12410 /*DirectInit=*/false);
12411 }
12412 if (VDPrivate->isInvalidDecl()) {
12413 if (IsImplicitClause) {
12414 Diag(RefExpr->getExprLoc(),
12415 diag::note_omp_task_predetermined_firstprivate_here);
12416 }
12417 continue;
12418 }
12419 CurContext->addDecl(VDPrivate);
12420 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
12421 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
12422 RefExpr->getExprLoc());
12423 DeclRefExpr *Ref = nullptr;
12424 if (!VD && !CurContext->isDependentContext()) {
12425 if (TopDVar.CKind == OMPC_lastprivate) {
12426 Ref = TopDVar.PrivateCopy;
12427 } else {
12428 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12429 if (!isOpenMPCapturedDecl(D))
12430 ExprCaptures.push_back(Ref->getDecl());
12431 }
12432 }
12433 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
12434 Vars.push_back((VD || CurContext->isDependentContext())
12435 ? RefExpr->IgnoreParens()
12436 : Ref);
12437 PrivateCopies.push_back(VDPrivateRefExpr);
12438 Inits.push_back(VDInitRefExpr);
12439 }
12440
12441 if (Vars.empty())
12442 return nullptr;
12443
12444 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12445 Vars, PrivateCopies, Inits,
12446 buildPreInits(Context, ExprCaptures));
12447 }
12448
12449 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
12450 SourceLocation StartLoc,
12451 SourceLocation LParenLoc,
12452 SourceLocation EndLoc) {
12453 SmallVector<Expr *, 8> Vars;
12454 SmallVector<Expr *, 8> SrcExprs;
12455 SmallVector<Expr *, 8> DstExprs;
12456 SmallVector<Expr *, 8> AssignmentOps;
12457 SmallVector<Decl *, 4> ExprCaptures;
12458 SmallVector<Expr *, 4> ExprPostUpdates;
12459 for (Expr *RefExpr : VarList) {
12460 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
12461 SourceLocation ELoc;
12462 SourceRange ERange;
12463 Expr *SimpleRefExpr = RefExpr;
12464 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12465 if (Res.second) {
12466 // It will be analyzed later.
12467 Vars.push_back(RefExpr);
12468 SrcExprs.push_back(nullptr);
12469 DstExprs.push_back(nullptr);
12470 AssignmentOps.push_back(nullptr);
12471 }
12472 ValueDecl *D = Res.first;
12473 if (!D)
12474 continue;
12475
12476 QualType Type = D->getType();
12477 auto *VD = dyn_cast<VarDecl>(D);
12478
12479 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
12480 // A variable that appears in a lastprivate clause must not have an
12481 // incomplete type or a reference type.
12482 if (RequireCompleteType(ELoc, Type,
12483 diag::err_omp_lastprivate_incomplete_type))
12484 continue;
12485 Type = Type.getNonReferenceType();
12486
12487 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12488 // A variable that is privatized must not have a const-qualified type
12489 // unless it is of class type with a mutable member. This restriction does
12490 // not apply to the firstprivate clause.
12491 //
12492 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
12493 // A variable that appears in a lastprivate clause must not have a
12494 // const-qualified type unless it is of class type with a mutable member.
12495 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
12496 continue;
12497
12498 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
12499 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
12500 // in a Construct]
12501 // Variables with the predetermined data-sharing attributes may not be
12502 // listed in data-sharing attributes clauses, except for the cases
12503 // listed below.
12504 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
12505 // A list item may appear in a firstprivate or lastprivate clause but not
12506 // both.
12507 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
12508 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
12509 (isOpenMPDistributeDirective(CurrDir) ||
12510 DVar.CKind != OMPC_firstprivate) &&
12511 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
12512 Diag(ELoc, diag::err_omp_wrong_dsa)
12513 << getOpenMPClauseName(DVar.CKind)
12514 << getOpenMPClauseName(OMPC_lastprivate);
12515 reportOriginalDsa(*this, DSAStack, D, DVar);
12516 continue;
12517 }
12518
12519 // OpenMP [2.14.3.5, Restrictions, p.2]
12520 // A list item that is private within a parallel region, or that appears in
12521 // the reduction clause of a parallel construct, must not appear in a
12522 // lastprivate clause on a worksharing construct if any of the corresponding
12523 // worksharing regions ever binds to any of the corresponding parallel
12524 // regions.
12525 DSAStackTy::DSAVarData TopDVar = DVar;
12526 if (isOpenMPWorksharingDirective(CurrDir) &&
12527 !isOpenMPParallelDirective(CurrDir) &&
12528 !isOpenMPTeamsDirective(CurrDir)) {
12529 DVar = DSAStack->getImplicitDSA(D, true);
12530 if (DVar.CKind != OMPC_shared) {
12531 Diag(ELoc, diag::err_omp_required_access)
12532 << getOpenMPClauseName(OMPC_lastprivate)
12533 << getOpenMPClauseName(OMPC_shared);
12534 reportOriginalDsa(*this, DSAStack, D, DVar);
12535 continue;
12536 }
12537 }
12538
12539 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
12540 // A variable of class type (or array thereof) that appears in a
12541 // lastprivate clause requires an accessible, unambiguous default
12542 // constructor for the class type, unless the list item is also specified
12543 // in a firstprivate clause.
12544 // A variable of class type (or array thereof) that appears in a
12545 // lastprivate clause requires an accessible, unambiguous copy assignment
12546 // operator for the class type.
12547 Type = Context.getBaseElementType(Type).getNonReferenceType();
12548 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
12549 Type.getUnqualifiedType(), ".lastprivate.src",
12550 D->hasAttrs() ? &D->getAttrs() : nullptr);
12551 DeclRefExpr *PseudoSrcExpr =
12552 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
12553 VarDecl *DstVD =
12554 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
12555 D->hasAttrs() ? &D->getAttrs() : nullptr);
12556 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
12557 // For arrays generate assignment operation for single element and replace
12558 // it by the original array element in CodeGen.
12559 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
12560 PseudoDstExpr, PseudoSrcExpr);
12561 if (AssignmentOp.isInvalid())
12562 continue;
12563 AssignmentOp =
12564 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
12565 if (AssignmentOp.isInvalid())
12566 continue;
12567
12568 DeclRefExpr *Ref = nullptr;
12569 if (!VD && !CurContext->isDependentContext()) {
12570 if (TopDVar.CKind == OMPC_firstprivate) {
12571 Ref = TopDVar.PrivateCopy;
12572 } else {
12573 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
12574 if (!isOpenMPCapturedDecl(D))
12575 ExprCaptures.push_back(Ref->getDecl());
12576 }
12577 if (TopDVar.CKind == OMPC_firstprivate ||
12578 (!isOpenMPCapturedDecl(D) &&
12579 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
12580 ExprResult RefRes = DefaultLvalueConversion(Ref);
12581 if (!RefRes.isUsable())
12582 continue;
12583 ExprResult PostUpdateRes =
12584 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
12585 RefRes.get());
12586 if (!PostUpdateRes.isUsable())
12587 continue;
12588 ExprPostUpdates.push_back(
12589 IgnoredValueConversions(PostUpdateRes.get()).get());
12590 }
12591 }
12592 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
12593 Vars.push_back((VD || CurContext->isDependentContext())
12594 ? RefExpr->IgnoreParens()
12595 : Ref);
12596 SrcExprs.push_back(PseudoSrcExpr);
12597 DstExprs.push_back(PseudoDstExpr);
12598 AssignmentOps.push_back(AssignmentOp.get());
12599 }
12600
12601 if (Vars.empty())
12602 return nullptr;
12603
12604 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12605 Vars, SrcExprs, DstExprs, AssignmentOps,
12606 buildPreInits(Context, ExprCaptures),
12607 buildPostUpdate(*this, ExprPostUpdates));
12608 }
12609
12610 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
12611 SourceLocation StartLoc,
12612 SourceLocation LParenLoc,
12613 SourceLocation EndLoc) {
12614 SmallVector<Expr *, 8> Vars;
12615 for (Expr *RefExpr : VarList) {
12616 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
12617 SourceLocation ELoc;
12618 SourceRange ERange;
12619 Expr *SimpleRefExpr = RefExpr;
12620 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12621 if (Res.second) {
12622 // It will be analyzed later.
12623 Vars.push_back(RefExpr);
12624 }
12625 ValueDecl *D = Res.first;
12626 if (!D)
12627 continue;
12628
12629 auto *VD = dyn_cast<VarDecl>(D);
12630 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12631 // in a Construct]
12632 // Variables with the predetermined data-sharing attributes may not be
12633 // listed in data-sharing attributes clauses, except for the cases
12634 // listed below. For these exceptions only, listing a predetermined
12635 // variable in a data-sharing attribute clause is allowed and overrides
12636 // the variable's predetermined data-sharing attributes.
12637 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
12638 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
12639 DVar.RefExpr) {
12640 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12641 << getOpenMPClauseName(OMPC_shared);
12642 reportOriginalDsa(*this, DSAStack, D, DVar);
12643 continue;
12644 }
12645
12646 DeclRefExpr *Ref = nullptr;
12647 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
12648 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12649 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
12650 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
12651 ? RefExpr->IgnoreParens()
12652 : Ref);
12653 }
12654
12655 if (Vars.empty())
12656 return nullptr;
12657
12658 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
12659 }
12660
12661 namespace {
12662 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
12663 DSAStackTy *Stack;
12664
12665 public:
12666 bool VisitDeclRefExpr(DeclRefExpr *E) {
12667 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
12668 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
12669 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
12670 return false;
12671 if (DVar.CKind != OMPC_unknown)
12672 return true;
12673 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
12674 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
12675 /*FromParent=*/true);
12676 return DVarPrivate.CKind != OMPC_unknown;
12677 }
12678 return false;
12679 }
12680 bool VisitStmt(Stmt *S) {
12681 for (Stmt *Child : S->children()) {
12682 if (Child && Visit(Child))
12683 return true;
12684 }
12685 return false;
12686 }
12687 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
12688 };
12689 } // namespace
12690
12691 namespace {
12692 // Transform MemberExpression for specified FieldDecl of current class to
12693 // DeclRefExpr to specified OMPCapturedExprDecl.
12694 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
12695 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
12696 ValueDecl *Field = nullptr;
12697 DeclRefExpr *CapturedExpr = nullptr;
12698
12699 public:
12700 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
12701 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
12702
12703 ExprResult TransformMemberExpr(MemberExpr *E) {
12704 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
12705 E->getMemberDecl() == Field) {
12706 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
12707 return CapturedExpr;
12708 }
12709 return BaseTransform::TransformMemberExpr(E);
12710 }
12711 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
12712 };
12713 } // namespace
12714
12715 template <typename T, typename U>
12716 static T filterLookupForUDReductionAndMapper(
12717 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
12718 for (U &Set : Lookups) {
12719 for (auto *D : Set) {
12720 if (T Res = Gen(cast<ValueDecl>(D)))
12721 return Res;
12722 }
12723 }
12724 return T();
12725 }
12726
12727 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
12728 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
12729
12730 for (auto RD : D->redecls()) {
12731 // Don't bother with extra checks if we already know this one isn't visible.
12732 if (RD == D)
12733 continue;
12734
12735 auto ND = cast<NamedDecl>(RD);
12736 if (LookupResult::isVisible(SemaRef, ND))
12737 return ND;
12738 }
12739
12740 return nullptr;
12741 }
12742
12743 static void
12744 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
12745 SourceLocation Loc, QualType Ty,
12746 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
12747 // Find all of the associated namespaces and classes based on the
12748 // arguments we have.
12749 Sema::AssociatedNamespaceSet AssociatedNamespaces;
12750 Sema::AssociatedClassSet AssociatedClasses;
12751 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
12752 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
12753 AssociatedClasses);
12754
12755 // C++ [basic.lookup.argdep]p3:
12756 // Let X be the lookup set produced by unqualified lookup (3.4.1)
12757 // and let Y be the lookup set produced by argument dependent
12758 // lookup (defined as follows). If X contains [...] then Y is
12759 // empty. Otherwise Y is the set of declarations found in the
12760 // namespaces associated with the argument types as described
12761 // below. The set of declarations found by the lookup of the name
12762 // is the union of X and Y.
12763 //
12764 // Here, we compute Y and add its members to the overloaded
12765 // candidate set.
12766 for (auto *NS : AssociatedNamespaces) {
12767 // When considering an associated namespace, the lookup is the
12768 // same as the lookup performed when the associated namespace is
12769 // used as a qualifier (3.4.3.2) except that:
12770 //
12771 // -- Any using-directives in the associated namespace are
12772 // ignored.
12773 //
12774 // -- Any namespace-scope friend functions declared in
12775 // associated classes are visible within their respective
12776 // namespaces even if they are not visible during an ordinary
12777 // lookup (11.4).
12778 DeclContext::lookup_result R = NS->lookup(Id.getName());
12779 for (auto *D : R) {
12780 auto *Underlying = D;
12781 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
12782 Underlying = USD->getTargetDecl();
12783
12784 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
12785 !isa<OMPDeclareMapperDecl>(Underlying))
12786 continue;
12787
12788 if (!SemaRef.isVisible(D)) {
12789 D = findAcceptableDecl(SemaRef, D);
12790 if (!D)
12791 continue;
12792 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
12793 Underlying = USD->getTargetDecl();
12794 }
12795 Lookups.emplace_back();
12796 Lookups.back().addDecl(Underlying);
12797 }
12798 }
12799 }
12800
12801 static ExprResult
12802 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
12803 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
12804 const DeclarationNameInfo &ReductionId, QualType Ty,
12805 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
12806 if (ReductionIdScopeSpec.isInvalid())
12807 return ExprError();
12808 SmallVector<UnresolvedSet<8>, 4> Lookups;
12809 if (S) {
12810 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
12811 Lookup.suppressDiagnostics();
12812 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
12813 NamedDecl *D = Lookup.getRepresentativeDecl();
12814 do {
12815 S = S->getParent();
12816 } while (S && !S->isDeclScope(D));
12817 if (S)
12818 S = S->getParent();
12819 Lookups.emplace_back();
12820 Lookups.back().append(Lookup.begin(), Lookup.end());
12821 Lookup.clear();
12822 }
12823 } else if (auto *ULE =
12824 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
12825 Lookups.push_back(UnresolvedSet<8>());
12826 Decl *PrevD = nullptr;
12827 for (NamedDecl *D : ULE->decls()) {
12828 if (D == PrevD)
12829 Lookups.push_back(UnresolvedSet<8>());
12830 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
12831 Lookups.back().addDecl(DRD);
12832 PrevD = D;
12833 }
12834 }
12835 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
12836 Ty->isInstantiationDependentType() ||
12837 Ty->containsUnexpandedParameterPack() ||
12838 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
12839 return !D->isInvalidDecl() &&
12840 (D->getType()->isDependentType() ||
12841 D->getType()->isInstantiationDependentType() ||
12842 D->getType()->containsUnexpandedParameterPack());
12843 })) {
12844 UnresolvedSet<8> ResSet;
12845 for (const UnresolvedSet<8> &Set : Lookups) {
12846 if (Set.empty())
12847 continue;
12848 ResSet.append(Set.begin(), Set.end());
12849 // The last item marks the end of all declarations at the specified scope.
12850 ResSet.addDecl(Set[Set.size() - 1]);
12851 }
12852 return UnresolvedLookupExpr::Create(
12853 SemaRef.Context, /*NamingClass=*/nullptr,
12854 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
12855 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
12856 }
12857 // Lookup inside the classes.
12858 // C++ [over.match.oper]p3:
12859 // For a unary operator @ with an operand of a type whose
12860 // cv-unqualified version is T1, and for a binary operator @ with
12861 // a left operand of a type whose cv-unqualified version is T1 and
12862 // a right operand of a type whose cv-unqualified version is T2,
12863 // three sets of candidate functions, designated member
12864 // candidates, non-member candidates and built-in candidates, are
12865 // constructed as follows:
12866 // -- If T1 is a complete class type or a class currently being
12867 // defined, the set of member candidates is the result of the
12868 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
12869 // the set of member candidates is empty.
12870 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
12871 Lookup.suppressDiagnostics();
12872 if (const auto *TyRec = Ty->getAs<RecordType>()) {
12873 // Complete the type if it can be completed.
12874 // If the type is neither complete nor being defined, bail out now.
12875 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
12876 TyRec->getDecl()->getDefinition()) {
12877 Lookup.clear();
12878 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
12879 if (Lookup.empty()) {
12880 Lookups.emplace_back();
12881 Lookups.back().append(Lookup.begin(), Lookup.end());
12882 }
12883 }
12884 }
12885 // Perform ADL.
12886 if (SemaRef.getLangOpts().CPlusPlus)
12887 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
12888 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
12889 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
12890 if (!D->isInvalidDecl() &&
12891 SemaRef.Context.hasSameType(D->getType(), Ty))
12892 return D;
12893 return nullptr;
12894 }))
12895 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
12896 VK_LValue, Loc);
12897 if (SemaRef.getLangOpts().CPlusPlus) {
12898 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
12899 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
12900 if (!D->isInvalidDecl() &&
12901 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
12902 !Ty.isMoreQualifiedThan(D->getType()))
12903 return D;
12904 return nullptr;
12905 })) {
12906 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
12907 /*DetectVirtual=*/false);
12908 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
12909 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
12910 VD->getType().getUnqualifiedType()))) {
12911 if (SemaRef.CheckBaseClassAccess(
12912 Loc, VD->getType(), Ty, Paths.front(),
12913 /*DiagID=*/0) != Sema::AR_inaccessible) {
12914 SemaRef.BuildBasePathArray(Paths, BasePath);
12915 return SemaRef.BuildDeclRefExpr(
12916 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
12917 }
12918 }
12919 }
12920 }
12921 }
12922 if (ReductionIdScopeSpec.isSet()) {
12923 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
12924 return ExprError();
12925 }
12926 return ExprEmpty();
12927 }
12928
12929 namespace {
12930 /// Data for the reduction-based clauses.
12931 struct ReductionData {
12932 /// List of original reduction items.
12933 SmallVector<Expr *, 8> Vars;
12934 /// List of private copies of the reduction items.
12935 SmallVector<Expr *, 8> Privates;
12936 /// LHS expressions for the reduction_op expressions.
12937 SmallVector<Expr *, 8> LHSs;
12938 /// RHS expressions for the reduction_op expressions.
12939 SmallVector<Expr *, 8> RHSs;
12940 /// Reduction operation expression.
12941 SmallVector<Expr *, 8> ReductionOps;
12942 /// Taskgroup descriptors for the corresponding reduction items in
12943 /// in_reduction clauses.
12944 SmallVector<Expr *, 8> TaskgroupDescriptors;
12945 /// List of captures for clause.
12946 SmallVector<Decl *, 4> ExprCaptures;
12947 /// List of postupdate expressions.
12948 SmallVector<Expr *, 4> ExprPostUpdates;
12949 ReductionData() = delete;
12950 /// Reserves required memory for the reduction data.
12951 ReductionData(unsigned Size) {
12952 Vars.reserve(Size);
12953 Privates.reserve(Size);
12954 LHSs.reserve(Size);
12955 RHSs.reserve(Size);
12956 ReductionOps.reserve(Size);
12957 TaskgroupDescriptors.reserve(Size);
12958 ExprCaptures.reserve(Size);
12959 ExprPostUpdates.reserve(Size);
12960 }
12961 /// Stores reduction item and reduction operation only (required for dependent
12962 /// reduction item).
12963 void push(Expr *Item, Expr *ReductionOp) {
12964 Vars.emplace_back(Item);
12965 Privates.emplace_back(nullptr);
12966 LHSs.emplace_back(nullptr);
12967 RHSs.emplace_back(nullptr);
12968 ReductionOps.emplace_back(ReductionOp);
12969 TaskgroupDescriptors.emplace_back(nullptr);
12970 }
12971 /// Stores reduction data.
12972 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
12973 Expr *TaskgroupDescriptor) {
12974 Vars.emplace_back(Item);
12975 Privates.emplace_back(Private);
12976 LHSs.emplace_back(LHS);
12977 RHSs.emplace_back(RHS);
12978 ReductionOps.emplace_back(ReductionOp);
12979 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
12980 }
12981 };
12982 } // namespace
12983
12984 static bool checkOMPArraySectionConstantForReduction(
12985 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
12986 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
12987 const Expr *Length = OASE->getLength();
12988 if (Length == nullptr) {
12989 // For array sections of the form [1:] or [:], we would need to analyze
12990 // the lower bound...
12991 if (OASE->getColonLoc().isValid())
12992 return false;
12993
12994 // This is an array subscript which has implicit length 1!
12995 SingleElement = true;
12996 ArraySizes.push_back(llvm::APSInt::get(1));
12997 } else {
12998 Expr::EvalResult Result;
12999 if (!Length->EvaluateAsInt(Result, Context))
13000 return false;
13001
13002 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
13003 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
13004 ArraySizes.push_back(ConstantLengthValue);
13005 }
13006
13007 // Get the base of this array section and walk up from there.
13008 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
13009
13010 // We require length = 1 for all array sections except the right-most to
13011 // guarantee that the memory region is contiguous and has no holes in it.
13012 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
13013 Length = TempOASE->getLength();
13014 if (Length == nullptr) {
13015 // For array sections of the form [1:] or [:], we would need to analyze
13016 // the lower bound...
13017 if (OASE->getColonLoc().isValid())
13018 return false;
13019
13020 // This is an array subscript which has implicit length 1!
13021 ArraySizes.push_back(llvm::APSInt::get(1));
13022 } else {
13023 Expr::EvalResult Result;
13024 if (!Length->EvaluateAsInt(Result, Context))
13025 return false;
13026
13027 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
13028 if (ConstantLengthValue.getSExtValue() != 1)
13029 return false;
13030
13031 ArraySizes.push_back(ConstantLengthValue);
13032 }
13033 Base = TempOASE->getBase()->IgnoreParenImpCasts();
13034 }
13035
13036 // If we have a single element, we don't need to add the implicit lengths.
13037 if (!SingleElement) {
13038 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
13039 // Has implicit length 1!
13040 ArraySizes.push_back(llvm::APSInt::get(1));
13041 Base = TempASE->getBase()->IgnoreParenImpCasts();
13042 }
13043 }
13044
13045 // This array section can be privatized as a single value or as a constant
13046 // sized array.
13047 return true;
13048 }
13049
13050 static bool actOnOMPReductionKindClause(
13051 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
13052 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13053 SourceLocation ColonLoc, SourceLocation EndLoc,
13054 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13055 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
13056 DeclarationName DN = ReductionId.getName();
13057 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
13058 BinaryOperatorKind BOK = BO_Comma;
13059
13060 ASTContext &Context = S.Context;
13061 // OpenMP [2.14.3.6, reduction clause]
13062 // C
13063 // reduction-identifier is either an identifier or one of the following
13064 // operators: +, -, *, &, |, ^, && and ||
13065 // C++
13066 // reduction-identifier is either an id-expression or one of the following
13067 // operators: +, -, *, &, |, ^, && and ||
13068 switch (OOK) {
13069 case OO_Plus:
13070 case OO_Minus:
13071 BOK = BO_Add;
13072 break;
13073 case OO_Star:
13074 BOK = BO_Mul;
13075 break;
13076 case OO_Amp:
13077 BOK = BO_And;
13078 break;
13079 case OO_Pipe:
13080 BOK = BO_Or;
13081 break;
13082 case OO_Caret:
13083 BOK = BO_Xor;
13084 break;
13085 case OO_AmpAmp:
13086 BOK = BO_LAnd;
13087 break;
13088 case OO_PipePipe:
13089 BOK = BO_LOr;
13090 break;
13091 case OO_New:
13092 case OO_Delete:
13093 case OO_Array_New:
13094 case OO_Array_Delete:
13095 case OO_Slash:
13096 case OO_Percent:
13097 case OO_Tilde:
13098 case OO_Exclaim:
13099 case OO_Equal:
13100 case OO_Less:
13101 case OO_Greater:
13102 case OO_LessEqual:
13103 case OO_GreaterEqual:
13104 case OO_PlusEqual:
13105 case OO_MinusEqual:
13106 case OO_StarEqual:
13107 case OO_SlashEqual:
13108 case OO_PercentEqual:
13109 case OO_CaretEqual:
13110 case OO_AmpEqual:
13111 case OO_PipeEqual:
13112 case OO_LessLess:
13113 case OO_GreaterGreater:
13114 case OO_LessLessEqual:
13115 case OO_GreaterGreaterEqual:
13116 case OO_EqualEqual:
13117 case OO_ExclaimEqual:
13118 case OO_Spaceship:
13119 case OO_PlusPlus:
13120 case OO_MinusMinus:
13121 case OO_Comma:
13122 case OO_ArrowStar:
13123 case OO_Arrow:
13124 case OO_Call:
13125 case OO_Subscript:
13126 case OO_Conditional:
13127 case OO_Coawait:
13128 case NUM_OVERLOADED_OPERATORS:
13129 llvm_unreachable("Unexpected reduction identifier");
13130 case OO_None:
13131 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
13132 if (II->isStr("max"))
13133 BOK = BO_GT;
13134 else if (II->isStr("min"))
13135 BOK = BO_LT;
13136 }
13137 break;
13138 }
13139 SourceRange ReductionIdRange;
13140 if (ReductionIdScopeSpec.isValid())
13141 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
13142 else
13143 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
13144 ReductionIdRange.setEnd(ReductionId.getEndLoc());
13145
13146 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
13147 bool FirstIter = true;
13148 for (Expr *RefExpr : VarList) {
13149 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
13150 // OpenMP [2.1, C/C++]
13151 // A list item is a variable or array section, subject to the restrictions
13152 // specified in Section 2.4 on page 42 and in each of the sections
13153 // describing clauses and directives for which a list appears.
13154 // OpenMP [2.14.3.3, Restrictions, p.1]
13155 // A variable that is part of another variable (as an array or
13156 // structure element) cannot appear in a private clause.
13157 if (!FirstIter && IR != ER)
13158 ++IR;
13159 FirstIter = false;
13160 SourceLocation ELoc;
13161 SourceRange ERange;
13162 Expr *SimpleRefExpr = RefExpr;
13163 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
13164 /*AllowArraySection=*/true);
13165 if (Res.second) {
13166 // Try to find 'declare reduction' corresponding construct before using
13167 // builtin/overloaded operators.
13168 QualType Type = Context.DependentTy;
13169 CXXCastPath BasePath;
13170 ExprResult DeclareReductionRef = buildDeclareReductionRef(
13171 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
13172 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
13173 Expr *ReductionOp = nullptr;
13174 if (S.CurContext->isDependentContext() &&
13175 (DeclareReductionRef.isUnset() ||
13176 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
13177 ReductionOp = DeclareReductionRef.get();
13178 // It will be analyzed later.
13179 RD.push(RefExpr, ReductionOp);
13180 }
13181 ValueDecl *D = Res.first;
13182 if (!D)
13183 continue;
13184
13185 Expr *TaskgroupDescriptor = nullptr;
13186 QualType Type;
13187 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
13188 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
13189 if (ASE) {
13190 Type = ASE->getType().getNonReferenceType();
13191 } else if (OASE) {
13192 QualType BaseType =
13193 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
13194 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
13195 Type = ATy->getElementType();
13196 else
13197 Type = BaseType->getPointeeType();
13198 Type = Type.getNonReferenceType();
13199 } else {
13200 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
13201 }
13202 auto *VD = dyn_cast<VarDecl>(D);
13203
13204 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13205 // A variable that appears in a private clause must not have an incomplete
13206 // type or a reference type.
13207 if (S.RequireCompleteType(ELoc, D->getType(),
13208 diag::err_omp_reduction_incomplete_type))
13209 continue;
13210 // OpenMP [2.14.3.6, reduction clause, Restrictions]
13211 // A list item that appears in a reduction clause must not be
13212 // const-qualified.
13213 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
13214 /*AcceptIfMutable*/ false, ASE || OASE))
13215 continue;
13216
13217 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
13218 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
13219 // If a list-item is a reference type then it must bind to the same object
13220 // for all threads of the team.
13221 if (!ASE && !OASE) {
13222 if (VD) {
13223 VarDecl *VDDef = VD->getDefinition();
13224 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
13225 DSARefChecker Check(Stack);
13226 if (Check.Visit(VDDef->getInit())) {
13227 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
13228 << getOpenMPClauseName(ClauseKind) << ERange;
13229 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
13230 continue;
13231 }
13232 }
13233 }
13234
13235 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
13236 // in a Construct]
13237 // Variables with the predetermined data-sharing attributes may not be
13238 // listed in data-sharing attributes clauses, except for the cases
13239 // listed below. For these exceptions only, listing a predetermined
13240 // variable in a data-sharing attribute clause is allowed and overrides
13241 // the variable's predetermined data-sharing attributes.
13242 // OpenMP [2.14.3.6, Restrictions, p.3]
13243 // Any number of reduction clauses can be specified on the directive,
13244 // but a list item can appear only once in the reduction clauses for that
13245 // directive.
13246 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
13247 if (DVar.CKind == OMPC_reduction) {
13248 S.Diag(ELoc, diag::err_omp_once_referenced)
13249 << getOpenMPClauseName(ClauseKind);
13250 if (DVar.RefExpr)
13251 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
13252 continue;
13253 }
13254 if (DVar.CKind != OMPC_unknown) {
13255 S.Diag(ELoc, diag::err_omp_wrong_dsa)
13256 << getOpenMPClauseName(DVar.CKind)
13257 << getOpenMPClauseName(OMPC_reduction);
13258 reportOriginalDsa(S, Stack, D, DVar);
13259 continue;
13260 }
13261
13262 // OpenMP [2.14.3.6, Restrictions, p.1]
13263 // A list item that appears in a reduction clause of a worksharing
13264 // construct must be shared in the parallel regions to which any of the
13265 // worksharing regions arising from the worksharing construct bind.
13266 if (isOpenMPWorksharingDirective(CurrDir) &&
13267 !isOpenMPParallelDirective(CurrDir) &&
13268 !isOpenMPTeamsDirective(CurrDir)) {
13269 DVar = Stack->getImplicitDSA(D, true);
13270 if (DVar.CKind != OMPC_shared) {
13271 S.Diag(ELoc, diag::err_omp_required_access)
13272 << getOpenMPClauseName(OMPC_reduction)
13273 << getOpenMPClauseName(OMPC_shared);
13274 reportOriginalDsa(S, Stack, D, DVar);
13275 continue;
13276 }
13277 }
13278 }
13279
13280 // Try to find 'declare reduction' corresponding construct before using
13281 // builtin/overloaded operators.
13282 CXXCastPath BasePath;
13283 ExprResult DeclareReductionRef = buildDeclareReductionRef(
13284 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
13285 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
13286 if (DeclareReductionRef.isInvalid())
13287 continue;
13288 if (S.CurContext->isDependentContext() &&
13289 (DeclareReductionRef.isUnset() ||
13290 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
13291 RD.push(RefExpr, DeclareReductionRef.get());
13292 continue;
13293 }
13294 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
13295 // Not allowed reduction identifier is found.
13296 S.Diag(ReductionId.getBeginLoc(),
13297 diag::err_omp_unknown_reduction_identifier)
13298 << Type << ReductionIdRange;
13299 continue;
13300 }
13301
13302 // OpenMP [2.14.3.6, reduction clause, Restrictions]
13303 // The type of a list item that appears in a reduction clause must be valid
13304 // for the reduction-identifier. For a max or min reduction in C, the type
13305 // of the list item must be an allowed arithmetic data type: char, int,
13306 // float, double, or _Bool, possibly modified with long, short, signed, or
13307 // unsigned. For a max or min reduction in C++, the type of the list item
13308 // must be an allowed arithmetic data type: char, wchar_t, int, float,
13309 // double, or bool, possibly modified with long, short, signed, or unsigned.
13310 if (DeclareReductionRef.isUnset()) {
13311 if ((BOK == BO_GT || BOK == BO_LT) &&
13312 !(Type->isScalarType() ||
13313 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
13314 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
13315 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
13316 if (!ASE && !OASE) {
13317 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13318 VarDecl::DeclarationOnly;
13319 S.Diag(D->getLocation(),
13320 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13321 << D;
13322 }
13323 continue;
13324 }
13325 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
13326 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
13327 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
13328 << getOpenMPClauseName(ClauseKind);
13329 if (!ASE && !OASE) {
13330 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13331 VarDecl::DeclarationOnly;
13332 S.Diag(D->getLocation(),
13333 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13334 << D;
13335 }
13336 continue;
13337 }
13338 }
13339
13340 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
13341 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
13342 D->hasAttrs() ? &D->getAttrs() : nullptr);
13343 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
13344 D->hasAttrs() ? &D->getAttrs() : nullptr);
13345 QualType PrivateTy = Type;
13346
13347 // Try if we can determine constant lengths for all array sections and avoid
13348 // the VLA.
13349 bool ConstantLengthOASE = false;
13350 if (OASE) {
13351 bool SingleElement;
13352 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
13353 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
13354 Context, OASE, SingleElement, ArraySizes);
13355
13356 // If we don't have a single element, we must emit a constant array type.
13357 if (ConstantLengthOASE && !SingleElement) {
13358 for (llvm::APSInt &Size : ArraySizes)
13359 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
13360 ArrayType::Normal,
13361 /*IndexTypeQuals=*/0);
13362 }
13363 }
13364
13365 if ((OASE && !ConstantLengthOASE) ||
13366 (!OASE && !ASE &&
13367 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
13368 if (!Context.getTargetInfo().isVLASupported()) {
13369 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
13370 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13371 S.Diag(ELoc, diag::note_vla_unsupported);
13372 } else {
13373 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13374 S.targetDiag(ELoc, diag::note_vla_unsupported);
13375 }
13376 continue;
13377 }
13378 // For arrays/array sections only:
13379 // Create pseudo array type for private copy. The size for this array will
13380 // be generated during codegen.
13381 // For array subscripts or single variables Private Ty is the same as Type
13382 // (type of the variable or single array element).
13383 PrivateTy = Context.getVariableArrayType(
13384 Type,
13385 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
13386 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
13387 } else if (!ASE && !OASE &&
13388 Context.getAsArrayType(D->getType().getNonReferenceType())) {
13389 PrivateTy = D->getType().getNonReferenceType();
13390 }
13391 // Private copy.
13392 VarDecl *PrivateVD =
13393 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
13394 D->hasAttrs() ? &D->getAttrs() : nullptr,
13395 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13396 // Add initializer for private variable.
13397 Expr *Init = nullptr;
13398 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
13399 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
13400 if (DeclareReductionRef.isUsable()) {
13401 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
13402 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
13403 if (DRD->getInitializer()) {
13404 Init = DRDRef;
13405 RHSVD->setInit(DRDRef);
13406 RHSVD->setInitStyle(VarDecl::CallInit);
13407 }
13408 } else {
13409 switch (BOK) {
13410 case BO_Add:
13411 case BO_Xor:
13412 case BO_Or:
13413 case BO_LOr:
13414 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
13415 if (Type->isScalarType() || Type->isAnyComplexType())
13416 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
13417 break;
13418 case BO_Mul:
13419 case BO_LAnd:
13420 if (Type->isScalarType() || Type->isAnyComplexType()) {
13421 // '*' and '&&' reduction ops - initializer is '1'.
13422 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
13423 }
13424 break;
13425 case BO_And: {
13426 // '&' reduction op - initializer is '~0'.
13427 QualType OrigType = Type;
13428 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
13429 Type = ComplexTy->getElementType();
13430 if (Type->isRealFloatingType()) {
13431 llvm::APFloat InitValue =
13432 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
13433 /*isIEEE=*/true);
13434 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
13435 Type, ELoc);
13436 } else if (Type->isScalarType()) {
13437 uint64_t Size = Context.getTypeSize(Type);
13438 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
13439 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
13440 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
13441 }
13442 if (Init && OrigType->isAnyComplexType()) {
13443 // Init = 0xFFFF + 0xFFFFi;
13444 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
13445 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
13446 }
13447 Type = OrigType;
13448 break;
13449 }
13450 case BO_LT:
13451 case BO_GT: {
13452 // 'min' reduction op - initializer is 'Largest representable number in
13453 // the reduction list item type'.
13454 // 'max' reduction op - initializer is 'Least representable number in
13455 // the reduction list item type'.
13456 if (Type->isIntegerType() || Type->isPointerType()) {
13457 bool IsSigned = Type->hasSignedIntegerRepresentation();
13458 uint64_t Size = Context.getTypeSize(Type);
13459 QualType IntTy =
13460 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
13461 llvm::APInt InitValue =
13462 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
13463 : llvm::APInt::getMinValue(Size)
13464 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
13465 : llvm::APInt::getMaxValue(Size);
13466 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
13467 if (Type->isPointerType()) {
13468 // Cast to pointer type.
13469 ExprResult CastExpr = S.BuildCStyleCastExpr(
13470 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
13471 if (CastExpr.isInvalid())
13472 continue;
13473 Init = CastExpr.get();
13474 }
13475 } else if (Type->isRealFloatingType()) {
13476 llvm::APFloat InitValue = llvm::APFloat::getLargest(
13477 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
13478 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
13479 Type, ELoc);
13480 }
13481 break;
13482 }
13483 case BO_PtrMemD:
13484 case BO_PtrMemI:
13485 case BO_MulAssign:
13486 case BO_Div:
13487 case BO_Rem:
13488 case BO_Sub:
13489 case BO_Shl:
13490 case BO_Shr:
13491 case BO_LE:
13492 case BO_GE:
13493 case BO_EQ:
13494 case BO_NE:
13495 case BO_Cmp:
13496 case BO_AndAssign:
13497 case BO_XorAssign:
13498 case BO_OrAssign:
13499 case BO_Assign:
13500 case BO_AddAssign:
13501 case BO_SubAssign:
13502 case BO_DivAssign:
13503 case BO_RemAssign:
13504 case BO_ShlAssign:
13505 case BO_ShrAssign:
13506 case BO_Comma:
13507 llvm_unreachable("Unexpected reduction operation");
13508 }
13509 }
13510 if (Init && DeclareReductionRef.isUnset())
13511 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
13512 else if (!Init)
13513 S.ActOnUninitializedDecl(RHSVD);
13514 if (RHSVD->isInvalidDecl())
13515 continue;
13516 if (!RHSVD->hasInit() &&
13517 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
13518 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
13519 << Type << ReductionIdRange;
13520 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13521 VarDecl::DeclarationOnly;
13522 S.Diag(D->getLocation(),
13523 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13524 << D;
13525 continue;
13526 }
13527 // Store initializer for single element in private copy. Will be used during
13528 // codegen.
13529 PrivateVD->setInit(RHSVD->getInit());
13530 PrivateVD->setInitStyle(RHSVD->getInitStyle());
13531 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
13532 ExprResult ReductionOp;
13533 if (DeclareReductionRef.isUsable()) {
13534 QualType RedTy = DeclareReductionRef.get()->getType();
13535 QualType PtrRedTy = Context.getPointerType(RedTy);
13536 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
13537 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
13538 if (!BasePath.empty()) {
13539 LHS = S.DefaultLvalueConversion(LHS.get());
13540 RHS = S.DefaultLvalueConversion(RHS.get());
13541 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
13542 CK_UncheckedDerivedToBase, LHS.get(),
13543 &BasePath, LHS.get()->getValueKind());
13544 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
13545 CK_UncheckedDerivedToBase, RHS.get(),
13546 &BasePath, RHS.get()->getValueKind());
13547 }
13548 FunctionProtoType::ExtProtoInfo EPI;
13549 QualType Params[] = {PtrRedTy, PtrRedTy};
13550 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
13551 auto *OVE = new (Context) OpaqueValueExpr(
13552 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
13553 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
13554 Expr *Args[] = {LHS.get(), RHS.get()};
13555 ReductionOp =
13556 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
13557 } else {
13558 ReductionOp = S.BuildBinOp(
13559 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
13560 if (ReductionOp.isUsable()) {
13561 if (BOK != BO_LT && BOK != BO_GT) {
13562 ReductionOp =
13563 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
13564 BO_Assign, LHSDRE, ReductionOp.get());
13565 } else {
13566 auto *ConditionalOp = new (Context)
13567 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
13568 Type, VK_LValue, OK_Ordinary);
13569 ReductionOp =
13570 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
13571 BO_Assign, LHSDRE, ConditionalOp);
13572 }
13573 if (ReductionOp.isUsable())
13574 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
13575 /*DiscardedValue*/ false);
13576 }
13577 if (!ReductionOp.isUsable())
13578 continue;
13579 }
13580
13581 // OpenMP [2.15.4.6, Restrictions, p.2]
13582 // A list item that appears in an in_reduction clause of a task construct
13583 // must appear in a task_reduction clause of a construct associated with a
13584 // taskgroup region that includes the participating task in its taskgroup
13585 // set. The construct associated with the innermost region that meets this
13586 // condition must specify the same reduction-identifier as the in_reduction
13587 // clause.
13588 if (ClauseKind == OMPC_in_reduction) {
13589 SourceRange ParentSR;
13590 BinaryOperatorKind ParentBOK;
13591 const Expr *ParentReductionOp;
13592 Expr *ParentBOKTD, *ParentReductionOpTD;
13593 DSAStackTy::DSAVarData ParentBOKDSA =
13594 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
13595 ParentBOKTD);
13596 DSAStackTy::DSAVarData ParentReductionOpDSA =
13597 Stack->getTopMostTaskgroupReductionData(
13598 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
13599 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
13600 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
13601 if (!IsParentBOK && !IsParentReductionOp) {
13602 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
13603 continue;
13604 }
13605 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
13606 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
13607 IsParentReductionOp) {
13608 bool EmitError = true;
13609 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
13610 llvm::FoldingSetNodeID RedId, ParentRedId;
13611 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
13612 DeclareReductionRef.get()->Profile(RedId, Context,
13613 /*Canonical=*/true);
13614 EmitError = RedId != ParentRedId;
13615 }
13616 if (EmitError) {
13617 S.Diag(ReductionId.getBeginLoc(),
13618 diag::err_omp_reduction_identifier_mismatch)
13619 << ReductionIdRange << RefExpr->getSourceRange();
13620 S.Diag(ParentSR.getBegin(),
13621 diag::note_omp_previous_reduction_identifier)
13622 << ParentSR
13623 << (IsParentBOK ? ParentBOKDSA.RefExpr
13624 : ParentReductionOpDSA.RefExpr)
13625 ->getSourceRange();
13626 continue;
13627 }
13628 }
13629 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
13630 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
13631 }
13632
13633 DeclRefExpr *Ref = nullptr;
13634 Expr *VarsExpr = RefExpr->IgnoreParens();
13635 if (!VD && !S.CurContext->isDependentContext()) {
13636 if (ASE || OASE) {
13637 TransformExprToCaptures RebuildToCapture(S, D);
13638 VarsExpr =
13639 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
13640 Ref = RebuildToCapture.getCapturedExpr();
13641 } else {
13642 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
13643 }
13644 if (!S.isOpenMPCapturedDecl(D)) {
13645 RD.ExprCaptures.emplace_back(Ref->getDecl());
13646 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
13647 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
13648 if (!RefRes.isUsable())
13649 continue;
13650 ExprResult PostUpdateRes =
13651 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
13652 RefRes.get());
13653 if (!PostUpdateRes.isUsable())
13654 continue;
13655 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
13656 Stack->getCurrentDirective() == OMPD_taskgroup) {
13657 S.Diag(RefExpr->getExprLoc(),
13658 diag::err_omp_reduction_non_addressable_expression)
13659 << RefExpr->getSourceRange();
13660 continue;
13661 }
13662 RD.ExprPostUpdates.emplace_back(
13663 S.IgnoredValueConversions(PostUpdateRes.get()).get());
13664 }
13665 }
13666 }
13667 // All reduction items are still marked as reduction (to do not increase
13668 // code base size).
13669 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
13670 if (CurrDir == OMPD_taskgroup) {
13671 if (DeclareReductionRef.isUsable())
13672 Stack->addTaskgroupReductionData(D, ReductionIdRange,
13673 DeclareReductionRef.get());
13674 else
13675 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
13676 }
13677 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
13678 TaskgroupDescriptor);
13679 }
13680 return RD.Vars.empty();
13681 }
13682
13683 OMPClause *Sema::ActOnOpenMPReductionClause(
13684 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13685 SourceLocation ColonLoc, SourceLocation EndLoc,
13686 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13687 ArrayRef<Expr *> UnresolvedReductions) {
13688 ReductionData RD(VarList.size());
13689 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
13690 StartLoc, LParenLoc, ColonLoc, EndLoc,
13691 ReductionIdScopeSpec, ReductionId,
13692 UnresolvedReductions, RD))
13693 return nullptr;
13694
13695 return OMPReductionClause::Create(
13696 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
13697 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
13698 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
13699 buildPreInits(Context, RD.ExprCaptures),
13700 buildPostUpdate(*this, RD.ExprPostUpdates));
13701 }
13702
13703 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
13704 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13705 SourceLocation ColonLoc, SourceLocation EndLoc,
13706 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13707 ArrayRef<Expr *> UnresolvedReductions) {
13708 ReductionData RD(VarList.size());
13709 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
13710 StartLoc, LParenLoc, ColonLoc, EndLoc,
13711 ReductionIdScopeSpec, ReductionId,
13712 UnresolvedReductions, RD))
13713 return nullptr;
13714
13715 return OMPTaskReductionClause::Create(
13716 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
13717 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
13718 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
13719 buildPreInits(Context, RD.ExprCaptures),
13720 buildPostUpdate(*this, RD.ExprPostUpdates));
13721 }
13722
13723 OMPClause *Sema::ActOnOpenMPInReductionClause(
13724 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13725 SourceLocation ColonLoc, SourceLocation EndLoc,
13726 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13727 ArrayRef<Expr *> UnresolvedReductions) {
13728 ReductionData RD(VarList.size());
13729 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
13730 StartLoc, LParenLoc, ColonLoc, EndLoc,
13731 ReductionIdScopeSpec, ReductionId,
13732 UnresolvedReductions, RD))
13733 return nullptr;
13734
13735 return OMPInReductionClause::Create(
13736 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
13737 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
13738 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
13739 buildPreInits(Context, RD.ExprCaptures),
13740 buildPostUpdate(*this, RD.ExprPostUpdates));
13741 }
13742
13743 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
13744 SourceLocation LinLoc) {
13745 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
13746 LinKind == OMPC_LINEAR_unknown) {
13747 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
13748 return true;
13749 }
13750 return false;
13751 }
13752
13753 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
13754 OpenMPLinearClauseKind LinKind,
13755 QualType Type) {
13756 const auto *VD = dyn_cast_or_null<VarDecl>(D);
13757 // A variable must not have an incomplete type or a reference type.
13758 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
13759 return true;
13760 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
13761 !Type->isReferenceType()) {
13762 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
13763 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
13764 return true;
13765 }
13766 Type = Type.getNonReferenceType();
13767
13768 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13769 // A variable that is privatized must not have a const-qualified type
13770 // unless it is of class type with a mutable member. This restriction does
13771 // not apply to the firstprivate clause.
13772 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
13773 return true;
13774
13775 // A list item must be of integral or pointer type.
13776 Type = Type.getUnqualifiedType().getCanonicalType();
13777 const auto *Ty = Type.getTypePtrOrNull();
13778 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
13779 !Ty->isPointerType())) {
13780 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
13781 if (D) {
13782 bool IsDecl =
13783 !VD ||
13784 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13785 Diag(D->getLocation(),
13786 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13787 << D;
13788 }
13789 return true;
13790 }
13791 return false;
13792 }
13793
13794 OMPClause *Sema::ActOnOpenMPLinearClause(
13795 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
13796 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
13797 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
13798 SmallVector<Expr *, 8> Vars;
13799 SmallVector<Expr *, 8> Privates;
13800 SmallVector<Expr *, 8> Inits;
13801 SmallVector<Decl *, 4> ExprCaptures;
13802 SmallVector<Expr *, 4> ExprPostUpdates;
13803 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
13804 LinKind = OMPC_LINEAR_val;
13805 for (Expr *RefExpr : VarList) {
13806 assert(RefExpr && "NULL expr in OpenMP linear clause.");
13807 SourceLocation ELoc;
13808 SourceRange ERange;
13809 Expr *SimpleRefExpr = RefExpr;
13810 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13811 if (Res.second) {
13812 // It will be analyzed later.
13813 Vars.push_back(RefExpr);
13814 Privates.push_back(nullptr);
13815 Inits.push_back(nullptr);
13816 }
13817 ValueDecl *D = Res.first;
13818 if (!D)
13819 continue;
13820
13821 QualType Type = D->getType();
13822 auto *VD = dyn_cast<VarDecl>(D);
13823
13824 // OpenMP [2.14.3.7, linear clause]
13825 // A list-item cannot appear in more than one linear clause.
13826 // A list-item that appears in a linear clause cannot appear in any
13827 // other data-sharing attribute clause.
13828 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13829 if (DVar.RefExpr) {
13830 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13831 << getOpenMPClauseName(OMPC_linear);
13832 reportOriginalDsa(*this, DSAStack, D, DVar);
13833 continue;
13834 }
13835
13836 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
13837 continue;
13838 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
13839
13840 // Build private copy of original var.
13841 VarDecl *Private =
13842 buildVarDecl(*this, ELoc, Type, D->getName(),
13843 D->hasAttrs() ? &D->getAttrs() : nullptr,
13844 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13845 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
13846 // Build var to save initial value.
13847 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
13848 Expr *InitExpr;
13849 DeclRefExpr *Ref = nullptr;
13850 if (!VD && !CurContext->isDependentContext()) {
13851 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13852 if (!isOpenMPCapturedDecl(D)) {
13853 ExprCaptures.push_back(Ref->getDecl());
13854 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
13855 ExprResult RefRes = DefaultLvalueConversion(Ref);
13856 if (!RefRes.isUsable())
13857 continue;
13858 ExprResult PostUpdateRes =
13859 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
13860 SimpleRefExpr, RefRes.get());
13861 if (!PostUpdateRes.isUsable())
13862 continue;
13863 ExprPostUpdates.push_back(
13864 IgnoredValueConversions(PostUpdateRes.get()).get());
13865 }
13866 }
13867 }
13868 if (LinKind == OMPC_LINEAR_uval)
13869 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
13870 else
13871 InitExpr = VD ? SimpleRefExpr : Ref;
13872 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
13873 /*DirectInit=*/false);
13874 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
13875
13876 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
13877 Vars.push_back((VD || CurContext->isDependentContext())
13878 ? RefExpr->IgnoreParens()
13879 : Ref);
13880 Privates.push_back(PrivateRef);
13881 Inits.push_back(InitRef);
13882 }
13883
13884 if (Vars.empty())
13885 return nullptr;
13886
13887 Expr *StepExpr = Step;
13888 Expr *CalcStepExpr = nullptr;
13889 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
13890 !Step->isInstantiationDependent() &&
13891 !Step->containsUnexpandedParameterPack()) {
13892 SourceLocation StepLoc = Step->getBeginLoc();
13893 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
13894 if (Val.isInvalid())
13895 return nullptr;
13896 StepExpr = Val.get();
13897
13898 // Build var to save the step value.
13899 VarDecl *SaveVar =
13900 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
13901 ExprResult SaveRef =
13902 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
13903 ExprResult CalcStep =
13904 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
13905 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
13906
13907 // Warn about zero linear step (it would be probably better specified as
13908 // making corresponding variables 'const').
13909 llvm::APSInt Result;
13910 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
13911 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
13912 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
13913 << (Vars.size() > 1);
13914 if (!IsConstant && CalcStep.isUsable()) {
13915 // Calculate the step beforehand instead of doing this on each iteration.
13916 // (This is not used if the number of iterations may be kfold-ed).
13917 CalcStepExpr = CalcStep.get();
13918 }
13919 }
13920
13921 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
13922 ColonLoc, EndLoc, Vars, Privates, Inits,
13923 StepExpr, CalcStepExpr,
13924 buildPreInits(Context, ExprCaptures),
13925 buildPostUpdate(*this, ExprPostUpdates));
13926 }
13927
13928 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
13929 Expr *NumIterations, Sema &SemaRef,
13930 Scope *S, DSAStackTy *Stack) {
13931 // Walk the vars and build update/final expressions for the CodeGen.
13932 SmallVector<Expr *, 8> Updates;
13933 SmallVector<Expr *, 8> Finals;
13934 SmallVector<Expr *, 8> UsedExprs;
13935 Expr *Step = Clause.getStep();
13936 Expr *CalcStep = Clause.getCalcStep();
13937 // OpenMP [2.14.3.7, linear clause]
13938 // If linear-step is not specified it is assumed to be 1.
13939 if (!Step)
13940 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
13941 else if (CalcStep)
13942 Step = cast<BinaryOperator>(CalcStep)->getLHS();
13943 bool HasErrors = false;
13944 auto CurInit = Clause.inits().begin();
13945 auto CurPrivate = Clause.privates().begin();
13946 OpenMPLinearClauseKind LinKind = Clause.getModifier();
13947 for (Expr *RefExpr : Clause.varlists()) {
13948 SourceLocation ELoc;
13949 SourceRange ERange;
13950 Expr *SimpleRefExpr = RefExpr;
13951 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
13952 ValueDecl *D = Res.first;
13953 if (Res.second || !D) {
13954 Updates.push_back(nullptr);
13955 Finals.push_back(nullptr);
13956 HasErrors = true;
13957 continue;
13958 }
13959 auto &&Info = Stack->isLoopControlVariable(D);
13960 // OpenMP [2.15.11, distribute simd Construct]
13961 // A list item may not appear in a linear clause, unless it is the loop
13962 // iteration variable.
13963 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
13964 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
13965 SemaRef.Diag(ELoc,
13966 diag::err_omp_linear_distribute_var_non_loop_iteration);
13967 Updates.push_back(nullptr);
13968 Finals.push_back(nullptr);
13969 HasErrors = true;
13970 continue;
13971 }
13972 Expr *InitExpr = *CurInit;
13973
13974 // Build privatized reference to the current linear var.
13975 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
13976 Expr *CapturedRef;
13977 if (LinKind == OMPC_LINEAR_uval)
13978 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
13979 else
13980 CapturedRef =
13981 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
13982 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
13983 /*RefersToCapture=*/true);
13984
13985 // Build update: Var = InitExpr + IV * Step
13986 ExprResult Update;
13987 if (!Info.first)
13988 Update = buildCounterUpdate(
13989 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
13990 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
13991 else
13992 Update = *CurPrivate;
13993 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
13994 /*DiscardedValue*/ false);
13995
13996 // Build final: Var = InitExpr + NumIterations * Step
13997 ExprResult Final;
13998 if (!Info.first)
13999 Final =
14000 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
14001 InitExpr, NumIterations, Step, /*Subtract=*/false,
14002 /*IsNonRectangularLB=*/false);
14003 else
14004 Final = *CurPrivate;
14005 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
14006 /*DiscardedValue*/ false);
14007
14008 if (!Update.isUsable() || !Final.isUsable()) {
14009 Updates.push_back(nullptr);
14010 Finals.push_back(nullptr);
14011 UsedExprs.push_back(nullptr);
14012 HasErrors = true;
14013 } else {
14014 Updates.push_back(Update.get());
14015 Finals.push_back(Final.get());
14016 if (!Info.first)
14017 UsedExprs.push_back(SimpleRefExpr);
14018 }
14019 ++CurInit;
14020 ++CurPrivate;
14021 }
14022 if (Expr *S = Clause.getStep())
14023 UsedExprs.push_back(S);
14024 // Fill the remaining part with the nullptr.
14025 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
14026 Clause.setUpdates(Updates);
14027 Clause.setFinals(Finals);
14028 Clause.setUsedExprs(UsedExprs);
14029 return HasErrors;
14030 }
14031
14032 OMPClause *Sema::ActOnOpenMPAlignedClause(
14033 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
14034 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
14035 SmallVector<Expr *, 8> Vars;
14036 for (Expr *RefExpr : VarList) {
14037 assert(RefExpr && "NULL expr in OpenMP linear clause.");
14038 SourceLocation ELoc;
14039 SourceRange ERange;
14040 Expr *SimpleRefExpr = RefExpr;
14041 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14042 if (Res.second) {
14043 // It will be analyzed later.
14044 Vars.push_back(RefExpr);
14045 }
14046 ValueDecl *D = Res.first;
14047 if (!D)
14048 continue;
14049
14050 QualType QType = D->getType();
14051 auto *VD = dyn_cast<VarDecl>(D);
14052
14053 // OpenMP [2.8.1, simd construct, Restrictions]
14054 // The type of list items appearing in the aligned clause must be
14055 // array, pointer, reference to array, or reference to pointer.
14056 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
14057 const Type *Ty = QType.getTypePtrOrNull();
14058 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
14059 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
14060 << QType << getLangOpts().CPlusPlus << ERange;
14061 bool IsDecl =
14062 !VD ||
14063 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14064 Diag(D->getLocation(),
14065 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14066 << D;
14067 continue;
14068 }
14069
14070 // OpenMP [2.8.1, simd construct, Restrictions]
14071 // A list-item cannot appear in more than one aligned clause.
14072 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
14073 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
14074 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
14075 << getOpenMPClauseName(OMPC_aligned);
14076 continue;
14077 }
14078
14079 DeclRefExpr *Ref = nullptr;
14080 if (!VD && isOpenMPCapturedDecl(D))
14081 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14082 Vars.push_back(DefaultFunctionArrayConversion(
14083 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
14084 .get());
14085 }
14086
14087 // OpenMP [2.8.1, simd construct, Description]
14088 // The parameter of the aligned clause, alignment, must be a constant
14089 // positive integer expression.
14090 // If no optional parameter is specified, implementation-defined default
14091 // alignments for SIMD instructions on the target platforms are assumed.
14092 if (Alignment != nullptr) {
14093 ExprResult AlignResult =
14094 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
14095 if (AlignResult.isInvalid())
14096 return nullptr;
14097 Alignment = AlignResult.get();
14098 }
14099 if (Vars.empty())
14100 return nullptr;
14101
14102 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
14103 EndLoc, Vars, Alignment);
14104 }
14105
14106 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
14107 SourceLocation StartLoc,
14108 SourceLocation LParenLoc,
14109 SourceLocation EndLoc) {
14110 SmallVector<Expr *, 8> Vars;
14111 SmallVector<Expr *, 8> SrcExprs;
14112 SmallVector<Expr *, 8> DstExprs;
14113 SmallVector<Expr *, 8> AssignmentOps;
14114 for (Expr *RefExpr : VarList) {
14115 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
14116 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
14117 // It will be analyzed later.
14118 Vars.push_back(RefExpr);
14119 SrcExprs.push_back(nullptr);
14120 DstExprs.push_back(nullptr);
14121 AssignmentOps.push_back(nullptr);
14122 continue;
14123 }
14124
14125 SourceLocation ELoc = RefExpr->getExprLoc();
14126 // OpenMP [2.1, C/C++]
14127 // A list item is a variable name.
14128 // OpenMP [2.14.4.1, Restrictions, p.1]
14129 // A list item that appears in a copyin clause must be threadprivate.
14130 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
14131 if (!DE || !isa<VarDecl>(DE->getDecl())) {
14132 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
14133 << 0 << RefExpr->getSourceRange();
14134 continue;
14135 }
14136
14137 Decl *D = DE->getDecl();
14138 auto *VD = cast<VarDecl>(D);
14139
14140 QualType Type = VD->getType();
14141 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
14142 // It will be analyzed later.
14143 Vars.push_back(DE);
14144 SrcExprs.push_back(nullptr);
14145 DstExprs.push_back(nullptr);
14146 AssignmentOps.push_back(nullptr);
14147 continue;
14148 }
14149
14150 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
14151 // A list item that appears in a copyin clause must be threadprivate.
14152 if (!DSAStack->isThreadPrivate(VD)) {
14153 Diag(ELoc, diag::err_omp_required_access)
14154 << getOpenMPClauseName(OMPC_copyin)
14155 << getOpenMPDirectiveName(OMPD_threadprivate);
14156 continue;
14157 }
14158
14159 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
14160 // A variable of class type (or array thereof) that appears in a
14161 // copyin clause requires an accessible, unambiguous copy assignment
14162 // operator for the class type.
14163 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14164 VarDecl *SrcVD =
14165 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
14166 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
14167 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
14168 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
14169 VarDecl *DstVD =
14170 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
14171 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
14172 DeclRefExpr *PseudoDstExpr =
14173 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
14174 // For arrays generate assignment operation for single element and replace
14175 // it by the original array element in CodeGen.
14176 ExprResult AssignmentOp =
14177 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
14178 PseudoSrcExpr);
14179 if (AssignmentOp.isInvalid())
14180 continue;
14181 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
14182 /*DiscardedValue*/ false);
14183 if (AssignmentOp.isInvalid())
14184 continue;
14185
14186 DSAStack->addDSA(VD, DE, OMPC_copyin);
14187 Vars.push_back(DE);
14188 SrcExprs.push_back(PseudoSrcExpr);
14189 DstExprs.push_back(PseudoDstExpr);
14190 AssignmentOps.push_back(AssignmentOp.get());
14191 }
14192
14193 if (Vars.empty())
14194 return nullptr;
14195
14196 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
14197 SrcExprs, DstExprs, AssignmentOps);
14198 }
14199
14200 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
14201 SourceLocation StartLoc,
14202 SourceLocation LParenLoc,
14203 SourceLocation EndLoc) {
14204 SmallVector<Expr *, 8> Vars;
14205 SmallVector<Expr *, 8> SrcExprs;
14206 SmallVector<Expr *, 8> DstExprs;
14207 SmallVector<Expr *, 8> AssignmentOps;
14208 for (Expr *RefExpr : VarList) {
14209 assert(RefExpr && "NULL expr in OpenMP linear clause.");
14210 SourceLocation ELoc;
14211 SourceRange ERange;
14212 Expr *SimpleRefExpr = RefExpr;
14213 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14214 if (Res.second) {
14215 // It will be analyzed later.
14216 Vars.push_back(RefExpr);
14217 SrcExprs.push_back(nullptr);
14218 DstExprs.push_back(nullptr);
14219 AssignmentOps.push_back(nullptr);
14220 }
14221 ValueDecl *D = Res.first;
14222 if (!D)
14223 continue;
14224
14225 QualType Type = D->getType();
14226 auto *VD = dyn_cast<VarDecl>(D);
14227
14228 // OpenMP [2.14.4.2, Restrictions, p.2]
14229 // A list item that appears in a copyprivate clause may not appear in a
14230 // private or firstprivate clause on the single construct.
14231 if (!VD || !DSAStack->isThreadPrivate(VD)) {
14232 DSAStackTy::DSAVarData DVar =
14233 DSAStack->getTopDSA(D, /*FromParent=*/false);
14234 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
14235 DVar.RefExpr) {
14236 Diag(ELoc, diag::err_omp_wrong_dsa)
14237 << getOpenMPClauseName(DVar.CKind)
14238 << getOpenMPClauseName(OMPC_copyprivate);
14239 reportOriginalDsa(*this, DSAStack, D, DVar);
14240 continue;
14241 }
14242
14243 // OpenMP [2.11.4.2, Restrictions, p.1]
14244 // All list items that appear in a copyprivate clause must be either
14245 // threadprivate or private in the enclosing context.
14246 if (DVar.CKind == OMPC_unknown) {
14247 DVar = DSAStack->getImplicitDSA(D, false);
14248 if (DVar.CKind == OMPC_shared) {
14249 Diag(ELoc, diag::err_omp_required_access)
14250 << getOpenMPClauseName(OMPC_copyprivate)
14251 << "threadprivate or private in the enclosing context";
14252 reportOriginalDsa(*this, DSAStack, D, DVar);
14253 continue;
14254 }
14255 }
14256 }
14257
14258 // Variably modified types are not supported.
14259 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
14260 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14261 << getOpenMPClauseName(OMPC_copyprivate) << Type
14262 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14263 bool IsDecl =
14264 !VD ||
14265 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14266 Diag(D->getLocation(),
14267 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14268 << D;
14269 continue;
14270 }
14271
14272 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
14273 // A variable of class type (or array thereof) that appears in a
14274 // copyin clause requires an accessible, unambiguous copy assignment
14275 // operator for the class type.
14276 Type = Context.getBaseElementType(Type.getNonReferenceType())
14277 .getUnqualifiedType();
14278 VarDecl *SrcVD =
14279 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
14280 D->hasAttrs() ? &D->getAttrs() : nullptr);
14281 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
14282 VarDecl *DstVD =
14283 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
14284 D->hasAttrs() ? &D->getAttrs() : nullptr);
14285 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14286 ExprResult AssignmentOp = BuildBinOp(
14287 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
14288 if (AssignmentOp.isInvalid())
14289 continue;
14290 AssignmentOp =
14291 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14292 if (AssignmentOp.isInvalid())
14293 continue;
14294
14295 // No need to mark vars as copyprivate, they are already threadprivate or
14296 // implicitly private.
14297 assert(VD || isOpenMPCapturedDecl(D));
14298 Vars.push_back(
14299 VD ? RefExpr->IgnoreParens()
14300 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
14301 SrcExprs.push_back(PseudoSrcExpr);
14302 DstExprs.push_back(PseudoDstExpr);
14303 AssignmentOps.push_back(AssignmentOp.get());
14304 }
14305
14306 if (Vars.empty())
14307 return nullptr;
14308
14309 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14310 Vars, SrcExprs, DstExprs, AssignmentOps);
14311 }
14312
14313 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
14314 SourceLocation StartLoc,
14315 SourceLocation LParenLoc,
14316 SourceLocation EndLoc) {
14317 if (VarList.empty())
14318 return nullptr;
14319
14320 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
14321 }
14322
14323 OMPClause *
14324 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
14325 SourceLocation DepLoc, SourceLocation ColonLoc,
14326 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
14327 SourceLocation LParenLoc, SourceLocation EndLoc) {
14328 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
14329 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
14330 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
14331 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
14332 return nullptr;
14333 }
14334 if (DSAStack->getCurrentDirective() != OMPD_ordered &&
14335 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
14336 DepKind == OMPC_DEPEND_sink)) {
14337 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
14338 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
14339 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14340 /*Last=*/OMPC_DEPEND_unknown, Except)
14341 << getOpenMPClauseName(OMPC_depend);
14342 return nullptr;
14343 }
14344 SmallVector<Expr *, 8> Vars;
14345 DSAStackTy::OperatorOffsetTy OpsOffs;
14346 llvm::APSInt DepCounter(/*BitWidth=*/32);
14347 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
14348 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
14349 if (const Expr *OrderedCountExpr =
14350 DSAStack->getParentOrderedRegionParam().first) {
14351 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
14352 TotalDepCount.setIsUnsigned(/*Val=*/true);
14353 }
14354 }
14355 for (Expr *RefExpr : VarList) {
14356 assert(RefExpr && "NULL expr in OpenMP shared clause.");
14357 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
14358 // It will be analyzed later.
14359 Vars.push_back(RefExpr);
14360 continue;
14361 }
14362
14363 SourceLocation ELoc = RefExpr->getExprLoc();
14364 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
14365 if (DepKind == OMPC_DEPEND_sink) {
14366 if (DSAStack->getParentOrderedRegionParam().first &&
14367 DepCounter >= TotalDepCount) {
14368 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
14369 continue;
14370 }
14371 ++DepCounter;
14372 // OpenMP [2.13.9, Summary]
14373 // depend(dependence-type : vec), where dependence-type is:
14374 // 'sink' and where vec is the iteration vector, which has the form:
14375 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
14376 // where n is the value specified by the ordered clause in the loop
14377 // directive, xi denotes the loop iteration variable of the i-th nested
14378 // loop associated with the loop directive, and di is a constant
14379 // non-negative integer.
14380 if (CurContext->isDependentContext()) {
14381 // It will be analyzed later.
14382 Vars.push_back(RefExpr);
14383 continue;
14384 }
14385 SimpleExpr = SimpleExpr->IgnoreImplicit();
14386 OverloadedOperatorKind OOK = OO_None;
14387 SourceLocation OOLoc;
14388 Expr *LHS = SimpleExpr;
14389 Expr *RHS = nullptr;
14390 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
14391 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
14392 OOLoc = BO->getOperatorLoc();
14393 LHS = BO->getLHS()->IgnoreParenImpCasts();
14394 RHS = BO->getRHS()->IgnoreParenImpCasts();
14395 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
14396 OOK = OCE->getOperator();
14397 OOLoc = OCE->getOperatorLoc();
14398 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
14399 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
14400 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
14401 OOK = MCE->getMethodDecl()
14402 ->getNameInfo()
14403 .getName()
14404 .getCXXOverloadedOperator();
14405 OOLoc = MCE->getCallee()->getExprLoc();
14406 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
14407 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
14408 }
14409 SourceLocation ELoc;
14410 SourceRange ERange;
14411 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
14412 if (Res.second) {
14413 // It will be analyzed later.
14414 Vars.push_back(RefExpr);
14415 }
14416 ValueDecl *D = Res.first;
14417 if (!D)
14418 continue;
14419
14420 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
14421 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
14422 continue;
14423 }
14424 if (RHS) {
14425 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
14426 RHS, OMPC_depend, /*StrictlyPositive=*/false);
14427 if (RHSRes.isInvalid())
14428 continue;
14429 }
14430 if (!CurContext->isDependentContext() &&
14431 DSAStack->getParentOrderedRegionParam().first &&
14432 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
14433 const ValueDecl *VD =
14434 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
14435 if (VD)
14436 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
14437 << 1 << VD;
14438 else
14439 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
14440 continue;
14441 }
14442 OpsOffs.emplace_back(RHS, OOK);
14443 } else {
14444 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
14445 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
14446 (ASE &&
14447 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
14448 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
14449 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
14450 << RefExpr->getSourceRange();
14451 continue;
14452 }
14453
14454 ExprResult Res;
14455 {
14456 Sema::TentativeAnalysisScope Trap(*this);
14457 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
14458 RefExpr->IgnoreParenImpCasts());
14459 }
14460 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
14461 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
14462 << RefExpr->getSourceRange();
14463 continue;
14464 }
14465 }
14466 Vars.push_back(RefExpr->IgnoreParenImpCasts());
14467 }
14468
14469 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
14470 TotalDepCount > VarList.size() &&
14471 DSAStack->getParentOrderedRegionParam().first &&
14472 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
14473 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
14474 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
14475 }
14476 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
14477 Vars.empty())
14478 return nullptr;
14479
14480 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14481 DepKind, DepLoc, ColonLoc, Vars,
14482 TotalDepCount.getZExtValue());
14483 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
14484 DSAStack->isParentOrderedRegion())
14485 DSAStack->addDoacrossDependClause(C, OpsOffs);
14486 return C;
14487 }
14488
14489 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
14490 SourceLocation LParenLoc,
14491 SourceLocation EndLoc) {
14492 Expr *ValExpr = Device;
14493 Stmt *HelperValStmt = nullptr;
14494
14495 // OpenMP [2.9.1, Restrictions]
14496 // The device expression must evaluate to a non-negative integer value.
14497 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
14498 /*StrictlyPositive=*/false))
14499 return nullptr;
14500
14501 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14502 OpenMPDirectiveKind CaptureRegion =
14503 getOpenMPCaptureRegionForClause(DKind, OMPC_device);
14504 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14505 ValExpr = MakeFullExpr(ValExpr).get();
14506 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14507 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14508 HelperValStmt = buildPreInits(Context, Captures);
14509 }
14510
14511 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
14512 StartLoc, LParenLoc, EndLoc);
14513 }
14514
14515 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
14516 DSAStackTy *Stack, QualType QTy,
14517 bool FullCheck = true) {
14518 NamedDecl *ND;
14519 if (QTy->isIncompleteType(&ND)) {
14520 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
14521 return false;
14522 }
14523 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
14524 !QTy.isTrivialType(SemaRef.Context))
14525 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
14526 return true;
14527 }
14528
14529 /// Return true if it can be proven that the provided array expression
14530 /// (array section or array subscript) does NOT specify the whole size of the
14531 /// array whose base type is \a BaseQTy.
14532 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
14533 const Expr *E,
14534 QualType BaseQTy) {
14535 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
14536
14537 // If this is an array subscript, it refers to the whole size if the size of
14538 // the dimension is constant and equals 1. Also, an array section assumes the
14539 // format of an array subscript if no colon is used.
14540 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
14541 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
14542 return ATy->getSize().getSExtValue() != 1;
14543 // Size can't be evaluated statically.
14544 return false;
14545 }
14546
14547 assert(OASE && "Expecting array section if not an array subscript.");
14548 const Expr *LowerBound = OASE->getLowerBound();
14549 const Expr *Length = OASE->getLength();
14550
14551 // If there is a lower bound that does not evaluates to zero, we are not
14552 // covering the whole dimension.
14553 if (LowerBound) {
14554 Expr::EvalResult Result;
14555 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
14556 return false; // Can't get the integer value as a constant.
14557
14558 llvm::APSInt ConstLowerBound = Result.Val.getInt();
14559 if (ConstLowerBound.getSExtValue())
14560 return true;
14561 }
14562
14563 // If we don't have a length we covering the whole dimension.
14564 if (!Length)
14565 return false;
14566
14567 // If the base is a pointer, we don't have a way to get the size of the
14568 // pointee.
14569 if (BaseQTy->isPointerType())
14570 return false;
14571
14572 // We can only check if the length is the same as the size of the dimension
14573 // if we have a constant array.
14574 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
14575 if (!CATy)
14576 return false;
14577
14578 Expr::EvalResult Result;
14579 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
14580 return false; // Can't get the integer value as a constant.
14581
14582 llvm::APSInt ConstLength = Result.Val.getInt();
14583 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
14584 }
14585
14586 // Return true if it can be proven that the provided array expression (array
14587 // section or array subscript) does NOT specify a single element of the array
14588 // whose base type is \a BaseQTy.
14589 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
14590 const Expr *E,
14591 QualType BaseQTy) {
14592 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
14593
14594 // An array subscript always refer to a single element. Also, an array section
14595 // assumes the format of an array subscript if no colon is used.
14596 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
14597 return false;
14598
14599 assert(OASE && "Expecting array section if not an array subscript.");
14600 const Expr *Length = OASE->getLength();
14601
14602 // If we don't have a length we have to check if the array has unitary size
14603 // for this dimension. Also, we should always expect a length if the base type
14604 // is pointer.
14605 if (!Length) {
14606 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
14607 return ATy->getSize().getSExtValue() != 1;
14608 // We cannot assume anything.
14609 return false;
14610 }
14611
14612 // Check if the length evaluates to 1.
14613 Expr::EvalResult Result;
14614 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
14615 return false; // Can't get the integer value as a constant.
14616
14617 llvm::APSInt ConstLength = Result.Val.getInt();
14618 return ConstLength.getSExtValue() != 1;
14619 }
14620
14621 // Return the expression of the base of the mappable expression or null if it
14622 // cannot be determined and do all the necessary checks to see if the expression
14623 // is valid as a standalone mappable expression. In the process, record all the
14624 // components of the expression.
14625 static const Expr *checkMapClauseExpressionBase(
14626 Sema &SemaRef, Expr *E,
14627 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
14628 OpenMPClauseKind CKind, bool NoDiagnose) {
14629 SourceLocation ELoc = E->getExprLoc();
14630 SourceRange ERange = E->getSourceRange();
14631
14632 // The base of elements of list in a map clause have to be either:
14633 // - a reference to variable or field.
14634 // - a member expression.
14635 // - an array expression.
14636 //
14637 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
14638 // reference to 'r'.
14639 //
14640 // If we have:
14641 //
14642 // struct SS {
14643 // Bla S;
14644 // foo() {
14645 // #pragma omp target map (S.Arr[:12]);
14646 // }
14647 // }
14648 //
14649 // We want to retrieve the member expression 'this->S';
14650
14651 const Expr *RelevantExpr = nullptr;
14652
14653 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
14654 // If a list item is an array section, it must specify contiguous storage.
14655 //
14656 // For this restriction it is sufficient that we make sure only references
14657 // to variables or fields and array expressions, and that no array sections
14658 // exist except in the rightmost expression (unless they cover the whole
14659 // dimension of the array). E.g. these would be invalid:
14660 //
14661 // r.ArrS[3:5].Arr[6:7]
14662 //
14663 // r.ArrS[3:5].x
14664 //
14665 // but these would be valid:
14666 // r.ArrS[3].Arr[6:7]
14667 //
14668 // r.ArrS[3].x
14669
14670 bool AllowUnitySizeArraySection = true;
14671 bool AllowWholeSizeArraySection = true;
14672
14673 while (!RelevantExpr) {
14674 E = E->IgnoreParenImpCasts();
14675
14676 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
14677 if (!isa<VarDecl>(CurE->getDecl()))
14678 return nullptr;
14679
14680 RelevantExpr = CurE;
14681
14682 // If we got a reference to a declaration, we should not expect any array
14683 // section before that.
14684 AllowUnitySizeArraySection = false;
14685 AllowWholeSizeArraySection = false;
14686
14687 // Record the component.
14688 CurComponents.emplace_back(CurE, CurE->getDecl());
14689 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
14690 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
14691
14692 if (isa<CXXThisExpr>(BaseE))
14693 // We found a base expression: this->Val.
14694 RelevantExpr = CurE;
14695 else
14696 E = BaseE;
14697
14698 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
14699 if (!NoDiagnose) {
14700 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
14701 << CurE->getSourceRange();
14702 return nullptr;
14703 }
14704 if (RelevantExpr)
14705 return nullptr;
14706 continue;
14707 }
14708
14709 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
14710
14711 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
14712 // A bit-field cannot appear in a map clause.
14713 //
14714 if (FD->isBitField()) {
14715 if (!NoDiagnose) {
14716 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
14717 << CurE->getSourceRange() << getOpenMPClauseName(CKind);
14718 return nullptr;
14719 }
14720 if (RelevantExpr)
14721 return nullptr;
14722 continue;
14723 }
14724
14725 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
14726 // If the type of a list item is a reference to a type T then the type
14727 // will be considered to be T for all purposes of this clause.
14728 QualType CurType = BaseE->getType().getNonReferenceType();
14729
14730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
14731 // A list item cannot be a variable that is a member of a structure with
14732 // a union type.
14733 //
14734 if (CurType->isUnionType()) {
14735 if (!NoDiagnose) {
14736 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
14737 << CurE->getSourceRange();
14738 return nullptr;
14739 }
14740 continue;
14741 }
14742
14743 // If we got a member expression, we should not expect any array section
14744 // before that:
14745 //
14746 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
14747 // If a list item is an element of a structure, only the rightmost symbol
14748 // of the variable reference can be an array section.
14749 //
14750 AllowUnitySizeArraySection = false;
14751 AllowWholeSizeArraySection = false;
14752
14753 // Record the component.
14754 CurComponents.emplace_back(CurE, FD);
14755 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
14756 E = CurE->getBase()->IgnoreParenImpCasts();
14757
14758 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
14759 if (!NoDiagnose) {
14760 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
14761 << 0 << CurE->getSourceRange();
14762 return nullptr;
14763 }
14764 continue;
14765 }
14766
14767 // If we got an array subscript that express the whole dimension we
14768 // can have any array expressions before. If it only expressing part of
14769 // the dimension, we can only have unitary-size array expressions.
14770 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
14771 E->getType()))
14772 AllowWholeSizeArraySection = false;
14773
14774 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
14775 Expr::EvalResult Result;
14776 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
14777 if (!Result.Val.getInt().isNullValue()) {
14778 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
14779 diag::err_omp_invalid_map_this_expr);
14780 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
14781 diag::note_omp_invalid_subscript_on_this_ptr_map);
14782 }
14783 }
14784 RelevantExpr = TE;
14785 }
14786
14787 // Record the component - we don't have any declaration associated.
14788 CurComponents.emplace_back(CurE, nullptr);
14789 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
14790 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
14791 E = CurE->getBase()->IgnoreParenImpCasts();
14792
14793 QualType CurType =
14794 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
14795
14796 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
14797 // If the type of a list item is a reference to a type T then the type
14798 // will be considered to be T for all purposes of this clause.
14799 if (CurType->isReferenceType())
14800 CurType = CurType->getPointeeType();
14801
14802 bool IsPointer = CurType->isAnyPointerType();
14803
14804 if (!IsPointer && !CurType->isArrayType()) {
14805 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
14806 << 0 << CurE->getSourceRange();
14807 return nullptr;
14808 }
14809
14810 bool NotWhole =
14811 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
14812 bool NotUnity =
14813 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
14814
14815 if (AllowWholeSizeArraySection) {
14816 // Any array section is currently allowed. Allowing a whole size array
14817 // section implies allowing a unity array section as well.
14818 //
14819 // If this array section refers to the whole dimension we can still
14820 // accept other array sections before this one, except if the base is a
14821 // pointer. Otherwise, only unitary sections are accepted.
14822 if (NotWhole || IsPointer)
14823 AllowWholeSizeArraySection = false;
14824 } else if (AllowUnitySizeArraySection && NotUnity) {
14825 // A unity or whole array section is not allowed and that is not
14826 // compatible with the properties of the current array section.
14827 SemaRef.Diag(
14828 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
14829 << CurE->getSourceRange();
14830 return nullptr;
14831 }
14832
14833 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
14834 Expr::EvalResult ResultR;
14835 Expr::EvalResult ResultL;
14836 if (CurE->getLength()->EvaluateAsInt(ResultR,
14837 SemaRef.getASTContext())) {
14838 if (!ResultR.Val.getInt().isOneValue()) {
14839 SemaRef.Diag(CurE->getLength()->getExprLoc(),
14840 diag::err_omp_invalid_map_this_expr);
14841 SemaRef.Diag(CurE->getLength()->getExprLoc(),
14842 diag::note_omp_invalid_length_on_this_ptr_mapping);
14843 }
14844 }
14845 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
14846 ResultL, SemaRef.getASTContext())) {
14847 if (!ResultL.Val.getInt().isNullValue()) {
14848 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
14849 diag::err_omp_invalid_map_this_expr);
14850 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
14851 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
14852 }
14853 }
14854 RelevantExpr = TE;
14855 }
14856
14857 // Record the component - we don't have any declaration associated.
14858 CurComponents.emplace_back(CurE, nullptr);
14859 } else {
14860 if (!NoDiagnose) {
14861 // If nothing else worked, this is not a valid map clause expression.
14862 SemaRef.Diag(
14863 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
14864 << ERange;
14865 }
14866 return nullptr;
14867 }
14868 }
14869
14870 return RelevantExpr;
14871 }
14872
14873 // Return true if expression E associated with value VD has conflicts with other
14874 // map information.
14875 static bool checkMapConflicts(
14876 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
14877 bool CurrentRegionOnly,
14878 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
14879 OpenMPClauseKind CKind) {
14880 assert(VD && E);
14881 SourceLocation ELoc = E->getExprLoc();
14882 SourceRange ERange = E->getSourceRange();
14883
14884 // In order to easily check the conflicts we need to match each component of
14885 // the expression under test with the components of the expressions that are
14886 // already in the stack.
14887
14888 assert(!CurComponents.empty() && "Map clause expression with no components!");
14889 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
14890 "Map clause expression with unexpected base!");
14891
14892 // Variables to help detecting enclosing problems in data environment nests.
14893 bool IsEnclosedByDataEnvironmentExpr = false;
14894 const Expr *EnclosingExpr = nullptr;
14895
14896 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
14897 VD, CurrentRegionOnly,
14898 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
14899 ERange, CKind, &EnclosingExpr,
14900 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
14901 StackComponents,
14902 OpenMPClauseKind) {
14903 assert(!StackComponents.empty() &&
14904 "Map clause expression with no components!");
14905 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
14906 "Map clause expression with unexpected base!");
14907 (void)VD;
14908
14909 // The whole expression in the stack.
14910 const Expr *RE = StackComponents.front().getAssociatedExpression();
14911
14912 // Expressions must start from the same base. Here we detect at which
14913 // point both expressions diverge from each other and see if we can
14914 // detect if the memory referred to both expressions is contiguous and
14915 // do not overlap.
14916 auto CI = CurComponents.rbegin();
14917 auto CE = CurComponents.rend();
14918 auto SI = StackComponents.rbegin();
14919 auto SE = StackComponents.rend();
14920 for (; CI != CE && SI != SE; ++CI, ++SI) {
14921
14922 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
14923 // At most one list item can be an array item derived from a given
14924 // variable in map clauses of the same construct.
14925 if (CurrentRegionOnly &&
14926 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
14927 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
14928 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
14929 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
14930 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
14931 diag::err_omp_multiple_array_items_in_map_clause)
14932 << CI->getAssociatedExpression()->getSourceRange();
14933 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
14934 diag::note_used_here)
14935 << SI->getAssociatedExpression()->getSourceRange();
14936 return true;
14937 }
14938
14939 // Do both expressions have the same kind?
14940 if (CI->getAssociatedExpression()->getStmtClass() !=
14941 SI->getAssociatedExpression()->getStmtClass())
14942 break;
14943
14944 // Are we dealing with different variables/fields?
14945 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
14946 break;
14947 }
14948 // Check if the extra components of the expressions in the enclosing
14949 // data environment are redundant for the current base declaration.
14950 // If they are, the maps completely overlap, which is legal.
14951 for (; SI != SE; ++SI) {
14952 QualType Type;
14953 if (const auto *ASE =
14954 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
14955 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
14956 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
14957 SI->getAssociatedExpression())) {
14958 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
14959 Type =
14960 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
14961 }
14962 if (Type.isNull() || Type->isAnyPointerType() ||
14963 checkArrayExpressionDoesNotReferToWholeSize(
14964 SemaRef, SI->getAssociatedExpression(), Type))
14965 break;
14966 }
14967
14968 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
14969 // List items of map clauses in the same construct must not share
14970 // original storage.
14971 //
14972 // If the expressions are exactly the same or one is a subset of the
14973 // other, it means they are sharing storage.
14974 if (CI == CE && SI == SE) {
14975 if (CurrentRegionOnly) {
14976 if (CKind == OMPC_map) {
14977 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
14978 } else {
14979 assert(CKind == OMPC_to || CKind == OMPC_from);
14980 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
14981 << ERange;
14982 }
14983 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
14984 << RE->getSourceRange();
14985 return true;
14986 }
14987 // If we find the same expression in the enclosing data environment,
14988 // that is legal.
14989 IsEnclosedByDataEnvironmentExpr = true;
14990 return false;
14991 }
14992
14993 QualType DerivedType =
14994 std::prev(CI)->getAssociatedDeclaration()->getType();
14995 SourceLocation DerivedLoc =
14996 std::prev(CI)->getAssociatedExpression()->getExprLoc();
14997
14998 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
14999 // If the type of a list item is a reference to a type T then the type
15000 // will be considered to be T for all purposes of this clause.
15001 DerivedType = DerivedType.getNonReferenceType();
15002
15003 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
15004 // A variable for which the type is pointer and an array section
15005 // derived from that variable must not appear as list items of map
15006 // clauses of the same construct.
15007 //
15008 // Also, cover one of the cases in:
15009 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
15010 // If any part of the original storage of a list item has corresponding
15011 // storage in the device data environment, all of the original storage
15012 // must have corresponding storage in the device data environment.
15013 //
15014 if (DerivedType->isAnyPointerType()) {
15015 if (CI == CE || SI == SE) {
15016 SemaRef.Diag(
15017 DerivedLoc,
15018 diag::err_omp_pointer_mapped_along_with_derived_section)
15019 << DerivedLoc;
15020 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15021 << RE->getSourceRange();
15022 return true;
15023 }
15024 if (CI->getAssociatedExpression()->getStmtClass() !=
15025 SI->getAssociatedExpression()->getStmtClass() ||
15026 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
15027 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
15028 assert(CI != CE && SI != SE);
15029 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
15030 << DerivedLoc;
15031 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15032 << RE->getSourceRange();
15033 return true;
15034 }
15035 }
15036
15037 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
15038 // List items of map clauses in the same construct must not share
15039 // original storage.
15040 //
15041 // An expression is a subset of the other.
15042 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
15043 if (CKind == OMPC_map) {
15044 if (CI != CE || SI != SE) {
15045 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
15046 // a pointer.
15047 auto Begin =
15048 CI != CE ? CurComponents.begin() : StackComponents.begin();
15049 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
15050 auto It = Begin;
15051 while (It != End && !It->getAssociatedDeclaration())
15052 std::advance(It, 1);
15053 assert(It != End &&
15054 "Expected at least one component with the declaration.");
15055 if (It != Begin && It->getAssociatedDeclaration()
15056 ->getType()
15057 .getCanonicalType()
15058 ->isAnyPointerType()) {
15059 IsEnclosedByDataEnvironmentExpr = false;
15060 EnclosingExpr = nullptr;
15061 return false;
15062 }
15063 }
15064 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
15065 } else {
15066 assert(CKind == OMPC_to || CKind == OMPC_from);
15067 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
15068 << ERange;
15069 }
15070 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15071 << RE->getSourceRange();
15072 return true;
15073 }
15074
15075 // The current expression uses the same base as other expression in the
15076 // data environment but does not contain it completely.
15077 if (!CurrentRegionOnly && SI != SE)
15078 EnclosingExpr = RE;
15079
15080 // The current expression is a subset of the expression in the data
15081 // environment.
15082 IsEnclosedByDataEnvironmentExpr |=
15083 (!CurrentRegionOnly && CI != CE && SI == SE);
15084
15085 return false;
15086 });
15087
15088 if (CurrentRegionOnly)
15089 return FoundError;
15090
15091 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
15092 // If any part of the original storage of a list item has corresponding
15093 // storage in the device data environment, all of the original storage must
15094 // have corresponding storage in the device data environment.
15095 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
15096 // If a list item is an element of a structure, and a different element of
15097 // the structure has a corresponding list item in the device data environment
15098 // prior to a task encountering the construct associated with the map clause,
15099 // then the list item must also have a corresponding list item in the device
15100 // data environment prior to the task encountering the construct.
15101 //
15102 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
15103 SemaRef.Diag(ELoc,
15104 diag::err_omp_original_storage_is_shared_and_does_not_contain)
15105 << ERange;
15106 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
15107 << EnclosingExpr->getSourceRange();
15108 return true;
15109 }
15110
15111 return FoundError;
15112 }
15113
15114 // Look up the user-defined mapper given the mapper name and mapped type, and
15115 // build a reference to it.
15116 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
15117 CXXScopeSpec &MapperIdScopeSpec,
15118 const DeclarationNameInfo &MapperId,
15119 QualType Type,
15120 Expr *UnresolvedMapper) {
15121 if (MapperIdScopeSpec.isInvalid())
15122 return ExprError();
15123 // Get the actual type for the array type.
15124 if (Type->isArrayType()) {
15125 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
15126 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
15127 }
15128 // Find all user-defined mappers with the given MapperId.
15129 SmallVector<UnresolvedSet<8>, 4> Lookups;
15130 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
15131 Lookup.suppressDiagnostics();
15132 if (S) {
15133 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
15134 NamedDecl *D = Lookup.getRepresentativeDecl();
15135 while (S && !S->isDeclScope(D))
15136 S = S->getParent();
15137 if (S)
15138 S = S->getParent();
15139 Lookups.emplace_back();
15140 Lookups.back().append(Lookup.begin(), Lookup.end());
15141 Lookup.clear();
15142 }
15143 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
15144 // Extract the user-defined mappers with the given MapperId.
15145 Lookups.push_back(UnresolvedSet<8>());
15146 for (NamedDecl *D : ULE->decls()) {
15147 auto *DMD = cast<OMPDeclareMapperDecl>(D);
15148 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
15149 Lookups.back().addDecl(DMD);
15150 }
15151 }
15152 // Defer the lookup for dependent types. The results will be passed through
15153 // UnresolvedMapper on instantiation.
15154 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
15155 Type->isInstantiationDependentType() ||
15156 Type->containsUnexpandedParameterPack() ||
15157 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
15158 return !D->isInvalidDecl() &&
15159 (D->getType()->isDependentType() ||
15160 D->getType()->isInstantiationDependentType() ||
15161 D->getType()->containsUnexpandedParameterPack());
15162 })) {
15163 UnresolvedSet<8> URS;
15164 for (const UnresolvedSet<8> &Set : Lookups) {
15165 if (Set.empty())
15166 continue;
15167 URS.append(Set.begin(), Set.end());
15168 }
15169 return UnresolvedLookupExpr::Create(
15170 SemaRef.Context, /*NamingClass=*/nullptr,
15171 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
15172 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
15173 }
15174 SourceLocation Loc = MapperId.getLoc();
15175 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
15176 // The type must be of struct, union or class type in C and C++
15177 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
15178 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
15179 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
15180 return ExprError();
15181 }
15182 // Perform argument dependent lookup.
15183 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
15184 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
15185 // Return the first user-defined mapper with the desired type.
15186 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15187 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
15188 if (!D->isInvalidDecl() &&
15189 SemaRef.Context.hasSameType(D->getType(), Type))
15190 return D;
15191 return nullptr;
15192 }))
15193 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
15194 // Find the first user-defined mapper with a type derived from the desired
15195 // type.
15196 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15197 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
15198 if (!D->isInvalidDecl() &&
15199 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
15200 !Type.isMoreQualifiedThan(D->getType()))
15201 return D;
15202 return nullptr;
15203 })) {
15204 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
15205 /*DetectVirtual=*/false);
15206 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
15207 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
15208 VD->getType().getUnqualifiedType()))) {
15209 if (SemaRef.CheckBaseClassAccess(
15210 Loc, VD->getType(), Type, Paths.front(),
15211 /*DiagID=*/0) != Sema::AR_inaccessible) {
15212 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
15213 }
15214 }
15215 }
15216 }
15217 // Report error if a mapper is specified, but cannot be found.
15218 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
15219 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
15220 << Type << MapperId.getName();
15221 return ExprError();
15222 }
15223 return ExprEmpty();
15224 }
15225
15226 namespace {
15227 // Utility struct that gathers all the related lists associated with a mappable
15228 // expression.
15229 struct MappableVarListInfo {
15230 // The list of expressions.
15231 ArrayRef<Expr *> VarList;
15232 // The list of processed expressions.
15233 SmallVector<Expr *, 16> ProcessedVarList;
15234 // The mappble components for each expression.
15235 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
15236 // The base declaration of the variable.
15237 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
15238 // The reference to the user-defined mapper associated with every expression.
15239 SmallVector<Expr *, 16> UDMapperList;
15240
15241 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
15242 // We have a list of components and base declarations for each entry in the
15243 // variable list.
15244 VarComponents.reserve(VarList.size());
15245 VarBaseDeclarations.reserve(VarList.size());
15246 }
15247 };
15248 }
15249
15250 // Check the validity of the provided variable list for the provided clause kind
15251 // \a CKind. In the check process the valid expressions, mappable expression
15252 // components, variables, and user-defined mappers are extracted and used to
15253 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
15254 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
15255 // and \a MapperId are expected to be valid if the clause kind is 'map'.
15256 static void checkMappableExpressionList(
15257 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
15258 MappableVarListInfo &MVLI, SourceLocation StartLoc,
15259 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
15260 ArrayRef<Expr *> UnresolvedMappers,
15261 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
15262 bool IsMapTypeImplicit = false) {
15263 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
15264 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
15265 "Unexpected clause kind with mappable expressions!");
15266
15267 // If the identifier of user-defined mapper is not specified, it is "default".
15268 // We do not change the actual name in this clause to distinguish whether a
15269 // mapper is specified explicitly, i.e., it is not explicitly specified when
15270 // MapperId.getName() is empty.
15271 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
15272 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
15273 MapperId.setName(DeclNames.getIdentifier(
15274 &SemaRef.getASTContext().Idents.get("default")));
15275 }
15276
15277 // Iterators to find the current unresolved mapper expression.
15278 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
15279 bool UpdateUMIt = false;
15280 Expr *UnresolvedMapper = nullptr;
15281
15282 // Keep track of the mappable components and base declarations in this clause.
15283 // Each entry in the list is going to have a list of components associated. We
15284 // record each set of the components so that we can build the clause later on.
15285 // In the end we should have the same amount of declarations and component
15286 // lists.
15287
15288 for (Expr *RE : MVLI.VarList) {
15289 assert(RE && "Null expr in omp to/from/map clause");
15290 SourceLocation ELoc = RE->getExprLoc();
15291
15292 // Find the current unresolved mapper expression.
15293 if (UpdateUMIt && UMIt != UMEnd) {
15294 UMIt++;
15295 assert(
15296 UMIt != UMEnd &&
15297 "Expect the size of UnresolvedMappers to match with that of VarList");
15298 }
15299 UpdateUMIt = true;
15300 if (UMIt != UMEnd)
15301 UnresolvedMapper = *UMIt;
15302
15303 const Expr *VE = RE->IgnoreParenLValueCasts();
15304
15305 if (VE->isValueDependent() || VE->isTypeDependent() ||
15306 VE->isInstantiationDependent() ||
15307 VE->containsUnexpandedParameterPack()) {
15308 // Try to find the associated user-defined mapper.
15309 ExprResult ER = buildUserDefinedMapperRef(
15310 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15311 VE->getType().getCanonicalType(), UnresolvedMapper);
15312 if (ER.isInvalid())
15313 continue;
15314 MVLI.UDMapperList.push_back(ER.get());
15315 // We can only analyze this information once the missing information is
15316 // resolved.
15317 MVLI.ProcessedVarList.push_back(RE);
15318 continue;
15319 }
15320
15321 Expr *SimpleExpr = RE->IgnoreParenCasts();
15322
15323 if (!RE->IgnoreParenImpCasts()->isLValue()) {
15324 SemaRef.Diag(ELoc,
15325 diag::err_omp_expected_named_var_member_or_array_expression)
15326 << RE->getSourceRange();
15327 continue;
15328 }
15329
15330 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
15331 ValueDecl *CurDeclaration = nullptr;
15332
15333 // Obtain the array or member expression bases if required. Also, fill the
15334 // components array with all the components identified in the process.
15335 const Expr *BE = checkMapClauseExpressionBase(
15336 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
15337 if (!BE)
15338 continue;
15339
15340 assert(!CurComponents.empty() &&
15341 "Invalid mappable expression information.");
15342
15343 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
15344 // Add store "this" pointer to class in DSAStackTy for future checking
15345 DSAS->addMappedClassesQualTypes(TE->getType());
15346 // Try to find the associated user-defined mapper.
15347 ExprResult ER = buildUserDefinedMapperRef(
15348 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15349 VE->getType().getCanonicalType(), UnresolvedMapper);
15350 if (ER.isInvalid())
15351 continue;
15352 MVLI.UDMapperList.push_back(ER.get());
15353 // Skip restriction checking for variable or field declarations
15354 MVLI.ProcessedVarList.push_back(RE);
15355 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15356 MVLI.VarComponents.back().append(CurComponents.begin(),
15357 CurComponents.end());
15358 MVLI.VarBaseDeclarations.push_back(nullptr);
15359 continue;
15360 }
15361
15362 // For the following checks, we rely on the base declaration which is
15363 // expected to be associated with the last component. The declaration is
15364 // expected to be a variable or a field (if 'this' is being mapped).
15365 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
15366 assert(CurDeclaration && "Null decl on map clause.");
15367 assert(
15368 CurDeclaration->isCanonicalDecl() &&
15369 "Expecting components to have associated only canonical declarations.");
15370
15371 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
15372 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
15373
15374 assert((VD || FD) && "Only variables or fields are expected here!");
15375 (void)FD;
15376
15377 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
15378 // threadprivate variables cannot appear in a map clause.
15379 // OpenMP 4.5 [2.10.5, target update Construct]
15380 // threadprivate variables cannot appear in a from clause.
15381 if (VD && DSAS->isThreadPrivate(VD)) {
15382 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
15383 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
15384 << getOpenMPClauseName(CKind);
15385 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
15386 continue;
15387 }
15388
15389 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
15390 // A list item cannot appear in both a map clause and a data-sharing
15391 // attribute clause on the same construct.
15392
15393 // Check conflicts with other map clause expressions. We check the conflicts
15394 // with the current construct separately from the enclosing data
15395 // environment, because the restrictions are different. We only have to
15396 // check conflicts across regions for the map clauses.
15397 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
15398 /*CurrentRegionOnly=*/true, CurComponents, CKind))
15399 break;
15400 if (CKind == OMPC_map &&
15401 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
15402 /*CurrentRegionOnly=*/false, CurComponents, CKind))
15403 break;
15404
15405 // OpenMP 4.5 [2.10.5, target update Construct]
15406 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
15407 // If the type of a list item is a reference to a type T then the type will
15408 // be considered to be T for all purposes of this clause.
15409 auto I = llvm::find_if(
15410 CurComponents,
15411 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
15412 return MC.getAssociatedDeclaration();
15413 });
15414 assert(I != CurComponents.end() && "Null decl on map clause.");
15415 QualType Type =
15416 I->getAssociatedDeclaration()->getType().getNonReferenceType();
15417
15418 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
15419 // A list item in a to or from clause must have a mappable type.
15420 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
15421 // A list item must have a mappable type.
15422 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
15423 DSAS, Type))
15424 continue;
15425
15426 if (CKind == OMPC_map) {
15427 // target enter data
15428 // OpenMP [2.10.2, Restrictions, p. 99]
15429 // A map-type must be specified in all map clauses and must be either
15430 // to or alloc.
15431 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
15432 if (DKind == OMPD_target_enter_data &&
15433 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
15434 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
15435 << (IsMapTypeImplicit ? 1 : 0)
15436 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
15437 << getOpenMPDirectiveName(DKind);
15438 continue;
15439 }
15440
15441 // target exit_data
15442 // OpenMP [2.10.3, Restrictions, p. 102]
15443 // A map-type must be specified in all map clauses and must be either
15444 // from, release, or delete.
15445 if (DKind == OMPD_target_exit_data &&
15446 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
15447 MapType == OMPC_MAP_delete)) {
15448 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
15449 << (IsMapTypeImplicit ? 1 : 0)
15450 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
15451 << getOpenMPDirectiveName(DKind);
15452 continue;
15453 }
15454
15455 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15456 // A list item cannot appear in both a map clause and a data-sharing
15457 // attribute clause on the same construct
15458 //
15459 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15460 // A list item cannot appear in both a map clause and a data-sharing
15461 // attribute clause on the same construct unless the construct is a
15462 // combined construct.
15463 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
15464 isOpenMPTargetExecutionDirective(DKind)) ||
15465 DKind == OMPD_target)) {
15466 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
15467 if (isOpenMPPrivate(DVar.CKind)) {
15468 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15469 << getOpenMPClauseName(DVar.CKind)
15470 << getOpenMPClauseName(OMPC_map)
15471 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
15472 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
15473 continue;
15474 }
15475 }
15476 }
15477
15478 // Try to find the associated user-defined mapper.
15479 ExprResult ER = buildUserDefinedMapperRef(
15480 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15481 Type.getCanonicalType(), UnresolvedMapper);
15482 if (ER.isInvalid())
15483 continue;
15484 MVLI.UDMapperList.push_back(ER.get());
15485
15486 // Save the current expression.
15487 MVLI.ProcessedVarList.push_back(RE);
15488
15489 // Store the components in the stack so that they can be used to check
15490 // against other clauses later on.
15491 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
15492 /*WhereFoundClauseKind=*/OMPC_map);
15493
15494 // Save the components and declaration to create the clause. For purposes of
15495 // the clause creation, any component list that has has base 'this' uses
15496 // null as base declaration.
15497 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15498 MVLI.VarComponents.back().append(CurComponents.begin(),
15499 CurComponents.end());
15500 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
15501 : CurDeclaration);
15502 }
15503 }
15504
15505 OMPClause *Sema::ActOnOpenMPMapClause(
15506 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15507 ArrayRef<SourceLocation> MapTypeModifiersLoc,
15508 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
15509 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
15510 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
15511 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
15512 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
15513 OMPC_MAP_MODIFIER_unknown,
15514 OMPC_MAP_MODIFIER_unknown};
15515 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers];
15516
15517 // Process map-type-modifiers, flag errors for duplicate modifiers.
15518 unsigned Count = 0;
15519 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
15520 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
15521 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
15522 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
15523 continue;
15524 }
15525 assert(Count < OMPMapClause::NumberOfModifiers &&
15526 "Modifiers exceed the allowed number of map type modifiers");
15527 Modifiers[Count] = MapTypeModifiers[I];
15528 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
15529 ++Count;
15530 }
15531
15532 MappableVarListInfo MVLI(VarList);
15533 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
15534 MapperIdScopeSpec, MapperId, UnresolvedMappers,
15535 MapType, IsMapTypeImplicit);
15536
15537 // We need to produce a map clause even if we don't have variables so that
15538 // other diagnostics related with non-existing map clauses are accurate.
15539 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
15540 MVLI.VarBaseDeclarations, MVLI.VarComponents,
15541 MVLI.UDMapperList, Modifiers, ModifiersLoc,
15542 MapperIdScopeSpec.getWithLocInContext(Context),
15543 MapperId, MapType, IsMapTypeImplicit, MapLoc);
15544 }
15545
15546 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
15547 TypeResult ParsedType) {
15548 assert(ParsedType.isUsable());
15549
15550 QualType ReductionType = GetTypeFromParser(ParsedType.get());
15551 if (ReductionType.isNull())
15552 return QualType();
15553
15554 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
15555 // A type name in a declare reduction directive cannot be a function type, an
15556 // array type, a reference type, or a type qualified with const, volatile or
15557 // restrict.
15558 if (ReductionType.hasQualifiers()) {
15559 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
15560 return QualType();
15561 }
15562
15563 if (ReductionType->isFunctionType()) {
15564 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
15565 return QualType();
15566 }
15567 if (ReductionType->isReferenceType()) {
15568 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
15569 return QualType();
15570 }
15571 if (ReductionType->isArrayType()) {
15572 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
15573 return QualType();
15574 }
15575 return ReductionType;
15576 }
15577
15578 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
15579 Scope *S, DeclContext *DC, DeclarationName Name,
15580 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
15581 AccessSpecifier AS, Decl *PrevDeclInScope) {
15582 SmallVector<Decl *, 8> Decls;
15583 Decls.reserve(ReductionTypes.size());
15584
15585 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
15586 forRedeclarationInCurContext());
15587 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
15588 // A reduction-identifier may not be re-declared in the current scope for the
15589 // same type or for a type that is compatible according to the base language
15590 // rules.
15591 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
15592 OMPDeclareReductionDecl *PrevDRD = nullptr;
15593 bool InCompoundScope = true;
15594 if (S != nullptr) {
15595 // Find previous declaration with the same name not referenced in other
15596 // declarations.
15597 FunctionScopeInfo *ParentFn = getEnclosingFunction();
15598 InCompoundScope =
15599 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
15600 LookupName(Lookup, S);
15601 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
15602 /*AllowInlineNamespace=*/false);
15603 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
15604 LookupResult::Filter Filter = Lookup.makeFilter();
15605 while (Filter.hasNext()) {
15606 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
15607 if (InCompoundScope) {
15608 auto I = UsedAsPrevious.find(PrevDecl);
15609 if (I == UsedAsPrevious.end())
15610 UsedAsPrevious[PrevDecl] = false;
15611 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
15612 UsedAsPrevious[D] = true;
15613 }
15614 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
15615 PrevDecl->getLocation();
15616 }
15617 Filter.done();
15618 if (InCompoundScope) {
15619 for (const auto &PrevData : UsedAsPrevious) {
15620 if (!PrevData.second) {
15621 PrevDRD = PrevData.first;
15622 break;
15623 }
15624 }
15625 }
15626 } else if (PrevDeclInScope != nullptr) {
15627 auto *PrevDRDInScope = PrevDRD =
15628 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
15629 do {
15630 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
15631 PrevDRDInScope->getLocation();
15632 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
15633 } while (PrevDRDInScope != nullptr);
15634 }
15635 for (const auto &TyData : ReductionTypes) {
15636 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
15637 bool Invalid = false;
15638 if (I != PreviousRedeclTypes.end()) {
15639 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
15640 << TyData.first;
15641 Diag(I->second, diag::note_previous_definition);
15642 Invalid = true;
15643 }
15644 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
15645 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
15646 Name, TyData.first, PrevDRD);
15647 DC->addDecl(DRD);
15648 DRD->setAccess(AS);
15649 Decls.push_back(DRD);
15650 if (Invalid)
15651 DRD->setInvalidDecl();
15652 else
15653 PrevDRD = DRD;
15654 }
15655
15656 return DeclGroupPtrTy::make(
15657 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
15658 }
15659
15660 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
15661 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15662
15663 // Enter new function scope.
15664 PushFunctionScope();
15665 setFunctionHasBranchProtectedScope();
15666 getCurFunction()->setHasOMPDeclareReductionCombiner();
15667
15668 if (S != nullptr)
15669 PushDeclContext(S, DRD);
15670 else
15671 CurContext = DRD;
15672
15673 PushExpressionEvaluationContext(
15674 ExpressionEvaluationContext::PotentiallyEvaluated);
15675
15676 QualType ReductionType = DRD->getType();
15677 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
15678 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
15679 // uses semantics of argument handles by value, but it should be passed by
15680 // reference. C lang does not support references, so pass all parameters as
15681 // pointers.
15682 // Create 'T omp_in;' variable.
15683 VarDecl *OmpInParm =
15684 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
15685 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
15686 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
15687 // uses semantics of argument handles by value, but it should be passed by
15688 // reference. C lang does not support references, so pass all parameters as
15689 // pointers.
15690 // Create 'T omp_out;' variable.
15691 VarDecl *OmpOutParm =
15692 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
15693 if (S != nullptr) {
15694 PushOnScopeChains(OmpInParm, S);
15695 PushOnScopeChains(OmpOutParm, S);
15696 } else {
15697 DRD->addDecl(OmpInParm);
15698 DRD->addDecl(OmpOutParm);
15699 }
15700 Expr *InE =
15701 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
15702 Expr *OutE =
15703 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
15704 DRD->setCombinerData(InE, OutE);
15705 }
15706
15707 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
15708 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15709 DiscardCleanupsInEvaluationContext();
15710 PopExpressionEvaluationContext();
15711
15712 PopDeclContext();
15713 PopFunctionScopeInfo();
15714
15715 if (Combiner != nullptr)
15716 DRD->setCombiner(Combiner);
15717 else
15718 DRD->setInvalidDecl();
15719 }
15720
15721 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
15722 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15723
15724 // Enter new function scope.
15725 PushFunctionScope();
15726 setFunctionHasBranchProtectedScope();
15727
15728 if (S != nullptr)
15729 PushDeclContext(S, DRD);
15730 else
15731 CurContext = DRD;
15732
15733 PushExpressionEvaluationContext(
15734 ExpressionEvaluationContext::PotentiallyEvaluated);
15735
15736 QualType ReductionType = DRD->getType();
15737 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
15738 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
15739 // uses semantics of argument handles by value, but it should be passed by
15740 // reference. C lang does not support references, so pass all parameters as
15741 // pointers.
15742 // Create 'T omp_priv;' variable.
15743 VarDecl *OmpPrivParm =
15744 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
15745 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
15746 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
15747 // uses semantics of argument handles by value, but it should be passed by
15748 // reference. C lang does not support references, so pass all parameters as
15749 // pointers.
15750 // Create 'T omp_orig;' variable.
15751 VarDecl *OmpOrigParm =
15752 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
15753 if (S != nullptr) {
15754 PushOnScopeChains(OmpPrivParm, S);
15755 PushOnScopeChains(OmpOrigParm, S);
15756 } else {
15757 DRD->addDecl(OmpPrivParm);
15758 DRD->addDecl(OmpOrigParm);
15759 }
15760 Expr *OrigE =
15761 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
15762 Expr *PrivE =
15763 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
15764 DRD->setInitializerData(OrigE, PrivE);
15765 return OmpPrivParm;
15766 }
15767
15768 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
15769 VarDecl *OmpPrivParm) {
15770 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15771 DiscardCleanupsInEvaluationContext();
15772 PopExpressionEvaluationContext();
15773
15774 PopDeclContext();
15775 PopFunctionScopeInfo();
15776
15777 if (Initializer != nullptr) {
15778 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
15779 } else if (OmpPrivParm->hasInit()) {
15780 DRD->setInitializer(OmpPrivParm->getInit(),
15781 OmpPrivParm->isDirectInit()
15782 ? OMPDeclareReductionDecl::DirectInit
15783 : OMPDeclareReductionDecl::CopyInit);
15784 } else {
15785 DRD->setInvalidDecl();
15786 }
15787 }
15788
15789 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
15790 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
15791 for (Decl *D : DeclReductions.get()) {
15792 if (IsValid) {
15793 if (S)
15794 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
15795 /*AddToContext=*/false);
15796 } else {
15797 D->setInvalidDecl();
15798 }
15799 }
15800 return DeclReductions;
15801 }
15802
15803 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
15804 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
15805 QualType T = TInfo->getType();
15806 if (D.isInvalidType())
15807 return true;
15808
15809 if (getLangOpts().CPlusPlus) {
15810 // Check that there are no default arguments (C++ only).
15811 CheckExtraCXXDefaultArguments(D);
15812 }
15813
15814 return CreateParsedType(T, TInfo);
15815 }
15816
15817 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
15818 TypeResult ParsedType) {
15819 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
15820
15821 QualType MapperType = GetTypeFromParser(ParsedType.get());
15822 assert(!MapperType.isNull() && "Expect valid mapper type");
15823
15824 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
15825 // The type must be of struct, union or class type in C and C++
15826 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
15827 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
15828 return QualType();
15829 }
15830 return MapperType;
15831 }
15832
15833 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
15834 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
15835 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
15836 Decl *PrevDeclInScope) {
15837 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
15838 forRedeclarationInCurContext());
15839 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
15840 // A mapper-identifier may not be redeclared in the current scope for the
15841 // same type or for a type that is compatible according to the base language
15842 // rules.
15843 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
15844 OMPDeclareMapperDecl *PrevDMD = nullptr;
15845 bool InCompoundScope = true;
15846 if (S != nullptr) {
15847 // Find previous declaration with the same name not referenced in other
15848 // declarations.
15849 FunctionScopeInfo *ParentFn = getEnclosingFunction();
15850 InCompoundScope =
15851 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
15852 LookupName(Lookup, S);
15853 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
15854 /*AllowInlineNamespace=*/false);
15855 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
15856 LookupResult::Filter Filter = Lookup.makeFilter();
15857 while (Filter.hasNext()) {
15858 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
15859 if (InCompoundScope) {
15860 auto I = UsedAsPrevious.find(PrevDecl);
15861 if (I == UsedAsPrevious.end())
15862 UsedAsPrevious[PrevDecl] = false;
15863 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
15864 UsedAsPrevious[D] = true;
15865 }
15866 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
15867 PrevDecl->getLocation();
15868 }
15869 Filter.done();
15870 if (InCompoundScope) {
15871 for (const auto &PrevData : UsedAsPrevious) {
15872 if (!PrevData.second) {
15873 PrevDMD = PrevData.first;
15874 break;
15875 }
15876 }
15877 }
15878 } else if (PrevDeclInScope) {
15879 auto *PrevDMDInScope = PrevDMD =
15880 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
15881 do {
15882 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
15883 PrevDMDInScope->getLocation();
15884 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
15885 } while (PrevDMDInScope != nullptr);
15886 }
15887 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
15888 bool Invalid = false;
15889 if (I != PreviousRedeclTypes.end()) {
15890 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
15891 << MapperType << Name;
15892 Diag(I->second, diag::note_previous_definition);
15893 Invalid = true;
15894 }
15895 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
15896 MapperType, VN, PrevDMD);
15897 DC->addDecl(DMD);
15898 DMD->setAccess(AS);
15899 if (Invalid)
15900 DMD->setInvalidDecl();
15901
15902 // Enter new function scope.
15903 PushFunctionScope();
15904 setFunctionHasBranchProtectedScope();
15905
15906 CurContext = DMD;
15907
15908 return DMD;
15909 }
15910
15911 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
15912 Scope *S,
15913 QualType MapperType,
15914 SourceLocation StartLoc,
15915 DeclarationName VN) {
15916 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
15917 if (S)
15918 PushOnScopeChains(VD, S);
15919 else
15920 DMD->addDecl(VD);
15921 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
15922 DMD->setMapperVarRef(MapperVarRefExpr);
15923 }
15924
15925 Sema::DeclGroupPtrTy
15926 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
15927 ArrayRef<OMPClause *> ClauseList) {
15928 PopDeclContext();
15929 PopFunctionScopeInfo();
15930
15931 if (D) {
15932 if (S)
15933 PushOnScopeChains(D, S, /*AddToContext=*/false);
15934 D->CreateClauses(Context, ClauseList);
15935 }
15936
15937 return DeclGroupPtrTy::make(DeclGroupRef(D));
15938 }
15939
15940 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
15941 SourceLocation StartLoc,
15942 SourceLocation LParenLoc,
15943 SourceLocation EndLoc) {
15944 Expr *ValExpr = NumTeams;
15945 Stmt *HelperValStmt = nullptr;
15946
15947 // OpenMP [teams Constrcut, Restrictions]
15948 // The num_teams expression must evaluate to a positive integer value.
15949 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
15950 /*StrictlyPositive=*/true))
15951 return nullptr;
15952
15953 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15954 OpenMPDirectiveKind CaptureRegion =
15955 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
15956 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15957 ValExpr = MakeFullExpr(ValExpr).get();
15958 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15959 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15960 HelperValStmt = buildPreInits(Context, Captures);
15961 }
15962
15963 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
15964 StartLoc, LParenLoc, EndLoc);
15965 }
15966
15967 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
15968 SourceLocation StartLoc,
15969 SourceLocation LParenLoc,
15970 SourceLocation EndLoc) {
15971 Expr *ValExpr = ThreadLimit;
15972 Stmt *HelperValStmt = nullptr;
15973
15974 // OpenMP [teams Constrcut, Restrictions]
15975 // The thread_limit expression must evaluate to a positive integer value.
15976 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
15977 /*StrictlyPositive=*/true))
15978 return nullptr;
15979
15980 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15981 OpenMPDirectiveKind CaptureRegion =
15982 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
15983 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15984 ValExpr = MakeFullExpr(ValExpr).get();
15985 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15986 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15987 HelperValStmt = buildPreInits(Context, Captures);
15988 }
15989
15990 return new (Context) OMPThreadLimitClause(
15991 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15992 }
15993
15994 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
15995 SourceLocation StartLoc,
15996 SourceLocation LParenLoc,
15997 SourceLocation EndLoc) {
15998 Expr *ValExpr = Priority;
15999 Stmt *HelperValStmt = nullptr;
16000 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16001
16002 // OpenMP [2.9.1, task Constrcut]
16003 // The priority-value is a non-negative numerical scalar expression.
16004 if (!isNonNegativeIntegerValue(
16005 ValExpr, *this, OMPC_priority,
16006 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
16007 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16008 return nullptr;
16009
16010 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
16011 StartLoc, LParenLoc, EndLoc);
16012 }
16013
16014 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
16015 SourceLocation StartLoc,
16016 SourceLocation LParenLoc,
16017 SourceLocation EndLoc) {
16018 Expr *ValExpr = Grainsize;
16019 Stmt *HelperValStmt = nullptr;
16020 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16021
16022 // OpenMP [2.9.2, taskloop Constrcut]
16023 // The parameter of the grainsize clause must be a positive integer
16024 // expression.
16025 if (!isNonNegativeIntegerValue(
16026 ValExpr, *this, OMPC_grainsize,
16027 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
16028 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16029 return nullptr;
16030
16031 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
16032 StartLoc, LParenLoc, EndLoc);
16033 }
16034
16035 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
16036 SourceLocation StartLoc,
16037 SourceLocation LParenLoc,
16038 SourceLocation EndLoc) {
16039 Expr *ValExpr = NumTasks;
16040 Stmt *HelperValStmt = nullptr;
16041 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16042
16043 // OpenMP [2.9.2, taskloop Constrcut]
16044 // The parameter of the num_tasks clause must be a positive integer
16045 // expression.
16046 if (!isNonNegativeIntegerValue(
16047 ValExpr, *this, OMPC_num_tasks,
16048 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
16049 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16050 return nullptr;
16051
16052 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
16053 StartLoc, LParenLoc, EndLoc);
16054 }
16055
16056 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
16057 SourceLocation LParenLoc,
16058 SourceLocation EndLoc) {
16059 // OpenMP [2.13.2, critical construct, Description]
16060 // ... where hint-expression is an integer constant expression that evaluates
16061 // to a valid lock hint.
16062 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
16063 if (HintExpr.isInvalid())
16064 return nullptr;
16065 return new (Context)
16066 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
16067 }
16068
16069 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
16070 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16071 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
16072 SourceLocation EndLoc) {
16073 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
16074 std::string Values;
16075 Values += "'";
16076 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
16077 Values += "'";
16078 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16079 << Values << getOpenMPClauseName(OMPC_dist_schedule);
16080 return nullptr;
16081 }
16082 Expr *ValExpr = ChunkSize;
16083 Stmt *HelperValStmt = nullptr;
16084 if (ChunkSize) {
16085 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16086 !ChunkSize->isInstantiationDependent() &&
16087 !ChunkSize->containsUnexpandedParameterPack()) {
16088 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
16089 ExprResult Val =
16090 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16091 if (Val.isInvalid())
16092 return nullptr;
16093
16094 ValExpr = Val.get();
16095
16096 // OpenMP [2.7.1, Restrictions]
16097 // chunk_size must be a loop invariant integer expression with a positive
16098 // value.
16099 llvm::APSInt Result;
16100 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
16101 if (Result.isSigned() && !Result.isStrictlyPositive()) {
16102 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16103 << "dist_schedule" << ChunkSize->getSourceRange();
16104 return nullptr;
16105 }
16106 } else if (getOpenMPCaptureRegionForClause(
16107 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
16108 OMPD_unknown &&
16109 !CurContext->isDependentContext()) {
16110 ValExpr = MakeFullExpr(ValExpr).get();
16111 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16112 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16113 HelperValStmt = buildPreInits(Context, Captures);
16114 }
16115 }
16116 }
16117
16118 return new (Context)
16119 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
16120 Kind, ValExpr, HelperValStmt);
16121 }
16122
16123 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
16124 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
16125 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
16126 SourceLocation KindLoc, SourceLocation EndLoc) {
16127 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
16128 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
16129 std::string Value;
16130 SourceLocation Loc;
16131 Value += "'";
16132 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
16133 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
16134 OMPC_DEFAULTMAP_MODIFIER_tofrom);
16135 Loc = MLoc;
16136 } else {
16137 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
16138 OMPC_DEFAULTMAP_scalar);
16139 Loc = KindLoc;
16140 }
16141 Value += "'";
16142 Diag(Loc, diag::err_omp_unexpected_clause_value)
16143 << Value << getOpenMPClauseName(OMPC_defaultmap);
16144 return nullptr;
16145 }
16146 DSAStack->setDefaultDMAToFromScalar(StartLoc);
16147
16148 return new (Context)
16149 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
16150 }
16151
16152 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
16153 DeclContext *CurLexicalContext = getCurLexicalContext();
16154 if (!CurLexicalContext->isFileContext() &&
16155 !CurLexicalContext->isExternCContext() &&
16156 !CurLexicalContext->isExternCXXContext() &&
16157 !isa<CXXRecordDecl>(CurLexicalContext) &&
16158 !isa<ClassTemplateDecl>(CurLexicalContext) &&
16159 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
16160 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
16161 Diag(Loc, diag::err_omp_region_not_file_context);
16162 return false;
16163 }
16164 ++DeclareTargetNestingLevel;
16165 return true;
16166 }
16167
16168 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
16169 assert(DeclareTargetNestingLevel > 0 &&
16170 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
16171 --DeclareTargetNestingLevel;
16172 }
16173
16174 NamedDecl *
16175 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
16176 const DeclarationNameInfo &Id,
16177 NamedDeclSetType &SameDirectiveDecls) {
16178 LookupResult Lookup(*this, Id, LookupOrdinaryName);
16179 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
16180
16181 if (Lookup.isAmbiguous())
16182 return nullptr;
16183 Lookup.suppressDiagnostics();
16184
16185 if (!Lookup.isSingleResult()) {
16186 VarOrFuncDeclFilterCCC CCC(*this);
16187 if (TypoCorrection Corrected =
16188 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
16189 CTK_ErrorRecovery)) {
16190 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
16191 << Id.getName());
16192 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
16193 return nullptr;
16194 }
16195
16196 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
16197 return nullptr;
16198 }
16199
16200 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
16201 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
16202 !isa<FunctionTemplateDecl>(ND)) {
16203 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
16204 return nullptr;
16205 }
16206 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
16207 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
16208 return ND;
16209 }
16210
16211 void Sema::ActOnOpenMPDeclareTargetName(
16212 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
16213 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
16214 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
16215 isa<FunctionTemplateDecl>(ND)) &&
16216 "Expected variable, function or function template.");
16217
16218 // Diagnose marking after use as it may lead to incorrect diagnosis and
16219 // codegen.
16220 if (LangOpts.OpenMP >= 50 &&
16221 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
16222 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
16223
16224 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
16225 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
16226 if (DevTy.hasValue() && *DevTy != DT) {
16227 Diag(Loc, diag::err_omp_device_type_mismatch)
16228 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
16229 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
16230 return;
16231 }
16232 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
16233 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
16234 if (!Res) {
16235 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
16236 SourceRange(Loc, Loc));
16237 ND->addAttr(A);
16238 if (ASTMutationListener *ML = Context.getASTMutationListener())
16239 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
16240 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
16241 } else if (*Res != MT) {
16242 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
16243 }
16244 }
16245
16246 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
16247 Sema &SemaRef, Decl *D) {
16248 if (!D || !isa<VarDecl>(D))
16249 return;
16250 auto *VD = cast<VarDecl>(D);
16251 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
16252 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16253 if (SemaRef.LangOpts.OpenMP >= 50 &&
16254 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
16255 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
16256 VD->hasGlobalStorage()) {
16257 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
16258 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16259 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
16260 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
16261 // If a lambda declaration and definition appears between a
16262 // declare target directive and the matching end declare target
16263 // directive, all variables that are captured by the lambda
16264 // expression must also appear in a to clause.
16265 SemaRef.Diag(VD->getLocation(),
16266 diag::err_omp_lambda_capture_in_declare_target_not_to);
16267 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
16268 << VD << 0 << SR;
16269 return;
16270 }
16271 }
16272 if (MapTy.hasValue())
16273 return;
16274 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
16275 SemaRef.Diag(SL, diag::note_used_here) << SR;
16276 }
16277
16278 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
16279 Sema &SemaRef, DSAStackTy *Stack,
16280 ValueDecl *VD) {
16281 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
16282 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
16283 /*FullCheck=*/false);
16284 }
16285
16286 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
16287 SourceLocation IdLoc) {
16288 if (!D || D->isInvalidDecl())
16289 return;
16290 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
16291 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
16292 if (auto *VD = dyn_cast<VarDecl>(D)) {
16293 // Only global variables can be marked as declare target.
16294 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
16295 !VD->isStaticDataMember())
16296 return;
16297 // 2.10.6: threadprivate variable cannot appear in a declare target
16298 // directive.
16299 if (DSAStack->isThreadPrivate(VD)) {
16300 Diag(SL, diag::err_omp_threadprivate_in_target);
16301 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
16302 return;
16303 }
16304 }
16305 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
16306 D = FTD->getTemplatedDecl();
16307 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
16308 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
16309 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
16310 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
16311 Diag(IdLoc, diag::err_omp_function_in_link_clause);
16312 Diag(FD->getLocation(), diag::note_defined_here) << FD;
16313 return;
16314 }
16315 // Mark the function as must be emitted for the device.
16316 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
16317 OMPDeclareTargetDeclAttr::getDeviceType(FD);
16318 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
16319 *DevTy != OMPDeclareTargetDeclAttr::DT_Host)
16320 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false);
16321 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
16322 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost)
16323 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false);
16324 }
16325 if (auto *VD = dyn_cast<ValueDecl>(D)) {
16326 // Problem if any with var declared with incomplete type will be reported
16327 // as normal, so no need to check it here.
16328 if ((E || !VD->getType()->isIncompleteType()) &&
16329 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
16330 return;
16331 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
16332 // Checking declaration inside declare target region.
16333 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
16334 isa<FunctionTemplateDecl>(D)) {
16335 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
16336 Context, OMPDeclareTargetDeclAttr::MT_To,
16337 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
16338 D->addAttr(A);
16339 if (ASTMutationListener *ML = Context.getASTMutationListener())
16340 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
16341 }
16342 return;
16343 }
16344 }
16345 if (!E)
16346 return;
16347 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
16348 }
16349
16350 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
16351 CXXScopeSpec &MapperIdScopeSpec,
16352 DeclarationNameInfo &MapperId,
16353 const OMPVarListLocTy &Locs,
16354 ArrayRef<Expr *> UnresolvedMappers) {
16355 MappableVarListInfo MVLI(VarList);
16356 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
16357 MapperIdScopeSpec, MapperId, UnresolvedMappers);
16358 if (MVLI.ProcessedVarList.empty())
16359 return nullptr;
16360
16361 return OMPToClause::Create(
16362 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
16363 MVLI.VarComponents, MVLI.UDMapperList,
16364 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
16365 }
16366
16367 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
16368 CXXScopeSpec &MapperIdScopeSpec,
16369 DeclarationNameInfo &MapperId,
16370 const OMPVarListLocTy &Locs,
16371 ArrayRef<Expr *> UnresolvedMappers) {
16372 MappableVarListInfo MVLI(VarList);
16373 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
16374 MapperIdScopeSpec, MapperId, UnresolvedMappers);
16375 if (MVLI.ProcessedVarList.empty())
16376 return nullptr;
16377
16378 return OMPFromClause::Create(
16379 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
16380 MVLI.VarComponents, MVLI.UDMapperList,
16381 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
16382 }
16383
16384 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
16385 const OMPVarListLocTy &Locs) {
16386 MappableVarListInfo MVLI(VarList);
16387 SmallVector<Expr *, 8> PrivateCopies;
16388 SmallVector<Expr *, 8> Inits;
16389
16390 for (Expr *RefExpr : VarList) {
16391 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
16392 SourceLocation ELoc;
16393 SourceRange ERange;
16394 Expr *SimpleRefExpr = RefExpr;
16395 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16396 if (Res.second) {
16397 // It will be analyzed later.
16398 MVLI.ProcessedVarList.push_back(RefExpr);
16399 PrivateCopies.push_back(nullptr);
16400 Inits.push_back(nullptr);
16401 }
16402 ValueDecl *D = Res.first;
16403 if (!D)
16404 continue;
16405
16406 QualType Type = D->getType();
16407 Type = Type.getNonReferenceType().getUnqualifiedType();
16408
16409 auto *VD = dyn_cast<VarDecl>(D);
16410
16411 // Item should be a pointer or reference to pointer.
16412 if (!Type->isPointerType()) {
16413 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
16414 << 0 << RefExpr->getSourceRange();
16415 continue;
16416 }
16417
16418 // Build the private variable and the expression that refers to it.
16419 auto VDPrivate =
16420 buildVarDecl(*this, ELoc, Type, D->getName(),
16421 D->hasAttrs() ? &D->getAttrs() : nullptr,
16422 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
16423 if (VDPrivate->isInvalidDecl())
16424 continue;
16425
16426 CurContext->addDecl(VDPrivate);
16427 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
16428 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
16429
16430 // Add temporary variable to initialize the private copy of the pointer.
16431 VarDecl *VDInit =
16432 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
16433 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
16434 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
16435 AddInitializerToDecl(VDPrivate,
16436 DefaultLvalueConversion(VDInitRefExpr).get(),
16437 /*DirectInit=*/false);
16438
16439 // If required, build a capture to implement the privatization initialized
16440 // with the current list item value.
16441 DeclRefExpr *Ref = nullptr;
16442 if (!VD)
16443 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16444 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
16445 PrivateCopies.push_back(VDPrivateRefExpr);
16446 Inits.push_back(VDInitRefExpr);
16447
16448 // We need to add a data sharing attribute for this variable to make sure it
16449 // is correctly captured. A variable that shows up in a use_device_ptr has
16450 // similar properties of a first private variable.
16451 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
16452
16453 // Create a mappable component for the list item. List items in this clause
16454 // only need a component.
16455 MVLI.VarBaseDeclarations.push_back(D);
16456 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16457 MVLI.VarComponents.back().push_back(
16458 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
16459 }
16460
16461 if (MVLI.ProcessedVarList.empty())
16462 return nullptr;
16463
16464 return OMPUseDevicePtrClause::Create(
16465 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
16466 MVLI.VarBaseDeclarations, MVLI.VarComponents);
16467 }
16468
16469 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
16470 const OMPVarListLocTy &Locs) {
16471 MappableVarListInfo MVLI(VarList);
16472 for (Expr *RefExpr : VarList) {
16473 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
16474 SourceLocation ELoc;
16475 SourceRange ERange;
16476 Expr *SimpleRefExpr = RefExpr;
16477 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16478 if (Res.second) {
16479 // It will be analyzed later.
16480 MVLI.ProcessedVarList.push_back(RefExpr);
16481 }
16482 ValueDecl *D = Res.first;
16483 if (!D)
16484 continue;
16485
16486 QualType Type = D->getType();
16487 // item should be a pointer or array or reference to pointer or array
16488 if (!Type.getNonReferenceType()->isPointerType() &&
16489 !Type.getNonReferenceType()->isArrayType()) {
16490 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
16491 << 0 << RefExpr->getSourceRange();
16492 continue;
16493 }
16494
16495 // Check if the declaration in the clause does not show up in any data
16496 // sharing attribute.
16497 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
16498 if (isOpenMPPrivate(DVar.CKind)) {
16499 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
16500 << getOpenMPClauseName(DVar.CKind)
16501 << getOpenMPClauseName(OMPC_is_device_ptr)
16502 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16503 reportOriginalDsa(*this, DSAStack, D, DVar);
16504 continue;
16505 }
16506
16507 const Expr *ConflictExpr;
16508 if (DSAStack->checkMappableExprComponentListsForDecl(
16509 D, /*CurrentRegionOnly=*/true,
16510 [&ConflictExpr](
16511 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
16512 OpenMPClauseKind) -> bool {
16513 ConflictExpr = R.front().getAssociatedExpression();
16514 return true;
16515 })) {
16516 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
16517 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
16518 << ConflictExpr->getSourceRange();
16519 continue;
16520 }
16521
16522 // Store the components in the stack so that they can be used to check
16523 // against other clauses later on.
16524 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
16525 DSAStack->addMappableExpressionComponents(
16526 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
16527
16528 // Record the expression we've just processed.
16529 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
16530
16531 // Create a mappable component for the list item. List items in this clause
16532 // only need a component. We use a null declaration to signal fields in
16533 // 'this'.
16534 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
16535 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
16536 "Unexpected device pointer expression!");
16537 MVLI.VarBaseDeclarations.push_back(
16538 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
16539 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16540 MVLI.VarComponents.back().push_back(MC);
16541 }
16542
16543 if (MVLI.ProcessedVarList.empty())
16544 return nullptr;
16545
16546 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
16547 MVLI.VarBaseDeclarations,
16548 MVLI.VarComponents);
16549 }
16550
16551 OMPClause *Sema::ActOnOpenMPAllocateClause(
16552 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16553 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16554 if (Allocator) {
16555 // OpenMP [2.11.4 allocate Clause, Description]
16556 // allocator is an expression of omp_allocator_handle_t type.
16557 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
16558 return nullptr;
16559
16560 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
16561 if (AllocatorRes.isInvalid())
16562 return nullptr;
16563 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
16564 DSAStack->getOMPAllocatorHandleT(),
16565 Sema::AA_Initializing,
16566 /*AllowExplicit=*/true);
16567 if (AllocatorRes.isInvalid())
16568 return nullptr;
16569 Allocator = AllocatorRes.get();
16570 } else {
16571 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
16572 // allocate clauses that appear on a target construct or on constructs in a
16573 // target region must specify an allocator expression unless a requires
16574 // directive with the dynamic_allocators clause is present in the same
16575 // compilation unit.
16576 if (LangOpts.OpenMPIsDevice &&
16577 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
16578 targetDiag(StartLoc, diag::err_expected_allocator_expression);
16579 }
16580 // Analyze and build list of variables.
16581 SmallVector<Expr *, 8> Vars;
16582 for (Expr *RefExpr : VarList) {
16583 assert(RefExpr && "NULL expr in OpenMP private clause.");
16584 SourceLocation ELoc;
16585 SourceRange ERange;
16586 Expr *SimpleRefExpr = RefExpr;
16587 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16588 if (Res.second) {
16589 // It will be analyzed later.
16590 Vars.push_back(RefExpr);
16591 }
16592 ValueDecl *D = Res.first;
16593 if (!D)
16594 continue;
16595
16596 auto *VD = dyn_cast<VarDecl>(D);
16597 DeclRefExpr *Ref = nullptr;
16598 if (!VD && !CurContext->isDependentContext())
16599 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16600 Vars.push_back((VD || CurContext->isDependentContext())
16601 ? RefExpr->IgnoreParens()
16602 : Ref);
16603 }
16604
16605 if (Vars.empty())
16606 return nullptr;
16607
16608 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
16609 ColonLoc, EndLoc, Vars);
16610 }
16611