1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/CXXInheritance.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/DiagnosticSema.h"
27 #include "clang/Basic/OpenMPKinds.h"
28 #include "clang/Basic/PartialDiagnostic.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Sema/Initialization.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
34 #include "clang/Sema/SemaInternal.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/Frontend/OpenMP/OMPConstants.h"
39 #include <set>
40
41 using namespace clang;
42 using namespace llvm::omp;
43
44 //===----------------------------------------------------------------------===//
45 // Stack of data-sharing attributes for variables
46 //===----------------------------------------------------------------------===//
47
48 static const Expr *checkMapClauseExpressionBase(
49 Sema &SemaRef, Expr *E,
50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
51 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
52
53 namespace {
54 /// Default data sharing attributes, which can be applied to directive.
55 enum DefaultDataSharingAttributes {
56 DSA_unspecified = 0, /// Data sharing attribute not specified.
57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
60 };
61
62 /// Stack for tracking declarations used in OpenMP directives and
63 /// clauses and their data-sharing attributes.
64 class DSAStackTy {
65 public:
66 struct DSAVarData {
67 OpenMPDirectiveKind DKind = OMPD_unknown;
68 OpenMPClauseKind CKind = OMPC_unknown;
69 unsigned Modifier = 0;
70 const Expr *RefExpr = nullptr;
71 DeclRefExpr *PrivateCopy = nullptr;
72 SourceLocation ImplicitDSALoc;
73 bool AppliedToPointee = false;
74 DSAVarData() = default;
DSAVarData__anon0bb9e2bb0111::DSAStackTy::DSAVarData75 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
76 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
77 SourceLocation ImplicitDSALoc, unsigned Modifier,
78 bool AppliedToPointee)
79 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
80 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
81 AppliedToPointee(AppliedToPointee) {}
82 };
83 using OperatorOffsetTy =
84 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
85 using DoacrossDependMapTy =
86 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
87 /// Kind of the declaration used in the uses_allocators clauses.
88 enum class UsesAllocatorsDeclKind {
89 /// Predefined allocator
90 PredefinedAllocator,
91 /// User-defined allocator
92 UserDefinedAllocator,
93 /// The declaration that represent allocator trait
94 AllocatorTrait,
95 };
96
97 private:
98 struct DSAInfo {
99 OpenMPClauseKind Attributes = OMPC_unknown;
100 unsigned Modifier = 0;
101 /// Pointer to a reference expression and a flag which shows that the
102 /// variable is marked as lastprivate(true) or not (false).
103 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
104 DeclRefExpr *PrivateCopy = nullptr;
105 /// true if the attribute is applied to the pointee, not the variable
106 /// itself.
107 bool AppliedToPointee = false;
108 };
109 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
110 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
111 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
112 using LoopControlVariablesMapTy =
113 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
114 /// Struct that associates a component with the clause kind where they are
115 /// found.
116 struct MappedExprComponentTy {
117 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
118 OpenMPClauseKind Kind = OMPC_unknown;
119 };
120 using MappedExprComponentsTy =
121 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
122 using CriticalsWithHintsTy =
123 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
124 struct ReductionData {
125 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
126 SourceRange ReductionRange;
127 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
128 ReductionData() = default;
set__anon0bb9e2bb0111::DSAStackTy::ReductionData129 void set(BinaryOperatorKind BO, SourceRange RR) {
130 ReductionRange = RR;
131 ReductionOp = BO;
132 }
set__anon0bb9e2bb0111::DSAStackTy::ReductionData133 void set(const Expr *RefExpr, SourceRange RR) {
134 ReductionRange = RR;
135 ReductionOp = RefExpr;
136 }
137 };
138 using DeclReductionMapTy =
139 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
140 struct DefaultmapInfo {
141 OpenMPDefaultmapClauseModifier ImplicitBehavior =
142 OMPC_DEFAULTMAP_MODIFIER_unknown;
143 SourceLocation SLoc;
144 DefaultmapInfo() = default;
DefaultmapInfo__anon0bb9e2bb0111::DSAStackTy::DefaultmapInfo145 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
146 : ImplicitBehavior(M), SLoc(Loc) {}
147 };
148
149 struct SharingMapTy {
150 DeclSAMapTy SharingMap;
151 DeclReductionMapTy ReductionMap;
152 UsedRefMapTy AlignedMap;
153 UsedRefMapTy NontemporalMap;
154 MappedExprComponentsTy MappedExprComponents;
155 LoopControlVariablesMapTy LCVMap;
156 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
157 SourceLocation DefaultAttrLoc;
158 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
159 OpenMPDirectiveKind Directive = OMPD_unknown;
160 DeclarationNameInfo DirectiveName;
161 Scope *CurScope = nullptr;
162 DeclContext *Context = nullptr;
163 SourceLocation ConstructLoc;
164 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
165 /// get the data (loop counters etc.) about enclosing loop-based construct.
166 /// This data is required during codegen.
167 DoacrossDependMapTy DoacrossDepends;
168 /// First argument (Expr *) contains optional argument of the
169 /// 'ordered' clause, the second one is true if the regions has 'ordered'
170 /// clause, false otherwise.
171 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
172 unsigned AssociatedLoops = 1;
173 bool HasMutipleLoops = false;
174 const Decl *PossiblyLoopCounter = nullptr;
175 bool NowaitRegion = false;
176 bool CancelRegion = false;
177 bool LoopStart = false;
178 bool BodyComplete = false;
179 SourceLocation PrevScanLocation;
180 SourceLocation PrevOrderedLocation;
181 SourceLocation InnerTeamsRegionLoc;
182 /// Reference to the taskgroup task_reduction reference expression.
183 Expr *TaskgroupReductionRef = nullptr;
184 llvm::DenseSet<QualType> MappedClassesQualTypes;
185 SmallVector<Expr *, 4> InnerUsedAllocators;
186 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
187 /// List of globals marked as declare target link in this target region
188 /// (isOpenMPTargetExecutionDirective(Directive) == true).
189 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
190 /// List of decls used in inclusive/exclusive clauses of the scan directive.
191 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
192 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
193 UsesAllocatorsDecls;
194 Expr *DeclareMapperVar = nullptr;
SharingMapTy__anon0bb9e2bb0111::DSAStackTy::SharingMapTy195 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
196 Scope *CurScope, SourceLocation Loc)
197 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
198 ConstructLoc(Loc) {}
199 SharingMapTy() = default;
200 };
201
202 using StackTy = SmallVector<SharingMapTy, 4>;
203
204 /// Stack of used declaration and their data-sharing attributes.
205 DeclSAMapTy Threadprivates;
206 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
207 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
208 /// true, if check for DSA must be from parent directive, false, if
209 /// from current directive.
210 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
211 Sema &SemaRef;
212 bool ForceCapturing = false;
213 /// true if all the variables in the target executable directives must be
214 /// captured by reference.
215 bool ForceCaptureByReferenceInTargetExecutable = false;
216 CriticalsWithHintsTy Criticals;
217 unsigned IgnoredStackElements = 0;
218
219 /// Iterators over the stack iterate in order from innermost to outermost
220 /// directive.
221 using const_iterator = StackTy::const_reverse_iterator;
begin() const222 const_iterator begin() const {
223 return Stack.empty() ? const_iterator()
224 : Stack.back().first.rbegin() + IgnoredStackElements;
225 }
end() const226 const_iterator end() const {
227 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
228 }
229 using iterator = StackTy::reverse_iterator;
begin()230 iterator begin() {
231 return Stack.empty() ? iterator()
232 : Stack.back().first.rbegin() + IgnoredStackElements;
233 }
end()234 iterator end() {
235 return Stack.empty() ? iterator() : Stack.back().first.rend();
236 }
237
238 // Convenience operations to get at the elements of the stack.
239
isStackEmpty() const240 bool isStackEmpty() const {
241 return Stack.empty() ||
242 Stack.back().second != CurrentNonCapturingFunctionScope ||
243 Stack.back().first.size() <= IgnoredStackElements;
244 }
getStackSize() const245 size_t getStackSize() const {
246 return isStackEmpty() ? 0
247 : Stack.back().first.size() - IgnoredStackElements;
248 }
249
getTopOfStackOrNull()250 SharingMapTy *getTopOfStackOrNull() {
251 size_t Size = getStackSize();
252 if (Size == 0)
253 return nullptr;
254 return &Stack.back().first[Size - 1];
255 }
getTopOfStackOrNull() const256 const SharingMapTy *getTopOfStackOrNull() const {
257 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
258 }
getTopOfStack()259 SharingMapTy &getTopOfStack() {
260 assert(!isStackEmpty() && "no current directive");
261 return *getTopOfStackOrNull();
262 }
getTopOfStack() const263 const SharingMapTy &getTopOfStack() const {
264 return const_cast<DSAStackTy&>(*this).getTopOfStack();
265 }
266
getSecondOnStackOrNull()267 SharingMapTy *getSecondOnStackOrNull() {
268 size_t Size = getStackSize();
269 if (Size <= 1)
270 return nullptr;
271 return &Stack.back().first[Size - 2];
272 }
getSecondOnStackOrNull() const273 const SharingMapTy *getSecondOnStackOrNull() const {
274 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
275 }
276
277 /// Get the stack element at a certain level (previously returned by
278 /// \c getNestingLevel).
279 ///
280 /// Note that nesting levels count from outermost to innermost, and this is
281 /// the reverse of our iteration order where new inner levels are pushed at
282 /// the front of the stack.
getStackElemAtLevel(unsigned Level)283 SharingMapTy &getStackElemAtLevel(unsigned Level) {
284 assert(Level < getStackSize() && "no such stack element");
285 return Stack.back().first[Level];
286 }
getStackElemAtLevel(unsigned Level) const287 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
288 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
289 }
290
291 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
292
293 /// Checks if the variable is a local for OpenMP region.
294 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
295
296 /// Vector of previously declared requires directives
297 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
298 /// omp_allocator_handle_t type.
299 QualType OMPAllocatorHandleT;
300 /// omp_depend_t type.
301 QualType OMPDependT;
302 /// omp_event_handle_t type.
303 QualType OMPEventHandleT;
304 /// omp_alloctrait_t type.
305 QualType OMPAlloctraitT;
306 /// Expression for the predefined allocators.
307 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
308 nullptr};
309 /// Vector of previously encountered target directives
310 SmallVector<SourceLocation, 2> TargetLocations;
311 SourceLocation AtomicLocation;
312
313 public:
DSAStackTy(Sema & S)314 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
315
316 /// Sets omp_allocator_handle_t type.
setOMPAllocatorHandleT(QualType Ty)317 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
318 /// Gets omp_allocator_handle_t type.
getOMPAllocatorHandleT() const319 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
320 /// Sets omp_alloctrait_t type.
setOMPAlloctraitT(QualType Ty)321 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
322 /// Gets omp_alloctrait_t type.
getOMPAlloctraitT() const323 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
324 /// Sets the given default allocator.
setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)325 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
326 Expr *Allocator) {
327 OMPPredefinedAllocators[AllocatorKind] = Allocator;
328 }
329 /// Returns the specified default allocator.
getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const330 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
331 return OMPPredefinedAllocators[AllocatorKind];
332 }
333 /// Sets omp_depend_t type.
setOMPDependT(QualType Ty)334 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
335 /// Gets omp_depend_t type.
getOMPDependT() const336 QualType getOMPDependT() const { return OMPDependT; }
337
338 /// Sets omp_event_handle_t type.
setOMPEventHandleT(QualType Ty)339 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
340 /// Gets omp_event_handle_t type.
getOMPEventHandleT() const341 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
342
isClauseParsingMode() const343 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const344 OpenMPClauseKind getClauseParsingMode() const {
345 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
346 return ClauseKindMode;
347 }
setClauseParsingMode(OpenMPClauseKind K)348 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
349
isBodyComplete() const350 bool isBodyComplete() const {
351 const SharingMapTy *Top = getTopOfStackOrNull();
352 return Top && Top->BodyComplete;
353 }
setBodyComplete()354 void setBodyComplete() {
355 getTopOfStack().BodyComplete = true;
356 }
357
isForceVarCapturing() const358 bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)359 void setForceVarCapturing(bool V) { ForceCapturing = V; }
360
setForceCaptureByReferenceInTargetExecutable(bool V)361 void setForceCaptureByReferenceInTargetExecutable(bool V) {
362 ForceCaptureByReferenceInTargetExecutable = V;
363 }
isForceCaptureByReferenceInTargetExecutable() const364 bool isForceCaptureByReferenceInTargetExecutable() const {
365 return ForceCaptureByReferenceInTargetExecutable;
366 }
367
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)368 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
369 Scope *CurScope, SourceLocation Loc) {
370 assert(!IgnoredStackElements &&
371 "cannot change stack while ignoring elements");
372 if (Stack.empty() ||
373 Stack.back().second != CurrentNonCapturingFunctionScope)
374 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
375 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
376 Stack.back().first.back().DefaultAttrLoc = Loc;
377 }
378
pop()379 void pop() {
380 assert(!IgnoredStackElements &&
381 "cannot change stack while ignoring elements");
382 assert(!Stack.back().first.empty() &&
383 "Data-sharing attributes stack is empty!");
384 Stack.back().first.pop_back();
385 }
386
387 /// RAII object to temporarily leave the scope of a directive when we want to
388 /// logically operate in its parent.
389 class ParentDirectiveScope {
390 DSAStackTy &Self;
391 bool Active;
392 public:
ParentDirectiveScope(DSAStackTy & Self,bool Activate)393 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
394 : Self(Self), Active(false) {
395 if (Activate)
396 enable();
397 }
~ParentDirectiveScope()398 ~ParentDirectiveScope() { disable(); }
disable()399 void disable() {
400 if (Active) {
401 --Self.IgnoredStackElements;
402 Active = false;
403 }
404 }
enable()405 void enable() {
406 if (!Active) {
407 ++Self.IgnoredStackElements;
408 Active = true;
409 }
410 }
411 };
412
413 /// Marks that we're started loop parsing.
loopInit()414 void loopInit() {
415 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
416 "Expected loop-based directive.");
417 getTopOfStack().LoopStart = true;
418 }
419 /// Start capturing of the variables in the loop context.
loopStart()420 void loopStart() {
421 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
422 "Expected loop-based directive.");
423 getTopOfStack().LoopStart = false;
424 }
425 /// true, if variables are captured, false otherwise.
isLoopStarted() const426 bool isLoopStarted() const {
427 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
428 "Expected loop-based directive.");
429 return !getTopOfStack().LoopStart;
430 }
431 /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)432 void resetPossibleLoopCounter(const Decl *D = nullptr) {
433 getTopOfStack().PossiblyLoopCounter =
434 D ? D->getCanonicalDecl() : D;
435 }
436 /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const437 const Decl *getPossiblyLoopCunter() const {
438 return getTopOfStack().PossiblyLoopCounter;
439 }
440 /// Start new OpenMP region stack in new non-capturing function.
pushFunction()441 void pushFunction() {
442 assert(!IgnoredStackElements &&
443 "cannot change stack while ignoring elements");
444 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
445 assert(!isa<CapturingScopeInfo>(CurFnScope));
446 CurrentNonCapturingFunctionScope = CurFnScope;
447 }
448 /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)449 void popFunction(const FunctionScopeInfo *OldFSI) {
450 assert(!IgnoredStackElements &&
451 "cannot change stack while ignoring elements");
452 if (!Stack.empty() && Stack.back().second == OldFSI) {
453 assert(Stack.back().first.empty());
454 Stack.pop_back();
455 }
456 CurrentNonCapturingFunctionScope = nullptr;
457 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
458 if (!isa<CapturingScopeInfo>(FSI)) {
459 CurrentNonCapturingFunctionScope = FSI;
460 break;
461 }
462 }
463 }
464
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)465 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
466 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
467 }
468 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const469 getCriticalWithHint(const DeclarationNameInfo &Name) const {
470 auto I = Criticals.find(Name.getAsString());
471 if (I != Criticals.end())
472 return I->second;
473 return std::make_pair(nullptr, llvm::APSInt());
474 }
475 /// If 'aligned' declaration for given variable \a D was not seen yet,
476 /// add it and return NULL; otherwise return previous occurrence's expression
477 /// for diagnostics.
478 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
479 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
480 /// add it and return NULL; otherwise return previous occurrence's expression
481 /// for diagnostics.
482 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
483
484 /// Register specified variable as loop control variable.
485 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
486 /// Check if the specified variable is a loop control variable for
487 /// current region.
488 /// \return The index of the loop control variable in the list of associated
489 /// for-loops (from outer to inner).
490 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
491 /// Check if the specified variable is a loop control variable for
492 /// parent region.
493 /// \return The index of the loop control variable in the list of associated
494 /// for-loops (from outer to inner).
495 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
496 /// Check if the specified variable is a loop control variable for
497 /// current region.
498 /// \return The index of the loop control variable in the list of associated
499 /// for-loops (from outer to inner).
500 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
501 unsigned Level) const;
502 /// Get the loop control variable for the I-th loop (or nullptr) in
503 /// parent directive.
504 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
505
506 /// Marks the specified decl \p D as used in scan directive.
markDeclAsUsedInScanDirective(ValueDecl * D)507 void markDeclAsUsedInScanDirective(ValueDecl *D) {
508 if (SharingMapTy *Stack = getSecondOnStackOrNull())
509 Stack->UsedInScanDirective.insert(D);
510 }
511
512 /// Checks if the specified declaration was used in the inner scan directive.
isUsedInScanDirective(ValueDecl * D) const513 bool isUsedInScanDirective(ValueDecl *D) const {
514 if (const SharingMapTy *Stack = getTopOfStackOrNull())
515 return Stack->UsedInScanDirective.count(D) > 0;
516 return false;
517 }
518
519 /// Adds explicit data sharing attribute to the specified declaration.
520 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
521 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
522 bool AppliedToPointee = false);
523
524 /// Adds additional information for the reduction items with the reduction id
525 /// represented as an operator.
526 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
527 BinaryOperatorKind BOK);
528 /// Adds additional information for the reduction items with the reduction id
529 /// represented as reduction identifier.
530 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
531 const Expr *ReductionRef);
532 /// Returns the location and reduction operation from the innermost parent
533 /// region for the given \p D.
534 const DSAVarData
535 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
536 BinaryOperatorKind &BOK,
537 Expr *&TaskgroupDescriptor) const;
538 /// Returns the location and reduction operation from the innermost parent
539 /// region for the given \p D.
540 const DSAVarData
541 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
542 const Expr *&ReductionRef,
543 Expr *&TaskgroupDescriptor) const;
544 /// Return reduction reference expression for the current taskgroup or
545 /// parallel/worksharing directives with task reductions.
getTaskgroupReductionRef() const546 Expr *getTaskgroupReductionRef() const {
547 assert((getTopOfStack().Directive == OMPD_taskgroup ||
548 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
549 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
550 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
551 "taskgroup reference expression requested for non taskgroup or "
552 "parallel/worksharing directive.");
553 return getTopOfStack().TaskgroupReductionRef;
554 }
555 /// Checks if the given \p VD declaration is actually a taskgroup reduction
556 /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const557 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
558 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
559 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
560 ->getDecl() == VD;
561 }
562
563 /// Returns data sharing attributes from top of the stack for the
564 /// specified declaration.
565 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
566 /// Returns data-sharing attributes for the specified declaration.
567 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
568 /// Returns data-sharing attributes for the specified declaration.
569 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
570 /// Checks if the specified variables has data-sharing attributes which
571 /// match specified \a CPred predicate in any directive which matches \a DPred
572 /// predicate.
573 const DSAVarData
574 hasDSA(ValueDecl *D,
575 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
576 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
577 bool FromParent) const;
578 /// Checks if the specified variables has data-sharing attributes which
579 /// match specified \a CPred predicate in any innermost directive which
580 /// matches \a DPred predicate.
581 const DSAVarData
582 hasInnermostDSA(ValueDecl *D,
583 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
584 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
585 bool FromParent) const;
586 /// Checks if the specified variables has explicit data-sharing
587 /// attributes which match specified \a CPred predicate at the specified
588 /// OpenMP region.
589 bool
590 hasExplicitDSA(const ValueDecl *D,
591 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
592 unsigned Level, bool NotLastprivate = false) const;
593
594 /// Returns true if the directive at level \Level matches in the
595 /// specified \a DPred predicate.
596 bool hasExplicitDirective(
597 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
598 unsigned Level) const;
599
600 /// Finds a directive which matches specified \a DPred predicate.
601 bool hasDirective(
602 const llvm::function_ref<bool(
603 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
604 DPred,
605 bool FromParent) const;
606
607 /// Returns currently analyzed directive.
getCurrentDirective() const608 OpenMPDirectiveKind getCurrentDirective() const {
609 const SharingMapTy *Top = getTopOfStackOrNull();
610 return Top ? Top->Directive : OMPD_unknown;
611 }
612 /// Returns directive kind at specified level.
getDirective(unsigned Level) const613 OpenMPDirectiveKind getDirective(unsigned Level) const {
614 assert(!isStackEmpty() && "No directive at specified level.");
615 return getStackElemAtLevel(Level).Directive;
616 }
617 /// Returns the capture region at the specified level.
getCaptureRegion(unsigned Level,unsigned OpenMPCaptureLevel) const618 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
619 unsigned OpenMPCaptureLevel) const {
620 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
621 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
622 return CaptureRegions[OpenMPCaptureLevel];
623 }
624 /// Returns parent directive.
getParentDirective() const625 OpenMPDirectiveKind getParentDirective() const {
626 const SharingMapTy *Parent = getSecondOnStackOrNull();
627 return Parent ? Parent->Directive : OMPD_unknown;
628 }
629
630 /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)631 void addRequiresDecl(OMPRequiresDecl *RD) {
632 RequiresDecls.push_back(RD);
633 }
634
635 /// Checks if the defined 'requires' directive has specified type of clause.
636 template <typename ClauseType>
hasRequiresDeclWithClause() const637 bool hasRequiresDeclWithClause() const {
638 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
639 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
640 return isa<ClauseType>(C);
641 });
642 });
643 }
644
645 /// Checks for a duplicate clause amongst previously declared requires
646 /// directives
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const647 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
648 bool IsDuplicate = false;
649 for (OMPClause *CNew : ClauseList) {
650 for (const OMPRequiresDecl *D : RequiresDecls) {
651 for (const OMPClause *CPrev : D->clauselists()) {
652 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
653 SemaRef.Diag(CNew->getBeginLoc(),
654 diag::err_omp_requires_clause_redeclaration)
655 << getOpenMPClauseName(CNew->getClauseKind());
656 SemaRef.Diag(CPrev->getBeginLoc(),
657 diag::note_omp_requires_previous_clause)
658 << getOpenMPClauseName(CPrev->getClauseKind());
659 IsDuplicate = true;
660 }
661 }
662 }
663 }
664 return IsDuplicate;
665 }
666
667 /// Add location of previously encountered target to internal vector
addTargetDirLocation(SourceLocation LocStart)668 void addTargetDirLocation(SourceLocation LocStart) {
669 TargetLocations.push_back(LocStart);
670 }
671
672 /// Add location for the first encountered atomicc directive.
addAtomicDirectiveLoc(SourceLocation Loc)673 void addAtomicDirectiveLoc(SourceLocation Loc) {
674 if (AtomicLocation.isInvalid())
675 AtomicLocation = Loc;
676 }
677
678 /// Returns the location of the first encountered atomic directive in the
679 /// module.
getAtomicDirectiveLoc() const680 SourceLocation getAtomicDirectiveLoc() const {
681 return AtomicLocation;
682 }
683
684 // Return previously encountered target region locations.
getEncounteredTargetLocs() const685 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
686 return TargetLocations;
687 }
688
689 /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)690 void setDefaultDSANone(SourceLocation Loc) {
691 getTopOfStack().DefaultAttr = DSA_none;
692 getTopOfStack().DefaultAttrLoc = Loc;
693 }
694 /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)695 void setDefaultDSAShared(SourceLocation Loc) {
696 getTopOfStack().DefaultAttr = DSA_shared;
697 getTopOfStack().DefaultAttrLoc = Loc;
698 }
699 /// Set default data sharing attribute to firstprivate.
setDefaultDSAFirstPrivate(SourceLocation Loc)700 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
701 getTopOfStack().DefaultAttr = DSA_firstprivate;
702 getTopOfStack().DefaultAttrLoc = Loc;
703 }
704 /// Set default data mapping attribute to Modifier:Kind
setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation Loc)705 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
706 OpenMPDefaultmapClauseKind Kind,
707 SourceLocation Loc) {
708 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
709 DMI.ImplicitBehavior = M;
710 DMI.SLoc = Loc;
711 }
712 /// Check whether the implicit-behavior has been set in defaultmap
checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory)713 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
714 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
715 return getTopOfStack()
716 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
717 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
718 getTopOfStack()
719 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
720 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
721 getTopOfStack()
722 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
723 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
724 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
725 OMPC_DEFAULTMAP_MODIFIER_unknown;
726 }
727
getDefaultDSA(unsigned Level) const728 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
729 return getStackSize() <= Level ? DSA_unspecified
730 : getStackElemAtLevel(Level).DefaultAttr;
731 }
getDefaultDSA() const732 DefaultDataSharingAttributes getDefaultDSA() const {
733 return isStackEmpty() ? DSA_unspecified
734 : getTopOfStack().DefaultAttr;
735 }
getDefaultDSALocation() const736 SourceLocation getDefaultDSALocation() const {
737 return isStackEmpty() ? SourceLocation()
738 : getTopOfStack().DefaultAttrLoc;
739 }
740 OpenMPDefaultmapClauseModifier
getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const741 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
742 return isStackEmpty()
743 ? OMPC_DEFAULTMAP_MODIFIER_unknown
744 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
745 }
746 OpenMPDefaultmapClauseModifier
getDefaultmapModifierAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const747 getDefaultmapModifierAtLevel(unsigned Level,
748 OpenMPDefaultmapClauseKind Kind) const {
749 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
750 }
isDefaultmapCapturedByRef(unsigned Level,OpenMPDefaultmapClauseKind Kind) const751 bool isDefaultmapCapturedByRef(unsigned Level,
752 OpenMPDefaultmapClauseKind Kind) const {
753 OpenMPDefaultmapClauseModifier M =
754 getDefaultmapModifierAtLevel(Level, Kind);
755 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
756 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
757 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
760 }
761 return true;
762 }
mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind)763 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
764 OpenMPDefaultmapClauseKind Kind) {
765 switch (Kind) {
766 case OMPC_DEFAULTMAP_scalar:
767 case OMPC_DEFAULTMAP_pointer:
768 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
769 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
770 (M == OMPC_DEFAULTMAP_MODIFIER_default);
771 case OMPC_DEFAULTMAP_aggregate:
772 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
773 default:
774 break;
775 }
776 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
777 }
mustBeFirstprivateAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const778 bool mustBeFirstprivateAtLevel(unsigned Level,
779 OpenMPDefaultmapClauseKind Kind) const {
780 OpenMPDefaultmapClauseModifier M =
781 getDefaultmapModifierAtLevel(Level, Kind);
782 return mustBeFirstprivateBase(M, Kind);
783 }
mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const784 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
785 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
786 return mustBeFirstprivateBase(M, Kind);
787 }
788
789 /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)790 bool isThreadPrivate(VarDecl *D) {
791 const DSAVarData DVar = getTopDSA(D, false);
792 return isOpenMPThreadPrivate(DVar.CKind);
793 }
794
795 /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)796 void setOrderedRegion(bool IsOrdered, const Expr *Param,
797 OMPOrderedClause *Clause) {
798 if (IsOrdered)
799 getTopOfStack().OrderedRegion.emplace(Param, Clause);
800 else
801 getTopOfStack().OrderedRegion.reset();
802 }
803 /// Returns true, if region is ordered (has associated 'ordered' clause),
804 /// false - otherwise.
isOrderedRegion() const805 bool isOrderedRegion() const {
806 if (const SharingMapTy *Top = getTopOfStackOrNull())
807 return Top->OrderedRegion.hasValue();
808 return false;
809 }
810 /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const811 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
812 if (const SharingMapTy *Top = getTopOfStackOrNull())
813 if (Top->OrderedRegion.hasValue())
814 return Top->OrderedRegion.getValue();
815 return std::make_pair(nullptr, nullptr);
816 }
817 /// Returns true, if parent region is ordered (has associated
818 /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const819 bool isParentOrderedRegion() const {
820 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
821 return Parent->OrderedRegion.hasValue();
822 return false;
823 }
824 /// Returns optional parameter for the ordered region.
825 std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const826 getParentOrderedRegionParam() const {
827 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
828 if (Parent->OrderedRegion.hasValue())
829 return Parent->OrderedRegion.getValue();
830 return std::make_pair(nullptr, nullptr);
831 }
832 /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)833 void setNowaitRegion(bool IsNowait = true) {
834 getTopOfStack().NowaitRegion = IsNowait;
835 }
836 /// Returns true, if parent region is nowait (has associated
837 /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const838 bool isParentNowaitRegion() const {
839 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
840 return Parent->NowaitRegion;
841 return false;
842 }
843 /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)844 void setParentCancelRegion(bool Cancel = true) {
845 if (SharingMapTy *Parent = getSecondOnStackOrNull())
846 Parent->CancelRegion |= Cancel;
847 }
848 /// Return true if current region has inner cancel construct.
isCancelRegion() const849 bool isCancelRegion() const {
850 const SharingMapTy *Top = getTopOfStackOrNull();
851 return Top ? Top->CancelRegion : false;
852 }
853
854 /// Mark that parent region already has scan directive.
setParentHasScanDirective(SourceLocation Loc)855 void setParentHasScanDirective(SourceLocation Loc) {
856 if (SharingMapTy *Parent = getSecondOnStackOrNull())
857 Parent->PrevScanLocation = Loc;
858 }
859 /// Return true if current region has inner cancel construct.
doesParentHasScanDirective() const860 bool doesParentHasScanDirective() const {
861 const SharingMapTy *Top = getSecondOnStackOrNull();
862 return Top ? Top->PrevScanLocation.isValid() : false;
863 }
864 /// Return true if current region has inner cancel construct.
getParentScanDirectiveLoc() const865 SourceLocation getParentScanDirectiveLoc() const {
866 const SharingMapTy *Top = getSecondOnStackOrNull();
867 return Top ? Top->PrevScanLocation : SourceLocation();
868 }
869 /// Mark that parent region already has ordered directive.
setParentHasOrderedDirective(SourceLocation Loc)870 void setParentHasOrderedDirective(SourceLocation Loc) {
871 if (SharingMapTy *Parent = getSecondOnStackOrNull())
872 Parent->PrevOrderedLocation = Loc;
873 }
874 /// Return true if current region has inner ordered construct.
doesParentHasOrderedDirective() const875 bool doesParentHasOrderedDirective() const {
876 const SharingMapTy *Top = getSecondOnStackOrNull();
877 return Top ? Top->PrevOrderedLocation.isValid() : false;
878 }
879 /// Returns the location of the previously specified ordered directive.
getParentOrderedDirectiveLoc() const880 SourceLocation getParentOrderedDirectiveLoc() const {
881 const SharingMapTy *Top = getSecondOnStackOrNull();
882 return Top ? Top->PrevOrderedLocation : SourceLocation();
883 }
884
885 /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)886 void setAssociatedLoops(unsigned Val) {
887 getTopOfStack().AssociatedLoops = Val;
888 if (Val > 1)
889 getTopOfStack().HasMutipleLoops = true;
890 }
891 /// Return collapse value for region.
getAssociatedLoops() const892 unsigned getAssociatedLoops() const {
893 const SharingMapTy *Top = getTopOfStackOrNull();
894 return Top ? Top->AssociatedLoops : 0;
895 }
896 /// Returns true if the construct is associated with multiple loops.
hasMutipleLoops() const897 bool hasMutipleLoops() const {
898 const SharingMapTy *Top = getTopOfStackOrNull();
899 return Top ? Top->HasMutipleLoops : false;
900 }
901
902 /// Marks current target region as one with closely nested teams
903 /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)904 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
905 if (SharingMapTy *Parent = getSecondOnStackOrNull())
906 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
907 }
908 /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const909 bool hasInnerTeamsRegion() const {
910 return getInnerTeamsRegionLoc().isValid();
911 }
912 /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const913 SourceLocation getInnerTeamsRegionLoc() const {
914 const SharingMapTy *Top = getTopOfStackOrNull();
915 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
916 }
917
getCurScope() const918 Scope *getCurScope() const {
919 const SharingMapTy *Top = getTopOfStackOrNull();
920 return Top ? Top->CurScope : nullptr;
921 }
setContext(DeclContext * DC)922 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
getConstructLoc() const923 SourceLocation getConstructLoc() const {
924 const SharingMapTy *Top = getTopOfStackOrNull();
925 return Top ? Top->ConstructLoc : SourceLocation();
926 }
927
928 /// Do the check specified in \a Check to all component lists and return true
929 /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const930 bool checkMappableExprComponentListsForDecl(
931 const ValueDecl *VD, bool CurrentRegionOnly,
932 const llvm::function_ref<
933 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
934 OpenMPClauseKind)>
935 Check) const {
936 if (isStackEmpty())
937 return false;
938 auto SI = begin();
939 auto SE = end();
940
941 if (SI == SE)
942 return false;
943
944 if (CurrentRegionOnly)
945 SE = std::next(SI);
946 else
947 std::advance(SI, 1);
948
949 for (; SI != SE; ++SI) {
950 auto MI = SI->MappedExprComponents.find(VD);
951 if (MI != SI->MappedExprComponents.end())
952 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
953 MI->second.Components)
954 if (Check(L, MI->second.Kind))
955 return true;
956 }
957 return false;
958 }
959
960 /// Do the check specified in \a Check to all component lists at a given level
961 /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const962 bool checkMappableExprComponentListsForDeclAtLevel(
963 const ValueDecl *VD, unsigned Level,
964 const llvm::function_ref<
965 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
966 OpenMPClauseKind)>
967 Check) const {
968 if (getStackSize() <= Level)
969 return false;
970
971 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
972 auto MI = StackElem.MappedExprComponents.find(VD);
973 if (MI != StackElem.MappedExprComponents.end())
974 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
975 MI->second.Components)
976 if (Check(L, MI->second.Kind))
977 return true;
978 return false;
979 }
980
981 /// Create a new mappable expression component list associated with a given
982 /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)983 void addMappableExpressionComponents(
984 const ValueDecl *VD,
985 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
986 OpenMPClauseKind WhereFoundClauseKind) {
987 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
988 // Create new entry and append the new components there.
989 MEC.Components.resize(MEC.Components.size() + 1);
990 MEC.Components.back().append(Components.begin(), Components.end());
991 MEC.Kind = WhereFoundClauseKind;
992 }
993
getNestingLevel() const994 unsigned getNestingLevel() const {
995 assert(!isStackEmpty());
996 return getStackSize() - 1;
997 }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)998 void addDoacrossDependClause(OMPDependClause *C,
999 const OperatorOffsetTy &OpsOffs) {
1000 SharingMapTy *Parent = getSecondOnStackOrNull();
1001 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1002 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1003 }
1004 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const1005 getDoacrossDependClauses() const {
1006 const SharingMapTy &StackElem = getTopOfStack();
1007 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1008 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1009 return llvm::make_range(Ref.begin(), Ref.end());
1010 }
1011 return llvm::make_range(StackElem.DoacrossDepends.end(),
1012 StackElem.DoacrossDepends.end());
1013 }
1014
1015 // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)1016 void addMappedClassesQualTypes(QualType QT) {
1017 SharingMapTy &StackElem = getTopOfStack();
1018 StackElem.MappedClassesQualTypes.insert(QT);
1019 }
1020
1021 // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const1022 bool isClassPreviouslyMapped(QualType QT) const {
1023 const SharingMapTy &StackElem = getTopOfStack();
1024 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1025 }
1026
1027 /// Adds global declare target to the parent target region.
addToParentTargetRegionLinkGlobals(DeclRefExpr * E)1028 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1029 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1030 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1031 "Expected declare target link global.");
1032 for (auto &Elem : *this) {
1033 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1034 Elem.DeclareTargetLinkVarDecls.push_back(E);
1035 return;
1036 }
1037 }
1038 }
1039
1040 /// Returns the list of globals with declare target link if current directive
1041 /// is target.
getLinkGlobals() const1042 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1043 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1044 "Expected target executable directive.");
1045 return getTopOfStack().DeclareTargetLinkVarDecls;
1046 }
1047
1048 /// Adds list of allocators expressions.
addInnerAllocatorExpr(Expr * E)1049 void addInnerAllocatorExpr(Expr *E) {
1050 getTopOfStack().InnerUsedAllocators.push_back(E);
1051 }
1052 /// Return list of used allocators.
getInnerAllocators() const1053 ArrayRef<Expr *> getInnerAllocators() const {
1054 return getTopOfStack().InnerUsedAllocators;
1055 }
1056 /// Marks the declaration as implicitly firstprivate nin the task-based
1057 /// regions.
addImplicitTaskFirstprivate(unsigned Level,Decl * D)1058 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1059 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1060 }
1061 /// Checks if the decl is implicitly firstprivate in the task-based region.
isImplicitTaskFirstprivate(Decl * D) const1062 bool isImplicitTaskFirstprivate(Decl *D) const {
1063 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1064 }
1065
1066 /// Marks decl as used in uses_allocators clause as the allocator.
addUsesAllocatorsDecl(const Decl * D,UsesAllocatorsDeclKind Kind)1067 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1068 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1069 }
1070 /// Checks if specified decl is used in uses allocator clause as the
1071 /// allocator.
isUsesAllocatorsDecl(unsigned Level,const Decl * D) const1072 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1073 const Decl *D) const {
1074 const SharingMapTy &StackElem = getTopOfStack();
1075 auto I = StackElem.UsesAllocatorsDecls.find(D);
1076 if (I == StackElem.UsesAllocatorsDecls.end())
1077 return None;
1078 return I->getSecond();
1079 }
isUsesAllocatorsDecl(const Decl * D) const1080 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1081 const SharingMapTy &StackElem = getTopOfStack();
1082 auto I = StackElem.UsesAllocatorsDecls.find(D);
1083 if (I == StackElem.UsesAllocatorsDecls.end())
1084 return None;
1085 return I->getSecond();
1086 }
1087
addDeclareMapperVarRef(Expr * Ref)1088 void addDeclareMapperVarRef(Expr *Ref) {
1089 SharingMapTy &StackElem = getTopOfStack();
1090 StackElem.DeclareMapperVar = Ref;
1091 }
getDeclareMapperVarRef() const1092 const Expr *getDeclareMapperVarRef() const {
1093 const SharingMapTy *Top = getTopOfStackOrNull();
1094 return Top ? Top->DeclareMapperVar : nullptr;
1095 }
1096 };
1097
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)1098 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1099 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1100 }
1101
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)1102 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1103 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1104 DKind == OMPD_unknown;
1105 }
1106
1107 } // namespace
1108
getExprAsWritten(const Expr * E)1109 static const Expr *getExprAsWritten(const Expr *E) {
1110 if (const auto *FE = dyn_cast<FullExpr>(E))
1111 E = FE->getSubExpr();
1112
1113 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1114 E = MTE->getSubExpr();
1115
1116 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1117 E = Binder->getSubExpr();
1118
1119 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1120 E = ICE->getSubExprAsWritten();
1121 return E->IgnoreParens();
1122 }
1123
getExprAsWritten(Expr * E)1124 static Expr *getExprAsWritten(Expr *E) {
1125 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1126 }
1127
getCanonicalDecl(const ValueDecl * D)1128 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1129 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1130 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1131 D = ME->getMemberDecl();
1132 const auto *VD = dyn_cast<VarDecl>(D);
1133 const auto *FD = dyn_cast<FieldDecl>(D);
1134 if (VD != nullptr) {
1135 VD = VD->getCanonicalDecl();
1136 D = VD;
1137 } else {
1138 assert(FD);
1139 FD = FD->getCanonicalDecl();
1140 D = FD;
1141 }
1142 return D;
1143 }
1144
getCanonicalDecl(ValueDecl * D)1145 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1146 return const_cast<ValueDecl *>(
1147 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1148 }
1149
getDSA(const_iterator & Iter,ValueDecl * D) const1150 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1151 ValueDecl *D) const {
1152 D = getCanonicalDecl(D);
1153 auto *VD = dyn_cast<VarDecl>(D);
1154 const auto *FD = dyn_cast<FieldDecl>(D);
1155 DSAVarData DVar;
1156 if (Iter == end()) {
1157 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1158 // in a region but not in construct]
1159 // File-scope or namespace-scope variables referenced in called routines
1160 // in the region are shared unless they appear in a threadprivate
1161 // directive.
1162 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1163 DVar.CKind = OMPC_shared;
1164
1165 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1166 // in a region but not in construct]
1167 // Variables with static storage duration that are declared in called
1168 // routines in the region are shared.
1169 if (VD && VD->hasGlobalStorage())
1170 DVar.CKind = OMPC_shared;
1171
1172 // Non-static data members are shared by default.
1173 if (FD)
1174 DVar.CKind = OMPC_shared;
1175
1176 return DVar;
1177 }
1178
1179 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1180 // in a Construct, C/C++, predetermined, p.1]
1181 // Variables with automatic storage duration that are declared in a scope
1182 // inside the construct are private.
1183 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1184 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1185 DVar.CKind = OMPC_private;
1186 return DVar;
1187 }
1188
1189 DVar.DKind = Iter->Directive;
1190 // Explicitly specified attributes and local variables with predetermined
1191 // attributes.
1192 if (Iter->SharingMap.count(D)) {
1193 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1194 DVar.RefExpr = Data.RefExpr.getPointer();
1195 DVar.PrivateCopy = Data.PrivateCopy;
1196 DVar.CKind = Data.Attributes;
1197 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1198 DVar.Modifier = Data.Modifier;
1199 DVar.AppliedToPointee = Data.AppliedToPointee;
1200 return DVar;
1201 }
1202
1203 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1204 // in a Construct, C/C++, implicitly determined, p.1]
1205 // In a parallel or task construct, the data-sharing attributes of these
1206 // variables are determined by the default clause, if present.
1207 switch (Iter->DefaultAttr) {
1208 case DSA_shared:
1209 DVar.CKind = OMPC_shared;
1210 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1211 return DVar;
1212 case DSA_none:
1213 return DVar;
1214 case DSA_firstprivate:
1215 if (VD->getStorageDuration() == SD_Static &&
1216 VD->getDeclContext()->isFileContext()) {
1217 DVar.CKind = OMPC_unknown;
1218 } else {
1219 DVar.CKind = OMPC_firstprivate;
1220 }
1221 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1222 return DVar;
1223 case DSA_unspecified:
1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1225 // in a Construct, implicitly determined, p.2]
1226 // In a parallel construct, if no default clause is present, these
1227 // variables are shared.
1228 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1229 if ((isOpenMPParallelDirective(DVar.DKind) &&
1230 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1231 isOpenMPTeamsDirective(DVar.DKind)) {
1232 DVar.CKind = OMPC_shared;
1233 return DVar;
1234 }
1235
1236 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1237 // in a Construct, implicitly determined, p.4]
1238 // In a task construct, if no default clause is present, a variable that in
1239 // the enclosing context is determined to be shared by all implicit tasks
1240 // bound to the current team is shared.
1241 if (isOpenMPTaskingDirective(DVar.DKind)) {
1242 DSAVarData DVarTemp;
1243 const_iterator I = Iter, E = end();
1244 do {
1245 ++I;
1246 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1247 // Referenced in a Construct, implicitly determined, p.6]
1248 // In a task construct, if no default clause is present, a variable
1249 // whose data-sharing attribute is not determined by the rules above is
1250 // firstprivate.
1251 DVarTemp = getDSA(I, D);
1252 if (DVarTemp.CKind != OMPC_shared) {
1253 DVar.RefExpr = nullptr;
1254 DVar.CKind = OMPC_firstprivate;
1255 return DVar;
1256 }
1257 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1258 DVar.CKind =
1259 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1260 return DVar;
1261 }
1262 }
1263 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1264 // in a Construct, implicitly determined, p.3]
1265 // For constructs other than task, if no default clause is present, these
1266 // variables inherit their data-sharing attributes from the enclosing
1267 // context.
1268 return getDSA(++Iter, D);
1269 }
1270
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)1271 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1272 const Expr *NewDE) {
1273 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1274 D = getCanonicalDecl(D);
1275 SharingMapTy &StackElem = getTopOfStack();
1276 auto It = StackElem.AlignedMap.find(D);
1277 if (It == StackElem.AlignedMap.end()) {
1278 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1279 StackElem.AlignedMap[D] = NewDE;
1280 return nullptr;
1281 }
1282 assert(It->second && "Unexpected nullptr expr in the aligned map");
1283 return It->second;
1284 }
1285
addUniqueNontemporal(const ValueDecl * D,const Expr * NewDE)1286 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1287 const Expr *NewDE) {
1288 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1289 D = getCanonicalDecl(D);
1290 SharingMapTy &StackElem = getTopOfStack();
1291 auto It = StackElem.NontemporalMap.find(D);
1292 if (It == StackElem.NontemporalMap.end()) {
1293 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1294 StackElem.NontemporalMap[D] = NewDE;
1295 return nullptr;
1296 }
1297 assert(It->second && "Unexpected nullptr expr in the aligned map");
1298 return It->second;
1299 }
1300
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)1301 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1302 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1303 D = getCanonicalDecl(D);
1304 SharingMapTy &StackElem = getTopOfStack();
1305 StackElem.LCVMap.try_emplace(
1306 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1307 }
1308
1309 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const1310 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1311 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1312 D = getCanonicalDecl(D);
1313 const SharingMapTy &StackElem = getTopOfStack();
1314 auto It = StackElem.LCVMap.find(D);
1315 if (It != StackElem.LCVMap.end())
1316 return It->second;
1317 return {0, nullptr};
1318 }
1319
1320 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D,unsigned Level) const1321 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1322 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1323 D = getCanonicalDecl(D);
1324 for (unsigned I = Level + 1; I > 0; --I) {
1325 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1326 auto It = StackElem.LCVMap.find(D);
1327 if (It != StackElem.LCVMap.end())
1328 return It->second;
1329 }
1330 return {0, nullptr};
1331 }
1332
1333 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const1334 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1335 const SharingMapTy *Parent = getSecondOnStackOrNull();
1336 assert(Parent && "Data-sharing attributes stack is empty");
1337 D = getCanonicalDecl(D);
1338 auto It = Parent->LCVMap.find(D);
1339 if (It != Parent->LCVMap.end())
1340 return It->second;
1341 return {0, nullptr};
1342 }
1343
getParentLoopControlVariable(unsigned I) const1344 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1345 const SharingMapTy *Parent = getSecondOnStackOrNull();
1346 assert(Parent && "Data-sharing attributes stack is empty");
1347 if (Parent->LCVMap.size() < I)
1348 return nullptr;
1349 for (const auto &Pair : Parent->LCVMap)
1350 if (Pair.second.first == I)
1351 return Pair.first;
1352 return nullptr;
1353 }
1354
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy,unsigned Modifier,bool AppliedToPointee)1355 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1356 DeclRefExpr *PrivateCopy, unsigned Modifier,
1357 bool AppliedToPointee) {
1358 D = getCanonicalDecl(D);
1359 if (A == OMPC_threadprivate) {
1360 DSAInfo &Data = Threadprivates[D];
1361 Data.Attributes = A;
1362 Data.RefExpr.setPointer(E);
1363 Data.PrivateCopy = nullptr;
1364 Data.Modifier = Modifier;
1365 } else {
1366 DSAInfo &Data = getTopOfStack().SharingMap[D];
1367 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1368 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1369 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1370 (isLoopControlVariable(D).first && A == OMPC_private));
1371 Data.Modifier = Modifier;
1372 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1373 Data.RefExpr.setInt(/*IntVal=*/true);
1374 return;
1375 }
1376 const bool IsLastprivate =
1377 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1378 Data.Attributes = A;
1379 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1380 Data.PrivateCopy = PrivateCopy;
1381 Data.AppliedToPointee = AppliedToPointee;
1382 if (PrivateCopy) {
1383 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1384 Data.Modifier = Modifier;
1385 Data.Attributes = A;
1386 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1387 Data.PrivateCopy = nullptr;
1388 Data.AppliedToPointee = AppliedToPointee;
1389 }
1390 }
1391 }
1392
1393 /// Build a variable declaration for OpenMP loop iteration variable.
buildVarDecl(Sema & SemaRef,SourceLocation Loc,QualType Type,StringRef Name,const AttrVec * Attrs=nullptr,DeclRefExpr * OrigRef=nullptr)1394 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1395 StringRef Name, const AttrVec *Attrs = nullptr,
1396 DeclRefExpr *OrigRef = nullptr) {
1397 DeclContext *DC = SemaRef.CurContext;
1398 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1399 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1400 auto *Decl =
1401 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1402 if (Attrs) {
1403 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1404 I != E; ++I)
1405 Decl->addAttr(*I);
1406 }
1407 Decl->setImplicit();
1408 if (OrigRef) {
1409 Decl->addAttr(
1410 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1411 }
1412 return Decl;
1413 }
1414
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)1415 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1416 SourceLocation Loc,
1417 bool RefersToCapture = false) {
1418 D->setReferenced();
1419 D->markUsed(S.Context);
1420 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1421 SourceLocation(), D, RefersToCapture, Loc, Ty,
1422 VK_LValue);
1423 }
1424
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)1425 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1426 BinaryOperatorKind BOK) {
1427 D = getCanonicalDecl(D);
1428 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1429 assert(
1430 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1431 "Additional reduction info may be specified only for reduction items.");
1432 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1433 assert(ReductionData.ReductionRange.isInvalid() &&
1434 (getTopOfStack().Directive == OMPD_taskgroup ||
1435 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1436 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1437 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1438 "Additional reduction info may be specified only once for reduction "
1439 "items.");
1440 ReductionData.set(BOK, SR);
1441 Expr *&TaskgroupReductionRef =
1442 getTopOfStack().TaskgroupReductionRef;
1443 if (!TaskgroupReductionRef) {
1444 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1445 SemaRef.Context.VoidPtrTy, ".task_red.");
1446 TaskgroupReductionRef =
1447 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1448 }
1449 }
1450
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)1451 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1452 const Expr *ReductionRef) {
1453 D = getCanonicalDecl(D);
1454 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1455 assert(
1456 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1457 "Additional reduction info may be specified only for reduction items.");
1458 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1459 assert(ReductionData.ReductionRange.isInvalid() &&
1460 (getTopOfStack().Directive == OMPD_taskgroup ||
1461 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1462 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1463 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1464 "Additional reduction info may be specified only once for reduction "
1465 "items.");
1466 ReductionData.set(ReductionRef, SR);
1467 Expr *&TaskgroupReductionRef =
1468 getTopOfStack().TaskgroupReductionRef;
1469 if (!TaskgroupReductionRef) {
1470 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1471 SemaRef.Context.VoidPtrTy, ".task_red.");
1472 TaskgroupReductionRef =
1473 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1474 }
1475 }
1476
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1477 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1478 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1479 Expr *&TaskgroupDescriptor) const {
1480 D = getCanonicalDecl(D);
1481 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1482 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1483 const DSAInfo &Data = I->SharingMap.lookup(D);
1484 if (Data.Attributes != OMPC_reduction ||
1485 Data.Modifier != OMPC_REDUCTION_task)
1486 continue;
1487 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1488 if (!ReductionData.ReductionOp ||
1489 ReductionData.ReductionOp.is<const Expr *>())
1490 return DSAVarData();
1491 SR = ReductionData.ReductionRange;
1492 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1493 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1494 "expression for the descriptor is not "
1495 "set.");
1496 TaskgroupDescriptor = I->TaskgroupReductionRef;
1497 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1498 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1499 /*AppliedToPointee=*/false);
1500 }
1501 return DSAVarData();
1502 }
1503
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1504 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1505 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1506 Expr *&TaskgroupDescriptor) const {
1507 D = getCanonicalDecl(D);
1508 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1509 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1510 const DSAInfo &Data = I->SharingMap.lookup(D);
1511 if (Data.Attributes != OMPC_reduction ||
1512 Data.Modifier != OMPC_REDUCTION_task)
1513 continue;
1514 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1515 if (!ReductionData.ReductionOp ||
1516 !ReductionData.ReductionOp.is<const Expr *>())
1517 return DSAVarData();
1518 SR = ReductionData.ReductionRange;
1519 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1520 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1521 "expression for the descriptor is not "
1522 "set.");
1523 TaskgroupDescriptor = I->TaskgroupReductionRef;
1524 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1525 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1526 /*AppliedToPointee=*/false);
1527 }
1528 return DSAVarData();
1529 }
1530
isOpenMPLocal(VarDecl * D,const_iterator I) const1531 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1532 D = D->getCanonicalDecl();
1533 for (const_iterator E = end(); I != E; ++I) {
1534 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1535 isOpenMPTargetExecutionDirective(I->Directive)) {
1536 if (I->CurScope) {
1537 Scope *TopScope = I->CurScope->getParent();
1538 Scope *CurScope = getCurScope();
1539 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1540 CurScope = CurScope->getParent();
1541 return CurScope != TopScope;
1542 }
1543 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1544 if (I->Context == DC)
1545 return true;
1546 return false;
1547 }
1548 }
1549 return false;
1550 }
1551
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1552 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1553 bool AcceptIfMutable = true,
1554 bool *IsClassType = nullptr) {
1555 ASTContext &Context = SemaRef.getASTContext();
1556 Type = Type.getNonReferenceType().getCanonicalType();
1557 bool IsConstant = Type.isConstant(Context);
1558 Type = Context.getBaseElementType(Type);
1559 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1560 ? Type->getAsCXXRecordDecl()
1561 : nullptr;
1562 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1563 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1564 RD = CTD->getTemplatedDecl();
1565 if (IsClassType)
1566 *IsClassType = RD;
1567 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1568 RD->hasDefinition() && RD->hasMutableFields());
1569 }
1570
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1571 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1572 QualType Type, OpenMPClauseKind CKind,
1573 SourceLocation ELoc,
1574 bool AcceptIfMutable = true,
1575 bool ListItemNotVar = false) {
1576 ASTContext &Context = SemaRef.getASTContext();
1577 bool IsClassType;
1578 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1579 unsigned Diag = ListItemNotVar
1580 ? diag::err_omp_const_list_item
1581 : IsClassType ? diag::err_omp_const_not_mutable_variable
1582 : diag::err_omp_const_variable;
1583 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1584 if (!ListItemNotVar && D) {
1585 const VarDecl *VD = dyn_cast<VarDecl>(D);
1586 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1587 VarDecl::DeclarationOnly;
1588 SemaRef.Diag(D->getLocation(),
1589 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1590 << D;
1591 }
1592 return true;
1593 }
1594 return false;
1595 }
1596
getTopDSA(ValueDecl * D,bool FromParent)1597 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1598 bool FromParent) {
1599 D = getCanonicalDecl(D);
1600 DSAVarData DVar;
1601
1602 auto *VD = dyn_cast<VarDecl>(D);
1603 auto TI = Threadprivates.find(D);
1604 if (TI != Threadprivates.end()) {
1605 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1606 DVar.CKind = OMPC_threadprivate;
1607 DVar.Modifier = TI->getSecond().Modifier;
1608 return DVar;
1609 }
1610 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1611 DVar.RefExpr = buildDeclRefExpr(
1612 SemaRef, VD, D->getType().getNonReferenceType(),
1613 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1614 DVar.CKind = OMPC_threadprivate;
1615 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1616 return DVar;
1617 }
1618 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1619 // in a Construct, C/C++, predetermined, p.1]
1620 // Variables appearing in threadprivate directives are threadprivate.
1621 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1622 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1623 SemaRef.getLangOpts().OpenMPUseTLS &&
1624 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1625 (VD && VD->getStorageClass() == SC_Register &&
1626 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1627 DVar.RefExpr = buildDeclRefExpr(
1628 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1629 DVar.CKind = OMPC_threadprivate;
1630 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1631 return DVar;
1632 }
1633 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1634 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1635 !isLoopControlVariable(D).first) {
1636 const_iterator IterTarget =
1637 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1638 return isOpenMPTargetExecutionDirective(Data.Directive);
1639 });
1640 if (IterTarget != end()) {
1641 const_iterator ParentIterTarget = IterTarget + 1;
1642 for (const_iterator Iter = begin();
1643 Iter != ParentIterTarget; ++Iter) {
1644 if (isOpenMPLocal(VD, Iter)) {
1645 DVar.RefExpr =
1646 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1647 D->getLocation());
1648 DVar.CKind = OMPC_threadprivate;
1649 return DVar;
1650 }
1651 }
1652 if (!isClauseParsingMode() || IterTarget != begin()) {
1653 auto DSAIter = IterTarget->SharingMap.find(D);
1654 if (DSAIter != IterTarget->SharingMap.end() &&
1655 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1656 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1657 DVar.CKind = OMPC_threadprivate;
1658 return DVar;
1659 }
1660 const_iterator End = end();
1661 if (!SemaRef.isOpenMPCapturedByRef(
1662 D, std::distance(ParentIterTarget, End),
1663 /*OpenMPCaptureLevel=*/0)) {
1664 DVar.RefExpr =
1665 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1666 IterTarget->ConstructLoc);
1667 DVar.CKind = OMPC_threadprivate;
1668 return DVar;
1669 }
1670 }
1671 }
1672 }
1673
1674 if (isStackEmpty())
1675 // Not in OpenMP execution region and top scope was already checked.
1676 return DVar;
1677
1678 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1679 // in a Construct, C/C++, predetermined, p.4]
1680 // Static data members are shared.
1681 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1682 // in a Construct, C/C++, predetermined, p.7]
1683 // Variables with static storage duration that are declared in a scope
1684 // inside the construct are shared.
1685 if (VD && VD->isStaticDataMember()) {
1686 // Check for explicitly specified attributes.
1687 const_iterator I = begin();
1688 const_iterator EndI = end();
1689 if (FromParent && I != EndI)
1690 ++I;
1691 if (I != EndI) {
1692 auto It = I->SharingMap.find(D);
1693 if (It != I->SharingMap.end()) {
1694 const DSAInfo &Data = It->getSecond();
1695 DVar.RefExpr = Data.RefExpr.getPointer();
1696 DVar.PrivateCopy = Data.PrivateCopy;
1697 DVar.CKind = Data.Attributes;
1698 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1699 DVar.DKind = I->Directive;
1700 DVar.Modifier = Data.Modifier;
1701 DVar.AppliedToPointee = Data.AppliedToPointee;
1702 return DVar;
1703 }
1704 }
1705
1706 DVar.CKind = OMPC_shared;
1707 return DVar;
1708 }
1709
1710 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1711 // The predetermined shared attribute for const-qualified types having no
1712 // mutable members was removed after OpenMP 3.1.
1713 if (SemaRef.LangOpts.OpenMP <= 31) {
1714 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1715 // in a Construct, C/C++, predetermined, p.6]
1716 // Variables with const qualified type having no mutable member are
1717 // shared.
1718 if (isConstNotMutableType(SemaRef, D->getType())) {
1719 // Variables with const-qualified type having no mutable member may be
1720 // listed in a firstprivate clause, even if they are static data members.
1721 DSAVarData DVarTemp = hasInnermostDSA(
1722 D,
1723 [](OpenMPClauseKind C, bool) {
1724 return C == OMPC_firstprivate || C == OMPC_shared;
1725 },
1726 MatchesAlways, FromParent);
1727 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1728 return DVarTemp;
1729
1730 DVar.CKind = OMPC_shared;
1731 return DVar;
1732 }
1733 }
1734
1735 // Explicitly specified attributes and local variables with predetermined
1736 // attributes.
1737 const_iterator I = begin();
1738 const_iterator EndI = end();
1739 if (FromParent && I != EndI)
1740 ++I;
1741 if (I == EndI)
1742 return DVar;
1743 auto It = I->SharingMap.find(D);
1744 if (It != I->SharingMap.end()) {
1745 const DSAInfo &Data = It->getSecond();
1746 DVar.RefExpr = Data.RefExpr.getPointer();
1747 DVar.PrivateCopy = Data.PrivateCopy;
1748 DVar.CKind = Data.Attributes;
1749 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1750 DVar.DKind = I->Directive;
1751 DVar.Modifier = Data.Modifier;
1752 DVar.AppliedToPointee = Data.AppliedToPointee;
1753 }
1754
1755 return DVar;
1756 }
1757
getImplicitDSA(ValueDecl * D,bool FromParent) const1758 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1759 bool FromParent) const {
1760 if (isStackEmpty()) {
1761 const_iterator I;
1762 return getDSA(I, D);
1763 }
1764 D = getCanonicalDecl(D);
1765 const_iterator StartI = begin();
1766 const_iterator EndI = end();
1767 if (FromParent && StartI != EndI)
1768 ++StartI;
1769 return getDSA(StartI, D);
1770 }
1771
getImplicitDSA(ValueDecl * D,unsigned Level) const1772 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1773 unsigned Level) const {
1774 if (getStackSize() <= Level)
1775 return DSAVarData();
1776 D = getCanonicalDecl(D);
1777 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1778 return getDSA(StartI, D);
1779 }
1780
1781 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1782 DSAStackTy::hasDSA(ValueDecl *D,
1783 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1784 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1785 bool FromParent) const {
1786 if (isStackEmpty())
1787 return {};
1788 D = getCanonicalDecl(D);
1789 const_iterator I = begin();
1790 const_iterator EndI = end();
1791 if (FromParent && I != EndI)
1792 ++I;
1793 for (; I != EndI; ++I) {
1794 if (!DPred(I->Directive) &&
1795 !isImplicitOrExplicitTaskingRegion(I->Directive))
1796 continue;
1797 const_iterator NewI = I;
1798 DSAVarData DVar = getDSA(NewI, D);
1799 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1800 return DVar;
1801 }
1802 return {};
1803 }
1804
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1805 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1806 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1807 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1808 bool FromParent) const {
1809 if (isStackEmpty())
1810 return {};
1811 D = getCanonicalDecl(D);
1812 const_iterator StartI = begin();
1813 const_iterator EndI = end();
1814 if (FromParent && StartI != EndI)
1815 ++StartI;
1816 if (StartI == EndI || !DPred(StartI->Directive))
1817 return {};
1818 const_iterator NewI = StartI;
1819 DSAVarData DVar = getDSA(NewI, D);
1820 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1821 ? DVar
1822 : DSAVarData();
1823 }
1824
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,unsigned Level,bool NotLastprivate) const1825 bool DSAStackTy::hasExplicitDSA(
1826 const ValueDecl *D,
1827 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1828 unsigned Level, bool NotLastprivate) const {
1829 if (getStackSize() <= Level)
1830 return false;
1831 D = getCanonicalDecl(D);
1832 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1833 auto I = StackElem.SharingMap.find(D);
1834 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1835 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1836 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1837 return true;
1838 // Check predetermined rules for the loop control variables.
1839 auto LI = StackElem.LCVMap.find(D);
1840 if (LI != StackElem.LCVMap.end())
1841 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1842 return false;
1843 }
1844
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1845 bool DSAStackTy::hasExplicitDirective(
1846 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1847 unsigned Level) const {
1848 if (getStackSize() <= Level)
1849 return false;
1850 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1851 return DPred(StackElem.Directive);
1852 }
1853
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1854 bool DSAStackTy::hasDirective(
1855 const llvm::function_ref<bool(OpenMPDirectiveKind,
1856 const DeclarationNameInfo &, SourceLocation)>
1857 DPred,
1858 bool FromParent) const {
1859 // We look only in the enclosing region.
1860 size_t Skip = FromParent ? 2 : 1;
1861 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1862 I != E; ++I) {
1863 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1864 return true;
1865 }
1866 return false;
1867 }
1868
InitDataSharingAttributesStack()1869 void Sema::InitDataSharingAttributesStack() {
1870 VarDataSharingAttributesStack = new DSAStackTy(*this);
1871 }
1872
1873 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1874
pushOpenMPFunctionRegion()1875 void Sema::pushOpenMPFunctionRegion() {
1876 DSAStack->pushFunction();
1877 }
1878
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1879 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1880 DSAStack->popFunction(OldFSI);
1881 }
1882
isOpenMPDeviceDelayedContext(Sema & S)1883 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1884 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1885 "Expected OpenMP device compilation.");
1886 return !S.isInOpenMPTargetExecutionDirective() &&
1887 !S.isInOpenMPDeclareTargetContext();
1888 }
1889
1890 namespace {
1891 /// Status of the function emission on the host/device.
1892 enum class FunctionEmissionStatus {
1893 Emitted,
1894 Discarded,
1895 Unknown,
1896 };
1897 } // anonymous namespace
1898
diagIfOpenMPDeviceCode(SourceLocation Loc,unsigned DiagID)1899 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1900 unsigned DiagID) {
1901 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1902 "Expected OpenMP device compilation.");
1903
1904 FunctionDecl *FD = getCurFunctionDecl();
1905 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1906 if (FD) {
1907 FunctionEmissionStatus FES = getEmissionStatus(FD);
1908 switch (FES) {
1909 case FunctionEmissionStatus::Emitted:
1910 Kind = SemaDiagnosticBuilder::K_Immediate;
1911 break;
1912 case FunctionEmissionStatus::Unknown:
1913 Kind = isOpenMPDeviceDelayedContext(*this)
1914 ? SemaDiagnosticBuilder::K_Deferred
1915 : SemaDiagnosticBuilder::K_Immediate;
1916 break;
1917 case FunctionEmissionStatus::TemplateDiscarded:
1918 case FunctionEmissionStatus::OMPDiscarded:
1919 Kind = SemaDiagnosticBuilder::K_Nop;
1920 break;
1921 case FunctionEmissionStatus::CUDADiscarded:
1922 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1923 break;
1924 }
1925 }
1926
1927 return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1928 }
1929
diagIfOpenMPHostCode(SourceLocation Loc,unsigned DiagID)1930 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1931 unsigned DiagID) {
1932 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1933 "Expected OpenMP host compilation.");
1934 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1935 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1936 switch (FES) {
1937 case FunctionEmissionStatus::Emitted:
1938 Kind = SemaDiagnosticBuilder::K_Immediate;
1939 break;
1940 case FunctionEmissionStatus::Unknown:
1941 Kind = SemaDiagnosticBuilder::K_Deferred;
1942 break;
1943 case FunctionEmissionStatus::TemplateDiscarded:
1944 case FunctionEmissionStatus::OMPDiscarded:
1945 case FunctionEmissionStatus::CUDADiscarded:
1946 Kind = SemaDiagnosticBuilder::K_Nop;
1947 break;
1948 }
1949
1950 return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1951 }
1952
1953 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)1954 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1955 if (LO.OpenMP <= 45) {
1956 if (VD->getType().getNonReferenceType()->isScalarType())
1957 return OMPC_DEFAULTMAP_scalar;
1958 return OMPC_DEFAULTMAP_aggregate;
1959 }
1960 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1961 return OMPC_DEFAULTMAP_pointer;
1962 if (VD->getType().getNonReferenceType()->isScalarType())
1963 return OMPC_DEFAULTMAP_scalar;
1964 return OMPC_DEFAULTMAP_aggregate;
1965 }
1966
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const1967 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1968 unsigned OpenMPCaptureLevel) const {
1969 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1970
1971 ASTContext &Ctx = getASTContext();
1972 bool IsByRef = true;
1973
1974 // Find the directive that is associated with the provided scope.
1975 D = cast<ValueDecl>(D->getCanonicalDecl());
1976 QualType Ty = D->getType();
1977
1978 bool IsVariableUsedInMapClause = false;
1979 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1980 // This table summarizes how a given variable should be passed to the device
1981 // given its type and the clauses where it appears. This table is based on
1982 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1983 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1984 //
1985 // =========================================================================
1986 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1987 // | |(tofrom:scalar)| | pvt | | | |
1988 // =========================================================================
1989 // | scl | | | | - | | bycopy|
1990 // | scl | | - | x | - | - | bycopy|
1991 // | scl | | x | - | - | - | null |
1992 // | scl | x | | | - | | byref |
1993 // | scl | x | - | x | - | - | bycopy|
1994 // | scl | x | x | - | - | - | null |
1995 // | scl | | - | - | - | x | byref |
1996 // | scl | x | - | - | - | x | byref |
1997 //
1998 // | agg | n.a. | | | - | | byref |
1999 // | agg | n.a. | - | x | - | - | byref |
2000 // | agg | n.a. | x | - | - | - | null |
2001 // | agg | n.a. | - | - | - | x | byref |
2002 // | agg | n.a. | - | - | - | x[] | byref |
2003 //
2004 // | ptr | n.a. | | | - | | bycopy|
2005 // | ptr | n.a. | - | x | - | - | bycopy|
2006 // | ptr | n.a. | x | - | - | - | null |
2007 // | ptr | n.a. | - | - | - | x | byref |
2008 // | ptr | n.a. | - | - | - | x[] | bycopy|
2009 // | ptr | n.a. | - | - | x | | bycopy|
2010 // | ptr | n.a. | - | - | x | x | bycopy|
2011 // | ptr | n.a. | - | - | x | x[] | bycopy|
2012 // =========================================================================
2013 // Legend:
2014 // scl - scalar
2015 // ptr - pointer
2016 // agg - aggregate
2017 // x - applies
2018 // - - invalid in this combination
2019 // [] - mapped with an array section
2020 // byref - should be mapped by reference
2021 // byval - should be mapped by value
2022 // null - initialize a local variable to null on the device
2023 //
2024 // Observations:
2025 // - All scalar declarations that show up in a map clause have to be passed
2026 // by reference, because they may have been mapped in the enclosing data
2027 // environment.
2028 // - If the scalar value does not fit the size of uintptr, it has to be
2029 // passed by reference, regardless the result in the table above.
2030 // - For pointers mapped by value that have either an implicit map or an
2031 // array section, the runtime library may pass the NULL value to the
2032 // device instead of the value passed to it by the compiler.
2033
2034 if (Ty->isReferenceType())
2035 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2036
2037 // Locate map clauses and see if the variable being captured is referred to
2038 // in any of those clauses. Here we only care about variables, not fields,
2039 // because fields are part of aggregates.
2040 bool IsVariableAssociatedWithSection = false;
2041
2042 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2043 D, Level,
2044 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2045 OMPClauseMappableExprCommon::MappableExprComponentListRef
2046 MapExprComponents,
2047 OpenMPClauseKind WhereFoundClauseKind) {
2048 // Only the map clause information influences how a variable is
2049 // captured. E.g. is_device_ptr does not require changing the default
2050 // behavior.
2051 if (WhereFoundClauseKind != OMPC_map)
2052 return false;
2053
2054 auto EI = MapExprComponents.rbegin();
2055 auto EE = MapExprComponents.rend();
2056
2057 assert(EI != EE && "Invalid map expression!");
2058
2059 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2060 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2061
2062 ++EI;
2063 if (EI == EE)
2064 return false;
2065
2066 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2067 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2068 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2069 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2070 IsVariableAssociatedWithSection = true;
2071 // There is nothing more we need to know about this variable.
2072 return true;
2073 }
2074
2075 // Keep looking for more map info.
2076 return false;
2077 });
2078
2079 if (IsVariableUsedInMapClause) {
2080 // If variable is identified in a map clause it is always captured by
2081 // reference except if it is a pointer that is dereferenced somehow.
2082 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2083 } else {
2084 // By default, all the data that has a scalar type is mapped by copy
2085 // (except for reduction variables).
2086 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2087 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2088 !Ty->isAnyPointerType()) ||
2089 !Ty->isScalarType() ||
2090 DSAStack->isDefaultmapCapturedByRef(
2091 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2092 DSAStack->hasExplicitDSA(
2093 D,
2094 [](OpenMPClauseKind K, bool AppliedToPointee) {
2095 return K == OMPC_reduction && !AppliedToPointee;
2096 },
2097 Level);
2098 }
2099 }
2100
2101 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2102 IsByRef =
2103 ((IsVariableUsedInMapClause &&
2104 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2105 OMPD_target) ||
2106 !(DSAStack->hasExplicitDSA(
2107 D,
2108 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2109 return K == OMPC_firstprivate ||
2110 (K == OMPC_reduction && AppliedToPointee);
2111 },
2112 Level, /*NotLastprivate=*/true) ||
2113 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2114 // If the variable is artificial and must be captured by value - try to
2115 // capture by value.
2116 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2117 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2118 // If the variable is implicitly firstprivate and scalar - capture by
2119 // copy
2120 !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2121 !DSAStack->hasExplicitDSA(
2122 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2123 Level) &&
2124 !DSAStack->isLoopControlVariable(D, Level).first);
2125 }
2126
2127 // When passing data by copy, we need to make sure it fits the uintptr size
2128 // and alignment, because the runtime library only deals with uintptr types.
2129 // If it does not fit the uintptr size, we need to pass the data by reference
2130 // instead.
2131 if (!IsByRef &&
2132 (Ctx.getTypeSizeInChars(Ty) >
2133 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2134 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2135 IsByRef = true;
2136 }
2137
2138 return IsByRef;
2139 }
2140
getOpenMPNestingLevel() const2141 unsigned Sema::getOpenMPNestingLevel() const {
2142 assert(getLangOpts().OpenMP);
2143 return DSAStack->getNestingLevel();
2144 }
2145
isInOpenMPTargetExecutionDirective() const2146 bool Sema::isInOpenMPTargetExecutionDirective() const {
2147 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2148 !DSAStack->isClauseParsingMode()) ||
2149 DSAStack->hasDirective(
2150 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2151 SourceLocation) -> bool {
2152 return isOpenMPTargetExecutionDirective(K);
2153 },
2154 false);
2155 }
2156
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2157 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2158 unsigned StopAt) {
2159 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2160 D = getCanonicalDecl(D);
2161
2162 auto *VD = dyn_cast<VarDecl>(D);
2163 // Do not capture constexpr variables.
2164 if (VD && VD->isConstexpr())
2165 return nullptr;
2166
2167 // If we want to determine whether the variable should be captured from the
2168 // perspective of the current capturing scope, and we've already left all the
2169 // capturing scopes of the top directive on the stack, check from the
2170 // perspective of its parent directive (if any) instead.
2171 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2172 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2173
2174 // If we are attempting to capture a global variable in a directive with
2175 // 'target' we return true so that this global is also mapped to the device.
2176 //
2177 if (VD && !VD->hasLocalStorage() &&
2178 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2179 if (isInOpenMPDeclareTargetContext()) {
2180 // Try to mark variable as declare target if it is used in capturing
2181 // regions.
2182 if (LangOpts.OpenMP <= 45 &&
2183 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2184 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2185 return nullptr;
2186 }
2187 if (isInOpenMPTargetExecutionDirective()) {
2188 // If the declaration is enclosed in a 'declare target' directive,
2189 // then it should not be captured.
2190 //
2191 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2192 return nullptr;
2193 CapturedRegionScopeInfo *CSI = nullptr;
2194 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2195 llvm::reverse(FunctionScopes),
2196 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2197 if (!isa<CapturingScopeInfo>(FSI))
2198 return nullptr;
2199 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2200 if (RSI->CapRegionKind == CR_OpenMP) {
2201 CSI = RSI;
2202 break;
2203 }
2204 }
2205 assert(CSI && "Failed to find CapturedRegionScopeInfo");
2206 SmallVector<OpenMPDirectiveKind, 4> Regions;
2207 getOpenMPCaptureRegions(Regions,
2208 DSAStack->getDirective(CSI->OpenMPLevel));
2209 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2210 return VD;
2211 }
2212 }
2213
2214 if (CheckScopeInfo) {
2215 bool OpenMPFound = false;
2216 for (unsigned I = StopAt + 1; I > 0; --I) {
2217 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2218 if(!isa<CapturingScopeInfo>(FSI))
2219 return nullptr;
2220 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2221 if (RSI->CapRegionKind == CR_OpenMP) {
2222 OpenMPFound = true;
2223 break;
2224 }
2225 }
2226 if (!OpenMPFound)
2227 return nullptr;
2228 }
2229
2230 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2231 (!DSAStack->isClauseParsingMode() ||
2232 DSAStack->getParentDirective() != OMPD_unknown)) {
2233 auto &&Info = DSAStack->isLoopControlVariable(D);
2234 if (Info.first ||
2235 (VD && VD->hasLocalStorage() &&
2236 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2237 (VD && DSAStack->isForceVarCapturing()))
2238 return VD ? VD : Info.second;
2239 DSAStackTy::DSAVarData DVarTop =
2240 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2241 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2242 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2243 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2244 // Threadprivate variables must not be captured.
2245 if (isOpenMPThreadPrivate(DVarTop.CKind))
2246 return nullptr;
2247 // The variable is not private or it is the variable in the directive with
2248 // default(none) clause and not used in any clause.
2249 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2250 D,
2251 [](OpenMPClauseKind C, bool AppliedToPointee) {
2252 return isOpenMPPrivate(C) && !AppliedToPointee;
2253 },
2254 [](OpenMPDirectiveKind) { return true; },
2255 DSAStack->isClauseParsingMode());
2256 // Global shared must not be captured.
2257 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2258 ((DSAStack->getDefaultDSA() != DSA_none &&
2259 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2260 DVarTop.CKind == OMPC_shared))
2261 return nullptr;
2262 if (DVarPrivate.CKind != OMPC_unknown ||
2263 (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2264 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2265 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2266 }
2267 return nullptr;
2268 }
2269
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2270 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2271 unsigned Level) const {
2272 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2273 }
2274
startOpenMPLoop()2275 void Sema::startOpenMPLoop() {
2276 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2277 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2278 DSAStack->loopInit();
2279 }
2280
startOpenMPCXXRangeFor()2281 void Sema::startOpenMPCXXRangeFor() {
2282 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2283 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2284 DSAStack->resetPossibleLoopCounter();
2285 DSAStack->loopStart();
2286 }
2287 }
2288
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2289 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2290 unsigned CapLevel) const {
2291 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2292 if (DSAStack->hasExplicitDirective(
2293 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2294 Level)) {
2295 bool IsTriviallyCopyable =
2296 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2297 !D->getType()
2298 .getNonReferenceType()
2299 .getCanonicalType()
2300 ->getAsCXXRecordDecl();
2301 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2302 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2303 getOpenMPCaptureRegions(CaptureRegions, DKind);
2304 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2305 (IsTriviallyCopyable ||
2306 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2307 if (DSAStack->hasExplicitDSA(
2308 D,
2309 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2310 Level, /*NotLastprivate=*/true))
2311 return OMPC_firstprivate;
2312 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2313 if (DVar.CKind != OMPC_shared &&
2314 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2315 DSAStack->addImplicitTaskFirstprivate(Level, D);
2316 return OMPC_firstprivate;
2317 }
2318 }
2319 }
2320 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2321 if (DSAStack->getAssociatedLoops() > 0 &&
2322 !DSAStack->isLoopStarted()) {
2323 DSAStack->resetPossibleLoopCounter(D);
2324 DSAStack->loopStart();
2325 return OMPC_private;
2326 }
2327 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2328 DSAStack->isLoopControlVariable(D).first) &&
2329 !DSAStack->hasExplicitDSA(
2330 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2331 Level) &&
2332 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2333 return OMPC_private;
2334 }
2335 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2336 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2337 DSAStack->isForceVarCapturing() &&
2338 !DSAStack->hasExplicitDSA(
2339 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2340 Level))
2341 return OMPC_private;
2342 }
2343 // User-defined allocators are private since they must be defined in the
2344 // context of target region.
2345 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2346 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2347 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2348 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2349 return OMPC_private;
2350 return (DSAStack->hasExplicitDSA(
2351 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2352 Level) ||
2353 (DSAStack->isClauseParsingMode() &&
2354 DSAStack->getClauseParsingMode() == OMPC_private) ||
2355 // Consider taskgroup reduction descriptor variable a private
2356 // to avoid possible capture in the region.
2357 (DSAStack->hasExplicitDirective(
2358 [](OpenMPDirectiveKind K) {
2359 return K == OMPD_taskgroup ||
2360 ((isOpenMPParallelDirective(K) ||
2361 isOpenMPWorksharingDirective(K)) &&
2362 !isOpenMPSimdDirective(K));
2363 },
2364 Level) &&
2365 DSAStack->isTaskgroupReductionRef(D, Level)))
2366 ? OMPC_private
2367 : OMPC_unknown;
2368 }
2369
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2370 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2371 unsigned Level) {
2372 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2373 D = getCanonicalDecl(D);
2374 OpenMPClauseKind OMPC = OMPC_unknown;
2375 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2376 const unsigned NewLevel = I - 1;
2377 if (DSAStack->hasExplicitDSA(
2378 D,
2379 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2380 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2381 OMPC = K;
2382 return true;
2383 }
2384 return false;
2385 },
2386 NewLevel))
2387 break;
2388 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2389 D, NewLevel,
2390 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2391 OpenMPClauseKind) { return true; })) {
2392 OMPC = OMPC_map;
2393 break;
2394 }
2395 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2396 NewLevel)) {
2397 OMPC = OMPC_map;
2398 if (DSAStack->mustBeFirstprivateAtLevel(
2399 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2400 OMPC = OMPC_firstprivate;
2401 break;
2402 }
2403 }
2404 if (OMPC != OMPC_unknown)
2405 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2406 }
2407
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2408 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2409 unsigned CaptureLevel) const {
2410 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2411 // Return true if the current level is no longer enclosed in a target region.
2412
2413 SmallVector<OpenMPDirectiveKind, 4> Regions;
2414 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2415 const auto *VD = dyn_cast<VarDecl>(D);
2416 return VD && !VD->hasLocalStorage() &&
2417 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2418 Level) &&
2419 Regions[CaptureLevel] != OMPD_task;
2420 }
2421
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2422 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2423 unsigned CaptureLevel) const {
2424 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2425 // Return true if the current level is no longer enclosed in a target region.
2426
2427 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2428 if (!VD->hasLocalStorage()) {
2429 if (isInOpenMPTargetExecutionDirective())
2430 return true;
2431 DSAStackTy::DSAVarData TopDVar =
2432 DSAStack->getTopDSA(D, /*FromParent=*/false);
2433 unsigned NumLevels =
2434 getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2435 if (Level == 0)
2436 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2437 do {
2438 --Level;
2439 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2440 if (DVar.CKind != OMPC_shared)
2441 return true;
2442 } while (Level > 0);
2443 }
2444 }
2445 return true;
2446 }
2447
DestroyDataSharingAttributesStack()2448 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2449
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2450 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2451 OMPTraitInfo &TI) {
2452 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2453 }
2454
ActOnOpenMPEndDeclareVariant()2455 void Sema::ActOnOpenMPEndDeclareVariant() {
2456 assert(isInOpenMPDeclareVariantScope() &&
2457 "Not in OpenMP declare variant scope!");
2458
2459 OMPDeclareVariantScopes.pop_back();
2460 }
2461
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2462 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2463 const FunctionDecl *Callee,
2464 SourceLocation Loc) {
2465 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2466 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2467 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2468 // Ignore host functions during device analyzis.
2469 if (LangOpts.OpenMPIsDevice && DevTy &&
2470 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2471 return;
2472 // Ignore nohost functions during host analyzis.
2473 if (!LangOpts.OpenMPIsDevice && DevTy &&
2474 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2475 return;
2476 const FunctionDecl *FD = Callee->getMostRecentDecl();
2477 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2478 if (LangOpts.OpenMPIsDevice && DevTy &&
2479 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2480 // Diagnose host function called during device codegen.
2481 StringRef HostDevTy =
2482 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2483 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2484 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2485 diag::note_omp_marked_device_type_here)
2486 << HostDevTy;
2487 return;
2488 }
2489 if (!LangOpts.OpenMPIsDevice && DevTy &&
2490 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2491 // Diagnose nohost function called during host codegen.
2492 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2493 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2494 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2495 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2496 diag::note_omp_marked_device_type_here)
2497 << NoHostDevTy;
2498 }
2499 }
2500
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2501 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2502 const DeclarationNameInfo &DirName,
2503 Scope *CurScope, SourceLocation Loc) {
2504 DSAStack->push(DKind, DirName, CurScope, Loc);
2505 PushExpressionEvaluationContext(
2506 ExpressionEvaluationContext::PotentiallyEvaluated);
2507 }
2508
StartOpenMPClause(OpenMPClauseKind K)2509 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2510 DSAStack->setClauseParsingMode(K);
2511 }
2512
EndOpenMPClause()2513 void Sema::EndOpenMPClause() {
2514 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2515 }
2516
2517 static std::pair<ValueDecl *, bool>
2518 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2519 SourceRange &ERange, bool AllowArraySection = false);
2520
2521 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2522 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2523 ArrayRef<OMPClause *> Clauses) {
2524 bool InscanFound = false;
2525 SourceLocation InscanLoc;
2526 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2527 // A reduction clause without the inscan reduction-modifier may not appear on
2528 // a construct on which a reduction clause with the inscan reduction-modifier
2529 // appears.
2530 for (OMPClause *C : Clauses) {
2531 if (C->getClauseKind() != OMPC_reduction)
2532 continue;
2533 auto *RC = cast<OMPReductionClause>(C);
2534 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2535 InscanFound = true;
2536 InscanLoc = RC->getModifierLoc();
2537 continue;
2538 }
2539 if (RC->getModifier() == OMPC_REDUCTION_task) {
2540 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2541 // A reduction clause with the task reduction-modifier may only appear on
2542 // a parallel construct, a worksharing construct or a combined or
2543 // composite construct for which any of the aforementioned constructs is a
2544 // constituent construct and simd or loop are not constituent constructs.
2545 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2546 if (!(isOpenMPParallelDirective(CurDir) ||
2547 isOpenMPWorksharingDirective(CurDir)) ||
2548 isOpenMPSimdDirective(CurDir))
2549 S.Diag(RC->getModifierLoc(),
2550 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2551 continue;
2552 }
2553 }
2554 if (InscanFound) {
2555 for (OMPClause *C : Clauses) {
2556 if (C->getClauseKind() != OMPC_reduction)
2557 continue;
2558 auto *RC = cast<OMPReductionClause>(C);
2559 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2560 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2561 ? RC->getBeginLoc()
2562 : RC->getModifierLoc(),
2563 diag::err_omp_inscan_reduction_expected);
2564 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2565 continue;
2566 }
2567 for (Expr *Ref : RC->varlists()) {
2568 assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2569 SourceLocation ELoc;
2570 SourceRange ERange;
2571 Expr *SimpleRefExpr = Ref;
2572 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2573 /*AllowArraySection=*/true);
2574 ValueDecl *D = Res.first;
2575 if (!D)
2576 continue;
2577 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2578 S.Diag(Ref->getExprLoc(),
2579 diag::err_omp_reduction_not_inclusive_exclusive)
2580 << Ref->getSourceRange();
2581 }
2582 }
2583 }
2584 }
2585 }
2586
2587 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2588 ArrayRef<OMPClause *> Clauses);
2589 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2590 bool WithInit);
2591
2592 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2593 const ValueDecl *D,
2594 const DSAStackTy::DSAVarData &DVar,
2595 bool IsLoopIterVar = false);
2596
EndOpenMPDSABlock(Stmt * CurDirective)2597 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2598 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2599 // A variable of class type (or array thereof) that appears in a lastprivate
2600 // clause requires an accessible, unambiguous default constructor for the
2601 // class type, unless the list item is also specified in a firstprivate
2602 // clause.
2603 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2604 for (OMPClause *C : D->clauses()) {
2605 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2606 SmallVector<Expr *, 8> PrivateCopies;
2607 for (Expr *DE : Clause->varlists()) {
2608 if (DE->isValueDependent() || DE->isTypeDependent()) {
2609 PrivateCopies.push_back(nullptr);
2610 continue;
2611 }
2612 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2613 auto *VD = cast<VarDecl>(DRE->getDecl());
2614 QualType Type = VD->getType().getNonReferenceType();
2615 const DSAStackTy::DSAVarData DVar =
2616 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2617 if (DVar.CKind == OMPC_lastprivate) {
2618 // Generate helper private variable and initialize it with the
2619 // default value. The address of the original variable is replaced
2620 // by the address of the new private variable in CodeGen. This new
2621 // variable is not added to IdResolver, so the code in the OpenMP
2622 // region uses original variable for proper diagnostics.
2623 VarDecl *VDPrivate = buildVarDecl(
2624 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2625 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2626 ActOnUninitializedDecl(VDPrivate);
2627 if (VDPrivate->isInvalidDecl()) {
2628 PrivateCopies.push_back(nullptr);
2629 continue;
2630 }
2631 PrivateCopies.push_back(buildDeclRefExpr(
2632 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2633 } else {
2634 // The variable is also a firstprivate, so initialization sequence
2635 // for private copy is generated already.
2636 PrivateCopies.push_back(nullptr);
2637 }
2638 }
2639 Clause->setPrivateCopies(PrivateCopies);
2640 continue;
2641 }
2642 // Finalize nontemporal clause by handling private copies, if any.
2643 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2644 SmallVector<Expr *, 8> PrivateRefs;
2645 for (Expr *RefExpr : Clause->varlists()) {
2646 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2647 SourceLocation ELoc;
2648 SourceRange ERange;
2649 Expr *SimpleRefExpr = RefExpr;
2650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2651 if (Res.second)
2652 // It will be analyzed later.
2653 PrivateRefs.push_back(RefExpr);
2654 ValueDecl *D = Res.first;
2655 if (!D)
2656 continue;
2657
2658 const DSAStackTy::DSAVarData DVar =
2659 DSAStack->getTopDSA(D, /*FromParent=*/false);
2660 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2661 : SimpleRefExpr);
2662 }
2663 Clause->setPrivateRefs(PrivateRefs);
2664 continue;
2665 }
2666 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2667 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2668 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2669 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2670 if (!DRE)
2671 continue;
2672 ValueDecl *VD = DRE->getDecl();
2673 if (!VD || !isa<VarDecl>(VD))
2674 continue;
2675 DSAStackTy::DSAVarData DVar =
2676 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2677 // OpenMP [2.12.5, target Construct]
2678 // Memory allocators that appear in a uses_allocators clause cannot
2679 // appear in other data-sharing attribute clauses or data-mapping
2680 // attribute clauses in the same construct.
2681 Expr *MapExpr = nullptr;
2682 if (DVar.RefExpr ||
2683 DSAStack->checkMappableExprComponentListsForDecl(
2684 VD, /*CurrentRegionOnly=*/true,
2685 [VD, &MapExpr](
2686 OMPClauseMappableExprCommon::MappableExprComponentListRef
2687 MapExprComponents,
2688 OpenMPClauseKind C) {
2689 auto MI = MapExprComponents.rbegin();
2690 auto ME = MapExprComponents.rend();
2691 if (MI != ME &&
2692 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2693 VD->getCanonicalDecl()) {
2694 MapExpr = MI->getAssociatedExpression();
2695 return true;
2696 }
2697 return false;
2698 })) {
2699 Diag(D.Allocator->getExprLoc(),
2700 diag::err_omp_allocator_used_in_clauses)
2701 << D.Allocator->getSourceRange();
2702 if (DVar.RefExpr)
2703 reportOriginalDsa(*this, DSAStack, VD, DVar);
2704 else
2705 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2706 << MapExpr->getSourceRange();
2707 }
2708 }
2709 continue;
2710 }
2711 }
2712 // Check allocate clauses.
2713 if (!CurContext->isDependentContext())
2714 checkAllocateClauses(*this, DSAStack, D->clauses());
2715 checkReductionClauses(*this, DSAStack, D->clauses());
2716 }
2717
2718 DSAStack->pop();
2719 DiscardCleanupsInEvaluationContext();
2720 PopExpressionEvaluationContext();
2721 }
2722
2723 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2724 Expr *NumIterations, Sema &SemaRef,
2725 Scope *S, DSAStackTy *Stack);
2726
2727 namespace {
2728
2729 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2730 private:
2731 Sema &SemaRef;
2732
2733 public:
VarDeclFilterCCC(Sema & S)2734 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2735 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2736 NamedDecl *ND = Candidate.getCorrectionDecl();
2737 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2738 return VD->hasGlobalStorage() &&
2739 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2740 SemaRef.getCurScope());
2741 }
2742 return false;
2743 }
2744
clone()2745 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2746 return std::make_unique<VarDeclFilterCCC>(*this);
2747 }
2748
2749 };
2750
2751 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2752 private:
2753 Sema &SemaRef;
2754
2755 public:
VarOrFuncDeclFilterCCC(Sema & S)2756 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2757 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2758 NamedDecl *ND = Candidate.getCorrectionDecl();
2759 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2760 isa<FunctionDecl>(ND))) {
2761 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2762 SemaRef.getCurScope());
2763 }
2764 return false;
2765 }
2766
clone()2767 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2768 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2769 }
2770 };
2771
2772 } // namespace
2773
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)2774 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2775 CXXScopeSpec &ScopeSpec,
2776 const DeclarationNameInfo &Id,
2777 OpenMPDirectiveKind Kind) {
2778 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2779 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2780
2781 if (Lookup.isAmbiguous())
2782 return ExprError();
2783
2784 VarDecl *VD;
2785 if (!Lookup.isSingleResult()) {
2786 VarDeclFilterCCC CCC(*this);
2787 if (TypoCorrection Corrected =
2788 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2789 CTK_ErrorRecovery)) {
2790 diagnoseTypo(Corrected,
2791 PDiag(Lookup.empty()
2792 ? diag::err_undeclared_var_use_suggest
2793 : diag::err_omp_expected_var_arg_suggest)
2794 << Id.getName());
2795 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2796 } else {
2797 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2798 : diag::err_omp_expected_var_arg)
2799 << Id.getName();
2800 return ExprError();
2801 }
2802 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2803 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2804 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2805 return ExprError();
2806 }
2807 Lookup.suppressDiagnostics();
2808
2809 // OpenMP [2.9.2, Syntax, C/C++]
2810 // Variables must be file-scope, namespace-scope, or static block-scope.
2811 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2812 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2813 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2814 bool IsDecl =
2815 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2816 Diag(VD->getLocation(),
2817 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2818 << VD;
2819 return ExprError();
2820 }
2821
2822 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2823 NamedDecl *ND = CanonicalVD;
2824 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2825 // A threadprivate directive for file-scope variables must appear outside
2826 // any definition or declaration.
2827 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2828 !getCurLexicalContext()->isTranslationUnit()) {
2829 Diag(Id.getLoc(), diag::err_omp_var_scope)
2830 << getOpenMPDirectiveName(Kind) << VD;
2831 bool IsDecl =
2832 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2833 Diag(VD->getLocation(),
2834 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2835 << VD;
2836 return ExprError();
2837 }
2838 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2839 // A threadprivate directive for static class member variables must appear
2840 // in the class definition, in the same scope in which the member
2841 // variables are declared.
2842 if (CanonicalVD->isStaticDataMember() &&
2843 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2844 Diag(Id.getLoc(), diag::err_omp_var_scope)
2845 << getOpenMPDirectiveName(Kind) << VD;
2846 bool IsDecl =
2847 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2848 Diag(VD->getLocation(),
2849 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2850 << VD;
2851 return ExprError();
2852 }
2853 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2854 // A threadprivate directive for namespace-scope variables must appear
2855 // outside any definition or declaration other than the namespace
2856 // definition itself.
2857 if (CanonicalVD->getDeclContext()->isNamespace() &&
2858 (!getCurLexicalContext()->isFileContext() ||
2859 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2860 Diag(Id.getLoc(), diag::err_omp_var_scope)
2861 << getOpenMPDirectiveName(Kind) << VD;
2862 bool IsDecl =
2863 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2864 Diag(VD->getLocation(),
2865 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2866 << VD;
2867 return ExprError();
2868 }
2869 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2870 // A threadprivate directive for static block-scope variables must appear
2871 // in the scope of the variable and not in a nested scope.
2872 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2873 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2874 Diag(Id.getLoc(), diag::err_omp_var_scope)
2875 << getOpenMPDirectiveName(Kind) << VD;
2876 bool IsDecl =
2877 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2878 Diag(VD->getLocation(),
2879 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2880 << VD;
2881 return ExprError();
2882 }
2883
2884 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2885 // A threadprivate directive must lexically precede all references to any
2886 // of the variables in its list.
2887 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2888 !DSAStack->isThreadPrivate(VD)) {
2889 Diag(Id.getLoc(), diag::err_omp_var_used)
2890 << getOpenMPDirectiveName(Kind) << VD;
2891 return ExprError();
2892 }
2893
2894 QualType ExprType = VD->getType().getNonReferenceType();
2895 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2896 SourceLocation(), VD,
2897 /*RefersToEnclosingVariableOrCapture=*/false,
2898 Id.getLoc(), ExprType, VK_LValue);
2899 }
2900
2901 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)2902 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2903 ArrayRef<Expr *> VarList) {
2904 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2905 CurContext->addDecl(D);
2906 return DeclGroupPtrTy::make(DeclGroupRef(D));
2907 }
2908 return nullptr;
2909 }
2910
2911 namespace {
2912 class LocalVarRefChecker final
2913 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2914 Sema &SemaRef;
2915
2916 public:
VisitDeclRefExpr(const DeclRefExpr * E)2917 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2918 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2919 if (VD->hasLocalStorage()) {
2920 SemaRef.Diag(E->getBeginLoc(),
2921 diag::err_omp_local_var_in_threadprivate_init)
2922 << E->getSourceRange();
2923 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2924 << VD << VD->getSourceRange();
2925 return true;
2926 }
2927 }
2928 return false;
2929 }
VisitStmt(const Stmt * S)2930 bool VisitStmt(const Stmt *S) {
2931 for (const Stmt *Child : S->children()) {
2932 if (Child && Visit(Child))
2933 return true;
2934 }
2935 return false;
2936 }
LocalVarRefChecker(Sema & SemaRef)2937 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2938 };
2939 } // namespace
2940
2941 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)2942 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2943 SmallVector<Expr *, 8> Vars;
2944 for (Expr *RefExpr : VarList) {
2945 auto *DE = cast<DeclRefExpr>(RefExpr);
2946 auto *VD = cast<VarDecl>(DE->getDecl());
2947 SourceLocation ILoc = DE->getExprLoc();
2948
2949 // Mark variable as used.
2950 VD->setReferenced();
2951 VD->markUsed(Context);
2952
2953 QualType QType = VD->getType();
2954 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2955 // It will be analyzed later.
2956 Vars.push_back(DE);
2957 continue;
2958 }
2959
2960 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2961 // A threadprivate variable must not have an incomplete type.
2962 if (RequireCompleteType(ILoc, VD->getType(),
2963 diag::err_omp_threadprivate_incomplete_type)) {
2964 continue;
2965 }
2966
2967 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2968 // A threadprivate variable must not have a reference type.
2969 if (VD->getType()->isReferenceType()) {
2970 Diag(ILoc, diag::err_omp_ref_type_arg)
2971 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2972 bool IsDecl =
2973 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2974 Diag(VD->getLocation(),
2975 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2976 << VD;
2977 continue;
2978 }
2979
2980 // Check if this is a TLS variable. If TLS is not being supported, produce
2981 // the corresponding diagnostic.
2982 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2983 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2984 getLangOpts().OpenMPUseTLS &&
2985 getASTContext().getTargetInfo().isTLSSupported())) ||
2986 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2987 !VD->isLocalVarDecl())) {
2988 Diag(ILoc, diag::err_omp_var_thread_local)
2989 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2990 bool IsDecl =
2991 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2992 Diag(VD->getLocation(),
2993 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2994 << VD;
2995 continue;
2996 }
2997
2998 // Check if initial value of threadprivate variable reference variable with
2999 // local storage (it is not supported by runtime).
3000 if (const Expr *Init = VD->getAnyInitializer()) {
3001 LocalVarRefChecker Checker(*this);
3002 if (Checker.Visit(Init))
3003 continue;
3004 }
3005
3006 Vars.push_back(RefExpr);
3007 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3008 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3009 Context, SourceRange(Loc, Loc)));
3010 if (ASTMutationListener *ML = Context.getASTMutationListener())
3011 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3012 }
3013 OMPThreadPrivateDecl *D = nullptr;
3014 if (!Vars.empty()) {
3015 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3016 Vars);
3017 D->setAccess(AS_public);
3018 }
3019 return D;
3020 }
3021
3022 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3023 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3024 if (!Allocator)
3025 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3026 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3027 Allocator->isInstantiationDependent() ||
3028 Allocator->containsUnexpandedParameterPack())
3029 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3030 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3031 const Expr *AE = Allocator->IgnoreParenImpCasts();
3032 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3033 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3034 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3035 llvm::FoldingSetNodeID AEId, DAEId;
3036 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3037 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3038 if (AEId == DAEId) {
3039 AllocatorKindRes = AllocatorKind;
3040 break;
3041 }
3042 }
3043 return AllocatorKindRes;
3044 }
3045
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3046 static bool checkPreviousOMPAllocateAttribute(
3047 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3048 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3049 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3050 return false;
3051 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3052 Expr *PrevAllocator = A->getAllocator();
3053 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3054 getAllocatorKind(S, Stack, PrevAllocator);
3055 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3056 if (AllocatorsMatch &&
3057 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3058 Allocator && PrevAllocator) {
3059 const Expr *AE = Allocator->IgnoreParenImpCasts();
3060 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3061 llvm::FoldingSetNodeID AEId, PAEId;
3062 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3063 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3064 AllocatorsMatch = AEId == PAEId;
3065 }
3066 if (!AllocatorsMatch) {
3067 SmallString<256> AllocatorBuffer;
3068 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3069 if (Allocator)
3070 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3071 SmallString<256> PrevAllocatorBuffer;
3072 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3073 if (PrevAllocator)
3074 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3075 S.getPrintingPolicy());
3076
3077 SourceLocation AllocatorLoc =
3078 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3079 SourceRange AllocatorRange =
3080 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3081 SourceLocation PrevAllocatorLoc =
3082 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3083 SourceRange PrevAllocatorRange =
3084 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3085 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3086 << (Allocator ? 1 : 0) << AllocatorStream.str()
3087 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3088 << AllocatorRange;
3089 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3090 << PrevAllocatorRange;
3091 return true;
3092 }
3093 return false;
3094 }
3095
3096 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,SourceRange SR)3097 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3098 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3099 Expr *Allocator, SourceRange SR) {
3100 if (VD->hasAttr<OMPAllocateDeclAttr>())
3101 return;
3102 if (Allocator &&
3103 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3104 Allocator->isInstantiationDependent() ||
3105 Allocator->containsUnexpandedParameterPack()))
3106 return;
3107 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3108 Allocator, SR);
3109 VD->addAttr(A);
3110 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3111 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3112 }
3113
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3114 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3115 SourceLocation Loc, ArrayRef<Expr *> VarList,
3116 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3117 assert(Clauses.size() <= 1 && "Expected at most one clause.");
3118 Expr *Allocator = nullptr;
3119 if (Clauses.empty()) {
3120 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3121 // allocate directives that appear in a target region must specify an
3122 // allocator clause unless a requires directive with the dynamic_allocators
3123 // clause is present in the same compilation unit.
3124 if (LangOpts.OpenMPIsDevice &&
3125 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3126 targetDiag(Loc, diag::err_expected_allocator_clause);
3127 } else {
3128 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3129 }
3130 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3131 getAllocatorKind(*this, DSAStack, Allocator);
3132 SmallVector<Expr *, 8> Vars;
3133 for (Expr *RefExpr : VarList) {
3134 auto *DE = cast<DeclRefExpr>(RefExpr);
3135 auto *VD = cast<VarDecl>(DE->getDecl());
3136
3137 // Check if this is a TLS variable or global register.
3138 if (VD->getTLSKind() != VarDecl::TLS_None ||
3139 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3140 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3141 !VD->isLocalVarDecl()))
3142 continue;
3143
3144 // If the used several times in the allocate directive, the same allocator
3145 // must be used.
3146 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3147 AllocatorKind, Allocator))
3148 continue;
3149
3150 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3151 // If a list item has a static storage type, the allocator expression in the
3152 // allocator clause must be a constant expression that evaluates to one of
3153 // the predefined memory allocator values.
3154 if (Allocator && VD->hasGlobalStorage()) {
3155 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3156 Diag(Allocator->getExprLoc(),
3157 diag::err_omp_expected_predefined_allocator)
3158 << Allocator->getSourceRange();
3159 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3160 VarDecl::DeclarationOnly;
3161 Diag(VD->getLocation(),
3162 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3163 << VD;
3164 continue;
3165 }
3166 }
3167
3168 Vars.push_back(RefExpr);
3169 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3170 DE->getSourceRange());
3171 }
3172 if (Vars.empty())
3173 return nullptr;
3174 if (!Owner)
3175 Owner = getCurLexicalContext();
3176 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3177 D->setAccess(AS_public);
3178 Owner->addDecl(D);
3179 return DeclGroupPtrTy::make(DeclGroupRef(D));
3180 }
3181
3182 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3183 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3184 ArrayRef<OMPClause *> ClauseList) {
3185 OMPRequiresDecl *D = nullptr;
3186 if (!CurContext->isFileContext()) {
3187 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3188 } else {
3189 D = CheckOMPRequiresDecl(Loc, ClauseList);
3190 if (D) {
3191 CurContext->addDecl(D);
3192 DSAStack->addRequiresDecl(D);
3193 }
3194 }
3195 return DeclGroupPtrTy::make(DeclGroupRef(D));
3196 }
3197
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3198 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3199 ArrayRef<OMPClause *> ClauseList) {
3200 /// For target specific clauses, the requires directive cannot be
3201 /// specified after the handling of any of the target regions in the
3202 /// current compilation unit.
3203 ArrayRef<SourceLocation> TargetLocations =
3204 DSAStack->getEncounteredTargetLocs();
3205 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3206 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3207 for (const OMPClause *CNew : ClauseList) {
3208 // Check if any of the requires clauses affect target regions.
3209 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3210 isa<OMPUnifiedAddressClause>(CNew) ||
3211 isa<OMPReverseOffloadClause>(CNew) ||
3212 isa<OMPDynamicAllocatorsClause>(CNew)) {
3213 Diag(Loc, diag::err_omp_directive_before_requires)
3214 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3215 for (SourceLocation TargetLoc : TargetLocations) {
3216 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3217 << "target";
3218 }
3219 } else if (!AtomicLoc.isInvalid() &&
3220 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3221 Diag(Loc, diag::err_omp_directive_before_requires)
3222 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3223 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3224 << "atomic";
3225 }
3226 }
3227 }
3228
3229 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3230 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3231 ClauseList);
3232 return nullptr;
3233 }
3234
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3235 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3236 const ValueDecl *D,
3237 const DSAStackTy::DSAVarData &DVar,
3238 bool IsLoopIterVar) {
3239 if (DVar.RefExpr) {
3240 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3241 << getOpenMPClauseName(DVar.CKind);
3242 return;
3243 }
3244 enum {
3245 PDSA_StaticMemberShared,
3246 PDSA_StaticLocalVarShared,
3247 PDSA_LoopIterVarPrivate,
3248 PDSA_LoopIterVarLinear,
3249 PDSA_LoopIterVarLastprivate,
3250 PDSA_ConstVarShared,
3251 PDSA_GlobalVarShared,
3252 PDSA_TaskVarFirstprivate,
3253 PDSA_LocalVarPrivate,
3254 PDSA_Implicit
3255 } Reason = PDSA_Implicit;
3256 bool ReportHint = false;
3257 auto ReportLoc = D->getLocation();
3258 auto *VD = dyn_cast<VarDecl>(D);
3259 if (IsLoopIterVar) {
3260 if (DVar.CKind == OMPC_private)
3261 Reason = PDSA_LoopIterVarPrivate;
3262 else if (DVar.CKind == OMPC_lastprivate)
3263 Reason = PDSA_LoopIterVarLastprivate;
3264 else
3265 Reason = PDSA_LoopIterVarLinear;
3266 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3267 DVar.CKind == OMPC_firstprivate) {
3268 Reason = PDSA_TaskVarFirstprivate;
3269 ReportLoc = DVar.ImplicitDSALoc;
3270 } else if (VD && VD->isStaticLocal())
3271 Reason = PDSA_StaticLocalVarShared;
3272 else if (VD && VD->isStaticDataMember())
3273 Reason = PDSA_StaticMemberShared;
3274 else if (VD && VD->isFileVarDecl())
3275 Reason = PDSA_GlobalVarShared;
3276 else if (D->getType().isConstant(SemaRef.getASTContext()))
3277 Reason = PDSA_ConstVarShared;
3278 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3279 ReportHint = true;
3280 Reason = PDSA_LocalVarPrivate;
3281 }
3282 if (Reason != PDSA_Implicit) {
3283 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3284 << Reason << ReportHint
3285 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3286 } else if (DVar.ImplicitDSALoc.isValid()) {
3287 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3288 << getOpenMPClauseName(DVar.CKind);
3289 }
3290 }
3291
3292 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3293 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3294 bool IsAggregateOrDeclareTarget) {
3295 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3296 switch (M) {
3297 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3298 Kind = OMPC_MAP_alloc;
3299 break;
3300 case OMPC_DEFAULTMAP_MODIFIER_to:
3301 Kind = OMPC_MAP_to;
3302 break;
3303 case OMPC_DEFAULTMAP_MODIFIER_from:
3304 Kind = OMPC_MAP_from;
3305 break;
3306 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3307 Kind = OMPC_MAP_tofrom;
3308 break;
3309 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3310 case OMPC_DEFAULTMAP_MODIFIER_last:
3311 llvm_unreachable("Unexpected defaultmap implicit behavior");
3312 case OMPC_DEFAULTMAP_MODIFIER_none:
3313 case OMPC_DEFAULTMAP_MODIFIER_default:
3314 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3315 // IsAggregateOrDeclareTarget could be true if:
3316 // 1. the implicit behavior for aggregate is tofrom
3317 // 2. it's a declare target link
3318 if (IsAggregateOrDeclareTarget) {
3319 Kind = OMPC_MAP_tofrom;
3320 break;
3321 }
3322 llvm_unreachable("Unexpected defaultmap implicit behavior");
3323 }
3324 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3325 return Kind;
3326 }
3327
3328 namespace {
3329 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3330 DSAStackTy *Stack;
3331 Sema &SemaRef;
3332 bool ErrorFound = false;
3333 bool TryCaptureCXXThisMembers = false;
3334 CapturedStmt *CS = nullptr;
3335 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3336 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3337 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3338 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3339
VisitSubCaptures(OMPExecutableDirective * S)3340 void VisitSubCaptures(OMPExecutableDirective *S) {
3341 // Check implicitly captured variables.
3342 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3343 return;
3344 if (S->getDirectiveKind() == OMPD_atomic ||
3345 S->getDirectiveKind() == OMPD_critical ||
3346 S->getDirectiveKind() == OMPD_section ||
3347 S->getDirectiveKind() == OMPD_master) {
3348 Visit(S->getAssociatedStmt());
3349 return;
3350 }
3351 visitSubCaptures(S->getInnermostCapturedStmt());
3352 // Try to capture inner this->member references to generate correct mappings
3353 // and diagnostics.
3354 if (TryCaptureCXXThisMembers ||
3355 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3356 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3357 [](const CapturedStmt::Capture &C) {
3358 return C.capturesThis();
3359 }))) {
3360 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3361 TryCaptureCXXThisMembers = true;
3362 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3363 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3364 }
3365 // In tasks firstprivates are not captured anymore, need to analyze them
3366 // explicitly.
3367 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3368 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3369 for (OMPClause *C : S->clauses())
3370 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3371 for (Expr *Ref : FC->varlists())
3372 Visit(Ref);
3373 }
3374 }
3375 }
3376
3377 public:
VisitDeclRefExpr(DeclRefExpr * E)3378 void VisitDeclRefExpr(DeclRefExpr *E) {
3379 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3380 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3381 E->isInstantiationDependent())
3382 return;
3383 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3384 // Check the datasharing rules for the expressions in the clauses.
3385 if (!CS) {
3386 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3387 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3388 Visit(CED->getInit());
3389 return;
3390 }
3391 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3392 // Do not analyze internal variables and do not enclose them into
3393 // implicit clauses.
3394 return;
3395 VD = VD->getCanonicalDecl();
3396 // Skip internally declared variables.
3397 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3398 !Stack->isImplicitTaskFirstprivate(VD))
3399 return;
3400 // Skip allocators in uses_allocators clauses.
3401 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3402 return;
3403
3404 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3405 // Check if the variable has explicit DSA set and stop analysis if it so.
3406 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3407 return;
3408
3409 // Skip internally declared static variables.
3410 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3411 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3412 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3413 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3414 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3415 !Stack->isImplicitTaskFirstprivate(VD))
3416 return;
3417
3418 SourceLocation ELoc = E->getExprLoc();
3419 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3420 // The default(none) clause requires that each variable that is referenced
3421 // in the construct, and does not have a predetermined data-sharing
3422 // attribute, must have its data-sharing attribute explicitly determined
3423 // by being listed in a data-sharing attribute clause.
3424 if (DVar.CKind == OMPC_unknown &&
3425 (Stack->getDefaultDSA() == DSA_none ||
3426 Stack->getDefaultDSA() == DSA_firstprivate) &&
3427 isImplicitOrExplicitTaskingRegion(DKind) &&
3428 VarsWithInheritedDSA.count(VD) == 0) {
3429 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3430 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3431 DSAStackTy::DSAVarData DVar =
3432 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3433 InheritedDSA = DVar.CKind == OMPC_unknown;
3434 }
3435 if (InheritedDSA)
3436 VarsWithInheritedDSA[VD] = E;
3437 return;
3438 }
3439
3440 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3441 // If implicit-behavior is none, each variable referenced in the
3442 // construct that does not have a predetermined data-sharing attribute
3443 // and does not appear in a to or link clause on a declare target
3444 // directive must be listed in a data-mapping attribute clause, a
3445 // data-haring attribute clause (including a data-sharing attribute
3446 // clause on a combined construct where target. is one of the
3447 // constituent constructs), or an is_device_ptr clause.
3448 OpenMPDefaultmapClauseKind ClauseKind =
3449 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3450 if (SemaRef.getLangOpts().OpenMP >= 50) {
3451 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3452 OMPC_DEFAULTMAP_MODIFIER_none;
3453 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3454 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3455 // Only check for data-mapping attribute and is_device_ptr here
3456 // since we have already make sure that the declaration does not
3457 // have a data-sharing attribute above
3458 if (!Stack->checkMappableExprComponentListsForDecl(
3459 VD, /*CurrentRegionOnly=*/true,
3460 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3461 MapExprComponents,
3462 OpenMPClauseKind) {
3463 auto MI = MapExprComponents.rbegin();
3464 auto ME = MapExprComponents.rend();
3465 return MI != ME && MI->getAssociatedDeclaration() == VD;
3466 })) {
3467 VarsWithInheritedDSA[VD] = E;
3468 return;
3469 }
3470 }
3471 }
3472
3473 if (isOpenMPTargetExecutionDirective(DKind) &&
3474 !Stack->isLoopControlVariable(VD).first) {
3475 if (!Stack->checkMappableExprComponentListsForDecl(
3476 VD, /*CurrentRegionOnly=*/true,
3477 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3478 StackComponents,
3479 OpenMPClauseKind) {
3480 // Variable is used if it has been marked as an array, array
3481 // section, array shaping or the variable iself.
3482 return StackComponents.size() == 1 ||
3483 std::all_of(
3484 std::next(StackComponents.rbegin()),
3485 StackComponents.rend(),
3486 [](const OMPClauseMappableExprCommon::
3487 MappableComponent &MC) {
3488 return MC.getAssociatedDeclaration() ==
3489 nullptr &&
3490 (isa<OMPArraySectionExpr>(
3491 MC.getAssociatedExpression()) ||
3492 isa<OMPArrayShapingExpr>(
3493 MC.getAssociatedExpression()) ||
3494 isa<ArraySubscriptExpr>(
3495 MC.getAssociatedExpression()));
3496 });
3497 })) {
3498 bool IsFirstprivate = false;
3499 // By default lambdas are captured as firstprivates.
3500 if (const auto *RD =
3501 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3502 IsFirstprivate = RD->isLambda();
3503 IsFirstprivate =
3504 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3505 if (IsFirstprivate) {
3506 ImplicitFirstprivate.emplace_back(E);
3507 } else {
3508 OpenMPDefaultmapClauseModifier M =
3509 Stack->getDefaultmapModifier(ClauseKind);
3510 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3511 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3512 ImplicitMap[Kind].emplace_back(E);
3513 }
3514 return;
3515 }
3516 }
3517
3518 // OpenMP [2.9.3.6, Restrictions, p.2]
3519 // A list item that appears in a reduction clause of the innermost
3520 // enclosing worksharing or parallel construct may not be accessed in an
3521 // explicit task.
3522 DVar = Stack->hasInnermostDSA(
3523 VD,
3524 [](OpenMPClauseKind C, bool AppliedToPointee) {
3525 return C == OMPC_reduction && !AppliedToPointee;
3526 },
3527 [](OpenMPDirectiveKind K) {
3528 return isOpenMPParallelDirective(K) ||
3529 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3530 },
3531 /*FromParent=*/true);
3532 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3533 ErrorFound = true;
3534 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3535 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3536 return;
3537 }
3538
3539 // Define implicit data-sharing attributes for task.
3540 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3541 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3542 (Stack->getDefaultDSA() == DSA_firstprivate &&
3543 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3544 !Stack->isLoopControlVariable(VD).first) {
3545 ImplicitFirstprivate.push_back(E);
3546 return;
3547 }
3548
3549 // Store implicitly used globals with declare target link for parent
3550 // target.
3551 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3552 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3553 Stack->addToParentTargetRegionLinkGlobals(E);
3554 return;
3555 }
3556 }
3557 }
VisitMemberExpr(MemberExpr * E)3558 void VisitMemberExpr(MemberExpr *E) {
3559 if (E->isTypeDependent() || E->isValueDependent() ||
3560 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3561 return;
3562 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3563 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3564 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3565 if (!FD)
3566 return;
3567 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3568 // Check if the variable has explicit DSA set and stop analysis if it
3569 // so.
3570 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3571 return;
3572
3573 if (isOpenMPTargetExecutionDirective(DKind) &&
3574 !Stack->isLoopControlVariable(FD).first &&
3575 !Stack->checkMappableExprComponentListsForDecl(
3576 FD, /*CurrentRegionOnly=*/true,
3577 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3578 StackComponents,
3579 OpenMPClauseKind) {
3580 return isa<CXXThisExpr>(
3581 cast<MemberExpr>(
3582 StackComponents.back().getAssociatedExpression())
3583 ->getBase()
3584 ->IgnoreParens());
3585 })) {
3586 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3587 // A bit-field cannot appear in a map clause.
3588 //
3589 if (FD->isBitField())
3590 return;
3591
3592 // Check to see if the member expression is referencing a class that
3593 // has already been explicitly mapped
3594 if (Stack->isClassPreviouslyMapped(TE->getType()))
3595 return;
3596
3597 OpenMPDefaultmapClauseModifier Modifier =
3598 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3599 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3600 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3601 ImplicitMap[Kind].emplace_back(E);
3602 return;
3603 }
3604
3605 SourceLocation ELoc = E->getExprLoc();
3606 // OpenMP [2.9.3.6, Restrictions, p.2]
3607 // A list item that appears in a reduction clause of the innermost
3608 // enclosing worksharing or parallel construct may not be accessed in
3609 // an explicit task.
3610 DVar = Stack->hasInnermostDSA(
3611 FD,
3612 [](OpenMPClauseKind C, bool AppliedToPointee) {
3613 return C == OMPC_reduction && !AppliedToPointee;
3614 },
3615 [](OpenMPDirectiveKind K) {
3616 return isOpenMPParallelDirective(K) ||
3617 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3618 },
3619 /*FromParent=*/true);
3620 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3621 ErrorFound = true;
3622 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3623 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3624 return;
3625 }
3626
3627 // Define implicit data-sharing attributes for task.
3628 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3629 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3630 !Stack->isLoopControlVariable(FD).first) {
3631 // Check if there is a captured expression for the current field in the
3632 // region. Do not mark it as firstprivate unless there is no captured
3633 // expression.
3634 // TODO: try to make it firstprivate.
3635 if (DVar.CKind != OMPC_unknown)
3636 ImplicitFirstprivate.push_back(E);
3637 }
3638 return;
3639 }
3640 if (isOpenMPTargetExecutionDirective(DKind)) {
3641 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3642 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3643 Stack->getCurrentDirective(),
3644 /*NoDiagnose=*/true))
3645 return;
3646 const auto *VD = cast<ValueDecl>(
3647 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3648 if (!Stack->checkMappableExprComponentListsForDecl(
3649 VD, /*CurrentRegionOnly=*/true,
3650 [&CurComponents](
3651 OMPClauseMappableExprCommon::MappableExprComponentListRef
3652 StackComponents,
3653 OpenMPClauseKind) {
3654 auto CCI = CurComponents.rbegin();
3655 auto CCE = CurComponents.rend();
3656 for (const auto &SC : llvm::reverse(StackComponents)) {
3657 // Do both expressions have the same kind?
3658 if (CCI->getAssociatedExpression()->getStmtClass() !=
3659 SC.getAssociatedExpression()->getStmtClass())
3660 if (!((isa<OMPArraySectionExpr>(
3661 SC.getAssociatedExpression()) ||
3662 isa<OMPArrayShapingExpr>(
3663 SC.getAssociatedExpression())) &&
3664 isa<ArraySubscriptExpr>(
3665 CCI->getAssociatedExpression())))
3666 return false;
3667
3668 const Decl *CCD = CCI->getAssociatedDeclaration();
3669 const Decl *SCD = SC.getAssociatedDeclaration();
3670 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3671 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3672 if (SCD != CCD)
3673 return false;
3674 std::advance(CCI, 1);
3675 if (CCI == CCE)
3676 break;
3677 }
3678 return true;
3679 })) {
3680 Visit(E->getBase());
3681 }
3682 } else if (!TryCaptureCXXThisMembers) {
3683 Visit(E->getBase());
3684 }
3685 }
VisitOMPExecutableDirective(OMPExecutableDirective * S)3686 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3687 for (OMPClause *C : S->clauses()) {
3688 // Skip analysis of arguments of implicitly defined firstprivate clause
3689 // for task|target directives.
3690 // Skip analysis of arguments of implicitly defined map clause for target
3691 // directives.
3692 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3693 C->isImplicit() &&
3694 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3695 for (Stmt *CC : C->children()) {
3696 if (CC)
3697 Visit(CC);
3698 }
3699 }
3700 }
3701 // Check implicitly captured variables.
3702 VisitSubCaptures(S);
3703 }
VisitStmt(Stmt * S)3704 void VisitStmt(Stmt *S) {
3705 for (Stmt *C : S->children()) {
3706 if (C) {
3707 // Check implicitly captured variables in the task-based directives to
3708 // check if they must be firstprivatized.
3709 Visit(C);
3710 }
3711 }
3712 }
3713
visitSubCaptures(CapturedStmt * S)3714 void visitSubCaptures(CapturedStmt *S) {
3715 for (const CapturedStmt::Capture &Cap : S->captures()) {
3716 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3717 continue;
3718 VarDecl *VD = Cap.getCapturedVar();
3719 // Do not try to map the variable if it or its sub-component was mapped
3720 // already.
3721 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3722 Stack->checkMappableExprComponentListsForDecl(
3723 VD, /*CurrentRegionOnly=*/true,
3724 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3725 OpenMPClauseKind) { return true; }))
3726 continue;
3727 DeclRefExpr *DRE = buildDeclRefExpr(
3728 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3729 Cap.getLocation(), /*RefersToCapture=*/true);
3730 Visit(DRE);
3731 }
3732 }
isErrorFound() const3733 bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const3734 ArrayRef<Expr *> getImplicitFirstprivate() const {
3735 return ImplicitFirstprivate;
3736 }
getImplicitMap(OpenMPDefaultmapClauseKind Kind) const3737 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3738 return ImplicitMap[Kind];
3739 }
getVarsWithInheritedDSA() const3740 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3741 return VarsWithInheritedDSA;
3742 }
3743
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)3744 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3745 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3746 // Process declare target link variables for the target directives.
3747 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3748 for (DeclRefExpr *E : Stack->getLinkGlobals())
3749 Visit(E);
3750 }
3751 }
3752 };
3753 } // namespace
3754
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)3755 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3756 switch (DKind) {
3757 case OMPD_parallel:
3758 case OMPD_parallel_for:
3759 case OMPD_parallel_for_simd:
3760 case OMPD_parallel_sections:
3761 case OMPD_parallel_master:
3762 case OMPD_teams:
3763 case OMPD_teams_distribute:
3764 case OMPD_teams_distribute_simd: {
3765 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3766 QualType KmpInt32PtrTy =
3767 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3768 Sema::CapturedParamNameType Params[] = {
3769 std::make_pair(".global_tid.", KmpInt32PtrTy),
3770 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3771 std::make_pair(StringRef(), QualType()) // __context with shared vars
3772 };
3773 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3774 Params);
3775 break;
3776 }
3777 case OMPD_target_teams:
3778 case OMPD_target_parallel:
3779 case OMPD_target_parallel_for:
3780 case OMPD_target_parallel_for_simd:
3781 case OMPD_target_teams_distribute:
3782 case OMPD_target_teams_distribute_simd: {
3783 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3784 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3785 QualType KmpInt32PtrTy =
3786 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3787 QualType Args[] = {VoidPtrTy};
3788 FunctionProtoType::ExtProtoInfo EPI;
3789 EPI.Variadic = true;
3790 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3791 Sema::CapturedParamNameType Params[] = {
3792 std::make_pair(".global_tid.", KmpInt32Ty),
3793 std::make_pair(".part_id.", KmpInt32PtrTy),
3794 std::make_pair(".privates.", VoidPtrTy),
3795 std::make_pair(
3796 ".copy_fn.",
3797 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3798 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3799 std::make_pair(StringRef(), QualType()) // __context with shared vars
3800 };
3801 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3802 Params, /*OpenMPCaptureLevel=*/0);
3803 // Mark this captured region as inlined, because we don't use outlined
3804 // function directly.
3805 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3806 AlwaysInlineAttr::CreateImplicit(
3807 Context, {}, AttributeCommonInfo::AS_Keyword,
3808 AlwaysInlineAttr::Keyword_forceinline));
3809 Sema::CapturedParamNameType ParamsTarget[] = {
3810 std::make_pair(StringRef(), QualType()) // __context with shared vars
3811 };
3812 // Start a captured region for 'target' with no implicit parameters.
3813 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3814 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3815 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3816 std::make_pair(".global_tid.", KmpInt32PtrTy),
3817 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3818 std::make_pair(StringRef(), QualType()) // __context with shared vars
3819 };
3820 // Start a captured region for 'teams' or 'parallel'. Both regions have
3821 // the same implicit parameters.
3822 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3823 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3824 break;
3825 }
3826 case OMPD_target:
3827 case OMPD_target_simd: {
3828 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3829 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3830 QualType KmpInt32PtrTy =
3831 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3832 QualType Args[] = {VoidPtrTy};
3833 FunctionProtoType::ExtProtoInfo EPI;
3834 EPI.Variadic = true;
3835 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3836 Sema::CapturedParamNameType Params[] = {
3837 std::make_pair(".global_tid.", KmpInt32Ty),
3838 std::make_pair(".part_id.", KmpInt32PtrTy),
3839 std::make_pair(".privates.", VoidPtrTy),
3840 std::make_pair(
3841 ".copy_fn.",
3842 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3843 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3844 std::make_pair(StringRef(), QualType()) // __context with shared vars
3845 };
3846 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3847 Params, /*OpenMPCaptureLevel=*/0);
3848 // Mark this captured region as inlined, because we don't use outlined
3849 // function directly.
3850 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3851 AlwaysInlineAttr::CreateImplicit(
3852 Context, {}, AttributeCommonInfo::AS_Keyword,
3853 AlwaysInlineAttr::Keyword_forceinline));
3854 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3855 std::make_pair(StringRef(), QualType()),
3856 /*OpenMPCaptureLevel=*/1);
3857 break;
3858 }
3859 case OMPD_atomic:
3860 case OMPD_critical:
3861 case OMPD_section:
3862 case OMPD_master:
3863 break;
3864 case OMPD_simd:
3865 case OMPD_for:
3866 case OMPD_for_simd:
3867 case OMPD_sections:
3868 case OMPD_single:
3869 case OMPD_taskgroup:
3870 case OMPD_distribute:
3871 case OMPD_distribute_simd:
3872 case OMPD_ordered:
3873 case OMPD_target_data: {
3874 Sema::CapturedParamNameType Params[] = {
3875 std::make_pair(StringRef(), QualType()) // __context with shared vars
3876 };
3877 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3878 Params);
3879 break;
3880 }
3881 case OMPD_task: {
3882 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3883 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3884 QualType KmpInt32PtrTy =
3885 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3886 QualType Args[] = {VoidPtrTy};
3887 FunctionProtoType::ExtProtoInfo EPI;
3888 EPI.Variadic = true;
3889 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3890 Sema::CapturedParamNameType Params[] = {
3891 std::make_pair(".global_tid.", KmpInt32Ty),
3892 std::make_pair(".part_id.", KmpInt32PtrTy),
3893 std::make_pair(".privates.", VoidPtrTy),
3894 std::make_pair(
3895 ".copy_fn.",
3896 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3897 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3898 std::make_pair(StringRef(), QualType()) // __context with shared vars
3899 };
3900 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3901 Params);
3902 // Mark this captured region as inlined, because we don't use outlined
3903 // function directly.
3904 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3905 AlwaysInlineAttr::CreateImplicit(
3906 Context, {}, AttributeCommonInfo::AS_Keyword,
3907 AlwaysInlineAttr::Keyword_forceinline));
3908 break;
3909 }
3910 case OMPD_taskloop:
3911 case OMPD_taskloop_simd:
3912 case OMPD_master_taskloop:
3913 case OMPD_master_taskloop_simd: {
3914 QualType KmpInt32Ty =
3915 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3916 .withConst();
3917 QualType KmpUInt64Ty =
3918 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3919 .withConst();
3920 QualType KmpInt64Ty =
3921 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3922 .withConst();
3923 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3924 QualType KmpInt32PtrTy =
3925 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3926 QualType Args[] = {VoidPtrTy};
3927 FunctionProtoType::ExtProtoInfo EPI;
3928 EPI.Variadic = true;
3929 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3930 Sema::CapturedParamNameType Params[] = {
3931 std::make_pair(".global_tid.", KmpInt32Ty),
3932 std::make_pair(".part_id.", KmpInt32PtrTy),
3933 std::make_pair(".privates.", VoidPtrTy),
3934 std::make_pair(
3935 ".copy_fn.",
3936 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3937 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3938 std::make_pair(".lb.", KmpUInt64Ty),
3939 std::make_pair(".ub.", KmpUInt64Ty),
3940 std::make_pair(".st.", KmpInt64Ty),
3941 std::make_pair(".liter.", KmpInt32Ty),
3942 std::make_pair(".reductions.", VoidPtrTy),
3943 std::make_pair(StringRef(), QualType()) // __context with shared vars
3944 };
3945 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3946 Params);
3947 // Mark this captured region as inlined, because we don't use outlined
3948 // function directly.
3949 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3950 AlwaysInlineAttr::CreateImplicit(
3951 Context, {}, AttributeCommonInfo::AS_Keyword,
3952 AlwaysInlineAttr::Keyword_forceinline));
3953 break;
3954 }
3955 case OMPD_parallel_master_taskloop:
3956 case OMPD_parallel_master_taskloop_simd: {
3957 QualType KmpInt32Ty =
3958 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3959 .withConst();
3960 QualType KmpUInt64Ty =
3961 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3962 .withConst();
3963 QualType KmpInt64Ty =
3964 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3965 .withConst();
3966 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3967 QualType KmpInt32PtrTy =
3968 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3969 Sema::CapturedParamNameType ParamsParallel[] = {
3970 std::make_pair(".global_tid.", KmpInt32PtrTy),
3971 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3972 std::make_pair(StringRef(), QualType()) // __context with shared vars
3973 };
3974 // Start a captured region for 'parallel'.
3975 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3976 ParamsParallel, /*OpenMPCaptureLevel=*/0);
3977 QualType Args[] = {VoidPtrTy};
3978 FunctionProtoType::ExtProtoInfo EPI;
3979 EPI.Variadic = true;
3980 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3981 Sema::CapturedParamNameType Params[] = {
3982 std::make_pair(".global_tid.", KmpInt32Ty),
3983 std::make_pair(".part_id.", KmpInt32PtrTy),
3984 std::make_pair(".privates.", VoidPtrTy),
3985 std::make_pair(
3986 ".copy_fn.",
3987 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3988 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3989 std::make_pair(".lb.", KmpUInt64Ty),
3990 std::make_pair(".ub.", KmpUInt64Ty),
3991 std::make_pair(".st.", KmpInt64Ty),
3992 std::make_pair(".liter.", KmpInt32Ty),
3993 std::make_pair(".reductions.", VoidPtrTy),
3994 std::make_pair(StringRef(), QualType()) // __context with shared vars
3995 };
3996 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3997 Params, /*OpenMPCaptureLevel=*/1);
3998 // Mark this captured region as inlined, because we don't use outlined
3999 // function directly.
4000 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4001 AlwaysInlineAttr::CreateImplicit(
4002 Context, {}, AttributeCommonInfo::AS_Keyword,
4003 AlwaysInlineAttr::Keyword_forceinline));
4004 break;
4005 }
4006 case OMPD_distribute_parallel_for_simd:
4007 case OMPD_distribute_parallel_for: {
4008 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4009 QualType KmpInt32PtrTy =
4010 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4011 Sema::CapturedParamNameType Params[] = {
4012 std::make_pair(".global_tid.", KmpInt32PtrTy),
4013 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4014 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4015 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4016 std::make_pair(StringRef(), QualType()) // __context with shared vars
4017 };
4018 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4019 Params);
4020 break;
4021 }
4022 case OMPD_target_teams_distribute_parallel_for:
4023 case OMPD_target_teams_distribute_parallel_for_simd: {
4024 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4025 QualType KmpInt32PtrTy =
4026 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4027 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4028
4029 QualType Args[] = {VoidPtrTy};
4030 FunctionProtoType::ExtProtoInfo EPI;
4031 EPI.Variadic = true;
4032 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4033 Sema::CapturedParamNameType Params[] = {
4034 std::make_pair(".global_tid.", KmpInt32Ty),
4035 std::make_pair(".part_id.", KmpInt32PtrTy),
4036 std::make_pair(".privates.", VoidPtrTy),
4037 std::make_pair(
4038 ".copy_fn.",
4039 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4040 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4041 std::make_pair(StringRef(), QualType()) // __context with shared vars
4042 };
4043 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4044 Params, /*OpenMPCaptureLevel=*/0);
4045 // Mark this captured region as inlined, because we don't use outlined
4046 // function directly.
4047 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4048 AlwaysInlineAttr::CreateImplicit(
4049 Context, {}, AttributeCommonInfo::AS_Keyword,
4050 AlwaysInlineAttr::Keyword_forceinline));
4051 Sema::CapturedParamNameType ParamsTarget[] = {
4052 std::make_pair(StringRef(), QualType()) // __context with shared vars
4053 };
4054 // Start a captured region for 'target' with no implicit parameters.
4055 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4056 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4057
4058 Sema::CapturedParamNameType ParamsTeams[] = {
4059 std::make_pair(".global_tid.", KmpInt32PtrTy),
4060 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4061 std::make_pair(StringRef(), QualType()) // __context with shared vars
4062 };
4063 // Start a captured region for 'target' with no implicit parameters.
4064 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4065 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4066
4067 Sema::CapturedParamNameType ParamsParallel[] = {
4068 std::make_pair(".global_tid.", KmpInt32PtrTy),
4069 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4070 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4071 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4072 std::make_pair(StringRef(), QualType()) // __context with shared vars
4073 };
4074 // Start a captured region for 'teams' or 'parallel'. Both regions have
4075 // the same implicit parameters.
4076 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4077 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4078 break;
4079 }
4080
4081 case OMPD_teams_distribute_parallel_for:
4082 case OMPD_teams_distribute_parallel_for_simd: {
4083 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4084 QualType KmpInt32PtrTy =
4085 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4086
4087 Sema::CapturedParamNameType ParamsTeams[] = {
4088 std::make_pair(".global_tid.", KmpInt32PtrTy),
4089 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4090 std::make_pair(StringRef(), QualType()) // __context with shared vars
4091 };
4092 // Start a captured region for 'target' with no implicit parameters.
4093 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4094 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4095
4096 Sema::CapturedParamNameType ParamsParallel[] = {
4097 std::make_pair(".global_tid.", KmpInt32PtrTy),
4098 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4099 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4100 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4101 std::make_pair(StringRef(), QualType()) // __context with shared vars
4102 };
4103 // Start a captured region for 'teams' or 'parallel'. Both regions have
4104 // the same implicit parameters.
4105 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4106 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4107 break;
4108 }
4109 case OMPD_target_update:
4110 case OMPD_target_enter_data:
4111 case OMPD_target_exit_data: {
4112 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4113 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4114 QualType KmpInt32PtrTy =
4115 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4116 QualType Args[] = {VoidPtrTy};
4117 FunctionProtoType::ExtProtoInfo EPI;
4118 EPI.Variadic = true;
4119 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4120 Sema::CapturedParamNameType Params[] = {
4121 std::make_pair(".global_tid.", KmpInt32Ty),
4122 std::make_pair(".part_id.", KmpInt32PtrTy),
4123 std::make_pair(".privates.", VoidPtrTy),
4124 std::make_pair(
4125 ".copy_fn.",
4126 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4127 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4128 std::make_pair(StringRef(), QualType()) // __context with shared vars
4129 };
4130 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4131 Params);
4132 // Mark this captured region as inlined, because we don't use outlined
4133 // function directly.
4134 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4135 AlwaysInlineAttr::CreateImplicit(
4136 Context, {}, AttributeCommonInfo::AS_Keyword,
4137 AlwaysInlineAttr::Keyword_forceinline));
4138 break;
4139 }
4140 case OMPD_threadprivate:
4141 case OMPD_allocate:
4142 case OMPD_taskyield:
4143 case OMPD_barrier:
4144 case OMPD_taskwait:
4145 case OMPD_cancellation_point:
4146 case OMPD_cancel:
4147 case OMPD_flush:
4148 case OMPD_depobj:
4149 case OMPD_scan:
4150 case OMPD_declare_reduction:
4151 case OMPD_declare_mapper:
4152 case OMPD_declare_simd:
4153 case OMPD_declare_target:
4154 case OMPD_end_declare_target:
4155 case OMPD_requires:
4156 case OMPD_declare_variant:
4157 case OMPD_begin_declare_variant:
4158 case OMPD_end_declare_variant:
4159 llvm_unreachable("OpenMP Directive is not allowed");
4160 case OMPD_unknown:
4161 default:
4162 llvm_unreachable("Unknown OpenMP directive");
4163 }
4164 DSAStack->setContext(CurContext);
4165 }
4166
getNumberOfConstructScopes(unsigned Level) const4167 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4168 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4169 }
4170
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4171 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4172 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4173 getOpenMPCaptureRegions(CaptureRegions, DKind);
4174 return CaptureRegions.size();
4175 }
4176
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)4177 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4178 Expr *CaptureExpr, bool WithInit,
4179 bool AsExpression) {
4180 assert(CaptureExpr);
4181 ASTContext &C = S.getASTContext();
4182 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4183 QualType Ty = Init->getType();
4184 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4185 if (S.getLangOpts().CPlusPlus) {
4186 Ty = C.getLValueReferenceType(Ty);
4187 } else {
4188 Ty = C.getPointerType(Ty);
4189 ExprResult Res =
4190 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4191 if (!Res.isUsable())
4192 return nullptr;
4193 Init = Res.get();
4194 }
4195 WithInit = true;
4196 }
4197 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4198 CaptureExpr->getBeginLoc());
4199 if (!WithInit)
4200 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4201 S.CurContext->addHiddenDecl(CED);
4202 Sema::TentativeAnalysisScope Trap(S);
4203 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4204 return CED;
4205 }
4206
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4207 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4208 bool WithInit) {
4209 OMPCapturedExprDecl *CD;
4210 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4211 CD = cast<OMPCapturedExprDecl>(VD);
4212 else
4213 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4214 /*AsExpression=*/false);
4215 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4216 CaptureExpr->getExprLoc());
4217 }
4218
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4219 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4220 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4221 if (!Ref) {
4222 OMPCapturedExprDecl *CD = buildCaptureDecl(
4223 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4224 /*WithInit=*/true, /*AsExpression=*/true);
4225 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4226 CaptureExpr->getExprLoc());
4227 }
4228 ExprResult Res = Ref;
4229 if (!S.getLangOpts().CPlusPlus &&
4230 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4231 Ref->getType()->isPointerType()) {
4232 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4233 if (!Res.isUsable())
4234 return ExprError();
4235 }
4236 return S.DefaultLvalueConversion(Res.get());
4237 }
4238
4239 namespace {
4240 // OpenMP directives parsed in this section are represented as a
4241 // CapturedStatement with an associated statement. If a syntax error
4242 // is detected during the parsing of the associated statement, the
4243 // compiler must abort processing and close the CapturedStatement.
4244 //
4245 // Combined directives such as 'target parallel' have more than one
4246 // nested CapturedStatements. This RAII ensures that we unwind out
4247 // of all the nested CapturedStatements when an error is found.
4248 class CaptureRegionUnwinderRAII {
4249 private:
4250 Sema &S;
4251 bool &ErrorFound;
4252 OpenMPDirectiveKind DKind = OMPD_unknown;
4253
4254 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4255 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4256 OpenMPDirectiveKind DKind)
4257 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4258 ~CaptureRegionUnwinderRAII() {
4259 if (ErrorFound) {
4260 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4261 while (--ThisCaptureLevel >= 0)
4262 S.ActOnCapturedRegionError();
4263 }
4264 }
4265 };
4266 } // namespace
4267
tryCaptureOpenMPLambdas(ValueDecl * V)4268 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4269 // Capture variables captured by reference in lambdas for target-based
4270 // directives.
4271 if (!CurContext->isDependentContext() &&
4272 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4273 isOpenMPTargetDataManagementDirective(
4274 DSAStack->getCurrentDirective()))) {
4275 QualType Type = V->getType();
4276 if (const auto *RD = Type.getCanonicalType()
4277 .getNonReferenceType()
4278 ->getAsCXXRecordDecl()) {
4279 bool SavedForceCaptureByReferenceInTargetExecutable =
4280 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4281 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4282 /*V=*/true);
4283 if (RD->isLambda()) {
4284 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4285 FieldDecl *ThisCapture;
4286 RD->getCaptureFields(Captures, ThisCapture);
4287 for (const LambdaCapture &LC : RD->captures()) {
4288 if (LC.getCaptureKind() == LCK_ByRef) {
4289 VarDecl *VD = LC.getCapturedVar();
4290 DeclContext *VDC = VD->getDeclContext();
4291 if (!VDC->Encloses(CurContext))
4292 continue;
4293 MarkVariableReferenced(LC.getLocation(), VD);
4294 } else if (LC.getCaptureKind() == LCK_This) {
4295 QualType ThisTy = getCurrentThisType();
4296 if (!ThisTy.isNull() &&
4297 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4298 CheckCXXThisCapture(LC.getLocation());
4299 }
4300 }
4301 }
4302 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4303 SavedForceCaptureByReferenceInTargetExecutable);
4304 }
4305 }
4306 }
4307
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4308 static bool checkOrderedOrderSpecified(Sema &S,
4309 const ArrayRef<OMPClause *> Clauses) {
4310 const OMPOrderedClause *Ordered = nullptr;
4311 const OMPOrderClause *Order = nullptr;
4312
4313 for (const OMPClause *Clause : Clauses) {
4314 if (Clause->getClauseKind() == OMPC_ordered)
4315 Ordered = cast<OMPOrderedClause>(Clause);
4316 else if (Clause->getClauseKind() == OMPC_order) {
4317 Order = cast<OMPOrderClause>(Clause);
4318 if (Order->getKind() != OMPC_ORDER_concurrent)
4319 Order = nullptr;
4320 }
4321 if (Ordered && Order)
4322 break;
4323 }
4324
4325 if (Ordered && Order) {
4326 S.Diag(Order->getKindKwLoc(),
4327 diag::err_omp_simple_clause_incompatible_with_ordered)
4328 << getOpenMPClauseName(OMPC_order)
4329 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4330 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4331 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4332 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4333 return true;
4334 }
4335 return false;
4336 }
4337
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4338 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4339 ArrayRef<OMPClause *> Clauses) {
4340 if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4341 DSAStack->getCurrentDirective() == OMPD_critical ||
4342 DSAStack->getCurrentDirective() == OMPD_section ||
4343 DSAStack->getCurrentDirective() == OMPD_master)
4344 return S;
4345
4346 bool ErrorFound = false;
4347 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4348 *this, ErrorFound, DSAStack->getCurrentDirective());
4349 if (!S.isUsable()) {
4350 ErrorFound = true;
4351 return StmtError();
4352 }
4353
4354 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4355 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4356 OMPOrderedClause *OC = nullptr;
4357 OMPScheduleClause *SC = nullptr;
4358 SmallVector<const OMPLinearClause *, 4> LCs;
4359 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4360 // This is required for proper codegen.
4361 for (OMPClause *Clause : Clauses) {
4362 if (!LangOpts.OpenMPSimd &&
4363 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4364 Clause->getClauseKind() == OMPC_in_reduction) {
4365 // Capture taskgroup task_reduction descriptors inside the tasking regions
4366 // with the corresponding in_reduction items.
4367 auto *IRC = cast<OMPInReductionClause>(Clause);
4368 for (Expr *E : IRC->taskgroup_descriptors())
4369 if (E)
4370 MarkDeclarationsReferencedInExpr(E);
4371 }
4372 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4373 Clause->getClauseKind() == OMPC_copyprivate ||
4374 (getLangOpts().OpenMPUseTLS &&
4375 getASTContext().getTargetInfo().isTLSSupported() &&
4376 Clause->getClauseKind() == OMPC_copyin)) {
4377 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4378 // Mark all variables in private list clauses as used in inner region.
4379 for (Stmt *VarRef : Clause->children()) {
4380 if (auto *E = cast_or_null<Expr>(VarRef)) {
4381 MarkDeclarationsReferencedInExpr(E);
4382 }
4383 }
4384 DSAStack->setForceVarCapturing(/*V=*/false);
4385 } else if (CaptureRegions.size() > 1 ||
4386 CaptureRegions.back() != OMPD_unknown) {
4387 if (auto *C = OMPClauseWithPreInit::get(Clause))
4388 PICs.push_back(C);
4389 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4390 if (Expr *E = C->getPostUpdateExpr())
4391 MarkDeclarationsReferencedInExpr(E);
4392 }
4393 }
4394 if (Clause->getClauseKind() == OMPC_schedule)
4395 SC = cast<OMPScheduleClause>(Clause);
4396 else if (Clause->getClauseKind() == OMPC_ordered)
4397 OC = cast<OMPOrderedClause>(Clause);
4398 else if (Clause->getClauseKind() == OMPC_linear)
4399 LCs.push_back(cast<OMPLinearClause>(Clause));
4400 }
4401 // Capture allocator expressions if used.
4402 for (Expr *E : DSAStack->getInnerAllocators())
4403 MarkDeclarationsReferencedInExpr(E);
4404 // OpenMP, 2.7.1 Loop Construct, Restrictions
4405 // The nonmonotonic modifier cannot be specified if an ordered clause is
4406 // specified.
4407 if (SC &&
4408 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4409 SC->getSecondScheduleModifier() ==
4410 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4411 OC) {
4412 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4413 ? SC->getFirstScheduleModifierLoc()
4414 : SC->getSecondScheduleModifierLoc(),
4415 diag::err_omp_simple_clause_incompatible_with_ordered)
4416 << getOpenMPClauseName(OMPC_schedule)
4417 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4418 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4419 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4420 ErrorFound = true;
4421 }
4422 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4423 // If an order(concurrent) clause is present, an ordered clause may not appear
4424 // on the same directive.
4425 if (checkOrderedOrderSpecified(*this, Clauses))
4426 ErrorFound = true;
4427 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4428 for (const OMPLinearClause *C : LCs) {
4429 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4430 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4431 }
4432 ErrorFound = true;
4433 }
4434 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4435 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4436 OC->getNumForLoops()) {
4437 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4438 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4439 ErrorFound = true;
4440 }
4441 if (ErrorFound) {
4442 return StmtError();
4443 }
4444 StmtResult SR = S;
4445 unsigned CompletedRegions = 0;
4446 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4447 // Mark all variables in private list clauses as used in inner region.
4448 // Required for proper codegen of combined directives.
4449 // TODO: add processing for other clauses.
4450 if (ThisCaptureRegion != OMPD_unknown) {
4451 for (const clang::OMPClauseWithPreInit *C : PICs) {
4452 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4453 // Find the particular capture region for the clause if the
4454 // directive is a combined one with multiple capture regions.
4455 // If the directive is not a combined one, the capture region
4456 // associated with the clause is OMPD_unknown and is generated
4457 // only once.
4458 if (CaptureRegion == ThisCaptureRegion ||
4459 CaptureRegion == OMPD_unknown) {
4460 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4461 for (Decl *D : DS->decls())
4462 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4463 }
4464 }
4465 }
4466 }
4467 if (ThisCaptureRegion == OMPD_target) {
4468 // Capture allocator traits in the target region. They are used implicitly
4469 // and, thus, are not captured by default.
4470 for (OMPClause *C : Clauses) {
4471 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4472 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4473 ++I) {
4474 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4475 if (Expr *E = D.AllocatorTraits)
4476 MarkDeclarationsReferencedInExpr(E);
4477 }
4478 continue;
4479 }
4480 }
4481 }
4482 if (++CompletedRegions == CaptureRegions.size())
4483 DSAStack->setBodyComplete();
4484 SR = ActOnCapturedRegionEnd(SR.get());
4485 }
4486 return SR;
4487 }
4488
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4489 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4490 OpenMPDirectiveKind CancelRegion,
4491 SourceLocation StartLoc) {
4492 // CancelRegion is only needed for cancel and cancellation_point.
4493 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4494 return false;
4495
4496 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4497 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4498 return false;
4499
4500 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4501 << getOpenMPDirectiveName(CancelRegion);
4502 return true;
4503 }
4504
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4505 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4506 OpenMPDirectiveKind CurrentRegion,
4507 const DeclarationNameInfo &CurrentName,
4508 OpenMPDirectiveKind CancelRegion,
4509 SourceLocation StartLoc) {
4510 if (Stack->getCurScope()) {
4511 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4512 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4513 bool NestingProhibited = false;
4514 bool CloseNesting = true;
4515 bool OrphanSeen = false;
4516 enum {
4517 NoRecommend,
4518 ShouldBeInParallelRegion,
4519 ShouldBeInOrderedRegion,
4520 ShouldBeInTargetRegion,
4521 ShouldBeInTeamsRegion,
4522 ShouldBeInLoopSimdRegion,
4523 } Recommend = NoRecommend;
4524 if (isOpenMPSimdDirective(ParentRegion) &&
4525 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4526 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4527 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4528 CurrentRegion != OMPD_scan))) {
4529 // OpenMP [2.16, Nesting of Regions]
4530 // OpenMP constructs may not be nested inside a simd region.
4531 // OpenMP [2.8.1,simd Construct, Restrictions]
4532 // An ordered construct with the simd clause is the only OpenMP
4533 // construct that can appear in the simd region.
4534 // Allowing a SIMD construct nested in another SIMD construct is an
4535 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4536 // message.
4537 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4538 // The only OpenMP constructs that can be encountered during execution of
4539 // a simd region are the atomic construct, the loop construct, the simd
4540 // construct and the ordered construct with the simd clause.
4541 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4542 ? diag::err_omp_prohibited_region_simd
4543 : diag::warn_omp_nesting_simd)
4544 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4545 return CurrentRegion != OMPD_simd;
4546 }
4547 if (ParentRegion == OMPD_atomic) {
4548 // OpenMP [2.16, Nesting of Regions]
4549 // OpenMP constructs may not be nested inside an atomic region.
4550 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4551 return true;
4552 }
4553 if (CurrentRegion == OMPD_section) {
4554 // OpenMP [2.7.2, sections Construct, Restrictions]
4555 // Orphaned section directives are prohibited. That is, the section
4556 // directives must appear within the sections construct and must not be
4557 // encountered elsewhere in the sections region.
4558 if (ParentRegion != OMPD_sections &&
4559 ParentRegion != OMPD_parallel_sections) {
4560 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4561 << (ParentRegion != OMPD_unknown)
4562 << getOpenMPDirectiveName(ParentRegion);
4563 return true;
4564 }
4565 return false;
4566 }
4567 // Allow some constructs (except teams and cancellation constructs) to be
4568 // orphaned (they could be used in functions, called from OpenMP regions
4569 // with the required preconditions).
4570 if (ParentRegion == OMPD_unknown &&
4571 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4572 CurrentRegion != OMPD_cancellation_point &&
4573 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4574 return false;
4575 if (CurrentRegion == OMPD_cancellation_point ||
4576 CurrentRegion == OMPD_cancel) {
4577 // OpenMP [2.16, Nesting of Regions]
4578 // A cancellation point construct for which construct-type-clause is
4579 // taskgroup must be nested inside a task construct. A cancellation
4580 // point construct for which construct-type-clause is not taskgroup must
4581 // be closely nested inside an OpenMP construct that matches the type
4582 // specified in construct-type-clause.
4583 // A cancel construct for which construct-type-clause is taskgroup must be
4584 // nested inside a task construct. A cancel construct for which
4585 // construct-type-clause is not taskgroup must be closely nested inside an
4586 // OpenMP construct that matches the type specified in
4587 // construct-type-clause.
4588 NestingProhibited =
4589 !((CancelRegion == OMPD_parallel &&
4590 (ParentRegion == OMPD_parallel ||
4591 ParentRegion == OMPD_target_parallel)) ||
4592 (CancelRegion == OMPD_for &&
4593 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4594 ParentRegion == OMPD_target_parallel_for ||
4595 ParentRegion == OMPD_distribute_parallel_for ||
4596 ParentRegion == OMPD_teams_distribute_parallel_for ||
4597 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4598 (CancelRegion == OMPD_taskgroup &&
4599 (ParentRegion == OMPD_task ||
4600 (SemaRef.getLangOpts().OpenMP >= 50 &&
4601 (ParentRegion == OMPD_taskloop ||
4602 ParentRegion == OMPD_master_taskloop ||
4603 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4604 (CancelRegion == OMPD_sections &&
4605 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4606 ParentRegion == OMPD_parallel_sections)));
4607 OrphanSeen = ParentRegion == OMPD_unknown;
4608 } else if (CurrentRegion == OMPD_master) {
4609 // OpenMP [2.16, Nesting of Regions]
4610 // A master region may not be closely nested inside a worksharing,
4611 // atomic, or explicit task region.
4612 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4613 isOpenMPTaskingDirective(ParentRegion);
4614 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4615 // OpenMP [2.16, Nesting of Regions]
4616 // A critical region may not be nested (closely or otherwise) inside a
4617 // critical region with the same name. Note that this restriction is not
4618 // sufficient to prevent deadlock.
4619 SourceLocation PreviousCriticalLoc;
4620 bool DeadLock = Stack->hasDirective(
4621 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4622 const DeclarationNameInfo &DNI,
4623 SourceLocation Loc) {
4624 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4625 PreviousCriticalLoc = Loc;
4626 return true;
4627 }
4628 return false;
4629 },
4630 false /* skip top directive */);
4631 if (DeadLock) {
4632 SemaRef.Diag(StartLoc,
4633 diag::err_omp_prohibited_region_critical_same_name)
4634 << CurrentName.getName();
4635 if (PreviousCriticalLoc.isValid())
4636 SemaRef.Diag(PreviousCriticalLoc,
4637 diag::note_omp_previous_critical_region);
4638 return true;
4639 }
4640 } else if (CurrentRegion == OMPD_barrier) {
4641 // OpenMP [2.16, Nesting of Regions]
4642 // A barrier region may not be closely nested inside a worksharing,
4643 // explicit task, critical, ordered, atomic, or master region.
4644 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4645 isOpenMPTaskingDirective(ParentRegion) ||
4646 ParentRegion == OMPD_master ||
4647 ParentRegion == OMPD_parallel_master ||
4648 ParentRegion == OMPD_critical ||
4649 ParentRegion == OMPD_ordered;
4650 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4651 !isOpenMPParallelDirective(CurrentRegion) &&
4652 !isOpenMPTeamsDirective(CurrentRegion)) {
4653 // OpenMP [2.16, Nesting of Regions]
4654 // A worksharing region may not be closely nested inside a worksharing,
4655 // explicit task, critical, ordered, atomic, or master region.
4656 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4657 isOpenMPTaskingDirective(ParentRegion) ||
4658 ParentRegion == OMPD_master ||
4659 ParentRegion == OMPD_parallel_master ||
4660 ParentRegion == OMPD_critical ||
4661 ParentRegion == OMPD_ordered;
4662 Recommend = ShouldBeInParallelRegion;
4663 } else if (CurrentRegion == OMPD_ordered) {
4664 // OpenMP [2.16, Nesting of Regions]
4665 // An ordered region may not be closely nested inside a critical,
4666 // atomic, or explicit task region.
4667 // An ordered region must be closely nested inside a loop region (or
4668 // parallel loop region) with an ordered clause.
4669 // OpenMP [2.8.1,simd Construct, Restrictions]
4670 // An ordered construct with the simd clause is the only OpenMP construct
4671 // that can appear in the simd region.
4672 NestingProhibited = ParentRegion == OMPD_critical ||
4673 isOpenMPTaskingDirective(ParentRegion) ||
4674 !(isOpenMPSimdDirective(ParentRegion) ||
4675 Stack->isParentOrderedRegion());
4676 Recommend = ShouldBeInOrderedRegion;
4677 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4678 // OpenMP [2.16, Nesting of Regions]
4679 // If specified, a teams construct must be contained within a target
4680 // construct.
4681 NestingProhibited =
4682 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4683 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4684 ParentRegion != OMPD_target);
4685 OrphanSeen = ParentRegion == OMPD_unknown;
4686 Recommend = ShouldBeInTargetRegion;
4687 } else if (CurrentRegion == OMPD_scan) {
4688 // OpenMP [2.16, Nesting of Regions]
4689 // If specified, a teams construct must be contained within a target
4690 // construct.
4691 NestingProhibited =
4692 SemaRef.LangOpts.OpenMP < 50 ||
4693 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4694 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4695 ParentRegion != OMPD_parallel_for_simd);
4696 OrphanSeen = ParentRegion == OMPD_unknown;
4697 Recommend = ShouldBeInLoopSimdRegion;
4698 }
4699 if (!NestingProhibited &&
4700 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4701 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4702 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4703 // OpenMP [2.16, Nesting of Regions]
4704 // distribute, parallel, parallel sections, parallel workshare, and the
4705 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4706 // constructs that can be closely nested in the teams region.
4707 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4708 !isOpenMPDistributeDirective(CurrentRegion);
4709 Recommend = ShouldBeInParallelRegion;
4710 }
4711 if (!NestingProhibited &&
4712 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4713 // OpenMP 4.5 [2.17 Nesting of Regions]
4714 // The region associated with the distribute construct must be strictly
4715 // nested inside a teams region
4716 NestingProhibited =
4717 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4718 Recommend = ShouldBeInTeamsRegion;
4719 }
4720 if (!NestingProhibited &&
4721 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4722 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4723 // OpenMP 4.5 [2.17 Nesting of Regions]
4724 // If a target, target update, target data, target enter data, or
4725 // target exit data construct is encountered during execution of a
4726 // target region, the behavior is unspecified.
4727 NestingProhibited = Stack->hasDirective(
4728 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4729 SourceLocation) {
4730 if (isOpenMPTargetExecutionDirective(K)) {
4731 OffendingRegion = K;
4732 return true;
4733 }
4734 return false;
4735 },
4736 false /* don't skip top directive */);
4737 CloseNesting = false;
4738 }
4739 if (NestingProhibited) {
4740 if (OrphanSeen) {
4741 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4742 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4743 } else {
4744 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4745 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4746 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4747 }
4748 return true;
4749 }
4750 }
4751 return false;
4752 }
4753
4754 struct Kind2Unsigned {
4755 using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned4756 unsigned operator()(argument_type DK) { return unsigned(DK); }
4757 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)4758 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4759 ArrayRef<OMPClause *> Clauses,
4760 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4761 bool ErrorFound = false;
4762 unsigned NamedModifiersNumber = 0;
4763 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4764 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4765 SmallVector<SourceLocation, 4> NameModifierLoc;
4766 for (const OMPClause *C : Clauses) {
4767 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4768 // At most one if clause without a directive-name-modifier can appear on
4769 // the directive.
4770 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4771 if (FoundNameModifiers[CurNM]) {
4772 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4773 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4774 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4775 ErrorFound = true;
4776 } else if (CurNM != OMPD_unknown) {
4777 NameModifierLoc.push_back(IC->getNameModifierLoc());
4778 ++NamedModifiersNumber;
4779 }
4780 FoundNameModifiers[CurNM] = IC;
4781 if (CurNM == OMPD_unknown)
4782 continue;
4783 // Check if the specified name modifier is allowed for the current
4784 // directive.
4785 // At most one if clause with the particular directive-name-modifier can
4786 // appear on the directive.
4787 bool MatchFound = false;
4788 for (auto NM : AllowedNameModifiers) {
4789 if (CurNM == NM) {
4790 MatchFound = true;
4791 break;
4792 }
4793 }
4794 if (!MatchFound) {
4795 S.Diag(IC->getNameModifierLoc(),
4796 diag::err_omp_wrong_if_directive_name_modifier)
4797 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4798 ErrorFound = true;
4799 }
4800 }
4801 }
4802 // If any if clause on the directive includes a directive-name-modifier then
4803 // all if clauses on the directive must include a directive-name-modifier.
4804 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4805 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4806 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4807 diag::err_omp_no_more_if_clause);
4808 } else {
4809 std::string Values;
4810 std::string Sep(", ");
4811 unsigned AllowedCnt = 0;
4812 unsigned TotalAllowedNum =
4813 AllowedNameModifiers.size() - NamedModifiersNumber;
4814 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4815 ++Cnt) {
4816 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4817 if (!FoundNameModifiers[NM]) {
4818 Values += "'";
4819 Values += getOpenMPDirectiveName(NM);
4820 Values += "'";
4821 if (AllowedCnt + 2 == TotalAllowedNum)
4822 Values += " or ";
4823 else if (AllowedCnt + 1 != TotalAllowedNum)
4824 Values += Sep;
4825 ++AllowedCnt;
4826 }
4827 }
4828 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4829 diag::err_omp_unnamed_if_clause)
4830 << (TotalAllowedNum > 1) << Values;
4831 }
4832 for (SourceLocation Loc : NameModifierLoc) {
4833 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4834 }
4835 ErrorFound = true;
4836 }
4837 return ErrorFound;
4838 }
4839
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)4840 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4841 SourceLocation &ELoc,
4842 SourceRange &ERange,
4843 bool AllowArraySection) {
4844 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4845 RefExpr->containsUnexpandedParameterPack())
4846 return std::make_pair(nullptr, true);
4847
4848 // OpenMP [3.1, C/C++]
4849 // A list item is a variable name.
4850 // OpenMP [2.9.3.3, Restrictions, p.1]
4851 // A variable that is part of another variable (as an array or
4852 // structure element) cannot appear in a private clause.
4853 RefExpr = RefExpr->IgnoreParens();
4854 enum {
4855 NoArrayExpr = -1,
4856 ArraySubscript = 0,
4857 OMPArraySection = 1
4858 } IsArrayExpr = NoArrayExpr;
4859 if (AllowArraySection) {
4860 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4861 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4862 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4863 Base = TempASE->getBase()->IgnoreParenImpCasts();
4864 RefExpr = Base;
4865 IsArrayExpr = ArraySubscript;
4866 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4867 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4868 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4869 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4870 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4871 Base = TempASE->getBase()->IgnoreParenImpCasts();
4872 RefExpr = Base;
4873 IsArrayExpr = OMPArraySection;
4874 }
4875 }
4876 ELoc = RefExpr->getExprLoc();
4877 ERange = RefExpr->getSourceRange();
4878 RefExpr = RefExpr->IgnoreParenImpCasts();
4879 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4880 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4881 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4882 (S.getCurrentThisType().isNull() || !ME ||
4883 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4884 !isa<FieldDecl>(ME->getMemberDecl()))) {
4885 if (IsArrayExpr != NoArrayExpr) {
4886 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4887 << ERange;
4888 } else {
4889 S.Diag(ELoc,
4890 AllowArraySection
4891 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4892 : diag::err_omp_expected_var_name_member_expr)
4893 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4894 }
4895 return std::make_pair(nullptr, false);
4896 }
4897 return std::make_pair(
4898 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4899 }
4900
4901 namespace {
4902 /// Checks if the allocator is used in uses_allocators clause to be allowed in
4903 /// target regions.
4904 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4905 DSAStackTy *S = nullptr;
4906
4907 public:
VisitDeclRefExpr(const DeclRefExpr * E)4908 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4909 return S->isUsesAllocatorsDecl(E->getDecl())
4910 .getValueOr(
4911 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4912 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4913 }
VisitStmt(const Stmt * S)4914 bool VisitStmt(const Stmt *S) {
4915 for (const Stmt *Child : S->children()) {
4916 if (Child && Visit(Child))
4917 return true;
4918 }
4919 return false;
4920 }
AllocatorChecker(DSAStackTy * S)4921 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4922 };
4923 } // namespace
4924
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)4925 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4926 ArrayRef<OMPClause *> Clauses) {
4927 assert(!S.CurContext->isDependentContext() &&
4928 "Expected non-dependent context.");
4929 auto AllocateRange =
4930 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4931 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4932 DeclToCopy;
4933 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4934 return isOpenMPPrivate(C->getClauseKind());
4935 });
4936 for (OMPClause *Cl : PrivateRange) {
4937 MutableArrayRef<Expr *>::iterator I, It, Et;
4938 if (Cl->getClauseKind() == OMPC_private) {
4939 auto *PC = cast<OMPPrivateClause>(Cl);
4940 I = PC->private_copies().begin();
4941 It = PC->varlist_begin();
4942 Et = PC->varlist_end();
4943 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4944 auto *PC = cast<OMPFirstprivateClause>(Cl);
4945 I = PC->private_copies().begin();
4946 It = PC->varlist_begin();
4947 Et = PC->varlist_end();
4948 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4949 auto *PC = cast<OMPLastprivateClause>(Cl);
4950 I = PC->private_copies().begin();
4951 It = PC->varlist_begin();
4952 Et = PC->varlist_end();
4953 } else if (Cl->getClauseKind() == OMPC_linear) {
4954 auto *PC = cast<OMPLinearClause>(Cl);
4955 I = PC->privates().begin();
4956 It = PC->varlist_begin();
4957 Et = PC->varlist_end();
4958 } else if (Cl->getClauseKind() == OMPC_reduction) {
4959 auto *PC = cast<OMPReductionClause>(Cl);
4960 I = PC->privates().begin();
4961 It = PC->varlist_begin();
4962 Et = PC->varlist_end();
4963 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4964 auto *PC = cast<OMPTaskReductionClause>(Cl);
4965 I = PC->privates().begin();
4966 It = PC->varlist_begin();
4967 Et = PC->varlist_end();
4968 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4969 auto *PC = cast<OMPInReductionClause>(Cl);
4970 I = PC->privates().begin();
4971 It = PC->varlist_begin();
4972 Et = PC->varlist_end();
4973 } else {
4974 llvm_unreachable("Expected private clause.");
4975 }
4976 for (Expr *E : llvm::make_range(It, Et)) {
4977 if (!*I) {
4978 ++I;
4979 continue;
4980 }
4981 SourceLocation ELoc;
4982 SourceRange ERange;
4983 Expr *SimpleRefExpr = E;
4984 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4985 /*AllowArraySection=*/true);
4986 DeclToCopy.try_emplace(Res.first,
4987 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4988 ++I;
4989 }
4990 }
4991 for (OMPClause *C : AllocateRange) {
4992 auto *AC = cast<OMPAllocateClause>(C);
4993 if (S.getLangOpts().OpenMP >= 50 &&
4994 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4995 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4996 AC->getAllocator()) {
4997 Expr *Allocator = AC->getAllocator();
4998 // OpenMP, 2.12.5 target Construct
4999 // Memory allocators that do not appear in a uses_allocators clause cannot
5000 // appear as an allocator in an allocate clause or be used in the target
5001 // region unless a requires directive with the dynamic_allocators clause
5002 // is present in the same compilation unit.
5003 AllocatorChecker Checker(Stack);
5004 if (Checker.Visit(Allocator))
5005 S.Diag(Allocator->getExprLoc(),
5006 diag::err_omp_allocator_not_in_uses_allocators)
5007 << Allocator->getSourceRange();
5008 }
5009 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5010 getAllocatorKind(S, Stack, AC->getAllocator());
5011 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5012 // For task, taskloop or target directives, allocation requests to memory
5013 // allocators with the trait access set to thread result in unspecified
5014 // behavior.
5015 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5016 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5017 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5018 S.Diag(AC->getAllocator()->getExprLoc(),
5019 diag::warn_omp_allocate_thread_on_task_target_directive)
5020 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5021 }
5022 for (Expr *E : AC->varlists()) {
5023 SourceLocation ELoc;
5024 SourceRange ERange;
5025 Expr *SimpleRefExpr = E;
5026 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5027 ValueDecl *VD = Res.first;
5028 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5029 if (!isOpenMPPrivate(Data.CKind)) {
5030 S.Diag(E->getExprLoc(),
5031 diag::err_omp_expected_private_copy_for_allocate);
5032 continue;
5033 }
5034 VarDecl *PrivateVD = DeclToCopy[VD];
5035 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5036 AllocatorKind, AC->getAllocator()))
5037 continue;
5038 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5039 E->getSourceRange());
5040 }
5041 }
5042 }
5043
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5044 StmtResult Sema::ActOnOpenMPExecutableDirective(
5045 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5046 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5047 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5048 StmtResult Res = StmtError();
5049 // First check CancelRegion which is then used in checkNestingOfRegions.
5050 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5051 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5052 StartLoc))
5053 return StmtError();
5054
5055 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5056 VarsWithInheritedDSAType VarsWithInheritedDSA;
5057 bool ErrorFound = false;
5058 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5059 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5060 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5061 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5062
5063 // Check default data sharing attributes for referenced variables.
5064 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5065 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5066 Stmt *S = AStmt;
5067 while (--ThisCaptureLevel >= 0)
5068 S = cast<CapturedStmt>(S)->getCapturedStmt();
5069 DSAChecker.Visit(S);
5070 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5071 !isOpenMPTaskingDirective(Kind)) {
5072 // Visit subcaptures to generate implicit clauses for captured vars.
5073 auto *CS = cast<CapturedStmt>(AStmt);
5074 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5075 getOpenMPCaptureRegions(CaptureRegions, Kind);
5076 // Ignore outer tasking regions for target directives.
5077 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5078 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5079 DSAChecker.visitSubCaptures(CS);
5080 }
5081 if (DSAChecker.isErrorFound())
5082 return StmtError();
5083 // Generate list of implicitly defined firstprivate variables.
5084 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5085
5086 SmallVector<Expr *, 4> ImplicitFirstprivates(
5087 DSAChecker.getImplicitFirstprivate().begin(),
5088 DSAChecker.getImplicitFirstprivate().end());
5089 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5090 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5091 ArrayRef<Expr *> ImplicitMap =
5092 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5093 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5094 }
5095 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5096 for (OMPClause *C : Clauses) {
5097 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5098 for (Expr *E : IRC->taskgroup_descriptors())
5099 if (E)
5100 ImplicitFirstprivates.emplace_back(E);
5101 }
5102 // OpenMP 5.0, 2.10.1 task Construct
5103 // [detach clause]... The event-handle will be considered as if it was
5104 // specified on a firstprivate clause.
5105 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5106 ImplicitFirstprivates.push_back(DC->getEventHandler());
5107 }
5108 if (!ImplicitFirstprivates.empty()) {
5109 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5110 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5111 SourceLocation())) {
5112 ClausesWithImplicit.push_back(Implicit);
5113 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5114 ImplicitFirstprivates.size();
5115 } else {
5116 ErrorFound = true;
5117 }
5118 }
5119 int ClauseKindCnt = -1;
5120 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5121 ++ClauseKindCnt;
5122 if (ImplicitMap.empty())
5123 continue;
5124 CXXScopeSpec MapperIdScopeSpec;
5125 DeclarationNameInfo MapperId;
5126 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5127 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5128 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5129 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5130 ImplicitMap, OMPVarListLocTy())) {
5131 ClausesWithImplicit.emplace_back(Implicit);
5132 ErrorFound |=
5133 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5134 } else {
5135 ErrorFound = true;
5136 }
5137 }
5138 }
5139
5140 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5141 switch (Kind) {
5142 case OMPD_parallel:
5143 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5144 EndLoc);
5145 AllowedNameModifiers.push_back(OMPD_parallel);
5146 break;
5147 case OMPD_simd:
5148 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5149 VarsWithInheritedDSA);
5150 if (LangOpts.OpenMP >= 50)
5151 AllowedNameModifiers.push_back(OMPD_simd);
5152 break;
5153 case OMPD_for:
5154 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5155 VarsWithInheritedDSA);
5156 break;
5157 case OMPD_for_simd:
5158 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5159 EndLoc, VarsWithInheritedDSA);
5160 if (LangOpts.OpenMP >= 50)
5161 AllowedNameModifiers.push_back(OMPD_simd);
5162 break;
5163 case OMPD_sections:
5164 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5165 EndLoc);
5166 break;
5167 case OMPD_section:
5168 assert(ClausesWithImplicit.empty() &&
5169 "No clauses are allowed for 'omp section' directive");
5170 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5171 break;
5172 case OMPD_single:
5173 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5174 EndLoc);
5175 break;
5176 case OMPD_master:
5177 assert(ClausesWithImplicit.empty() &&
5178 "No clauses are allowed for 'omp master' directive");
5179 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5180 break;
5181 case OMPD_critical:
5182 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5183 StartLoc, EndLoc);
5184 break;
5185 case OMPD_parallel_for:
5186 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5187 EndLoc, VarsWithInheritedDSA);
5188 AllowedNameModifiers.push_back(OMPD_parallel);
5189 break;
5190 case OMPD_parallel_for_simd:
5191 Res = ActOnOpenMPParallelForSimdDirective(
5192 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5193 AllowedNameModifiers.push_back(OMPD_parallel);
5194 if (LangOpts.OpenMP >= 50)
5195 AllowedNameModifiers.push_back(OMPD_simd);
5196 break;
5197 case OMPD_parallel_master:
5198 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5199 StartLoc, EndLoc);
5200 AllowedNameModifiers.push_back(OMPD_parallel);
5201 break;
5202 case OMPD_parallel_sections:
5203 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5204 StartLoc, EndLoc);
5205 AllowedNameModifiers.push_back(OMPD_parallel);
5206 break;
5207 case OMPD_task:
5208 Res =
5209 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5210 AllowedNameModifiers.push_back(OMPD_task);
5211 break;
5212 case OMPD_taskyield:
5213 assert(ClausesWithImplicit.empty() &&
5214 "No clauses are allowed for 'omp taskyield' directive");
5215 assert(AStmt == nullptr &&
5216 "No associated statement allowed for 'omp taskyield' directive");
5217 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5218 break;
5219 case OMPD_barrier:
5220 assert(ClausesWithImplicit.empty() &&
5221 "No clauses are allowed for 'omp barrier' directive");
5222 assert(AStmt == nullptr &&
5223 "No associated statement allowed for 'omp barrier' directive");
5224 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5225 break;
5226 case OMPD_taskwait:
5227 assert(ClausesWithImplicit.empty() &&
5228 "No clauses are allowed for 'omp taskwait' directive");
5229 assert(AStmt == nullptr &&
5230 "No associated statement allowed for 'omp taskwait' directive");
5231 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5232 break;
5233 case OMPD_taskgroup:
5234 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5235 EndLoc);
5236 break;
5237 case OMPD_flush:
5238 assert(AStmt == nullptr &&
5239 "No associated statement allowed for 'omp flush' directive");
5240 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5241 break;
5242 case OMPD_depobj:
5243 assert(AStmt == nullptr &&
5244 "No associated statement allowed for 'omp depobj' directive");
5245 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5246 break;
5247 case OMPD_scan:
5248 assert(AStmt == nullptr &&
5249 "No associated statement allowed for 'omp scan' directive");
5250 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5251 break;
5252 case OMPD_ordered:
5253 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5254 EndLoc);
5255 break;
5256 case OMPD_atomic:
5257 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5258 EndLoc);
5259 break;
5260 case OMPD_teams:
5261 Res =
5262 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5263 break;
5264 case OMPD_target:
5265 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5266 EndLoc);
5267 AllowedNameModifiers.push_back(OMPD_target);
5268 break;
5269 case OMPD_target_parallel:
5270 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5271 StartLoc, EndLoc);
5272 AllowedNameModifiers.push_back(OMPD_target);
5273 AllowedNameModifiers.push_back(OMPD_parallel);
5274 break;
5275 case OMPD_target_parallel_for:
5276 Res = ActOnOpenMPTargetParallelForDirective(
5277 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5278 AllowedNameModifiers.push_back(OMPD_target);
5279 AllowedNameModifiers.push_back(OMPD_parallel);
5280 break;
5281 case OMPD_cancellation_point:
5282 assert(ClausesWithImplicit.empty() &&
5283 "No clauses are allowed for 'omp cancellation point' directive");
5284 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5285 "cancellation point' directive");
5286 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5287 break;
5288 case OMPD_cancel:
5289 assert(AStmt == nullptr &&
5290 "No associated statement allowed for 'omp cancel' directive");
5291 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5292 CancelRegion);
5293 AllowedNameModifiers.push_back(OMPD_cancel);
5294 break;
5295 case OMPD_target_data:
5296 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5297 EndLoc);
5298 AllowedNameModifiers.push_back(OMPD_target_data);
5299 break;
5300 case OMPD_target_enter_data:
5301 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5302 EndLoc, AStmt);
5303 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5304 break;
5305 case OMPD_target_exit_data:
5306 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5307 EndLoc, AStmt);
5308 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5309 break;
5310 case OMPD_taskloop:
5311 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5312 EndLoc, VarsWithInheritedDSA);
5313 AllowedNameModifiers.push_back(OMPD_taskloop);
5314 break;
5315 case OMPD_taskloop_simd:
5316 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5317 EndLoc, VarsWithInheritedDSA);
5318 AllowedNameModifiers.push_back(OMPD_taskloop);
5319 if (LangOpts.OpenMP >= 50)
5320 AllowedNameModifiers.push_back(OMPD_simd);
5321 break;
5322 case OMPD_master_taskloop:
5323 Res = ActOnOpenMPMasterTaskLoopDirective(
5324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5325 AllowedNameModifiers.push_back(OMPD_taskloop);
5326 break;
5327 case OMPD_master_taskloop_simd:
5328 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5329 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5330 AllowedNameModifiers.push_back(OMPD_taskloop);
5331 if (LangOpts.OpenMP >= 50)
5332 AllowedNameModifiers.push_back(OMPD_simd);
5333 break;
5334 case OMPD_parallel_master_taskloop:
5335 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5336 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5337 AllowedNameModifiers.push_back(OMPD_taskloop);
5338 AllowedNameModifiers.push_back(OMPD_parallel);
5339 break;
5340 case OMPD_parallel_master_taskloop_simd:
5341 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5342 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5343 AllowedNameModifiers.push_back(OMPD_taskloop);
5344 AllowedNameModifiers.push_back(OMPD_parallel);
5345 if (LangOpts.OpenMP >= 50)
5346 AllowedNameModifiers.push_back(OMPD_simd);
5347 break;
5348 case OMPD_distribute:
5349 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5350 EndLoc, VarsWithInheritedDSA);
5351 break;
5352 case OMPD_target_update:
5353 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5354 EndLoc, AStmt);
5355 AllowedNameModifiers.push_back(OMPD_target_update);
5356 break;
5357 case OMPD_distribute_parallel_for:
5358 Res = ActOnOpenMPDistributeParallelForDirective(
5359 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5360 AllowedNameModifiers.push_back(OMPD_parallel);
5361 break;
5362 case OMPD_distribute_parallel_for_simd:
5363 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5364 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5365 AllowedNameModifiers.push_back(OMPD_parallel);
5366 if (LangOpts.OpenMP >= 50)
5367 AllowedNameModifiers.push_back(OMPD_simd);
5368 break;
5369 case OMPD_distribute_simd:
5370 Res = ActOnOpenMPDistributeSimdDirective(
5371 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5372 if (LangOpts.OpenMP >= 50)
5373 AllowedNameModifiers.push_back(OMPD_simd);
5374 break;
5375 case OMPD_target_parallel_for_simd:
5376 Res = ActOnOpenMPTargetParallelForSimdDirective(
5377 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5378 AllowedNameModifiers.push_back(OMPD_target);
5379 AllowedNameModifiers.push_back(OMPD_parallel);
5380 if (LangOpts.OpenMP >= 50)
5381 AllowedNameModifiers.push_back(OMPD_simd);
5382 break;
5383 case OMPD_target_simd:
5384 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5385 EndLoc, VarsWithInheritedDSA);
5386 AllowedNameModifiers.push_back(OMPD_target);
5387 if (LangOpts.OpenMP >= 50)
5388 AllowedNameModifiers.push_back(OMPD_simd);
5389 break;
5390 case OMPD_teams_distribute:
5391 Res = ActOnOpenMPTeamsDistributeDirective(
5392 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5393 break;
5394 case OMPD_teams_distribute_simd:
5395 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5396 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5397 if (LangOpts.OpenMP >= 50)
5398 AllowedNameModifiers.push_back(OMPD_simd);
5399 break;
5400 case OMPD_teams_distribute_parallel_for_simd:
5401 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5402 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5403 AllowedNameModifiers.push_back(OMPD_parallel);
5404 if (LangOpts.OpenMP >= 50)
5405 AllowedNameModifiers.push_back(OMPD_simd);
5406 break;
5407 case OMPD_teams_distribute_parallel_for:
5408 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5409 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5410 AllowedNameModifiers.push_back(OMPD_parallel);
5411 break;
5412 case OMPD_target_teams:
5413 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5414 EndLoc);
5415 AllowedNameModifiers.push_back(OMPD_target);
5416 break;
5417 case OMPD_target_teams_distribute:
5418 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5419 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5420 AllowedNameModifiers.push_back(OMPD_target);
5421 break;
5422 case OMPD_target_teams_distribute_parallel_for:
5423 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5424 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5425 AllowedNameModifiers.push_back(OMPD_target);
5426 AllowedNameModifiers.push_back(OMPD_parallel);
5427 break;
5428 case OMPD_target_teams_distribute_parallel_for_simd:
5429 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5430 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5431 AllowedNameModifiers.push_back(OMPD_target);
5432 AllowedNameModifiers.push_back(OMPD_parallel);
5433 if (LangOpts.OpenMP >= 50)
5434 AllowedNameModifiers.push_back(OMPD_simd);
5435 break;
5436 case OMPD_target_teams_distribute_simd:
5437 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5438 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5439 AllowedNameModifiers.push_back(OMPD_target);
5440 if (LangOpts.OpenMP >= 50)
5441 AllowedNameModifiers.push_back(OMPD_simd);
5442 break;
5443 case OMPD_declare_target:
5444 case OMPD_end_declare_target:
5445 case OMPD_threadprivate:
5446 case OMPD_allocate:
5447 case OMPD_declare_reduction:
5448 case OMPD_declare_mapper:
5449 case OMPD_declare_simd:
5450 case OMPD_requires:
5451 case OMPD_declare_variant:
5452 case OMPD_begin_declare_variant:
5453 case OMPD_end_declare_variant:
5454 llvm_unreachable("OpenMP Directive is not allowed");
5455 case OMPD_unknown:
5456 default:
5457 llvm_unreachable("Unknown OpenMP directive");
5458 }
5459
5460 ErrorFound = Res.isInvalid() || ErrorFound;
5461
5462 // Check variables in the clauses if default(none) or
5463 // default(firstprivate) was specified.
5464 if (DSAStack->getDefaultDSA() == DSA_none ||
5465 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5466 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
5467 for (OMPClause *C : Clauses) {
5468 switch (C->getClauseKind()) {
5469 case OMPC_num_threads:
5470 case OMPC_dist_schedule:
5471 // Do not analyse if no parent teams directive.
5472 if (isOpenMPTeamsDirective(Kind))
5473 break;
5474 continue;
5475 case OMPC_if:
5476 if (isOpenMPTeamsDirective(Kind) &&
5477 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5478 break;
5479 if (isOpenMPParallelDirective(Kind) &&
5480 isOpenMPTaskLoopDirective(Kind) &&
5481 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5482 break;
5483 continue;
5484 case OMPC_schedule:
5485 case OMPC_detach:
5486 break;
5487 case OMPC_grainsize:
5488 case OMPC_num_tasks:
5489 case OMPC_final:
5490 case OMPC_priority:
5491 // Do not analyze if no parent parallel directive.
5492 if (isOpenMPParallelDirective(Kind))
5493 break;
5494 continue;
5495 case OMPC_ordered:
5496 case OMPC_device:
5497 case OMPC_num_teams:
5498 case OMPC_thread_limit:
5499 case OMPC_hint:
5500 case OMPC_collapse:
5501 case OMPC_safelen:
5502 case OMPC_simdlen:
5503 case OMPC_default:
5504 case OMPC_proc_bind:
5505 case OMPC_private:
5506 case OMPC_firstprivate:
5507 case OMPC_lastprivate:
5508 case OMPC_shared:
5509 case OMPC_reduction:
5510 case OMPC_task_reduction:
5511 case OMPC_in_reduction:
5512 case OMPC_linear:
5513 case OMPC_aligned:
5514 case OMPC_copyin:
5515 case OMPC_copyprivate:
5516 case OMPC_nowait:
5517 case OMPC_untied:
5518 case OMPC_mergeable:
5519 case OMPC_allocate:
5520 case OMPC_read:
5521 case OMPC_write:
5522 case OMPC_update:
5523 case OMPC_capture:
5524 case OMPC_seq_cst:
5525 case OMPC_acq_rel:
5526 case OMPC_acquire:
5527 case OMPC_release:
5528 case OMPC_relaxed:
5529 case OMPC_depend:
5530 case OMPC_threads:
5531 case OMPC_simd:
5532 case OMPC_map:
5533 case OMPC_nogroup:
5534 case OMPC_defaultmap:
5535 case OMPC_to:
5536 case OMPC_from:
5537 case OMPC_use_device_ptr:
5538 case OMPC_use_device_addr:
5539 case OMPC_is_device_ptr:
5540 case OMPC_nontemporal:
5541 case OMPC_order:
5542 case OMPC_destroy:
5543 case OMPC_inclusive:
5544 case OMPC_exclusive:
5545 case OMPC_uses_allocators:
5546 case OMPC_affinity:
5547 continue;
5548 case OMPC_allocator:
5549 case OMPC_flush:
5550 case OMPC_depobj:
5551 case OMPC_threadprivate:
5552 case OMPC_uniform:
5553 case OMPC_unknown:
5554 case OMPC_unified_address:
5555 case OMPC_unified_shared_memory:
5556 case OMPC_reverse_offload:
5557 case OMPC_dynamic_allocators:
5558 case OMPC_atomic_default_mem_order:
5559 case OMPC_device_type:
5560 case OMPC_match:
5561 default:
5562 llvm_unreachable("Unexpected clause");
5563 }
5564 for (Stmt *CC : C->children()) {
5565 if (CC)
5566 DSAChecker.Visit(CC);
5567 }
5568 }
5569 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5570 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5571 }
5572 for (const auto &P : VarsWithInheritedDSA) {
5573 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5574 continue;
5575 ErrorFound = true;
5576 if (DSAStack->getDefaultDSA() == DSA_none ||
5577 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5578 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5579 << P.first << P.second->getSourceRange();
5580 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5581 } else if (getLangOpts().OpenMP >= 50) {
5582 Diag(P.second->getExprLoc(),
5583 diag::err_omp_defaultmap_no_attr_for_variable)
5584 << P.first << P.second->getSourceRange();
5585 Diag(DSAStack->getDefaultDSALocation(),
5586 diag::note_omp_defaultmap_attr_none);
5587 }
5588 }
5589
5590 if (!AllowedNameModifiers.empty())
5591 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5592 ErrorFound;
5593
5594 if (ErrorFound)
5595 return StmtError();
5596
5597 if (!CurContext->isDependentContext() &&
5598 isOpenMPTargetExecutionDirective(Kind) &&
5599 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5600 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5601 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5602 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5603 // Register target to DSA Stack.
5604 DSAStack->addTargetDirLocation(StartLoc);
5605 }
5606
5607 return Res;
5608 }
5609
ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,OMPDeclareSimdDeclAttr::BranchStateTy BS,Expr * Simdlen,ArrayRef<Expr * > Uniforms,ArrayRef<Expr * > Aligneds,ArrayRef<Expr * > Alignments,ArrayRef<Expr * > Linears,ArrayRef<unsigned> LinModifiers,ArrayRef<Expr * > Steps,SourceRange SR)5610 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5611 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5612 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5613 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5614 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5615 assert(Aligneds.size() == Alignments.size());
5616 assert(Linears.size() == LinModifiers.size());
5617 assert(Linears.size() == Steps.size());
5618 if (!DG || DG.get().isNull())
5619 return DeclGroupPtrTy();
5620
5621 const int SimdId = 0;
5622 if (!DG.get().isSingleDecl()) {
5623 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5624 << SimdId;
5625 return DG;
5626 }
5627 Decl *ADecl = DG.get().getSingleDecl();
5628 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5629 ADecl = FTD->getTemplatedDecl();
5630
5631 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5632 if (!FD) {
5633 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5634 return DeclGroupPtrTy();
5635 }
5636
5637 // OpenMP [2.8.2, declare simd construct, Description]
5638 // The parameter of the simdlen clause must be a constant positive integer
5639 // expression.
5640 ExprResult SL;
5641 if (Simdlen)
5642 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5643 // OpenMP [2.8.2, declare simd construct, Description]
5644 // The special this pointer can be used as if was one of the arguments to the
5645 // function in any of the linear, aligned, or uniform clauses.
5646 // The uniform clause declares one or more arguments to have an invariant
5647 // value for all concurrent invocations of the function in the execution of a
5648 // single SIMD loop.
5649 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5650 const Expr *UniformedLinearThis = nullptr;
5651 for (const Expr *E : Uniforms) {
5652 E = E->IgnoreParenImpCasts();
5653 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5654 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5655 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5656 FD->getParamDecl(PVD->getFunctionScopeIndex())
5657 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5658 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5659 continue;
5660 }
5661 if (isa<CXXThisExpr>(E)) {
5662 UniformedLinearThis = E;
5663 continue;
5664 }
5665 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5666 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5667 }
5668 // OpenMP [2.8.2, declare simd construct, Description]
5669 // The aligned clause declares that the object to which each list item points
5670 // is aligned to the number of bytes expressed in the optional parameter of
5671 // the aligned clause.
5672 // The special this pointer can be used as if was one of the arguments to the
5673 // function in any of the linear, aligned, or uniform clauses.
5674 // The type of list items appearing in the aligned clause must be array,
5675 // pointer, reference to array, or reference to pointer.
5676 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5677 const Expr *AlignedThis = nullptr;
5678 for (const Expr *E : Aligneds) {
5679 E = E->IgnoreParenImpCasts();
5680 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5681 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5682 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5683 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5684 FD->getParamDecl(PVD->getFunctionScopeIndex())
5685 ->getCanonicalDecl() == CanonPVD) {
5686 // OpenMP [2.8.1, simd construct, Restrictions]
5687 // A list-item cannot appear in more than one aligned clause.
5688 if (AlignedArgs.count(CanonPVD) > 0) {
5689 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5690 << 1 << getOpenMPClauseName(OMPC_aligned)
5691 << E->getSourceRange();
5692 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5693 diag::note_omp_explicit_dsa)
5694 << getOpenMPClauseName(OMPC_aligned);
5695 continue;
5696 }
5697 AlignedArgs[CanonPVD] = E;
5698 QualType QTy = PVD->getType()
5699 .getNonReferenceType()
5700 .getUnqualifiedType()
5701 .getCanonicalType();
5702 const Type *Ty = QTy.getTypePtrOrNull();
5703 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5704 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5705 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5706 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5707 }
5708 continue;
5709 }
5710 }
5711 if (isa<CXXThisExpr>(E)) {
5712 if (AlignedThis) {
5713 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5714 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5715 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5716 << getOpenMPClauseName(OMPC_aligned);
5717 }
5718 AlignedThis = E;
5719 continue;
5720 }
5721 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5722 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5723 }
5724 // The optional parameter of the aligned clause, alignment, must be a constant
5725 // positive integer expression. If no optional parameter is specified,
5726 // implementation-defined default alignments for SIMD instructions on the
5727 // target platforms are assumed.
5728 SmallVector<const Expr *, 4> NewAligns;
5729 for (Expr *E : Alignments) {
5730 ExprResult Align;
5731 if (E)
5732 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5733 NewAligns.push_back(Align.get());
5734 }
5735 // OpenMP [2.8.2, declare simd construct, Description]
5736 // The linear clause declares one or more list items to be private to a SIMD
5737 // lane and to have a linear relationship with respect to the iteration space
5738 // of a loop.
5739 // The special this pointer can be used as if was one of the arguments to the
5740 // function in any of the linear, aligned, or uniform clauses.
5741 // When a linear-step expression is specified in a linear clause it must be
5742 // either a constant integer expression or an integer-typed parameter that is
5743 // specified in a uniform clause on the directive.
5744 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5745 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5746 auto MI = LinModifiers.begin();
5747 for (const Expr *E : Linears) {
5748 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5749 ++MI;
5750 E = E->IgnoreParenImpCasts();
5751 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5752 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5753 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5754 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5755 FD->getParamDecl(PVD->getFunctionScopeIndex())
5756 ->getCanonicalDecl() == CanonPVD) {
5757 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5758 // A list-item cannot appear in more than one linear clause.
5759 if (LinearArgs.count(CanonPVD) > 0) {
5760 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5761 << getOpenMPClauseName(OMPC_linear)
5762 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5763 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5764 diag::note_omp_explicit_dsa)
5765 << getOpenMPClauseName(OMPC_linear);
5766 continue;
5767 }
5768 // Each argument can appear in at most one uniform or linear clause.
5769 if (UniformedArgs.count(CanonPVD) > 0) {
5770 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5771 << getOpenMPClauseName(OMPC_linear)
5772 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5773 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5774 diag::note_omp_explicit_dsa)
5775 << getOpenMPClauseName(OMPC_uniform);
5776 continue;
5777 }
5778 LinearArgs[CanonPVD] = E;
5779 if (E->isValueDependent() || E->isTypeDependent() ||
5780 E->isInstantiationDependent() ||
5781 E->containsUnexpandedParameterPack())
5782 continue;
5783 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5784 PVD->getOriginalType(),
5785 /*IsDeclareSimd=*/true);
5786 continue;
5787 }
5788 }
5789 if (isa<CXXThisExpr>(E)) {
5790 if (UniformedLinearThis) {
5791 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5792 << getOpenMPClauseName(OMPC_linear)
5793 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5794 << E->getSourceRange();
5795 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5796 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5797 : OMPC_linear);
5798 continue;
5799 }
5800 UniformedLinearThis = E;
5801 if (E->isValueDependent() || E->isTypeDependent() ||
5802 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5803 continue;
5804 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5805 E->getType(), /*IsDeclareSimd=*/true);
5806 continue;
5807 }
5808 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5809 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5810 }
5811 Expr *Step = nullptr;
5812 Expr *NewStep = nullptr;
5813 SmallVector<Expr *, 4> NewSteps;
5814 for (Expr *E : Steps) {
5815 // Skip the same step expression, it was checked already.
5816 if (Step == E || !E) {
5817 NewSteps.push_back(E ? NewStep : nullptr);
5818 continue;
5819 }
5820 Step = E;
5821 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5822 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5823 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5824 if (UniformedArgs.count(CanonPVD) == 0) {
5825 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5826 << Step->getSourceRange();
5827 } else if (E->isValueDependent() || E->isTypeDependent() ||
5828 E->isInstantiationDependent() ||
5829 E->containsUnexpandedParameterPack() ||
5830 CanonPVD->getType()->hasIntegerRepresentation()) {
5831 NewSteps.push_back(Step);
5832 } else {
5833 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5834 << Step->getSourceRange();
5835 }
5836 continue;
5837 }
5838 NewStep = Step;
5839 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5840 !Step->isInstantiationDependent() &&
5841 !Step->containsUnexpandedParameterPack()) {
5842 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5843 .get();
5844 if (NewStep)
5845 NewStep =
5846 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
5847 }
5848 NewSteps.push_back(NewStep);
5849 }
5850 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5851 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5852 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5853 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5854 const_cast<Expr **>(Linears.data()), Linears.size(),
5855 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5856 NewSteps.data(), NewSteps.size(), SR);
5857 ADecl->addAttr(NewAttr);
5858 return DG;
5859 }
5860
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)5861 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5862 QualType NewType) {
5863 assert(NewType->isFunctionProtoType() &&
5864 "Expected function type with prototype.");
5865 assert(FD->getType()->isFunctionNoProtoType() &&
5866 "Expected function with type with no prototype.");
5867 assert(FDWithProto->getType()->isFunctionProtoType() &&
5868 "Expected function with prototype.");
5869 // Synthesize parameters with the same types.
5870 FD->setType(NewType);
5871 SmallVector<ParmVarDecl *, 16> Params;
5872 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5873 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5874 SourceLocation(), nullptr, P->getType(),
5875 /*TInfo=*/nullptr, SC_None, nullptr);
5876 Param->setScopeInfo(0, Params.size());
5877 Param->setImplicit();
5878 Params.push_back(Param);
5879 }
5880
5881 FD->setParams(Params);
5882 }
5883
OMPDeclareVariantScope(OMPTraitInfo & TI)5884 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
5885 : TI(&TI), NameSuffix(TI.getMangledName()) {}
5886
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)5887 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
5888 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
5889 SmallVectorImpl<FunctionDecl *> &Bases) {
5890 if (!D.getIdentifier())
5891 return;
5892
5893 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5894
5895 // Template specialization is an extension, check if we do it.
5896 bool IsTemplated = !TemplateParamLists.empty();
5897 if (IsTemplated &
5898 !DVScope.TI->isExtensionActive(
5899 llvm::omp::TraitProperty::implementation_extension_allow_templates))
5900 return;
5901
5902 IdentifierInfo *BaseII = D.getIdentifier();
5903 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
5904 LookupOrdinaryName);
5905 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
5906
5907 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
5908 QualType FType = TInfo->getType();
5909
5910 bool IsConstexpr =
5911 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
5912 bool IsConsteval =
5913 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
5914
5915 for (auto *Candidate : Lookup) {
5916 auto *CandidateDecl = Candidate->getUnderlyingDecl();
5917 FunctionDecl *UDecl = nullptr;
5918 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
5919 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
5920 else if (!IsTemplated)
5921 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
5922 if (!UDecl)
5923 continue;
5924
5925 // Don't specialize constexpr/consteval functions with
5926 // non-constexpr/consteval functions.
5927 if (UDecl->isConstexpr() && !IsConstexpr)
5928 continue;
5929 if (UDecl->isConsteval() && !IsConsteval)
5930 continue;
5931
5932 QualType UDeclTy = UDecl->getType();
5933 if (!UDeclTy->isDependentType()) {
5934 QualType NewType = Context.mergeFunctionTypes(
5935 FType, UDeclTy, /* OfBlockPointer */ false,
5936 /* Unqualified */ false, /* AllowCXX */ true);
5937 if (NewType.isNull())
5938 continue;
5939 }
5940
5941 // Found a base!
5942 Bases.push_back(UDecl);
5943 }
5944
5945 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
5946 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
5947 // If no base was found we create a declaration that we use as base.
5948 if (Bases.empty() && UseImplicitBase) {
5949 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
5950 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
5951 BaseD->setImplicit(true);
5952 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
5953 Bases.push_back(BaseTemplD->getTemplatedDecl());
5954 else
5955 Bases.push_back(cast<FunctionDecl>(BaseD));
5956 }
5957
5958 std::string MangledName;
5959 MangledName += D.getIdentifier()->getName();
5960 MangledName += getOpenMPVariantManglingSeparatorStr();
5961 MangledName += DVScope.NameSuffix;
5962 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
5963
5964 VariantII.setMangledOpenMPVariantName(true);
5965 D.SetIdentifier(&VariantII, D.getBeginLoc());
5966 }
5967
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)5968 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
5969 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
5970 // Do not mark function as is used to prevent its emission if this is the
5971 // only place where it is used.
5972 EnterExpressionEvaluationContext Unevaluated(
5973 *this, Sema::ExpressionEvaluationContext::Unevaluated);
5974
5975 FunctionDecl *FD = nullptr;
5976 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
5977 FD = UTemplDecl->getTemplatedDecl();
5978 else
5979 FD = cast<FunctionDecl>(D);
5980 auto *VariantFuncRef = DeclRefExpr::Create(
5981 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
5982 /* RefersToEnclosingVariableOrCapture */ false,
5983 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
5984
5985 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5986 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
5987 Context, VariantFuncRef, DVScope.TI);
5988 for (FunctionDecl *BaseFD : Bases)
5989 BaseFD->addAttr(OMPDeclareVariantA);
5990 }
5991
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)5992 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
5993 SourceLocation LParenLoc,
5994 MultiExprArg ArgExprs,
5995 SourceLocation RParenLoc, Expr *ExecConfig) {
5996 // The common case is a regular call we do not want to specialize at all. Try
5997 // to make that case fast by bailing early.
5998 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
5999 if (!CE)
6000 return Call;
6001
6002 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6003 if (!CalleeFnDecl)
6004 return Call;
6005
6006 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6007 return Call;
6008
6009 ASTContext &Context = getASTContext();
6010 std::function<void(StringRef)> DiagUnknownTrait = [this,
6011 CE](StringRef ISATrait) {
6012 // TODO Track the selector locations in a way that is accessible here to
6013 // improve the diagnostic location.
6014 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6015 << ISATrait;
6016 };
6017 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6018 getCurFunctionDecl());
6019
6020 QualType CalleeFnType = CalleeFnDecl->getType();
6021
6022 SmallVector<Expr *, 4> Exprs;
6023 SmallVector<VariantMatchInfo, 4> VMIs;
6024 while (CalleeFnDecl) {
6025 for (OMPDeclareVariantAttr *A :
6026 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6027 Expr *VariantRef = A->getVariantFuncRef();
6028
6029 VariantMatchInfo VMI;
6030 OMPTraitInfo &TI = A->getTraitInfo();
6031 TI.getAsVariantMatchInfo(Context, VMI);
6032 if (!isVariantApplicableInContext(VMI, OMPCtx,
6033 /* DeviceSetOnly */ false))
6034 continue;
6035
6036 VMIs.push_back(VMI);
6037 Exprs.push_back(VariantRef);
6038 }
6039
6040 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6041 }
6042
6043 ExprResult NewCall;
6044 do {
6045 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6046 if (BestIdx < 0)
6047 return Call;
6048 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6049 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6050
6051 {
6052 // Try to build a (member) call expression for the current best applicable
6053 // variant expression. We allow this to fail in which case we continue
6054 // with the next best variant expression. The fail case is part of the
6055 // implementation defined behavior in the OpenMP standard when it talks
6056 // about what differences in the function prototypes: "Any differences
6057 // that the specific OpenMP context requires in the prototype of the
6058 // variant from the base function prototype are implementation defined."
6059 // This wording is there to allow the specialized variant to have a
6060 // different type than the base function. This is intended and OK but if
6061 // we cannot create a call the difference is not in the "implementation
6062 // defined range" we allow.
6063 Sema::TentativeAnalysisScope Trap(*this);
6064
6065 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6066 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6067 BestExpr = MemberExpr::CreateImplicit(
6068 Context, MemberCall->getImplicitObjectArgument(),
6069 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6070 MemberCall->getValueKind(), MemberCall->getObjectKind());
6071 }
6072 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6073 ExecConfig);
6074 if (NewCall.isUsable()) {
6075 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6076 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6077 QualType NewType = Context.mergeFunctionTypes(
6078 CalleeFnType, NewCalleeFnDecl->getType(),
6079 /* OfBlockPointer */ false,
6080 /* Unqualified */ false, /* AllowCXX */ true);
6081 if (!NewType.isNull())
6082 break;
6083 // Don't use the call if the function type was not compatible.
6084 NewCall = nullptr;
6085 }
6086 }
6087 }
6088
6089 VMIs.erase(VMIs.begin() + BestIdx);
6090 Exprs.erase(Exprs.begin() + BestIdx);
6091 } while (!VMIs.empty());
6092
6093 if (!NewCall.isUsable())
6094 return Call;
6095 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6096 }
6097
6098 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6099 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6100 Expr *VariantRef, OMPTraitInfo &TI,
6101 SourceRange SR) {
6102 if (!DG || DG.get().isNull())
6103 return None;
6104
6105 const int VariantId = 1;
6106 // Must be applied only to single decl.
6107 if (!DG.get().isSingleDecl()) {
6108 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6109 << VariantId << SR;
6110 return None;
6111 }
6112 Decl *ADecl = DG.get().getSingleDecl();
6113 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6114 ADecl = FTD->getTemplatedDecl();
6115
6116 // Decl must be a function.
6117 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6118 if (!FD) {
6119 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6120 << VariantId << SR;
6121 return None;
6122 }
6123
6124 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6125 return FD->hasAttrs() &&
6126 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6127 FD->hasAttr<TargetAttr>());
6128 };
6129 // OpenMP is not compatible with CPU-specific attributes.
6130 if (HasMultiVersionAttributes(FD)) {
6131 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6132 << SR;
6133 return None;
6134 }
6135
6136 // Allow #pragma omp declare variant only if the function is not used.
6137 if (FD->isUsed(false))
6138 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6139 << FD->getLocation();
6140
6141 // Check if the function was emitted already.
6142 const FunctionDecl *Definition;
6143 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6144 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6145 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6146 << FD->getLocation();
6147
6148 // The VariantRef must point to function.
6149 if (!VariantRef) {
6150 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6151 return None;
6152 }
6153
6154 auto ShouldDelayChecks = [](Expr *&E, bool) {
6155 return E && (E->isTypeDependent() || E->isValueDependent() ||
6156 E->containsUnexpandedParameterPack() ||
6157 E->isInstantiationDependent());
6158 };
6159 // Do not check templates, wait until instantiation.
6160 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6161 TI.anyScoreOrCondition(ShouldDelayChecks))
6162 return std::make_pair(FD, VariantRef);
6163
6164 // Deal with non-constant score and user condition expressions.
6165 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6166 bool IsScore) -> bool {
6167 if (!E || E->isIntegerConstantExpr(Context))
6168 return false;
6169
6170 if (IsScore) {
6171 // We warn on non-constant scores and pretend they were not present.
6172 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6173 << E;
6174 E = nullptr;
6175 } else {
6176 // We could replace a non-constant user condition with "false" but we
6177 // will soon need to handle these anyway for the dynamic version of
6178 // OpenMP context selectors.
6179 Diag(E->getExprLoc(),
6180 diag::err_omp_declare_variant_user_condition_not_constant)
6181 << E;
6182 }
6183 return true;
6184 };
6185 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6186 return None;
6187
6188 // Convert VariantRef expression to the type of the original function to
6189 // resolve possible conflicts.
6190 ExprResult VariantRefCast = VariantRef;
6191 if (LangOpts.CPlusPlus) {
6192 QualType FnPtrType;
6193 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6194 if (Method && !Method->isStatic()) {
6195 const Type *ClassType =
6196 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6197 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6198 ExprResult ER;
6199 {
6200 // Build adrr_of unary op to correctly handle type checks for member
6201 // functions.
6202 Sema::TentativeAnalysisScope Trap(*this);
6203 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6204 VariantRef);
6205 }
6206 if (!ER.isUsable()) {
6207 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6208 << VariantId << VariantRef->getSourceRange();
6209 return None;
6210 }
6211 VariantRef = ER.get();
6212 } else {
6213 FnPtrType = Context.getPointerType(FD->getType());
6214 }
6215 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6216 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6217 ImplicitConversionSequence ICS = TryImplicitConversion(
6218 VariantRef, FnPtrType.getUnqualifiedType(),
6219 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6220 /*InOverloadResolution=*/false,
6221 /*CStyle=*/false,
6222 /*AllowObjCWritebackConversion=*/false);
6223 if (ICS.isFailure()) {
6224 Diag(VariantRef->getExprLoc(),
6225 diag::err_omp_declare_variant_incompat_types)
6226 << VariantRef->getType()
6227 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6228 << VariantRef->getSourceRange();
6229 return None;
6230 }
6231 VariantRefCast = PerformImplicitConversion(
6232 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6233 if (!VariantRefCast.isUsable())
6234 return None;
6235 }
6236 // Drop previously built artificial addr_of unary op for member functions.
6237 if (Method && !Method->isStatic()) {
6238 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6239 if (auto *UO = dyn_cast<UnaryOperator>(
6240 PossibleAddrOfVariantRef->IgnoreImplicit()))
6241 VariantRefCast = UO->getSubExpr();
6242 }
6243 }
6244
6245 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6246 if (!ER.isUsable() ||
6247 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6248 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6249 << VariantId << VariantRef->getSourceRange();
6250 return None;
6251 }
6252
6253 // The VariantRef must point to function.
6254 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6255 if (!DRE) {
6256 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6257 << VariantId << VariantRef->getSourceRange();
6258 return None;
6259 }
6260 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6261 if (!NewFD) {
6262 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6263 << VariantId << VariantRef->getSourceRange();
6264 return None;
6265 }
6266
6267 // Check if function types are compatible in C.
6268 if (!LangOpts.CPlusPlus) {
6269 QualType NewType =
6270 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6271 if (NewType.isNull()) {
6272 Diag(VariantRef->getExprLoc(),
6273 diag::err_omp_declare_variant_incompat_types)
6274 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6275 return None;
6276 }
6277 if (NewType->isFunctionProtoType()) {
6278 if (FD->getType()->isFunctionNoProtoType())
6279 setPrototype(*this, FD, NewFD, NewType);
6280 else if (NewFD->getType()->isFunctionNoProtoType())
6281 setPrototype(*this, NewFD, FD, NewType);
6282 }
6283 }
6284
6285 // Check if variant function is not marked with declare variant directive.
6286 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6287 Diag(VariantRef->getExprLoc(),
6288 diag::warn_omp_declare_variant_marked_as_declare_variant)
6289 << VariantRef->getSourceRange();
6290 SourceRange SR =
6291 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6292 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6293 return None;
6294 }
6295
6296 enum DoesntSupport {
6297 VirtFuncs = 1,
6298 Constructors = 3,
6299 Destructors = 4,
6300 DeletedFuncs = 5,
6301 DefaultedFuncs = 6,
6302 ConstexprFuncs = 7,
6303 ConstevalFuncs = 8,
6304 };
6305 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6306 if (CXXFD->isVirtual()) {
6307 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6308 << VirtFuncs;
6309 return None;
6310 }
6311
6312 if (isa<CXXConstructorDecl>(FD)) {
6313 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6314 << Constructors;
6315 return None;
6316 }
6317
6318 if (isa<CXXDestructorDecl>(FD)) {
6319 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6320 << Destructors;
6321 return None;
6322 }
6323 }
6324
6325 if (FD->isDeleted()) {
6326 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6327 << DeletedFuncs;
6328 return None;
6329 }
6330
6331 if (FD->isDefaulted()) {
6332 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6333 << DefaultedFuncs;
6334 return None;
6335 }
6336
6337 if (FD->isConstexpr()) {
6338 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6339 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6340 return None;
6341 }
6342
6343 // Check general compatibility.
6344 if (areMultiversionVariantFunctionsCompatible(
6345 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6346 PartialDiagnosticAt(SourceLocation(),
6347 PartialDiagnostic::NullDiagnostic()),
6348 PartialDiagnosticAt(
6349 VariantRef->getExprLoc(),
6350 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6351 PartialDiagnosticAt(VariantRef->getExprLoc(),
6352 PDiag(diag::err_omp_declare_variant_diff)
6353 << FD->getLocation()),
6354 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6355 /*CLinkageMayDiffer=*/true))
6356 return None;
6357 return std::make_pair(FD, cast<Expr>(DRE));
6358 }
6359
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6360 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6361 Expr *VariantRef,
6362 OMPTraitInfo &TI,
6363 SourceRange SR) {
6364 auto *NewAttr =
6365 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6366 FD->addAttr(NewAttr);
6367 }
6368
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6369 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6370 Stmt *AStmt,
6371 SourceLocation StartLoc,
6372 SourceLocation EndLoc) {
6373 if (!AStmt)
6374 return StmtError();
6375
6376 auto *CS = cast<CapturedStmt>(AStmt);
6377 // 1.2.2 OpenMP Language Terminology
6378 // Structured block - An executable statement with a single entry at the
6379 // top and a single exit at the bottom.
6380 // The point of exit cannot be a branch out of the structured block.
6381 // longjmp() and throw() must not violate the entry/exit criteria.
6382 CS->getCapturedDecl()->setNothrow();
6383
6384 setFunctionHasBranchProtectedScope();
6385
6386 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6387 DSAStack->getTaskgroupReductionRef(),
6388 DSAStack->isCancelRegion());
6389 }
6390
6391 namespace {
6392 /// Iteration space of a single for loop.
6393 struct LoopIterationSpace final {
6394 /// True if the condition operator is the strict compare operator (<, > or
6395 /// !=).
6396 bool IsStrictCompare = false;
6397 /// Condition of the loop.
6398 Expr *PreCond = nullptr;
6399 /// This expression calculates the number of iterations in the loop.
6400 /// It is always possible to calculate it before starting the loop.
6401 Expr *NumIterations = nullptr;
6402 /// The loop counter variable.
6403 Expr *CounterVar = nullptr;
6404 /// Private loop counter variable.
6405 Expr *PrivateCounterVar = nullptr;
6406 /// This is initializer for the initial value of #CounterVar.
6407 Expr *CounterInit = nullptr;
6408 /// This is step for the #CounterVar used to generate its update:
6409 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6410 Expr *CounterStep = nullptr;
6411 /// Should step be subtracted?
6412 bool Subtract = false;
6413 /// Source range of the loop init.
6414 SourceRange InitSrcRange;
6415 /// Source range of the loop condition.
6416 SourceRange CondSrcRange;
6417 /// Source range of the loop increment.
6418 SourceRange IncSrcRange;
6419 /// Minimum value that can have the loop control variable. Used to support
6420 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6421 /// since only such variables can be used in non-loop invariant expressions.
6422 Expr *MinValue = nullptr;
6423 /// Maximum value that can have the loop control variable. Used to support
6424 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6425 /// since only such variables can be used in non-loop invariant expressions.
6426 Expr *MaxValue = nullptr;
6427 /// true, if the lower bound depends on the outer loop control var.
6428 bool IsNonRectangularLB = false;
6429 /// true, if the upper bound depends on the outer loop control var.
6430 bool IsNonRectangularUB = false;
6431 /// Index of the loop this loop depends on and forms non-rectangular loop
6432 /// nest.
6433 unsigned LoopDependentIdx = 0;
6434 /// Final condition for the non-rectangular loop nest support. It is used to
6435 /// check that the number of iterations for this particular counter must be
6436 /// finished.
6437 Expr *FinalCondition = nullptr;
6438 };
6439
6440 /// Helper class for checking canonical form of the OpenMP loops and
6441 /// extracting iteration space of each loop in the loop nest, that will be used
6442 /// for IR generation.
6443 class OpenMPIterationSpaceChecker {
6444 /// Reference to Sema.
6445 Sema &SemaRef;
6446 /// Data-sharing stack.
6447 DSAStackTy &Stack;
6448 /// A location for diagnostics (when there is no some better location).
6449 SourceLocation DefaultLoc;
6450 /// A location for diagnostics (when increment is not compatible).
6451 SourceLocation ConditionLoc;
6452 /// A source location for referring to loop init later.
6453 SourceRange InitSrcRange;
6454 /// A source location for referring to condition later.
6455 SourceRange ConditionSrcRange;
6456 /// A source location for referring to increment later.
6457 SourceRange IncrementSrcRange;
6458 /// Loop variable.
6459 ValueDecl *LCDecl = nullptr;
6460 /// Reference to loop variable.
6461 Expr *LCRef = nullptr;
6462 /// Lower bound (initializer for the var).
6463 Expr *LB = nullptr;
6464 /// Upper bound.
6465 Expr *UB = nullptr;
6466 /// Loop step (increment).
6467 Expr *Step = nullptr;
6468 /// This flag is true when condition is one of:
6469 /// Var < UB
6470 /// Var <= UB
6471 /// UB > Var
6472 /// UB >= Var
6473 /// This will have no value when the condition is !=
6474 llvm::Optional<bool> TestIsLessOp;
6475 /// This flag is true when condition is strict ( < or > ).
6476 bool TestIsStrictOp = false;
6477 /// This flag is true when step is subtracted on each iteration.
6478 bool SubtractStep = false;
6479 /// The outer loop counter this loop depends on (if any).
6480 const ValueDecl *DepDecl = nullptr;
6481 /// Contains number of loop (starts from 1) on which loop counter init
6482 /// expression of this loop depends on.
6483 Optional<unsigned> InitDependOnLC;
6484 /// Contains number of loop (starts from 1) on which loop counter condition
6485 /// expression of this loop depends on.
6486 Optional<unsigned> CondDependOnLC;
6487 /// Checks if the provide statement depends on the loop counter.
6488 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6489 /// Original condition required for checking of the exit condition for
6490 /// non-rectangular loop.
6491 Expr *Condition = nullptr;
6492
6493 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,DSAStackTy & Stack,SourceLocation DefaultLoc)6494 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6495 SourceLocation DefaultLoc)
6496 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6497 ConditionLoc(DefaultLoc) {}
6498 /// Check init-expr for canonical loop form and save loop counter
6499 /// variable - #Var and its initialization value - #LB.
6500 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6501 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6502 /// for less/greater and for strict/non-strict comparison.
6503 bool checkAndSetCond(Expr *S);
6504 /// Check incr-expr for canonical loop form and return true if it
6505 /// does not conform, otherwise save loop step (#Step).
6506 bool checkAndSetInc(Expr *S);
6507 /// Return the loop counter variable.
getLoopDecl() const6508 ValueDecl *getLoopDecl() const { return LCDecl; }
6509 /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const6510 Expr *getLoopDeclRefExpr() const { return LCRef; }
6511 /// Source range of the loop init.
getInitSrcRange() const6512 SourceRange getInitSrcRange() const { return InitSrcRange; }
6513 /// Source range of the loop condition.
getConditionSrcRange() const6514 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6515 /// Source range of the loop increment.
getIncrementSrcRange() const6516 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6517 /// True if the step should be subtracted.
shouldSubtractStep() const6518 bool shouldSubtractStep() const { return SubtractStep; }
6519 /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const6520 bool isStrictTestOp() const { return TestIsStrictOp; }
6521 /// Build the expression to calculate the number of iterations.
6522 Expr *buildNumIterations(
6523 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6524 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6525 /// Build the precondition expression for the loops.
6526 Expr *
6527 buildPreCond(Scope *S, Expr *Cond,
6528 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6529 /// Build reference expression to the counter be used for codegen.
6530 DeclRefExpr *
6531 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6532 DSAStackTy &DSA) const;
6533 /// Build reference expression to the private counter be used for
6534 /// codegen.
6535 Expr *buildPrivateCounterVar() const;
6536 /// Build initialization of the counter be used for codegen.
6537 Expr *buildCounterInit() const;
6538 /// Build step of the counter be used for codegen.
6539 Expr *buildCounterStep() const;
6540 /// Build loop data with counter value for depend clauses in ordered
6541 /// directives.
6542 Expr *
6543 buildOrderedLoopData(Scope *S, Expr *Counter,
6544 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6545 SourceLocation Loc, Expr *Inc = nullptr,
6546 OverloadedOperatorKind OOK = OO_Amp);
6547 /// Builds the minimum value for the loop counter.
6548 std::pair<Expr *, Expr *> buildMinMaxValues(
6549 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6550 /// Builds final condition for the non-rectangular loops.
6551 Expr *buildFinalCondition(Scope *S) const;
6552 /// Return true if any expression is dependent.
6553 bool dependent() const;
6554 /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const6555 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6556 /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const6557 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6558 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const6559 unsigned getLoopDependentIdx() const {
6560 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6561 }
6562
6563 private:
6564 /// Check the right-hand side of an assignment in the increment
6565 /// expression.
6566 bool checkAndSetIncRHS(Expr *RHS);
6567 /// Helper to set loop counter variable and its initializer.
6568 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6569 bool EmitDiags);
6570 /// Helper to set upper bound.
6571 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6572 SourceRange SR, SourceLocation SL);
6573 /// Helper to set loop increment.
6574 bool setStep(Expr *NewStep, bool Subtract);
6575 };
6576
dependent() const6577 bool OpenMPIterationSpaceChecker::dependent() const {
6578 if (!LCDecl) {
6579 assert(!LB && !UB && !Step);
6580 return false;
6581 }
6582 return LCDecl->getType()->isDependentType() ||
6583 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6584 (Step && Step->isValueDependent());
6585 }
6586
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)6587 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6588 Expr *NewLCRefExpr,
6589 Expr *NewLB, bool EmitDiags) {
6590 // State consistency checking to ensure correct usage.
6591 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
6592 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6593 if (!NewLCDecl || !NewLB)
6594 return true;
6595 LCDecl = getCanonicalDecl(NewLCDecl);
6596 LCRef = NewLCRefExpr;
6597 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6598 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6599 if ((Ctor->isCopyOrMoveConstructor() ||
6600 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6601 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6602 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6603 LB = NewLB;
6604 if (EmitDiags)
6605 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6606 return false;
6607 }
6608
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)6609 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6610 llvm::Optional<bool> LessOp,
6611 bool StrictOp, SourceRange SR,
6612 SourceLocation SL) {
6613 // State consistency checking to ensure correct usage.
6614 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
6615 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6616 if (!NewUB)
6617 return true;
6618 UB = NewUB;
6619 if (LessOp)
6620 TestIsLessOp = LessOp;
6621 TestIsStrictOp = StrictOp;
6622 ConditionSrcRange = SR;
6623 ConditionLoc = SL;
6624 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6625 return false;
6626 }
6627
setStep(Expr * NewStep,bool Subtract)6628 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6629 // State consistency checking to ensure correct usage.
6630 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
6631 if (!NewStep)
6632 return true;
6633 if (!NewStep->isValueDependent()) {
6634 // Check that the step is integer expression.
6635 SourceLocation StepLoc = NewStep->getBeginLoc();
6636 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6637 StepLoc, getExprAsWritten(NewStep));
6638 if (Val.isInvalid())
6639 return true;
6640 NewStep = Val.get();
6641
6642 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6643 // If test-expr is of form var relational-op b and relational-op is < or
6644 // <= then incr-expr must cause var to increase on each iteration of the
6645 // loop. If test-expr is of form var relational-op b and relational-op is
6646 // > or >= then incr-expr must cause var to decrease on each iteration of
6647 // the loop.
6648 // If test-expr is of form b relational-op var and relational-op is < or
6649 // <= then incr-expr must cause var to decrease on each iteration of the
6650 // loop. If test-expr is of form b relational-op var and relational-op is
6651 // > or >= then incr-expr must cause var to increase on each iteration of
6652 // the loop.
6653 Optional<llvm::APSInt> Result =
6654 NewStep->getIntegerConstantExpr(SemaRef.Context);
6655 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6656 bool IsConstNeg =
6657 Result && Result->isSigned() && (Subtract != Result->isNegative());
6658 bool IsConstPos =
6659 Result && Result->isSigned() && (Subtract == Result->isNegative());
6660 bool IsConstZero = Result && !Result->getBoolValue();
6661
6662 // != with increment is treated as <; != with decrement is treated as >
6663 if (!TestIsLessOp.hasValue())
6664 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6665 if (UB && (IsConstZero ||
6666 (TestIsLessOp.getValue() ?
6667 (IsConstNeg || (IsUnsigned && Subtract)) :
6668 (IsConstPos || (IsUnsigned && !Subtract))))) {
6669 SemaRef.Diag(NewStep->getExprLoc(),
6670 diag::err_omp_loop_incr_not_compatible)
6671 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6672 SemaRef.Diag(ConditionLoc,
6673 diag::note_omp_loop_cond_requres_compatible_incr)
6674 << TestIsLessOp.getValue() << ConditionSrcRange;
6675 return true;
6676 }
6677 if (TestIsLessOp.getValue() == Subtract) {
6678 NewStep =
6679 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6680 .get();
6681 Subtract = !Subtract;
6682 }
6683 }
6684
6685 Step = NewStep;
6686 SubtractStep = Subtract;
6687 return false;
6688 }
6689
6690 namespace {
6691 /// Checker for the non-rectangular loops. Checks if the initializer or
6692 /// condition expression references loop counter variable.
6693 class LoopCounterRefChecker final
6694 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6695 Sema &SemaRef;
6696 DSAStackTy &Stack;
6697 const ValueDecl *CurLCDecl = nullptr;
6698 const ValueDecl *DepDecl = nullptr;
6699 const ValueDecl *PrevDepDecl = nullptr;
6700 bool IsInitializer = true;
6701 unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)6702 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6703 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6704 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6705 << (IsInitializer ? 0 : 1);
6706 return false;
6707 }
6708 const auto &&Data = Stack.isLoopControlVariable(VD);
6709 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6710 // The type of the loop iterator on which we depend may not have a random
6711 // access iterator type.
6712 if (Data.first && VD->getType()->isRecordType()) {
6713 SmallString<128> Name;
6714 llvm::raw_svector_ostream OS(Name);
6715 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6716 /*Qualified=*/true);
6717 SemaRef.Diag(E->getExprLoc(),
6718 diag::err_omp_wrong_dependency_iterator_type)
6719 << OS.str();
6720 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6721 return false;
6722 }
6723 if (Data.first &&
6724 (DepDecl || (PrevDepDecl &&
6725 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6726 if (!DepDecl && PrevDepDecl)
6727 DepDecl = PrevDepDecl;
6728 SmallString<128> Name;
6729 llvm::raw_svector_ostream OS(Name);
6730 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6731 /*Qualified=*/true);
6732 SemaRef.Diag(E->getExprLoc(),
6733 diag::err_omp_invariant_or_linear_dependency)
6734 << OS.str();
6735 return false;
6736 }
6737 if (Data.first) {
6738 DepDecl = VD;
6739 BaseLoopId = Data.first;
6740 }
6741 return Data.first;
6742 }
6743
6744 public:
VisitDeclRefExpr(const DeclRefExpr * E)6745 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6746 const ValueDecl *VD = E->getDecl();
6747 if (isa<VarDecl>(VD))
6748 return checkDecl(E, VD);
6749 return false;
6750 }
VisitMemberExpr(const MemberExpr * E)6751 bool VisitMemberExpr(const MemberExpr *E) {
6752 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6753 const ValueDecl *VD = E->getMemberDecl();
6754 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6755 return checkDecl(E, VD);
6756 }
6757 return false;
6758 }
VisitStmt(const Stmt * S)6759 bool VisitStmt(const Stmt *S) {
6760 bool Res = false;
6761 for (const Stmt *Child : S->children())
6762 Res = (Child && Visit(Child)) || Res;
6763 return Res;
6764 }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr)6765 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6766 const ValueDecl *CurLCDecl, bool IsInitializer,
6767 const ValueDecl *PrevDepDecl = nullptr)
6768 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6769 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
getBaseLoopId() const6770 unsigned getBaseLoopId() const {
6771 assert(CurLCDecl && "Expected loop dependency.");
6772 return BaseLoopId;
6773 }
getDepDecl() const6774 const ValueDecl *getDepDecl() const {
6775 assert(CurLCDecl && "Expected loop dependency.");
6776 return DepDecl;
6777 }
6778 };
6779 } // namespace
6780
6781 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)6782 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6783 bool IsInitializer) {
6784 // Check for the non-rectangular loops.
6785 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6786 DepDecl);
6787 if (LoopStmtChecker.Visit(S)) {
6788 DepDecl = LoopStmtChecker.getDepDecl();
6789 return LoopStmtChecker.getBaseLoopId();
6790 }
6791 return llvm::None;
6792 }
6793
checkAndSetInit(Stmt * S,bool EmitDiags)6794 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6795 // Check init-expr for canonical loop form and save loop counter
6796 // variable - #Var and its initialization value - #LB.
6797 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6798 // var = lb
6799 // integer-type var = lb
6800 // random-access-iterator-type var = lb
6801 // pointer-type var = lb
6802 //
6803 if (!S) {
6804 if (EmitDiags) {
6805 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6806 }
6807 return true;
6808 }
6809 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6810 if (!ExprTemp->cleanupsHaveSideEffects())
6811 S = ExprTemp->getSubExpr();
6812
6813 InitSrcRange = S->getSourceRange();
6814 if (Expr *E = dyn_cast<Expr>(S))
6815 S = E->IgnoreParens();
6816 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6817 if (BO->getOpcode() == BO_Assign) {
6818 Expr *LHS = BO->getLHS()->IgnoreParens();
6819 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6820 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6821 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6822 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6823 EmitDiags);
6824 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6825 }
6826 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6827 if (ME->isArrow() &&
6828 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6829 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6830 EmitDiags);
6831 }
6832 }
6833 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6834 if (DS->isSingleDecl()) {
6835 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6836 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6837 // Accept non-canonical init form here but emit ext. warning.
6838 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6839 SemaRef.Diag(S->getBeginLoc(),
6840 diag::ext_omp_loop_not_canonical_init)
6841 << S->getSourceRange();
6842 return setLCDeclAndLB(
6843 Var,
6844 buildDeclRefExpr(SemaRef, Var,
6845 Var->getType().getNonReferenceType(),
6846 DS->getBeginLoc()),
6847 Var->getInit(), EmitDiags);
6848 }
6849 }
6850 }
6851 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6852 if (CE->getOperator() == OO_Equal) {
6853 Expr *LHS = CE->getArg(0);
6854 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6855 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6856 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6857 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6858 EmitDiags);
6859 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6860 }
6861 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6862 if (ME->isArrow() &&
6863 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6864 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6865 EmitDiags);
6866 }
6867 }
6868 }
6869
6870 if (dependent() || SemaRef.CurContext->isDependentContext())
6871 return false;
6872 if (EmitDiags) {
6873 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6874 << S->getSourceRange();
6875 }
6876 return true;
6877 }
6878
6879 /// Ignore parenthesizes, implicit casts, copy constructor and return the
6880 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)6881 static const ValueDecl *getInitLCDecl(const Expr *E) {
6882 if (!E)
6883 return nullptr;
6884 E = getExprAsWritten(E);
6885 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6886 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6887 if ((Ctor->isCopyOrMoveConstructor() ||
6888 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6889 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6890 E = CE->getArg(0)->IgnoreParenImpCasts();
6891 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6892 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6893 return getCanonicalDecl(VD);
6894 }
6895 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6896 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6897 return getCanonicalDecl(ME->getMemberDecl());
6898 return nullptr;
6899 }
6900
checkAndSetCond(Expr * S)6901 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6902 // Check test-expr for canonical form, save upper-bound UB, flags for
6903 // less/greater and for strict/non-strict comparison.
6904 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6905 // var relational-op b
6906 // b relational-op var
6907 //
6908 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6909 if (!S) {
6910 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6911 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6912 return true;
6913 }
6914 Condition = S;
6915 S = getExprAsWritten(S);
6916 SourceLocation CondLoc = S->getBeginLoc();
6917 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6918 if (BO->isRelationalOp()) {
6919 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6920 return setUB(BO->getRHS(),
6921 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6922 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6923 BO->getSourceRange(), BO->getOperatorLoc());
6924 if (getInitLCDecl(BO->getRHS()) == LCDecl)
6925 return setUB(BO->getLHS(),
6926 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6927 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6928 BO->getSourceRange(), BO->getOperatorLoc());
6929 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6930 return setUB(
6931 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6932 /*LessOp=*/llvm::None,
6933 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6934 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6935 if (CE->getNumArgs() == 2) {
6936 auto Op = CE->getOperator();
6937 switch (Op) {
6938 case OO_Greater:
6939 case OO_GreaterEqual:
6940 case OO_Less:
6941 case OO_LessEqual:
6942 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6943 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6944 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6945 CE->getOperatorLoc());
6946 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6947 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6948 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6949 CE->getOperatorLoc());
6950 break;
6951 case OO_ExclaimEqual:
6952 if (IneqCondIsCanonical)
6953 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6954 : CE->getArg(0),
6955 /*LessOp=*/llvm::None,
6956 /*StrictOp=*/true, CE->getSourceRange(),
6957 CE->getOperatorLoc());
6958 break;
6959 default:
6960 break;
6961 }
6962 }
6963 }
6964 if (dependent() || SemaRef.CurContext->isDependentContext())
6965 return false;
6966 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6967 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6968 return true;
6969 }
6970
checkAndSetIncRHS(Expr * RHS)6971 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6972 // RHS of canonical loop form increment can be:
6973 // var + incr
6974 // incr + var
6975 // var - incr
6976 //
6977 RHS = RHS->IgnoreParenImpCasts();
6978 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6979 if (BO->isAdditiveOp()) {
6980 bool IsAdd = BO->getOpcode() == BO_Add;
6981 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6982 return setStep(BO->getRHS(), !IsAdd);
6983 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6984 return setStep(BO->getLHS(), /*Subtract=*/false);
6985 }
6986 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6987 bool IsAdd = CE->getOperator() == OO_Plus;
6988 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6989 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6990 return setStep(CE->getArg(1), !IsAdd);
6991 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6992 return setStep(CE->getArg(0), /*Subtract=*/false);
6993 }
6994 }
6995 if (dependent() || SemaRef.CurContext->isDependentContext())
6996 return false;
6997 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6998 << RHS->getSourceRange() << LCDecl;
6999 return true;
7000 }
7001
checkAndSetInc(Expr * S)7002 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7003 // Check incr-expr for canonical loop form and return true if it
7004 // does not conform.
7005 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7006 // ++var
7007 // var++
7008 // --var
7009 // var--
7010 // var += incr
7011 // var -= incr
7012 // var = var + incr
7013 // var = incr + var
7014 // var = var - incr
7015 //
7016 if (!S) {
7017 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7018 return true;
7019 }
7020 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7021 if (!ExprTemp->cleanupsHaveSideEffects())
7022 S = ExprTemp->getSubExpr();
7023
7024 IncrementSrcRange = S->getSourceRange();
7025 S = S->IgnoreParens();
7026 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7027 if (UO->isIncrementDecrementOp() &&
7028 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7029 return setStep(SemaRef
7030 .ActOnIntegerConstant(UO->getBeginLoc(),
7031 (UO->isDecrementOp() ? -1 : 1))
7032 .get(),
7033 /*Subtract=*/false);
7034 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7035 switch (BO->getOpcode()) {
7036 case BO_AddAssign:
7037 case BO_SubAssign:
7038 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7039 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7040 break;
7041 case BO_Assign:
7042 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7043 return checkAndSetIncRHS(BO->getRHS());
7044 break;
7045 default:
7046 break;
7047 }
7048 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7049 switch (CE->getOperator()) {
7050 case OO_PlusPlus:
7051 case OO_MinusMinus:
7052 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7053 return setStep(SemaRef
7054 .ActOnIntegerConstant(
7055 CE->getBeginLoc(),
7056 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7057 .get(),
7058 /*Subtract=*/false);
7059 break;
7060 case OO_PlusEqual:
7061 case OO_MinusEqual:
7062 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7063 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7064 break;
7065 case OO_Equal:
7066 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7067 return checkAndSetIncRHS(CE->getArg(1));
7068 break;
7069 default:
7070 break;
7071 }
7072 }
7073 if (dependent() || SemaRef.CurContext->isDependentContext())
7074 return false;
7075 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7076 << S->getSourceRange() << LCDecl;
7077 return true;
7078 }
7079
7080 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7081 tryBuildCapture(Sema &SemaRef, Expr *Capture,
7082 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7083 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7084 return Capture;
7085 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7086 return SemaRef.PerformImplicitConversion(
7087 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7088 /*AllowExplicit=*/true);
7089 auto I = Captures.find(Capture);
7090 if (I != Captures.end())
7091 return buildCapture(SemaRef, Capture, I->second);
7092 DeclRefExpr *Ref = nullptr;
7093 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7094 Captures[Capture] = Ref;
7095 return Res;
7096 }
7097
7098 /// Calculate number of iterations, transforming to unsigned, if number of
7099 /// iterations may be larger than the original type.
7100 static Expr *
calculateNumIters(Sema & SemaRef,Scope * S,SourceLocation DefaultLoc,Expr * Lower,Expr * Upper,Expr * Step,QualType LCTy,bool TestIsStrictOp,bool RoundToStep,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7101 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7102 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7103 bool TestIsStrictOp, bool RoundToStep,
7104 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7105 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7106 if (!NewStep.isUsable())
7107 return nullptr;
7108 llvm::APSInt LRes, SRes;
7109 bool IsLowerConst = false, IsStepConst = false;
7110 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7111 LRes = *Res;
7112 IsLowerConst = true;
7113 }
7114 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7115 SRes = *Res;
7116 IsStepConst = true;
7117 }
7118 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7119 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7120 (TestIsStrictOp && LRes.isStrictlyPositive()));
7121 bool NeedToReorganize = false;
7122 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7123 if (!NoNeedToConvert && IsLowerConst &&
7124 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7125 NoNeedToConvert = true;
7126 if (RoundToStep) {
7127 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7128 ? LRes.getBitWidth()
7129 : SRes.getBitWidth();
7130 LRes = LRes.extend(BW + 1);
7131 LRes.setIsSigned(true);
7132 SRes = SRes.extend(BW + 1);
7133 SRes.setIsSigned(true);
7134 LRes -= SRes;
7135 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7136 LRes = LRes.trunc(BW);
7137 }
7138 if (TestIsStrictOp) {
7139 unsigned BW = LRes.getBitWidth();
7140 LRes = LRes.extend(BW + 1);
7141 LRes.setIsSigned(true);
7142 ++LRes;
7143 NoNeedToConvert =
7144 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7145 // truncate to the original bitwidth.
7146 LRes = LRes.trunc(BW);
7147 }
7148 NeedToReorganize = NoNeedToConvert;
7149 }
7150 llvm::APSInt URes;
7151 bool IsUpperConst = false;
7152 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7153 URes = *Res;
7154 IsUpperConst = true;
7155 }
7156 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7157 (!RoundToStep || IsStepConst)) {
7158 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7159 : URes.getBitWidth();
7160 LRes = LRes.extend(BW + 1);
7161 LRes.setIsSigned(true);
7162 URes = URes.extend(BW + 1);
7163 URes.setIsSigned(true);
7164 URes -= LRes;
7165 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7166 NeedToReorganize = NoNeedToConvert;
7167 }
7168 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7169 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7170 // unsigned.
7171 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7172 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7173 QualType LowerTy = Lower->getType();
7174 QualType UpperTy = Upper->getType();
7175 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7176 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7177 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7178 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7179 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7180 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7181 Upper =
7182 SemaRef
7183 .PerformImplicitConversion(
7184 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7185 CastType, Sema::AA_Converting)
7186 .get();
7187 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7188 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7189 }
7190 }
7191 if (!Lower || !Upper || NewStep.isInvalid())
7192 return nullptr;
7193
7194 ExprResult Diff;
7195 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7196 // 1]).
7197 if (NeedToReorganize) {
7198 Diff = Lower;
7199
7200 if (RoundToStep) {
7201 // Lower - Step
7202 Diff =
7203 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7204 if (!Diff.isUsable())
7205 return nullptr;
7206 }
7207
7208 // Lower - Step [+ 1]
7209 if (TestIsStrictOp)
7210 Diff = SemaRef.BuildBinOp(
7211 S, DefaultLoc, BO_Add, Diff.get(),
7212 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7213 if (!Diff.isUsable())
7214 return nullptr;
7215
7216 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7217 if (!Diff.isUsable())
7218 return nullptr;
7219
7220 // Upper - (Lower - Step [+ 1]).
7221 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7222 if (!Diff.isUsable())
7223 return nullptr;
7224 } else {
7225 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7226
7227 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7228 // BuildBinOp already emitted error, this one is to point user to upper
7229 // and lower bound, and to tell what is passed to 'operator-'.
7230 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7231 << Upper->getSourceRange() << Lower->getSourceRange();
7232 return nullptr;
7233 }
7234
7235 if (!Diff.isUsable())
7236 return nullptr;
7237
7238 // Upper - Lower [- 1]
7239 if (TestIsStrictOp)
7240 Diff = SemaRef.BuildBinOp(
7241 S, DefaultLoc, BO_Sub, Diff.get(),
7242 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7243 if (!Diff.isUsable())
7244 return nullptr;
7245
7246 if (RoundToStep) {
7247 // Upper - Lower [- 1] + Step
7248 Diff =
7249 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7250 if (!Diff.isUsable())
7251 return nullptr;
7252 }
7253 }
7254
7255 // Parentheses (for dumping/debugging purposes only).
7256 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7257 if (!Diff.isUsable())
7258 return nullptr;
7259
7260 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7261 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7262 if (!Diff.isUsable())
7263 return nullptr;
7264
7265 return Diff.get();
7266 }
7267
7268 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7269 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7270 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7271 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7272 QualType VarType = LCDecl->getType().getNonReferenceType();
7273 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7274 !SemaRef.getLangOpts().CPlusPlus)
7275 return nullptr;
7276 Expr *LBVal = LB;
7277 Expr *UBVal = UB;
7278 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7279 // max(LB(MinVal), LB(MaxVal))
7280 if (InitDependOnLC) {
7281 const LoopIterationSpace &IS =
7282 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7283 InitDependOnLC.getValueOr(
7284 CondDependOnLC.getValueOr(0))];
7285 if (!IS.MinValue || !IS.MaxValue)
7286 return nullptr;
7287 // OuterVar = Min
7288 ExprResult MinValue =
7289 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7290 if (!MinValue.isUsable())
7291 return nullptr;
7292
7293 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7294 IS.CounterVar, MinValue.get());
7295 if (!LBMinVal.isUsable())
7296 return nullptr;
7297 // OuterVar = Min, LBVal
7298 LBMinVal =
7299 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7300 if (!LBMinVal.isUsable())
7301 return nullptr;
7302 // (OuterVar = Min, LBVal)
7303 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7304 if (!LBMinVal.isUsable())
7305 return nullptr;
7306
7307 // OuterVar = Max
7308 ExprResult MaxValue =
7309 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7310 if (!MaxValue.isUsable())
7311 return nullptr;
7312
7313 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7314 IS.CounterVar, MaxValue.get());
7315 if (!LBMaxVal.isUsable())
7316 return nullptr;
7317 // OuterVar = Max, LBVal
7318 LBMaxVal =
7319 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7320 if (!LBMaxVal.isUsable())
7321 return nullptr;
7322 // (OuterVar = Max, LBVal)
7323 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7324 if (!LBMaxVal.isUsable())
7325 return nullptr;
7326
7327 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7328 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7329 if (!LBMin || !LBMax)
7330 return nullptr;
7331 // LB(MinVal) < LB(MaxVal)
7332 ExprResult MinLessMaxRes =
7333 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7334 if (!MinLessMaxRes.isUsable())
7335 return nullptr;
7336 Expr *MinLessMax =
7337 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7338 if (!MinLessMax)
7339 return nullptr;
7340 if (TestIsLessOp.getValue()) {
7341 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7342 // LB(MaxVal))
7343 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7344 MinLessMax, LBMin, LBMax);
7345 if (!MinLB.isUsable())
7346 return nullptr;
7347 LBVal = MinLB.get();
7348 } else {
7349 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7350 // LB(MaxVal))
7351 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7352 MinLessMax, LBMax, LBMin);
7353 if (!MaxLB.isUsable())
7354 return nullptr;
7355 LBVal = MaxLB.get();
7356 }
7357 }
7358 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7359 // min(UB(MinVal), UB(MaxVal))
7360 if (CondDependOnLC) {
7361 const LoopIterationSpace &IS =
7362 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7363 InitDependOnLC.getValueOr(
7364 CondDependOnLC.getValueOr(0))];
7365 if (!IS.MinValue || !IS.MaxValue)
7366 return nullptr;
7367 // OuterVar = Min
7368 ExprResult MinValue =
7369 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7370 if (!MinValue.isUsable())
7371 return nullptr;
7372
7373 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7374 IS.CounterVar, MinValue.get());
7375 if (!UBMinVal.isUsable())
7376 return nullptr;
7377 // OuterVar = Min, UBVal
7378 UBMinVal =
7379 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7380 if (!UBMinVal.isUsable())
7381 return nullptr;
7382 // (OuterVar = Min, UBVal)
7383 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7384 if (!UBMinVal.isUsable())
7385 return nullptr;
7386
7387 // OuterVar = Max
7388 ExprResult MaxValue =
7389 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7390 if (!MaxValue.isUsable())
7391 return nullptr;
7392
7393 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7394 IS.CounterVar, MaxValue.get());
7395 if (!UBMaxVal.isUsable())
7396 return nullptr;
7397 // OuterVar = Max, UBVal
7398 UBMaxVal =
7399 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7400 if (!UBMaxVal.isUsable())
7401 return nullptr;
7402 // (OuterVar = Max, UBVal)
7403 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7404 if (!UBMaxVal.isUsable())
7405 return nullptr;
7406
7407 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7408 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7409 if (!UBMin || !UBMax)
7410 return nullptr;
7411 // UB(MinVal) > UB(MaxVal)
7412 ExprResult MinGreaterMaxRes =
7413 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7414 if (!MinGreaterMaxRes.isUsable())
7415 return nullptr;
7416 Expr *MinGreaterMax =
7417 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7418 if (!MinGreaterMax)
7419 return nullptr;
7420 if (TestIsLessOp.getValue()) {
7421 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7422 // UB(MaxVal))
7423 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7424 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7425 if (!MaxUB.isUsable())
7426 return nullptr;
7427 UBVal = MaxUB.get();
7428 } else {
7429 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7430 // UB(MaxVal))
7431 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7432 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7433 if (!MinUB.isUsable())
7434 return nullptr;
7435 UBVal = MinUB.get();
7436 }
7437 }
7438 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7439 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7440 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7441 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7442 if (!Upper || !Lower)
7443 return nullptr;
7444
7445 ExprResult Diff =
7446 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7447 TestIsStrictOp, /*RoundToStep=*/true, Captures);
7448 if (!Diff.isUsable())
7449 return nullptr;
7450
7451 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7452 QualType Type = Diff.get()->getType();
7453 ASTContext &C = SemaRef.Context;
7454 bool UseVarType = VarType->hasIntegerRepresentation() &&
7455 C.getTypeSize(Type) > C.getTypeSize(VarType);
7456 if (!Type->isIntegerType() || UseVarType) {
7457 unsigned NewSize =
7458 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7459 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7460 : Type->hasSignedIntegerRepresentation();
7461 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7462 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7463 Diff = SemaRef.PerformImplicitConversion(
7464 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7465 if (!Diff.isUsable())
7466 return nullptr;
7467 }
7468 }
7469 if (LimitedType) {
7470 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7471 if (NewSize != C.getTypeSize(Type)) {
7472 if (NewSize < C.getTypeSize(Type)) {
7473 assert(NewSize == 64 && "incorrect loop var size");
7474 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7475 << InitSrcRange << ConditionSrcRange;
7476 }
7477 QualType NewType = C.getIntTypeForBitwidth(
7478 NewSize, Type->hasSignedIntegerRepresentation() ||
7479 C.getTypeSize(Type) < NewSize);
7480 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7481 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7482 Sema::AA_Converting, true);
7483 if (!Diff.isUsable())
7484 return nullptr;
7485 }
7486 }
7487 }
7488
7489 return Diff.get();
7490 }
7491
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7492 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7493 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7494 // Do not build for iterators, they cannot be used in non-rectangular loop
7495 // nests.
7496 if (LCDecl->getType()->isRecordType())
7497 return std::make_pair(nullptr, nullptr);
7498 // If we subtract, the min is in the condition, otherwise the min is in the
7499 // init value.
7500 Expr *MinExpr = nullptr;
7501 Expr *MaxExpr = nullptr;
7502 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7503 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7504 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7505 : CondDependOnLC.hasValue();
7506 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7507 : InitDependOnLC.hasValue();
7508 Expr *Lower =
7509 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7510 Expr *Upper =
7511 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7512 if (!Upper || !Lower)
7513 return std::make_pair(nullptr, nullptr);
7514
7515 if (TestIsLessOp.getValue())
7516 MinExpr = Lower;
7517 else
7518 MaxExpr = Upper;
7519
7520 // Build minimum/maximum value based on number of iterations.
7521 QualType VarType = LCDecl->getType().getNonReferenceType();
7522
7523 ExprResult Diff =
7524 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7525 TestIsStrictOp, /*RoundToStep=*/false, Captures);
7526 if (!Diff.isUsable())
7527 return std::make_pair(nullptr, nullptr);
7528
7529 // ((Upper - Lower [- 1]) / Step) * Step
7530 // Parentheses (for dumping/debugging purposes only).
7531 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7532 if (!Diff.isUsable())
7533 return std::make_pair(nullptr, nullptr);
7534
7535 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7536 if (!NewStep.isUsable())
7537 return std::make_pair(nullptr, nullptr);
7538 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7539 if (!Diff.isUsable())
7540 return std::make_pair(nullptr, nullptr);
7541
7542 // Parentheses (for dumping/debugging purposes only).
7543 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7544 if (!Diff.isUsable())
7545 return std::make_pair(nullptr, nullptr);
7546
7547 // Convert to the ptrdiff_t, if original type is pointer.
7548 if (VarType->isAnyPointerType() &&
7549 !SemaRef.Context.hasSameType(
7550 Diff.get()->getType(),
7551 SemaRef.Context.getUnsignedPointerDiffType())) {
7552 Diff = SemaRef.PerformImplicitConversion(
7553 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7554 Sema::AA_Converting, /*AllowExplicit=*/true);
7555 }
7556 if (!Diff.isUsable())
7557 return std::make_pair(nullptr, nullptr);
7558
7559 if (TestIsLessOp.getValue()) {
7560 // MinExpr = Lower;
7561 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7562 Diff = SemaRef.BuildBinOp(
7563 S, DefaultLoc, BO_Add,
7564 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7565 Diff.get());
7566 if (!Diff.isUsable())
7567 return std::make_pair(nullptr, nullptr);
7568 } else {
7569 // MaxExpr = Upper;
7570 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7571 Diff = SemaRef.BuildBinOp(
7572 S, DefaultLoc, BO_Sub,
7573 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7574 Diff.get());
7575 if (!Diff.isUsable())
7576 return std::make_pair(nullptr, nullptr);
7577 }
7578
7579 // Convert to the original type.
7580 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7581 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7582 Sema::AA_Converting,
7583 /*AllowExplicit=*/true);
7584 if (!Diff.isUsable())
7585 return std::make_pair(nullptr, nullptr);
7586
7587 Sema::TentativeAnalysisScope Trap(SemaRef);
7588 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7589 if (!Diff.isUsable())
7590 return std::make_pair(nullptr, nullptr);
7591
7592 if (TestIsLessOp.getValue())
7593 MaxExpr = Diff.get();
7594 else
7595 MinExpr = Diff.get();
7596
7597 return std::make_pair(MinExpr, MaxExpr);
7598 }
7599
buildFinalCondition(Scope * S) const7600 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7601 if (InitDependOnLC || CondDependOnLC)
7602 return Condition;
7603 return nullptr;
7604 }
7605
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7606 Expr *OpenMPIterationSpaceChecker::buildPreCond(
7607 Scope *S, Expr *Cond,
7608 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7609 // Do not build a precondition when the condition/initialization is dependent
7610 // to prevent pessimistic early loop exit.
7611 // TODO: this can be improved by calculating min/max values but not sure that
7612 // it will be very effective.
7613 if (CondDependOnLC || InitDependOnLC)
7614 return SemaRef.PerformImplicitConversion(
7615 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7616 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7617 /*AllowExplicit=*/true).get();
7618
7619 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7620 Sema::TentativeAnalysisScope Trap(SemaRef);
7621
7622 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7623 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7624 if (!NewLB.isUsable() || !NewUB.isUsable())
7625 return nullptr;
7626
7627 ExprResult CondExpr =
7628 SemaRef.BuildBinOp(S, DefaultLoc,
7629 TestIsLessOp.getValue() ?
7630 (TestIsStrictOp ? BO_LT : BO_LE) :
7631 (TestIsStrictOp ? BO_GT : BO_GE),
7632 NewLB.get(), NewUB.get());
7633 if (CondExpr.isUsable()) {
7634 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7635 SemaRef.Context.BoolTy))
7636 CondExpr = SemaRef.PerformImplicitConversion(
7637 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7638 /*AllowExplicit=*/true);
7639 }
7640
7641 // Otherwise use original loop condition and evaluate it in runtime.
7642 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7643 }
7644
7645 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const7646 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7647 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7648 DSAStackTy &DSA) const {
7649 auto *VD = dyn_cast<VarDecl>(LCDecl);
7650 if (!VD) {
7651 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7652 DeclRefExpr *Ref = buildDeclRefExpr(
7653 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7654 const DSAStackTy::DSAVarData Data =
7655 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7656 // If the loop control decl is explicitly marked as private, do not mark it
7657 // as captured again.
7658 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7659 Captures.insert(std::make_pair(LCRef, Ref));
7660 return Ref;
7661 }
7662 return cast<DeclRefExpr>(LCRef);
7663 }
7664
buildPrivateCounterVar() const7665 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7666 if (LCDecl && !LCDecl->isInvalidDecl()) {
7667 QualType Type = LCDecl->getType().getNonReferenceType();
7668 VarDecl *PrivateVar = buildVarDecl(
7669 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7670 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7671 isa<VarDecl>(LCDecl)
7672 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7673 : nullptr);
7674 if (PrivateVar->isInvalidDecl())
7675 return nullptr;
7676 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7677 }
7678 return nullptr;
7679 }
7680
7681 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const7682 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7683
7684 /// Build step of the counter be used for codegen.
buildCounterStep() const7685 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7686
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)7687 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7688 Scope *S, Expr *Counter,
7689 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7690 Expr *Inc, OverloadedOperatorKind OOK) {
7691 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7692 if (!Cnt)
7693 return nullptr;
7694 if (Inc) {
7695 assert((OOK == OO_Plus || OOK == OO_Minus) &&
7696 "Expected only + or - operations for depend clauses.");
7697 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7698 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7699 if (!Cnt)
7700 return nullptr;
7701 }
7702 QualType VarType = LCDecl->getType().getNonReferenceType();
7703 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7704 !SemaRef.getLangOpts().CPlusPlus)
7705 return nullptr;
7706 // Upper - Lower
7707 Expr *Upper = TestIsLessOp.getValue()
7708 ? Cnt
7709 : tryBuildCapture(SemaRef, LB, Captures).get();
7710 Expr *Lower = TestIsLessOp.getValue()
7711 ? tryBuildCapture(SemaRef, LB, Captures).get()
7712 : Cnt;
7713 if (!Upper || !Lower)
7714 return nullptr;
7715
7716 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7717 Step, VarType, /*TestIsStrictOp=*/false,
7718 /*RoundToStep=*/false, Captures);
7719 if (!Diff.isUsable())
7720 return nullptr;
7721
7722 return Diff.get();
7723 }
7724 } // namespace
7725
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)7726 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7727 assert(getLangOpts().OpenMP && "OpenMP is not active.");
7728 assert(Init && "Expected loop in canonical form.");
7729 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
7730 if (AssociatedLoops > 0 &&
7731 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
7732 DSAStack->loopStart();
7733 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
7734 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7735 if (ValueDecl *D = ISC.getLoopDecl()) {
7736 auto *VD = dyn_cast<VarDecl>(D);
7737 DeclRefExpr *PrivateRef = nullptr;
7738 if (!VD) {
7739 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7740 VD = Private;
7741 } else {
7742 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7743 /*WithInit=*/false);
7744 VD = cast<VarDecl>(PrivateRef->getDecl());
7745 }
7746 }
7747 DSAStack->addLoopControlVariable(D, VD);
7748 const Decl *LD = DSAStack->getPossiblyLoopCunter();
7749 if (LD != D->getCanonicalDecl()) {
7750 DSAStack->resetPossibleLoopCounter();
7751 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7752 MarkDeclarationsReferencedInExpr(
7753 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7754 Var->getType().getNonLValueExprType(Context),
7755 ForLoc, /*RefersToCapture=*/true));
7756 }
7757 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
7758 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7759 // Referenced in a Construct, C/C++]. The loop iteration variable in the
7760 // associated for-loop of a simd construct with just one associated
7761 // for-loop may be listed in a linear clause with a constant-linear-step
7762 // that is the increment of the associated for-loop. The loop iteration
7763 // variable(s) in the associated for-loop(s) of a for or parallel for
7764 // construct may be listed in a private or lastprivate clause.
7765 DSAStackTy::DSAVarData DVar =
7766 DSAStack->getTopDSA(D, /*FromParent=*/false);
7767 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7768 // is declared in the loop and it is predetermined as a private.
7769 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7770 OpenMPClauseKind PredeterminedCKind =
7771 isOpenMPSimdDirective(DKind)
7772 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7773 : OMPC_private;
7774 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7775 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7776 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7777 DVar.CKind != OMPC_private))) ||
7778 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7779 DKind == OMPD_master_taskloop ||
7780 DKind == OMPD_parallel_master_taskloop ||
7781 isOpenMPDistributeDirective(DKind)) &&
7782 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7783 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7784 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7785 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7786 << getOpenMPClauseName(DVar.CKind)
7787 << getOpenMPDirectiveName(DKind)
7788 << getOpenMPClauseName(PredeterminedCKind);
7789 if (DVar.RefExpr == nullptr)
7790 DVar.CKind = PredeterminedCKind;
7791 reportOriginalDsa(*this, DSAStack, D, DVar,
7792 /*IsLoopIterVar=*/true);
7793 } else if (LoopDeclRefExpr) {
7794 // Make the loop iteration variable private (for worksharing
7795 // constructs), linear (for simd directives with the only one
7796 // associated loop) or lastprivate (for simd directives with several
7797 // collapsed or ordered loops).
7798 if (DVar.CKind == OMPC_unknown)
7799 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7800 PrivateRef);
7801 }
7802 }
7803 }
7804 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
7805 }
7806 }
7807
7808 /// Called on a for stmt to check and extract its iteration space
7809 /// for further processing (such as collapsing).
checkOpenMPIterationSpace(OpenMPDirectiveKind DKind,Stmt * S,Sema & SemaRef,DSAStackTy & DSA,unsigned CurrentNestedLoopCount,unsigned NestedLoopCount,unsigned TotalNestedLoopCount,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7810 static bool checkOpenMPIterationSpace(
7811 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7812 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7813 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7814 Expr *OrderedLoopCountExpr,
7815 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7816 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7817 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7818 // OpenMP [2.9.1, Canonical Loop Form]
7819 // for (init-expr; test-expr; incr-expr) structured-block
7820 // for (range-decl: range-expr) structured-block
7821 auto *For = dyn_cast_or_null<ForStmt>(S);
7822 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7823 // Ranged for is supported only in OpenMP 5.0.
7824 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7825 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7826 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7827 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7828 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7829 if (TotalNestedLoopCount > 1) {
7830 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7831 SemaRef.Diag(DSA.getConstructLoc(),
7832 diag::note_omp_collapse_ordered_expr)
7833 << 2 << CollapseLoopCountExpr->getSourceRange()
7834 << OrderedLoopCountExpr->getSourceRange();
7835 else if (CollapseLoopCountExpr)
7836 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7837 diag::note_omp_collapse_ordered_expr)
7838 << 0 << CollapseLoopCountExpr->getSourceRange();
7839 else
7840 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7841 diag::note_omp_collapse_ordered_expr)
7842 << 1 << OrderedLoopCountExpr->getSourceRange();
7843 }
7844 return true;
7845 }
7846 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
7847 "No loop body.");
7848
7849 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7850 For ? For->getForLoc() : CXXFor->getForLoc());
7851
7852 // Check init.
7853 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7854 if (ISC.checkAndSetInit(Init))
7855 return true;
7856
7857 bool HasErrors = false;
7858
7859 // Check loop variable's type.
7860 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
7861 // OpenMP [2.6, Canonical Loop Form]
7862 // Var is one of the following:
7863 // A variable of signed or unsigned integer type.
7864 // For C++, a variable of a random access iterator type.
7865 // For C, a variable of a pointer type.
7866 QualType VarType = LCDecl->getType().getNonReferenceType();
7867 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
7868 !VarType->isPointerType() &&
7869 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
7870 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
7871 << SemaRef.getLangOpts().CPlusPlus;
7872 HasErrors = true;
7873 }
7874
7875 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
7876 // a Construct
7877 // The loop iteration variable(s) in the associated for-loop(s) of a for or
7878 // parallel for construct is (are) private.
7879 // The loop iteration variable in the associated for-loop of a simd
7880 // construct with just one associated for-loop is linear with a
7881 // constant-linear-step that is the increment of the associated for-loop.
7882 // Exclude loop var from the list of variables with implicitly defined data
7883 // sharing attributes.
7884 VarsWithImplicitDSA.erase(LCDecl);
7885
7886 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
7887
7888 // Check test-expr.
7889 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7890
7891 // Check incr-expr.
7892 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7893 }
7894
7895 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
7896 return HasErrors;
7897
7898 // Build the loop's iteration space representation.
7899 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7900 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7901 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7902 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7903 (isOpenMPWorksharingDirective(DKind) ||
7904 isOpenMPTaskLoopDirective(DKind) ||
7905 isOpenMPDistributeDirective(DKind)),
7906 Captures);
7907 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7908 ISC.buildCounterVar(Captures, DSA);
7909 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7910 ISC.buildPrivateCounterVar();
7911 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7912 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7913 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7914 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7915 ISC.getConditionSrcRange();
7916 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7917 ISC.getIncrementSrcRange();
7918 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7919 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7920 ISC.isStrictTestOp();
7921 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7922 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7923 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7924 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7925 ISC.buildFinalCondition(DSA.getCurScope());
7926 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7927 ISC.doesInitDependOnLC();
7928 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7929 ISC.doesCondDependOnLC();
7930 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7931 ISC.getLoopDependentIdx();
7932
7933 HasErrors |=
7934 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7935 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7936 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7937 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7938 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7939 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7940 if (!HasErrors && DSA.isOrderedRegion()) {
7941 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7942 if (CurrentNestedLoopCount <
7943 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7944 DSA.getOrderedRegionParam().second->setLoopNumIterations(
7945 CurrentNestedLoopCount,
7946 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7947 DSA.getOrderedRegionParam().second->setLoopCounter(
7948 CurrentNestedLoopCount,
7949 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7950 }
7951 }
7952 for (auto &Pair : DSA.getDoacrossDependClauses()) {
7953 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7954 // Erroneous case - clause has some problems.
7955 continue;
7956 }
7957 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7958 Pair.second.size() <= CurrentNestedLoopCount) {
7959 // Erroneous case - clause has some problems.
7960 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7961 continue;
7962 }
7963 Expr *CntValue;
7964 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7965 CntValue = ISC.buildOrderedLoopData(
7966 DSA.getCurScope(),
7967 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7968 Pair.first->getDependencyLoc());
7969 else
7970 CntValue = ISC.buildOrderedLoopData(
7971 DSA.getCurScope(),
7972 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7973 Pair.first->getDependencyLoc(),
7974 Pair.second[CurrentNestedLoopCount].first,
7975 Pair.second[CurrentNestedLoopCount].second);
7976 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7977 }
7978 }
7979
7980 return HasErrors;
7981 }
7982
7983 /// Build 'VarRef = Start.
7984 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7985 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7986 ExprResult Start, bool IsNonRectangularLB,
7987 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7988 // Build 'VarRef = Start.
7989 ExprResult NewStart = IsNonRectangularLB
7990 ? Start.get()
7991 : tryBuildCapture(SemaRef, Start.get(), Captures);
7992 if (!NewStart.isUsable())
7993 return ExprError();
7994 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7995 VarRef.get()->getType())) {
7996 NewStart = SemaRef.PerformImplicitConversion(
7997 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7998 /*AllowExplicit=*/true);
7999 if (!NewStart.isUsable())
8000 return ExprError();
8001 }
8002
8003 ExprResult Init =
8004 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8005 return Init;
8006 }
8007
8008 /// Build 'VarRef = Start + Iter * Step'.
buildCounterUpdate(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,ExprResult Iter,ExprResult Step,bool Subtract,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > * Captures=nullptr)8009 static ExprResult buildCounterUpdate(
8010 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8011 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8012 bool IsNonRectangularLB,
8013 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8014 // Add parentheses (for debugging purposes only).
8015 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8016 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8017 !Step.isUsable())
8018 return ExprError();
8019
8020 ExprResult NewStep = Step;
8021 if (Captures)
8022 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8023 if (NewStep.isInvalid())
8024 return ExprError();
8025 ExprResult Update =
8026 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8027 if (!Update.isUsable())
8028 return ExprError();
8029
8030 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8031 // 'VarRef = Start (+|-) Iter * Step'.
8032 if (!Start.isUsable())
8033 return ExprError();
8034 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8035 if (!NewStart.isUsable())
8036 return ExprError();
8037 if (Captures && !IsNonRectangularLB)
8038 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8039 if (NewStart.isInvalid())
8040 return ExprError();
8041
8042 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8043 ExprResult SavedUpdate = Update;
8044 ExprResult UpdateVal;
8045 if (VarRef.get()->getType()->isOverloadableType() ||
8046 NewStart.get()->getType()->isOverloadableType() ||
8047 Update.get()->getType()->isOverloadableType()) {
8048 Sema::TentativeAnalysisScope Trap(SemaRef);
8049
8050 Update =
8051 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8052 if (Update.isUsable()) {
8053 UpdateVal =
8054 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8055 VarRef.get(), SavedUpdate.get());
8056 if (UpdateVal.isUsable()) {
8057 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8058 UpdateVal.get());
8059 }
8060 }
8061 }
8062
8063 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8064 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8065 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8066 NewStart.get(), SavedUpdate.get());
8067 if (!Update.isUsable())
8068 return ExprError();
8069
8070 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8071 VarRef.get()->getType())) {
8072 Update = SemaRef.PerformImplicitConversion(
8073 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8074 if (!Update.isUsable())
8075 return ExprError();
8076 }
8077
8078 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8079 }
8080 return Update;
8081 }
8082
8083 /// Convert integer expression \a E to make it have at least \a Bits
8084 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)8085 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8086 if (E == nullptr)
8087 return ExprError();
8088 ASTContext &C = SemaRef.Context;
8089 QualType OldType = E->getType();
8090 unsigned HasBits = C.getTypeSize(OldType);
8091 if (HasBits >= Bits)
8092 return ExprResult(E);
8093 // OK to convert to signed, because new type has more bits than old.
8094 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8095 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8096 true);
8097 }
8098
8099 /// Check if the given expression \a E is a constant integer that fits
8100 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)8101 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8102 if (E == nullptr)
8103 return false;
8104 if (Optional<llvm::APSInt> Result =
8105 E->getIntegerConstantExpr(SemaRef.Context))
8106 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8107 return false;
8108 }
8109
8110 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)8111 static Stmt *buildPreInits(ASTContext &Context,
8112 MutableArrayRef<Decl *> PreInits) {
8113 if (!PreInits.empty()) {
8114 return new (Context) DeclStmt(
8115 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8116 SourceLocation(), SourceLocation());
8117 }
8118 return nullptr;
8119 }
8120
8121 /// Build preinits statement for the given declarations.
8122 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8123 buildPreInits(ASTContext &Context,
8124 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8125 if (!Captures.empty()) {
8126 SmallVector<Decl *, 16> PreInits;
8127 for (const auto &Pair : Captures)
8128 PreInits.push_back(Pair.second->getDecl());
8129 return buildPreInits(Context, PreInits);
8130 }
8131 return nullptr;
8132 }
8133
8134 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)8135 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8136 Expr *PostUpdate = nullptr;
8137 if (!PostUpdates.empty()) {
8138 for (Expr *E : PostUpdates) {
8139 Expr *ConvE = S.BuildCStyleCastExpr(
8140 E->getExprLoc(),
8141 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8142 E->getExprLoc(), E)
8143 .get();
8144 PostUpdate = PostUpdate
8145 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8146 PostUpdate, ConvE)
8147 .get()
8148 : ConvE;
8149 }
8150 }
8151 return PostUpdate;
8152 }
8153
8154 /// Called on a for stmt to check itself and nested loops (if any).
8155 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8156 /// number of collapsed loops otherwise.
8157 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopDirective::HelperExprs & Built)8158 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8159 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8160 DSAStackTy &DSA,
8161 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8162 OMPLoopDirective::HelperExprs &Built) {
8163 unsigned NestedLoopCount = 1;
8164 if (CollapseLoopCountExpr) {
8165 // Found 'collapse' clause - calculate collapse number.
8166 Expr::EvalResult Result;
8167 if (!CollapseLoopCountExpr->isValueDependent() &&
8168 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8169 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8170 } else {
8171 Built.clear(/*Size=*/1);
8172 return 1;
8173 }
8174 }
8175 unsigned OrderedLoopCount = 1;
8176 if (OrderedLoopCountExpr) {
8177 // Found 'ordered' clause - calculate collapse number.
8178 Expr::EvalResult EVResult;
8179 if (!OrderedLoopCountExpr->isValueDependent() &&
8180 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8181 SemaRef.getASTContext())) {
8182 llvm::APSInt Result = EVResult.Val.getInt();
8183 if (Result.getLimitedValue() < NestedLoopCount) {
8184 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8185 diag::err_omp_wrong_ordered_loop_count)
8186 << OrderedLoopCountExpr->getSourceRange();
8187 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8188 diag::note_collapse_loop_count)
8189 << CollapseLoopCountExpr->getSourceRange();
8190 }
8191 OrderedLoopCount = Result.getLimitedValue();
8192 } else {
8193 Built.clear(/*Size=*/1);
8194 return 1;
8195 }
8196 }
8197 // This is helper routine for loop directives (e.g., 'for', 'simd',
8198 // 'for simd', etc.).
8199 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8200 SmallVector<LoopIterationSpace, 4> IterSpaces(
8201 std::max(OrderedLoopCount, NestedLoopCount));
8202 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8203 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8204 if (checkOpenMPIterationSpace(
8205 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8206 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8207 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8208 return 0;
8209 // Move on to the next nested for loop, or to the loop body.
8210 // OpenMP [2.8.1, simd construct, Restrictions]
8211 // All loops associated with the construct must be perfectly nested; that
8212 // is, there must be no intervening code nor any OpenMP directive between
8213 // any two loops.
8214 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8215 CurStmt = For->getBody();
8216 } else {
8217 assert(isa<CXXForRangeStmt>(CurStmt) &&
8218 "Expected canonical for or range-based for loops.");
8219 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8220 }
8221 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8222 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8223 }
8224 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8225 if (checkOpenMPIterationSpace(
8226 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8227 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8228 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8229 return 0;
8230 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8231 // Handle initialization of captured loop iterator variables.
8232 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8233 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8234 Captures[DRE] = DRE;
8235 }
8236 }
8237 // Move on to the next nested for loop, or to the loop body.
8238 // OpenMP [2.8.1, simd construct, Restrictions]
8239 // All loops associated with the construct must be perfectly nested; that
8240 // is, there must be no intervening code nor any OpenMP directive between
8241 // any two loops.
8242 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8243 CurStmt = For->getBody();
8244 } else {
8245 assert(isa<CXXForRangeStmt>(CurStmt) &&
8246 "Expected canonical for or range-based for loops.");
8247 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8248 }
8249 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8250 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8251 }
8252
8253 Built.clear(/* size */ NestedLoopCount);
8254
8255 if (SemaRef.CurContext->isDependentContext())
8256 return NestedLoopCount;
8257
8258 // An example of what is generated for the following code:
8259 //
8260 // #pragma omp simd collapse(2) ordered(2)
8261 // for (i = 0; i < NI; ++i)
8262 // for (k = 0; k < NK; ++k)
8263 // for (j = J0; j < NJ; j+=2) {
8264 // <loop body>
8265 // }
8266 //
8267 // We generate the code below.
8268 // Note: the loop body may be outlined in CodeGen.
8269 // Note: some counters may be C++ classes, operator- is used to find number of
8270 // iterations and operator+= to calculate counter value.
8271 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8272 // or i64 is currently supported).
8273 //
8274 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8275 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8276 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8277 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8278 // // similar updates for vars in clauses (e.g. 'linear')
8279 // <loop body (using local i and j)>
8280 // }
8281 // i = NI; // assign final values of counters
8282 // j = NJ;
8283 //
8284
8285 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8286 // the iteration counts of the collapsed for loops.
8287 // Precondition tests if there is at least one iteration (all conditions are
8288 // true).
8289 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8290 Expr *N0 = IterSpaces[0].NumIterations;
8291 ExprResult LastIteration32 =
8292 widenIterationCount(/*Bits=*/32,
8293 SemaRef
8294 .PerformImplicitConversion(
8295 N0->IgnoreImpCasts(), N0->getType(),
8296 Sema::AA_Converting, /*AllowExplicit=*/true)
8297 .get(),
8298 SemaRef);
8299 ExprResult LastIteration64 = widenIterationCount(
8300 /*Bits=*/64,
8301 SemaRef
8302 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8303 Sema::AA_Converting,
8304 /*AllowExplicit=*/true)
8305 .get(),
8306 SemaRef);
8307
8308 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8309 return NestedLoopCount;
8310
8311 ASTContext &C = SemaRef.Context;
8312 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8313
8314 Scope *CurScope = DSA.getCurScope();
8315 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8316 if (PreCond.isUsable()) {
8317 PreCond =
8318 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8319 PreCond.get(), IterSpaces[Cnt].PreCond);
8320 }
8321 Expr *N = IterSpaces[Cnt].NumIterations;
8322 SourceLocation Loc = N->getExprLoc();
8323 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8324 if (LastIteration32.isUsable())
8325 LastIteration32 = SemaRef.BuildBinOp(
8326 CurScope, Loc, BO_Mul, LastIteration32.get(),
8327 SemaRef
8328 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8329 Sema::AA_Converting,
8330 /*AllowExplicit=*/true)
8331 .get());
8332 if (LastIteration64.isUsable())
8333 LastIteration64 = SemaRef.BuildBinOp(
8334 CurScope, Loc, BO_Mul, LastIteration64.get(),
8335 SemaRef
8336 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8337 Sema::AA_Converting,
8338 /*AllowExplicit=*/true)
8339 .get());
8340 }
8341
8342 // Choose either the 32-bit or 64-bit version.
8343 ExprResult LastIteration = LastIteration64;
8344 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8345 (LastIteration32.isUsable() &&
8346 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8347 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8348 fitsInto(
8349 /*Bits=*/32,
8350 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8351 LastIteration64.get(), SemaRef))))
8352 LastIteration = LastIteration32;
8353 QualType VType = LastIteration.get()->getType();
8354 QualType RealVType = VType;
8355 QualType StrideVType = VType;
8356 if (isOpenMPTaskLoopDirective(DKind)) {
8357 VType =
8358 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8359 StrideVType =
8360 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8361 }
8362
8363 if (!LastIteration.isUsable())
8364 return 0;
8365
8366 // Save the number of iterations.
8367 ExprResult NumIterations = LastIteration;
8368 {
8369 LastIteration = SemaRef.BuildBinOp(
8370 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8371 LastIteration.get(),
8372 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8373 if (!LastIteration.isUsable())
8374 return 0;
8375 }
8376
8377 // Calculate the last iteration number beforehand instead of doing this on
8378 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8379 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8380 ExprResult CalcLastIteration;
8381 if (!IsConstant) {
8382 ExprResult SaveRef =
8383 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8384 LastIteration = SaveRef;
8385
8386 // Prepare SaveRef + 1.
8387 NumIterations = SemaRef.BuildBinOp(
8388 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8389 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8390 if (!NumIterations.isUsable())
8391 return 0;
8392 }
8393
8394 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8395
8396 // Build variables passed into runtime, necessary for worksharing directives.
8397 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8398 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8399 isOpenMPDistributeDirective(DKind)) {
8400 // Lower bound variable, initialized with zero.
8401 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8402 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8403 SemaRef.AddInitializerToDecl(LBDecl,
8404 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8405 /*DirectInit*/ false);
8406
8407 // Upper bound variable, initialized with last iteration number.
8408 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8409 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8410 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8411 /*DirectInit*/ false);
8412
8413 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8414 // This will be used to implement clause 'lastprivate'.
8415 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8416 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8417 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8418 SemaRef.AddInitializerToDecl(ILDecl,
8419 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8420 /*DirectInit*/ false);
8421
8422 // Stride variable returned by runtime (we initialize it to 1 by default).
8423 VarDecl *STDecl =
8424 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8425 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8426 SemaRef.AddInitializerToDecl(STDecl,
8427 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8428 /*DirectInit*/ false);
8429
8430 // Build expression: UB = min(UB, LastIteration)
8431 // It is necessary for CodeGen of directives with static scheduling.
8432 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8433 UB.get(), LastIteration.get());
8434 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8435 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8436 LastIteration.get(), UB.get());
8437 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8438 CondOp.get());
8439 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8440
8441 // If we have a combined directive that combines 'distribute', 'for' or
8442 // 'simd' we need to be able to access the bounds of the schedule of the
8443 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8444 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8445 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8446 // Lower bound variable, initialized with zero.
8447 VarDecl *CombLBDecl =
8448 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8449 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8450 SemaRef.AddInitializerToDecl(
8451 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8452 /*DirectInit*/ false);
8453
8454 // Upper bound variable, initialized with last iteration number.
8455 VarDecl *CombUBDecl =
8456 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8457 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8458 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8459 /*DirectInit*/ false);
8460
8461 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8462 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8463 ExprResult CombCondOp =
8464 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8465 LastIteration.get(), CombUB.get());
8466 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8467 CombCondOp.get());
8468 CombEUB =
8469 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8470
8471 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8472 // We expect to have at least 2 more parameters than the 'parallel'
8473 // directive does - the lower and upper bounds of the previous schedule.
8474 assert(CD->getNumParams() >= 4 &&
8475 "Unexpected number of parameters in loop combined directive");
8476
8477 // Set the proper type for the bounds given what we learned from the
8478 // enclosed loops.
8479 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8480 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8481
8482 // Previous lower and upper bounds are obtained from the region
8483 // parameters.
8484 PrevLB =
8485 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8486 PrevUB =
8487 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8488 }
8489 }
8490
8491 // Build the iteration variable and its initialization before loop.
8492 ExprResult IV;
8493 ExprResult Init, CombInit;
8494 {
8495 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8496 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8497 Expr *RHS =
8498 (isOpenMPWorksharingDirective(DKind) ||
8499 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8500 ? LB.get()
8501 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8502 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8503 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8504
8505 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8506 Expr *CombRHS =
8507 (isOpenMPWorksharingDirective(DKind) ||
8508 isOpenMPTaskLoopDirective(DKind) ||
8509 isOpenMPDistributeDirective(DKind))
8510 ? CombLB.get()
8511 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8512 CombInit =
8513 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8514 CombInit =
8515 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8516 }
8517 }
8518
8519 bool UseStrictCompare =
8520 RealVType->hasUnsignedIntegerRepresentation() &&
8521 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8522 return LIS.IsStrictCompare;
8523 });
8524 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8525 // unsigned IV)) for worksharing loops.
8526 SourceLocation CondLoc = AStmt->getBeginLoc();
8527 Expr *BoundUB = UB.get();
8528 if (UseStrictCompare) {
8529 BoundUB =
8530 SemaRef
8531 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8532 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8533 .get();
8534 BoundUB =
8535 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8536 }
8537 ExprResult Cond =
8538 (isOpenMPWorksharingDirective(DKind) ||
8539 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8540 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8541 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8542 BoundUB)
8543 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8544 NumIterations.get());
8545 ExprResult CombDistCond;
8546 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8547 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8548 NumIterations.get());
8549 }
8550
8551 ExprResult CombCond;
8552 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8553 Expr *BoundCombUB = CombUB.get();
8554 if (UseStrictCompare) {
8555 BoundCombUB =
8556 SemaRef
8557 .BuildBinOp(
8558 CurScope, CondLoc, BO_Add, BoundCombUB,
8559 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8560 .get();
8561 BoundCombUB =
8562 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8563 .get();
8564 }
8565 CombCond =
8566 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8567 IV.get(), BoundCombUB);
8568 }
8569 // Loop increment (IV = IV + 1)
8570 SourceLocation IncLoc = AStmt->getBeginLoc();
8571 ExprResult Inc =
8572 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8573 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8574 if (!Inc.isUsable())
8575 return 0;
8576 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8577 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8578 if (!Inc.isUsable())
8579 return 0;
8580
8581 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8582 // Used for directives with static scheduling.
8583 // In combined construct, add combined version that use CombLB and CombUB
8584 // base variables for the update
8585 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8586 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8587 isOpenMPDistributeDirective(DKind)) {
8588 // LB + ST
8589 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8590 if (!NextLB.isUsable())
8591 return 0;
8592 // LB = LB + ST
8593 NextLB =
8594 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8595 NextLB =
8596 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8597 if (!NextLB.isUsable())
8598 return 0;
8599 // UB + ST
8600 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8601 if (!NextUB.isUsable())
8602 return 0;
8603 // UB = UB + ST
8604 NextUB =
8605 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8606 NextUB =
8607 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8608 if (!NextUB.isUsable())
8609 return 0;
8610 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8611 CombNextLB =
8612 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8613 if (!NextLB.isUsable())
8614 return 0;
8615 // LB = LB + ST
8616 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8617 CombNextLB.get());
8618 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8619 /*DiscardedValue*/ false);
8620 if (!CombNextLB.isUsable())
8621 return 0;
8622 // UB + ST
8623 CombNextUB =
8624 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8625 if (!CombNextUB.isUsable())
8626 return 0;
8627 // UB = UB + ST
8628 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8629 CombNextUB.get());
8630 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8631 /*DiscardedValue*/ false);
8632 if (!CombNextUB.isUsable())
8633 return 0;
8634 }
8635 }
8636
8637 // Create increment expression for distribute loop when combined in a same
8638 // directive with for as IV = IV + ST; ensure upper bound expression based
8639 // on PrevUB instead of NumIterations - used to implement 'for' when found
8640 // in combination with 'distribute', like in 'distribute parallel for'
8641 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8642 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8643 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8644 DistCond = SemaRef.BuildBinOp(
8645 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8646 assert(DistCond.isUsable() && "distribute cond expr was not built");
8647
8648 DistInc =
8649 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8650 assert(DistInc.isUsable() && "distribute inc expr was not built");
8651 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8652 DistInc.get());
8653 DistInc =
8654 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8655 assert(DistInc.isUsable() && "distribute inc expr was not built");
8656
8657 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8658 // construct
8659 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8660 ExprResult IsUBGreater =
8661 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8662 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8663 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8664 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8665 CondOp.get());
8666 PrevEUB =
8667 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8668
8669 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8670 // parallel for is in combination with a distribute directive with
8671 // schedule(static, 1)
8672 Expr *BoundPrevUB = PrevUB.get();
8673 if (UseStrictCompare) {
8674 BoundPrevUB =
8675 SemaRef
8676 .BuildBinOp(
8677 CurScope, CondLoc, BO_Add, BoundPrevUB,
8678 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8679 .get();
8680 BoundPrevUB =
8681 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8682 .get();
8683 }
8684 ParForInDistCond =
8685 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8686 IV.get(), BoundPrevUB);
8687 }
8688
8689 // Build updates and final values of the loop counters.
8690 bool HasErrors = false;
8691 Built.Counters.resize(NestedLoopCount);
8692 Built.Inits.resize(NestedLoopCount);
8693 Built.Updates.resize(NestedLoopCount);
8694 Built.Finals.resize(NestedLoopCount);
8695 Built.DependentCounters.resize(NestedLoopCount);
8696 Built.DependentInits.resize(NestedLoopCount);
8697 Built.FinalsConditions.resize(NestedLoopCount);
8698 {
8699 // We implement the following algorithm for obtaining the
8700 // original loop iteration variable values based on the
8701 // value of the collapsed loop iteration variable IV.
8702 //
8703 // Let n+1 be the number of collapsed loops in the nest.
8704 // Iteration variables (I0, I1, .... In)
8705 // Iteration counts (N0, N1, ... Nn)
8706 //
8707 // Acc = IV;
8708 //
8709 // To compute Ik for loop k, 0 <= k <= n, generate:
8710 // Prod = N(k+1) * N(k+2) * ... * Nn;
8711 // Ik = Acc / Prod;
8712 // Acc -= Ik * Prod;
8713 //
8714 ExprResult Acc = IV;
8715 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8716 LoopIterationSpace &IS = IterSpaces[Cnt];
8717 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8718 ExprResult Iter;
8719
8720 // Compute prod
8721 ExprResult Prod =
8722 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8723 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8724 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8725 IterSpaces[K].NumIterations);
8726
8727 // Iter = Acc / Prod
8728 // If there is at least one more inner loop to avoid
8729 // multiplication by 1.
8730 if (Cnt + 1 < NestedLoopCount)
8731 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8732 Acc.get(), Prod.get());
8733 else
8734 Iter = Acc;
8735 if (!Iter.isUsable()) {
8736 HasErrors = true;
8737 break;
8738 }
8739
8740 // Update Acc:
8741 // Acc -= Iter * Prod
8742 // Check if there is at least one more inner loop to avoid
8743 // multiplication by 1.
8744 if (Cnt + 1 < NestedLoopCount)
8745 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8746 Iter.get(), Prod.get());
8747 else
8748 Prod = Iter;
8749 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8750 Acc.get(), Prod.get());
8751
8752 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8753 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8754 DeclRefExpr *CounterVar = buildDeclRefExpr(
8755 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8756 /*RefersToCapture=*/true);
8757 ExprResult Init =
8758 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8759 IS.CounterInit, IS.IsNonRectangularLB, Captures);
8760 if (!Init.isUsable()) {
8761 HasErrors = true;
8762 break;
8763 }
8764 ExprResult Update = buildCounterUpdate(
8765 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8766 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8767 if (!Update.isUsable()) {
8768 HasErrors = true;
8769 break;
8770 }
8771
8772 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8773 ExprResult Final =
8774 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8775 IS.CounterInit, IS.NumIterations, IS.CounterStep,
8776 IS.Subtract, IS.IsNonRectangularLB, &Captures);
8777 if (!Final.isUsable()) {
8778 HasErrors = true;
8779 break;
8780 }
8781
8782 if (!Update.isUsable() || !Final.isUsable()) {
8783 HasErrors = true;
8784 break;
8785 }
8786 // Save results
8787 Built.Counters[Cnt] = IS.CounterVar;
8788 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8789 Built.Inits[Cnt] = Init.get();
8790 Built.Updates[Cnt] = Update.get();
8791 Built.Finals[Cnt] = Final.get();
8792 Built.DependentCounters[Cnt] = nullptr;
8793 Built.DependentInits[Cnt] = nullptr;
8794 Built.FinalsConditions[Cnt] = nullptr;
8795 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8796 Built.DependentCounters[Cnt] =
8797 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8798 Built.DependentInits[Cnt] =
8799 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8800 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8801 }
8802 }
8803 }
8804
8805 if (HasErrors)
8806 return 0;
8807
8808 // Save results
8809 Built.IterationVarRef = IV.get();
8810 Built.LastIteration = LastIteration.get();
8811 Built.NumIterations = NumIterations.get();
8812 Built.CalcLastIteration = SemaRef
8813 .ActOnFinishFullExpr(CalcLastIteration.get(),
8814 /*DiscardedValue=*/false)
8815 .get();
8816 Built.PreCond = PreCond.get();
8817 Built.PreInits = buildPreInits(C, Captures);
8818 Built.Cond = Cond.get();
8819 Built.Init = Init.get();
8820 Built.Inc = Inc.get();
8821 Built.LB = LB.get();
8822 Built.UB = UB.get();
8823 Built.IL = IL.get();
8824 Built.ST = ST.get();
8825 Built.EUB = EUB.get();
8826 Built.NLB = NextLB.get();
8827 Built.NUB = NextUB.get();
8828 Built.PrevLB = PrevLB.get();
8829 Built.PrevUB = PrevUB.get();
8830 Built.DistInc = DistInc.get();
8831 Built.PrevEUB = PrevEUB.get();
8832 Built.DistCombinedFields.LB = CombLB.get();
8833 Built.DistCombinedFields.UB = CombUB.get();
8834 Built.DistCombinedFields.EUB = CombEUB.get();
8835 Built.DistCombinedFields.Init = CombInit.get();
8836 Built.DistCombinedFields.Cond = CombCond.get();
8837 Built.DistCombinedFields.NLB = CombNextLB.get();
8838 Built.DistCombinedFields.NUB = CombNextUB.get();
8839 Built.DistCombinedFields.DistCond = CombDistCond.get();
8840 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8841
8842 return NestedLoopCount;
8843 }
8844
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)8845 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8846 auto CollapseClauses =
8847 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8848 if (CollapseClauses.begin() != CollapseClauses.end())
8849 return (*CollapseClauses.begin())->getNumForLoops();
8850 return nullptr;
8851 }
8852
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)8853 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8854 auto OrderedClauses =
8855 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8856 if (OrderedClauses.begin() != OrderedClauses.end())
8857 return (*OrderedClauses.begin())->getNumForLoops();
8858 return nullptr;
8859 }
8860
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)8861 static bool checkSimdlenSafelenSpecified(Sema &S,
8862 const ArrayRef<OMPClause *> Clauses) {
8863 const OMPSafelenClause *Safelen = nullptr;
8864 const OMPSimdlenClause *Simdlen = nullptr;
8865
8866 for (const OMPClause *Clause : Clauses) {
8867 if (Clause->getClauseKind() == OMPC_safelen)
8868 Safelen = cast<OMPSafelenClause>(Clause);
8869 else if (Clause->getClauseKind() == OMPC_simdlen)
8870 Simdlen = cast<OMPSimdlenClause>(Clause);
8871 if (Safelen && Simdlen)
8872 break;
8873 }
8874
8875 if (Simdlen && Safelen) {
8876 const Expr *SimdlenLength = Simdlen->getSimdlen();
8877 const Expr *SafelenLength = Safelen->getSafelen();
8878 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
8879 SimdlenLength->isInstantiationDependent() ||
8880 SimdlenLength->containsUnexpandedParameterPack())
8881 return false;
8882 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
8883 SafelenLength->isInstantiationDependent() ||
8884 SafelenLength->containsUnexpandedParameterPack())
8885 return false;
8886 Expr::EvalResult SimdlenResult, SafelenResult;
8887 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8888 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8889 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8890 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8891 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8892 // If both simdlen and safelen clauses are specified, the value of the
8893 // simdlen parameter must be less than or equal to the value of the safelen
8894 // parameter.
8895 if (SimdlenRes > SafelenRes) {
8896 S.Diag(SimdlenLength->getExprLoc(),
8897 diag::err_omp_wrong_simdlen_safelen_values)
8898 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8899 return true;
8900 }
8901 }
8902 return false;
8903 }
8904
8905 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8906 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8907 SourceLocation StartLoc, SourceLocation EndLoc,
8908 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8909 if (!AStmt)
8910 return StmtError();
8911
8912 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8913 OMPLoopDirective::HelperExprs B;
8914 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8915 // define the nested loops number.
8916 unsigned NestedLoopCount = checkOpenMPLoop(
8917 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8918 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8919 if (NestedLoopCount == 0)
8920 return StmtError();
8921
8922 assert((CurContext->isDependentContext() || B.builtAll()) &&
8923 "omp simd loop exprs were not built");
8924
8925 if (!CurContext->isDependentContext()) {
8926 // Finalize the clauses that need pre-built expressions for CodeGen.
8927 for (OMPClause *C : Clauses) {
8928 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8929 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8930 B.NumIterations, *this, CurScope,
8931 DSAStack))
8932 return StmtError();
8933 }
8934 }
8935
8936 if (checkSimdlenSafelenSpecified(*this, Clauses))
8937 return StmtError();
8938
8939 setFunctionHasBranchProtectedScope();
8940 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8941 Clauses, AStmt, B);
8942 }
8943
8944 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8945 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8946 SourceLocation StartLoc, SourceLocation EndLoc,
8947 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8948 if (!AStmt)
8949 return StmtError();
8950
8951 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8952 OMPLoopDirective::HelperExprs B;
8953 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8954 // define the nested loops number.
8955 unsigned NestedLoopCount = checkOpenMPLoop(
8956 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8957 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8958 if (NestedLoopCount == 0)
8959 return StmtError();
8960
8961 assert((CurContext->isDependentContext() || B.builtAll()) &&
8962 "omp for loop exprs were not built");
8963
8964 if (!CurContext->isDependentContext()) {
8965 // Finalize the clauses that need pre-built expressions for CodeGen.
8966 for (OMPClause *C : Clauses) {
8967 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8968 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8969 B.NumIterations, *this, CurScope,
8970 DSAStack))
8971 return StmtError();
8972 }
8973 }
8974
8975 setFunctionHasBranchProtectedScope();
8976 return OMPForDirective::Create(
8977 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8978 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
8979 }
8980
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8981 StmtResult Sema::ActOnOpenMPForSimdDirective(
8982 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8983 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8984 if (!AStmt)
8985 return StmtError();
8986
8987 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8988 OMPLoopDirective::HelperExprs B;
8989 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8990 // define the nested loops number.
8991 unsigned NestedLoopCount =
8992 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8993 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
8994 VarsWithImplicitDSA, B);
8995 if (NestedLoopCount == 0)
8996 return StmtError();
8997
8998 assert((CurContext->isDependentContext() || B.builtAll()) &&
8999 "omp for simd loop exprs were not built");
9000
9001 if (!CurContext->isDependentContext()) {
9002 // Finalize the clauses that need pre-built expressions for CodeGen.
9003 for (OMPClause *C : Clauses) {
9004 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9005 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9006 B.NumIterations, *this, CurScope,
9007 DSAStack))
9008 return StmtError();
9009 }
9010 }
9011
9012 if (checkSimdlenSafelenSpecified(*this, Clauses))
9013 return StmtError();
9014
9015 setFunctionHasBranchProtectedScope();
9016 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9017 Clauses, AStmt, B);
9018 }
9019
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9020 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9021 Stmt *AStmt,
9022 SourceLocation StartLoc,
9023 SourceLocation EndLoc) {
9024 if (!AStmt)
9025 return StmtError();
9026
9027 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9028 auto BaseStmt = AStmt;
9029 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9030 BaseStmt = CS->getCapturedStmt();
9031 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9032 auto S = C->children();
9033 if (S.begin() == S.end())
9034 return StmtError();
9035 // All associated statements must be '#pragma omp section' except for
9036 // the first one.
9037 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9038 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9039 if (SectionStmt)
9040 Diag(SectionStmt->getBeginLoc(),
9041 diag::err_omp_sections_substmt_not_section);
9042 return StmtError();
9043 }
9044 cast<OMPSectionDirective>(SectionStmt)
9045 ->setHasCancel(DSAStack->isCancelRegion());
9046 }
9047 } else {
9048 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9049 return StmtError();
9050 }
9051
9052 setFunctionHasBranchProtectedScope();
9053
9054 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9055 DSAStack->getTaskgroupReductionRef(),
9056 DSAStack->isCancelRegion());
9057 }
9058
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9059 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9060 SourceLocation StartLoc,
9061 SourceLocation EndLoc) {
9062 if (!AStmt)
9063 return StmtError();
9064
9065 setFunctionHasBranchProtectedScope();
9066 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9067
9068 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9069 DSAStack->isCancelRegion());
9070 }
9071
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9072 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9073 Stmt *AStmt,
9074 SourceLocation StartLoc,
9075 SourceLocation EndLoc) {
9076 if (!AStmt)
9077 return StmtError();
9078
9079 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9080
9081 setFunctionHasBranchProtectedScope();
9082
9083 // OpenMP [2.7.3, single Construct, Restrictions]
9084 // The copyprivate clause must not be used with the nowait clause.
9085 const OMPClause *Nowait = nullptr;
9086 const OMPClause *Copyprivate = nullptr;
9087 for (const OMPClause *Clause : Clauses) {
9088 if (Clause->getClauseKind() == OMPC_nowait)
9089 Nowait = Clause;
9090 else if (Clause->getClauseKind() == OMPC_copyprivate)
9091 Copyprivate = Clause;
9092 if (Copyprivate && Nowait) {
9093 Diag(Copyprivate->getBeginLoc(),
9094 diag::err_omp_single_copyprivate_with_nowait);
9095 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9096 return StmtError();
9097 }
9098 }
9099
9100 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9101 }
9102
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9103 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9104 SourceLocation StartLoc,
9105 SourceLocation EndLoc) {
9106 if (!AStmt)
9107 return StmtError();
9108
9109 setFunctionHasBranchProtectedScope();
9110
9111 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9112 }
9113
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9114 StmtResult Sema::ActOnOpenMPCriticalDirective(
9115 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9116 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9117 if (!AStmt)
9118 return StmtError();
9119
9120 bool ErrorFound = false;
9121 llvm::APSInt Hint;
9122 SourceLocation HintLoc;
9123 bool DependentHint = false;
9124 for (const OMPClause *C : Clauses) {
9125 if (C->getClauseKind() == OMPC_hint) {
9126 if (!DirName.getName()) {
9127 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9128 ErrorFound = true;
9129 }
9130 Expr *E = cast<OMPHintClause>(C)->getHint();
9131 if (E->isTypeDependent() || E->isValueDependent() ||
9132 E->isInstantiationDependent()) {
9133 DependentHint = true;
9134 } else {
9135 Hint = E->EvaluateKnownConstInt(Context);
9136 HintLoc = C->getBeginLoc();
9137 }
9138 }
9139 }
9140 if (ErrorFound)
9141 return StmtError();
9142 const auto Pair = DSAStack->getCriticalWithHint(DirName);
9143 if (Pair.first && DirName.getName() && !DependentHint) {
9144 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9145 Diag(StartLoc, diag::err_omp_critical_with_hint);
9146 if (HintLoc.isValid())
9147 Diag(HintLoc, diag::note_omp_critical_hint_here)
9148 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9149 else
9150 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9151 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9152 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9153 << 1
9154 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9155 /*Radix=*/10, /*Signed=*/false);
9156 } else {
9157 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9158 }
9159 }
9160 }
9161
9162 setFunctionHasBranchProtectedScope();
9163
9164 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9165 Clauses, AStmt);
9166 if (!Pair.first && DirName.getName() && !DependentHint)
9167 DSAStack->addCriticalWithHint(Dir, Hint);
9168 return Dir;
9169 }
9170
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9171 StmtResult Sema::ActOnOpenMPParallelForDirective(
9172 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9173 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9174 if (!AStmt)
9175 return StmtError();
9176
9177 auto *CS = cast<CapturedStmt>(AStmt);
9178 // 1.2.2 OpenMP Language Terminology
9179 // Structured block - An executable statement with a single entry at the
9180 // top and a single exit at the bottom.
9181 // The point of exit cannot be a branch out of the structured block.
9182 // longjmp() and throw() must not violate the entry/exit criteria.
9183 CS->getCapturedDecl()->setNothrow();
9184
9185 OMPLoopDirective::HelperExprs B;
9186 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9187 // define the nested loops number.
9188 unsigned NestedLoopCount =
9189 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9190 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9191 VarsWithImplicitDSA, B);
9192 if (NestedLoopCount == 0)
9193 return StmtError();
9194
9195 assert((CurContext->isDependentContext() || B.builtAll()) &&
9196 "omp parallel for loop exprs were not built");
9197
9198 if (!CurContext->isDependentContext()) {
9199 // Finalize the clauses that need pre-built expressions for CodeGen.
9200 for (OMPClause *C : Clauses) {
9201 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9202 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9203 B.NumIterations, *this, CurScope,
9204 DSAStack))
9205 return StmtError();
9206 }
9207 }
9208
9209 setFunctionHasBranchProtectedScope();
9210 return OMPParallelForDirective::Create(
9211 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9212 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9213 }
9214
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9215 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9216 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9217 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9218 if (!AStmt)
9219 return StmtError();
9220
9221 auto *CS = cast<CapturedStmt>(AStmt);
9222 // 1.2.2 OpenMP Language Terminology
9223 // Structured block - An executable statement with a single entry at the
9224 // top and a single exit at the bottom.
9225 // The point of exit cannot be a branch out of the structured block.
9226 // longjmp() and throw() must not violate the entry/exit criteria.
9227 CS->getCapturedDecl()->setNothrow();
9228
9229 OMPLoopDirective::HelperExprs B;
9230 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9231 // define the nested loops number.
9232 unsigned NestedLoopCount =
9233 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9234 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9235 VarsWithImplicitDSA, B);
9236 if (NestedLoopCount == 0)
9237 return StmtError();
9238
9239 if (!CurContext->isDependentContext()) {
9240 // Finalize the clauses that need pre-built expressions for CodeGen.
9241 for (OMPClause *C : Clauses) {
9242 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9243 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9244 B.NumIterations, *this, CurScope,
9245 DSAStack))
9246 return StmtError();
9247 }
9248 }
9249
9250 if (checkSimdlenSafelenSpecified(*this, Clauses))
9251 return StmtError();
9252
9253 setFunctionHasBranchProtectedScope();
9254 return OMPParallelForSimdDirective::Create(
9255 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9256 }
9257
9258 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9259 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9260 Stmt *AStmt, SourceLocation StartLoc,
9261 SourceLocation EndLoc) {
9262 if (!AStmt)
9263 return StmtError();
9264
9265 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9266 auto *CS = cast<CapturedStmt>(AStmt);
9267 // 1.2.2 OpenMP Language Terminology
9268 // Structured block - An executable statement with a single entry at the
9269 // top and a single exit at the bottom.
9270 // The point of exit cannot be a branch out of the structured block.
9271 // longjmp() and throw() must not violate the entry/exit criteria.
9272 CS->getCapturedDecl()->setNothrow();
9273
9274 setFunctionHasBranchProtectedScope();
9275
9276 return OMPParallelMasterDirective::Create(
9277 Context, StartLoc, EndLoc, Clauses, AStmt,
9278 DSAStack->getTaskgroupReductionRef());
9279 }
9280
9281 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9282 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9283 Stmt *AStmt, SourceLocation StartLoc,
9284 SourceLocation EndLoc) {
9285 if (!AStmt)
9286 return StmtError();
9287
9288 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9289 auto BaseStmt = AStmt;
9290 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9291 BaseStmt = CS->getCapturedStmt();
9292 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9293 auto S = C->children();
9294 if (S.begin() == S.end())
9295 return StmtError();
9296 // All associated statements must be '#pragma omp section' except for
9297 // the first one.
9298 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9299 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9300 if (SectionStmt)
9301 Diag(SectionStmt->getBeginLoc(),
9302 diag::err_omp_parallel_sections_substmt_not_section);
9303 return StmtError();
9304 }
9305 cast<OMPSectionDirective>(SectionStmt)
9306 ->setHasCancel(DSAStack->isCancelRegion());
9307 }
9308 } else {
9309 Diag(AStmt->getBeginLoc(),
9310 diag::err_omp_parallel_sections_not_compound_stmt);
9311 return StmtError();
9312 }
9313
9314 setFunctionHasBranchProtectedScope();
9315
9316 return OMPParallelSectionsDirective::Create(
9317 Context, StartLoc, EndLoc, Clauses, AStmt,
9318 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9319 }
9320
9321 /// detach and mergeable clauses are mutially exclusive, check for it.
checkDetachMergeableClauses(Sema & S,ArrayRef<OMPClause * > Clauses)9322 static bool checkDetachMergeableClauses(Sema &S,
9323 ArrayRef<OMPClause *> Clauses) {
9324 const OMPClause *PrevClause = nullptr;
9325 bool ErrorFound = false;
9326 for (const OMPClause *C : Clauses) {
9327 if (C->getClauseKind() == OMPC_detach ||
9328 C->getClauseKind() == OMPC_mergeable) {
9329 if (!PrevClause) {
9330 PrevClause = C;
9331 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9332 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9333 << getOpenMPClauseName(C->getClauseKind())
9334 << getOpenMPClauseName(PrevClause->getClauseKind());
9335 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9336 << getOpenMPClauseName(PrevClause->getClauseKind());
9337 ErrorFound = true;
9338 }
9339 }
9340 }
9341 return ErrorFound;
9342 }
9343
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9344 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9345 Stmt *AStmt, SourceLocation StartLoc,
9346 SourceLocation EndLoc) {
9347 if (!AStmt)
9348 return StmtError();
9349
9350 // OpenMP 5.0, 2.10.1 task Construct
9351 // If a detach clause appears on the directive, then a mergeable clause cannot
9352 // appear on the same directive.
9353 if (checkDetachMergeableClauses(*this, Clauses))
9354 return StmtError();
9355
9356 auto *CS = cast<CapturedStmt>(AStmt);
9357 // 1.2.2 OpenMP Language Terminology
9358 // Structured block - An executable statement with a single entry at the
9359 // top and a single exit at the bottom.
9360 // The point of exit cannot be a branch out of the structured block.
9361 // longjmp() and throw() must not violate the entry/exit criteria.
9362 CS->getCapturedDecl()->setNothrow();
9363
9364 setFunctionHasBranchProtectedScope();
9365
9366 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9367 DSAStack->isCancelRegion());
9368 }
9369
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)9370 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9371 SourceLocation EndLoc) {
9372 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9373 }
9374
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)9375 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9376 SourceLocation EndLoc) {
9377 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9378 }
9379
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)9380 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9381 SourceLocation EndLoc) {
9382 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9383 }
9384
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9385 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9386 Stmt *AStmt,
9387 SourceLocation StartLoc,
9388 SourceLocation EndLoc) {
9389 if (!AStmt)
9390 return StmtError();
9391
9392 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9393
9394 setFunctionHasBranchProtectedScope();
9395
9396 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9397 AStmt,
9398 DSAStack->getTaskgroupReductionRef());
9399 }
9400
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9401 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9402 SourceLocation StartLoc,
9403 SourceLocation EndLoc) {
9404 OMPFlushClause *FC = nullptr;
9405 OMPClause *OrderClause = nullptr;
9406 for (OMPClause *C : Clauses) {
9407 if (C->getClauseKind() == OMPC_flush)
9408 FC = cast<OMPFlushClause>(C);
9409 else
9410 OrderClause = C;
9411 }
9412 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9413 SourceLocation MemOrderLoc;
9414 for (const OMPClause *C : Clauses) {
9415 if (C->getClauseKind() == OMPC_acq_rel ||
9416 C->getClauseKind() == OMPC_acquire ||
9417 C->getClauseKind() == OMPC_release) {
9418 if (MemOrderKind != OMPC_unknown) {
9419 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9420 << getOpenMPDirectiveName(OMPD_flush) << 1
9421 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9422 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9423 << getOpenMPClauseName(MemOrderKind);
9424 } else {
9425 MemOrderKind = C->getClauseKind();
9426 MemOrderLoc = C->getBeginLoc();
9427 }
9428 }
9429 }
9430 if (FC && OrderClause) {
9431 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9432 << getOpenMPClauseName(OrderClause->getClauseKind());
9433 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9434 << getOpenMPClauseName(OrderClause->getClauseKind());
9435 return StmtError();
9436 }
9437 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9438 }
9439
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9440 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9441 SourceLocation StartLoc,
9442 SourceLocation EndLoc) {
9443 if (Clauses.empty()) {
9444 Diag(StartLoc, diag::err_omp_depobj_expected);
9445 return StmtError();
9446 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9447 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9448 return StmtError();
9449 }
9450 // Only depobj expression and another single clause is allowed.
9451 if (Clauses.size() > 2) {
9452 Diag(Clauses[2]->getBeginLoc(),
9453 diag::err_omp_depobj_single_clause_expected);
9454 return StmtError();
9455 } else if (Clauses.size() < 1) {
9456 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9457 return StmtError();
9458 }
9459 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9460 }
9461
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9462 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9463 SourceLocation StartLoc,
9464 SourceLocation EndLoc) {
9465 // Check that exactly one clause is specified.
9466 if (Clauses.size() != 1) {
9467 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9468 diag::err_omp_scan_single_clause_expected);
9469 return StmtError();
9470 }
9471 // Check that scan directive is used in the scopeof the OpenMP loop body.
9472 if (Scope *S = DSAStack->getCurScope()) {
9473 Scope *ParentS = S->getParent();
9474 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9475 !ParentS->getBreakParent()->isOpenMPLoopScope())
9476 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9477 << getOpenMPDirectiveName(OMPD_scan) << 5);
9478 }
9479 // Check that only one instance of scan directives is used in the same outer
9480 // region.
9481 if (DSAStack->doesParentHasScanDirective()) {
9482 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9483 Diag(DSAStack->getParentScanDirectiveLoc(),
9484 diag::note_omp_previous_directive)
9485 << "scan";
9486 return StmtError();
9487 }
9488 DSAStack->setParentHasScanDirective(StartLoc);
9489 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9490 }
9491
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9492 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9493 Stmt *AStmt,
9494 SourceLocation StartLoc,
9495 SourceLocation EndLoc) {
9496 const OMPClause *DependFound = nullptr;
9497 const OMPClause *DependSourceClause = nullptr;
9498 const OMPClause *DependSinkClause = nullptr;
9499 bool ErrorFound = false;
9500 const OMPThreadsClause *TC = nullptr;
9501 const OMPSIMDClause *SC = nullptr;
9502 for (const OMPClause *C : Clauses) {
9503 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9504 DependFound = C;
9505 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9506 if (DependSourceClause) {
9507 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9508 << getOpenMPDirectiveName(OMPD_ordered)
9509 << getOpenMPClauseName(OMPC_depend) << 2;
9510 ErrorFound = true;
9511 } else {
9512 DependSourceClause = C;
9513 }
9514 if (DependSinkClause) {
9515 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9516 << 0;
9517 ErrorFound = true;
9518 }
9519 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9520 if (DependSourceClause) {
9521 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9522 << 1;
9523 ErrorFound = true;
9524 }
9525 DependSinkClause = C;
9526 }
9527 } else if (C->getClauseKind() == OMPC_threads) {
9528 TC = cast<OMPThreadsClause>(C);
9529 } else if (C->getClauseKind() == OMPC_simd) {
9530 SC = cast<OMPSIMDClause>(C);
9531 }
9532 }
9533 if (!ErrorFound && !SC &&
9534 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
9535 // OpenMP [2.8.1,simd Construct, Restrictions]
9536 // An ordered construct with the simd clause is the only OpenMP construct
9537 // that can appear in the simd region.
9538 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9539 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9540 ErrorFound = true;
9541 } else if (DependFound && (TC || SC)) {
9542 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9543 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9544 ErrorFound = true;
9545 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
9546 Diag(DependFound->getBeginLoc(),
9547 diag::err_omp_ordered_directive_without_param);
9548 ErrorFound = true;
9549 } else if (TC || Clauses.empty()) {
9550 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
9551 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9552 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9553 << (TC != nullptr);
9554 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9555 ErrorFound = true;
9556 }
9557 }
9558 if ((!AStmt && !DependFound) || ErrorFound)
9559 return StmtError();
9560
9561 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9562 // During execution of an iteration of a worksharing-loop or a loop nest
9563 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9564 // must not execute more than one ordered region corresponding to an ordered
9565 // construct without a depend clause.
9566 if (!DependFound) {
9567 if (DSAStack->doesParentHasOrderedDirective()) {
9568 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9569 Diag(DSAStack->getParentOrderedDirectiveLoc(),
9570 diag::note_omp_previous_directive)
9571 << "ordered";
9572 return StmtError();
9573 }
9574 DSAStack->setParentHasOrderedDirective(StartLoc);
9575 }
9576
9577 if (AStmt) {
9578 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9579
9580 setFunctionHasBranchProtectedScope();
9581 }
9582
9583 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9584 }
9585
9586 namespace {
9587 /// Helper class for checking expression in 'omp atomic [update]'
9588 /// construct.
9589 class OpenMPAtomicUpdateChecker {
9590 /// Error results for atomic update expressions.
9591 enum ExprAnalysisErrorCode {
9592 /// A statement is not an expression statement.
9593 NotAnExpression,
9594 /// Expression is not builtin binary or unary operation.
9595 NotABinaryOrUnaryExpression,
9596 /// Unary operation is not post-/pre- increment/decrement operation.
9597 NotAnUnaryIncDecExpression,
9598 /// An expression is not of scalar type.
9599 NotAScalarType,
9600 /// A binary operation is not an assignment operation.
9601 NotAnAssignmentOp,
9602 /// RHS part of the binary operation is not a binary expression.
9603 NotABinaryExpression,
9604 /// RHS part is not additive/multiplicative/shift/biwise binary
9605 /// expression.
9606 NotABinaryOperator,
9607 /// RHS binary operation does not have reference to the updated LHS
9608 /// part.
9609 NotAnUpdateExpression,
9610 /// No errors is found.
9611 NoError
9612 };
9613 /// Reference to Sema.
9614 Sema &SemaRef;
9615 /// A location for note diagnostics (when error is found).
9616 SourceLocation NoteLoc;
9617 /// 'x' lvalue part of the source atomic expression.
9618 Expr *X;
9619 /// 'expr' rvalue part of the source atomic expression.
9620 Expr *E;
9621 /// Helper expression of the form
9622 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9623 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9624 Expr *UpdateExpr;
9625 /// Is 'x' a LHS in a RHS part of full update expression. It is
9626 /// important for non-associative operations.
9627 bool IsXLHSInRHSPart;
9628 BinaryOperatorKind Op;
9629 SourceLocation OpLoc;
9630 /// true if the source expression is a postfix unary operation, false
9631 /// if it is a prefix unary operation.
9632 bool IsPostfixUpdate;
9633
9634 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)9635 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9636 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9637 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9638 /// Check specified statement that it is suitable for 'atomic update'
9639 /// constructs and extract 'x', 'expr' and Operation from the original
9640 /// expression. If DiagId and NoteId == 0, then only check is performed
9641 /// without error notification.
9642 /// \param DiagId Diagnostic which should be emitted if error is found.
9643 /// \param NoteId Diagnostic note for the main error message.
9644 /// \return true if statement is not an update expression, false otherwise.
9645 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9646 /// Return the 'x' lvalue part of the source atomic expression.
getX() const9647 Expr *getX() const { return X; }
9648 /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const9649 Expr *getExpr() const { return E; }
9650 /// Return the update expression used in calculation of the updated
9651 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9652 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const9653 Expr *getUpdateExpr() const { return UpdateExpr; }
9654 /// Return true if 'x' is LHS in RHS part of full update expression,
9655 /// false otherwise.
isXLHSInRHSPart() const9656 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9657
9658 /// true if the source expression is a postfix unary operation, false
9659 /// if it is a prefix unary operation.
isPostfixUpdate() const9660 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9661
9662 private:
9663 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9664 unsigned NoteId = 0);
9665 };
9666 } // namespace
9667
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)9668 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9669 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9670 ExprAnalysisErrorCode ErrorFound = NoError;
9671 SourceLocation ErrorLoc, NoteLoc;
9672 SourceRange ErrorRange, NoteRange;
9673 // Allowed constructs are:
9674 // x = x binop expr;
9675 // x = expr binop x;
9676 if (AtomicBinOp->getOpcode() == BO_Assign) {
9677 X = AtomicBinOp->getLHS();
9678 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9679 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9680 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9681 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9682 AtomicInnerBinOp->isBitwiseOp()) {
9683 Op = AtomicInnerBinOp->getOpcode();
9684 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9685 Expr *LHS = AtomicInnerBinOp->getLHS();
9686 Expr *RHS = AtomicInnerBinOp->getRHS();
9687 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9688 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9689 /*Canonical=*/true);
9690 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9691 /*Canonical=*/true);
9692 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9693 /*Canonical=*/true);
9694 if (XId == LHSId) {
9695 E = RHS;
9696 IsXLHSInRHSPart = true;
9697 } else if (XId == RHSId) {
9698 E = LHS;
9699 IsXLHSInRHSPart = false;
9700 } else {
9701 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9702 ErrorRange = AtomicInnerBinOp->getSourceRange();
9703 NoteLoc = X->getExprLoc();
9704 NoteRange = X->getSourceRange();
9705 ErrorFound = NotAnUpdateExpression;
9706 }
9707 } else {
9708 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9709 ErrorRange = AtomicInnerBinOp->getSourceRange();
9710 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9711 NoteRange = SourceRange(NoteLoc, NoteLoc);
9712 ErrorFound = NotABinaryOperator;
9713 }
9714 } else {
9715 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9716 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9717 ErrorFound = NotABinaryExpression;
9718 }
9719 } else {
9720 ErrorLoc = AtomicBinOp->getExprLoc();
9721 ErrorRange = AtomicBinOp->getSourceRange();
9722 NoteLoc = AtomicBinOp->getOperatorLoc();
9723 NoteRange = SourceRange(NoteLoc, NoteLoc);
9724 ErrorFound = NotAnAssignmentOp;
9725 }
9726 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9727 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9728 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9729 return true;
9730 }
9731 if (SemaRef.CurContext->isDependentContext())
9732 E = X = UpdateExpr = nullptr;
9733 return ErrorFound != NoError;
9734 }
9735
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)9736 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9737 unsigned NoteId) {
9738 ExprAnalysisErrorCode ErrorFound = NoError;
9739 SourceLocation ErrorLoc, NoteLoc;
9740 SourceRange ErrorRange, NoteRange;
9741 // Allowed constructs are:
9742 // x++;
9743 // x--;
9744 // ++x;
9745 // --x;
9746 // x binop= expr;
9747 // x = x binop expr;
9748 // x = expr binop x;
9749 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9750 AtomicBody = AtomicBody->IgnoreParenImpCasts();
9751 if (AtomicBody->getType()->isScalarType() ||
9752 AtomicBody->isInstantiationDependent()) {
9753 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9754 AtomicBody->IgnoreParenImpCasts())) {
9755 // Check for Compound Assignment Operation
9756 Op = BinaryOperator::getOpForCompoundAssignment(
9757 AtomicCompAssignOp->getOpcode());
9758 OpLoc = AtomicCompAssignOp->getOperatorLoc();
9759 E = AtomicCompAssignOp->getRHS();
9760 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9761 IsXLHSInRHSPart = true;
9762 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9763 AtomicBody->IgnoreParenImpCasts())) {
9764 // Check for Binary Operation
9765 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9766 return true;
9767 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9768 AtomicBody->IgnoreParenImpCasts())) {
9769 // Check for Unary Operation
9770 if (AtomicUnaryOp->isIncrementDecrementOp()) {
9771 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9772 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9773 OpLoc = AtomicUnaryOp->getOperatorLoc();
9774 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9775 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9776 IsXLHSInRHSPart = true;
9777 } else {
9778 ErrorFound = NotAnUnaryIncDecExpression;
9779 ErrorLoc = AtomicUnaryOp->getExprLoc();
9780 ErrorRange = AtomicUnaryOp->getSourceRange();
9781 NoteLoc = AtomicUnaryOp->getOperatorLoc();
9782 NoteRange = SourceRange(NoteLoc, NoteLoc);
9783 }
9784 } else if (!AtomicBody->isInstantiationDependent()) {
9785 ErrorFound = NotABinaryOrUnaryExpression;
9786 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9787 NoteRange = ErrorRange = AtomicBody->getSourceRange();
9788 }
9789 } else {
9790 ErrorFound = NotAScalarType;
9791 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9792 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9793 }
9794 } else {
9795 ErrorFound = NotAnExpression;
9796 NoteLoc = ErrorLoc = S->getBeginLoc();
9797 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9798 }
9799 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9800 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9801 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9802 return true;
9803 }
9804 if (SemaRef.CurContext->isDependentContext())
9805 E = X = UpdateExpr = nullptr;
9806 if (ErrorFound == NoError && E && X) {
9807 // Build an update expression of form 'OpaqueValueExpr(x) binop
9808 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9809 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9810 auto *OVEX = new (SemaRef.getASTContext())
9811 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9812 auto *OVEExpr = new (SemaRef.getASTContext())
9813 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9814 ExprResult Update =
9815 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9816 IsXLHSInRHSPart ? OVEExpr : OVEX);
9817 if (Update.isInvalid())
9818 return true;
9819 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9820 Sema::AA_Casting);
9821 if (Update.isInvalid())
9822 return true;
9823 UpdateExpr = Update.get();
9824 }
9825 return ErrorFound != NoError;
9826 }
9827
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9828 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9829 Stmt *AStmt,
9830 SourceLocation StartLoc,
9831 SourceLocation EndLoc) {
9832 // Register location of the first atomic directive.
9833 DSAStack->addAtomicDirectiveLoc(StartLoc);
9834 if (!AStmt)
9835 return StmtError();
9836
9837 // 1.2.2 OpenMP Language Terminology
9838 // Structured block - An executable statement with a single entry at the
9839 // top and a single exit at the bottom.
9840 // The point of exit cannot be a branch out of the structured block.
9841 // longjmp() and throw() must not violate the entry/exit criteria.
9842 OpenMPClauseKind AtomicKind = OMPC_unknown;
9843 SourceLocation AtomicKindLoc;
9844 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9845 SourceLocation MemOrderLoc;
9846 for (const OMPClause *C : Clauses) {
9847 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9848 C->getClauseKind() == OMPC_update ||
9849 C->getClauseKind() == OMPC_capture) {
9850 if (AtomicKind != OMPC_unknown) {
9851 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9852 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9853 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9854 << getOpenMPClauseName(AtomicKind);
9855 } else {
9856 AtomicKind = C->getClauseKind();
9857 AtomicKindLoc = C->getBeginLoc();
9858 }
9859 }
9860 if (C->getClauseKind() == OMPC_seq_cst ||
9861 C->getClauseKind() == OMPC_acq_rel ||
9862 C->getClauseKind() == OMPC_acquire ||
9863 C->getClauseKind() == OMPC_release ||
9864 C->getClauseKind() == OMPC_relaxed) {
9865 if (MemOrderKind != OMPC_unknown) {
9866 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9867 << getOpenMPDirectiveName(OMPD_atomic) << 0
9868 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9869 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9870 << getOpenMPClauseName(MemOrderKind);
9871 } else {
9872 MemOrderKind = C->getClauseKind();
9873 MemOrderLoc = C->getBeginLoc();
9874 }
9875 }
9876 }
9877 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
9878 // If atomic-clause is read then memory-order-clause must not be acq_rel or
9879 // release.
9880 // If atomic-clause is write then memory-order-clause must not be acq_rel or
9881 // acquire.
9882 // If atomic-clause is update or not present then memory-order-clause must not
9883 // be acq_rel or acquire.
9884 if ((AtomicKind == OMPC_read &&
9885 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
9886 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
9887 AtomicKind == OMPC_unknown) &&
9888 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
9889 SourceLocation Loc = AtomicKindLoc;
9890 if (AtomicKind == OMPC_unknown)
9891 Loc = StartLoc;
9892 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
9893 << getOpenMPClauseName(AtomicKind)
9894 << (AtomicKind == OMPC_unknown ? 1 : 0)
9895 << getOpenMPClauseName(MemOrderKind);
9896 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9897 << getOpenMPClauseName(MemOrderKind);
9898 }
9899
9900 Stmt *Body = AStmt;
9901 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
9902 Body = EWC->getSubExpr();
9903
9904 Expr *X = nullptr;
9905 Expr *V = nullptr;
9906 Expr *E = nullptr;
9907 Expr *UE = nullptr;
9908 bool IsXLHSInRHSPart = false;
9909 bool IsPostfixUpdate = false;
9910 // OpenMP [2.12.6, atomic Construct]
9911 // In the next expressions:
9912 // * x and v (as applicable) are both l-value expressions with scalar type.
9913 // * During the execution of an atomic region, multiple syntactic
9914 // occurrences of x must designate the same storage location.
9915 // * Neither of v and expr (as applicable) may access the storage location
9916 // designated by x.
9917 // * Neither of x and expr (as applicable) may access the storage location
9918 // designated by v.
9919 // * expr is an expression with scalar type.
9920 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
9921 // * binop, binop=, ++, and -- are not overloaded operators.
9922 // * The expression x binop expr must be numerically equivalent to x binop
9923 // (expr). This requirement is satisfied if the operators in expr have
9924 // precedence greater than binop, or by using parentheses around expr or
9925 // subexpressions of expr.
9926 // * The expression expr binop x must be numerically equivalent to (expr)
9927 // binop x. This requirement is satisfied if the operators in expr have
9928 // precedence equal to or greater than binop, or by using parentheses around
9929 // expr or subexpressions of expr.
9930 // * For forms that allow multiple occurrences of x, the number of times
9931 // that x is evaluated is unspecified.
9932 if (AtomicKind == OMPC_read) {
9933 enum {
9934 NotAnExpression,
9935 NotAnAssignmentOp,
9936 NotAScalarType,
9937 NotAnLValue,
9938 NoError
9939 } ErrorFound = NoError;
9940 SourceLocation ErrorLoc, NoteLoc;
9941 SourceRange ErrorRange, NoteRange;
9942 // If clause is read:
9943 // v = x;
9944 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9945 const auto *AtomicBinOp =
9946 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9947 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9948 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9949 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
9950 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9951 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
9952 if (!X->isLValue() || !V->isLValue()) {
9953 const Expr *NotLValueExpr = X->isLValue() ? V : X;
9954 ErrorFound = NotAnLValue;
9955 ErrorLoc = AtomicBinOp->getExprLoc();
9956 ErrorRange = AtomicBinOp->getSourceRange();
9957 NoteLoc = NotLValueExpr->getExprLoc();
9958 NoteRange = NotLValueExpr->getSourceRange();
9959 }
9960 } else if (!X->isInstantiationDependent() ||
9961 !V->isInstantiationDependent()) {
9962 const Expr *NotScalarExpr =
9963 (X->isInstantiationDependent() || X->getType()->isScalarType())
9964 ? V
9965 : X;
9966 ErrorFound = NotAScalarType;
9967 ErrorLoc = AtomicBinOp->getExprLoc();
9968 ErrorRange = AtomicBinOp->getSourceRange();
9969 NoteLoc = NotScalarExpr->getExprLoc();
9970 NoteRange = NotScalarExpr->getSourceRange();
9971 }
9972 } else if (!AtomicBody->isInstantiationDependent()) {
9973 ErrorFound = NotAnAssignmentOp;
9974 ErrorLoc = AtomicBody->getExprLoc();
9975 ErrorRange = AtomicBody->getSourceRange();
9976 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9977 : AtomicBody->getExprLoc();
9978 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9979 : AtomicBody->getSourceRange();
9980 }
9981 } else {
9982 ErrorFound = NotAnExpression;
9983 NoteLoc = ErrorLoc = Body->getBeginLoc();
9984 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9985 }
9986 if (ErrorFound != NoError) {
9987 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
9988 << ErrorRange;
9989 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9990 << NoteRange;
9991 return StmtError();
9992 }
9993 if (CurContext->isDependentContext())
9994 V = X = nullptr;
9995 } else if (AtomicKind == OMPC_write) {
9996 enum {
9997 NotAnExpression,
9998 NotAnAssignmentOp,
9999 NotAScalarType,
10000 NotAnLValue,
10001 NoError
10002 } ErrorFound = NoError;
10003 SourceLocation ErrorLoc, NoteLoc;
10004 SourceRange ErrorRange, NoteRange;
10005 // If clause is write:
10006 // x = expr;
10007 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10008 const auto *AtomicBinOp =
10009 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10010 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10011 X = AtomicBinOp->getLHS();
10012 E = AtomicBinOp->getRHS();
10013 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10014 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10015 if (!X->isLValue()) {
10016 ErrorFound = NotAnLValue;
10017 ErrorLoc = AtomicBinOp->getExprLoc();
10018 ErrorRange = AtomicBinOp->getSourceRange();
10019 NoteLoc = X->getExprLoc();
10020 NoteRange = X->getSourceRange();
10021 }
10022 } else if (!X->isInstantiationDependent() ||
10023 !E->isInstantiationDependent()) {
10024 const Expr *NotScalarExpr =
10025 (X->isInstantiationDependent() || X->getType()->isScalarType())
10026 ? E
10027 : X;
10028 ErrorFound = NotAScalarType;
10029 ErrorLoc = AtomicBinOp->getExprLoc();
10030 ErrorRange = AtomicBinOp->getSourceRange();
10031 NoteLoc = NotScalarExpr->getExprLoc();
10032 NoteRange = NotScalarExpr->getSourceRange();
10033 }
10034 } else if (!AtomicBody->isInstantiationDependent()) {
10035 ErrorFound = NotAnAssignmentOp;
10036 ErrorLoc = AtomicBody->getExprLoc();
10037 ErrorRange = AtomicBody->getSourceRange();
10038 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10039 : AtomicBody->getExprLoc();
10040 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10041 : AtomicBody->getSourceRange();
10042 }
10043 } else {
10044 ErrorFound = NotAnExpression;
10045 NoteLoc = ErrorLoc = Body->getBeginLoc();
10046 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10047 }
10048 if (ErrorFound != NoError) {
10049 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10050 << ErrorRange;
10051 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10052 << NoteRange;
10053 return StmtError();
10054 }
10055 if (CurContext->isDependentContext())
10056 E = X = nullptr;
10057 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10058 // If clause is update:
10059 // x++;
10060 // x--;
10061 // ++x;
10062 // --x;
10063 // x binop= expr;
10064 // x = x binop expr;
10065 // x = expr binop x;
10066 OpenMPAtomicUpdateChecker Checker(*this);
10067 if (Checker.checkStatement(
10068 Body, (AtomicKind == OMPC_update)
10069 ? diag::err_omp_atomic_update_not_expression_statement
10070 : diag::err_omp_atomic_not_expression_statement,
10071 diag::note_omp_atomic_update))
10072 return StmtError();
10073 if (!CurContext->isDependentContext()) {
10074 E = Checker.getExpr();
10075 X = Checker.getX();
10076 UE = Checker.getUpdateExpr();
10077 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10078 }
10079 } else if (AtomicKind == OMPC_capture) {
10080 enum {
10081 NotAnAssignmentOp,
10082 NotACompoundStatement,
10083 NotTwoSubstatements,
10084 NotASpecificExpression,
10085 NoError
10086 } ErrorFound = NoError;
10087 SourceLocation ErrorLoc, NoteLoc;
10088 SourceRange ErrorRange, NoteRange;
10089 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10090 // If clause is a capture:
10091 // v = x++;
10092 // v = x--;
10093 // v = ++x;
10094 // v = --x;
10095 // v = x binop= expr;
10096 // v = x = x binop expr;
10097 // v = x = expr binop x;
10098 const auto *AtomicBinOp =
10099 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10100 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10101 V = AtomicBinOp->getLHS();
10102 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10103 OpenMPAtomicUpdateChecker Checker(*this);
10104 if (Checker.checkStatement(
10105 Body, diag::err_omp_atomic_capture_not_expression_statement,
10106 diag::note_omp_atomic_update))
10107 return StmtError();
10108 E = Checker.getExpr();
10109 X = Checker.getX();
10110 UE = Checker.getUpdateExpr();
10111 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10112 IsPostfixUpdate = Checker.isPostfixUpdate();
10113 } else if (!AtomicBody->isInstantiationDependent()) {
10114 ErrorLoc = AtomicBody->getExprLoc();
10115 ErrorRange = AtomicBody->getSourceRange();
10116 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10117 : AtomicBody->getExprLoc();
10118 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10119 : AtomicBody->getSourceRange();
10120 ErrorFound = NotAnAssignmentOp;
10121 }
10122 if (ErrorFound != NoError) {
10123 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10124 << ErrorRange;
10125 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10126 return StmtError();
10127 }
10128 if (CurContext->isDependentContext())
10129 UE = V = E = X = nullptr;
10130 } else {
10131 // If clause is a capture:
10132 // { v = x; x = expr; }
10133 // { v = x; x++; }
10134 // { v = x; x--; }
10135 // { v = x; ++x; }
10136 // { v = x; --x; }
10137 // { v = x; x binop= expr; }
10138 // { v = x; x = x binop expr; }
10139 // { v = x; x = expr binop x; }
10140 // { x++; v = x; }
10141 // { x--; v = x; }
10142 // { ++x; v = x; }
10143 // { --x; v = x; }
10144 // { x binop= expr; v = x; }
10145 // { x = x binop expr; v = x; }
10146 // { x = expr binop x; v = x; }
10147 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10148 // Check that this is { expr1; expr2; }
10149 if (CS->size() == 2) {
10150 Stmt *First = CS->body_front();
10151 Stmt *Second = CS->body_back();
10152 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10153 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10154 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10155 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10156 // Need to find what subexpression is 'v' and what is 'x'.
10157 OpenMPAtomicUpdateChecker Checker(*this);
10158 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10159 BinaryOperator *BinOp = nullptr;
10160 if (IsUpdateExprFound) {
10161 BinOp = dyn_cast<BinaryOperator>(First);
10162 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10163 }
10164 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10165 // { v = x; x++; }
10166 // { v = x; x--; }
10167 // { v = x; ++x; }
10168 // { v = x; --x; }
10169 // { v = x; x binop= expr; }
10170 // { v = x; x = x binop expr; }
10171 // { v = x; x = expr binop x; }
10172 // Check that the first expression has form v = x.
10173 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10174 llvm::FoldingSetNodeID XId, PossibleXId;
10175 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10176 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10177 IsUpdateExprFound = XId == PossibleXId;
10178 if (IsUpdateExprFound) {
10179 V = BinOp->getLHS();
10180 X = Checker.getX();
10181 E = Checker.getExpr();
10182 UE = Checker.getUpdateExpr();
10183 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10184 IsPostfixUpdate = true;
10185 }
10186 }
10187 if (!IsUpdateExprFound) {
10188 IsUpdateExprFound = !Checker.checkStatement(First);
10189 BinOp = nullptr;
10190 if (IsUpdateExprFound) {
10191 BinOp = dyn_cast<BinaryOperator>(Second);
10192 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10193 }
10194 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10195 // { x++; v = x; }
10196 // { x--; v = x; }
10197 // { ++x; v = x; }
10198 // { --x; v = x; }
10199 // { x binop= expr; v = x; }
10200 // { x = x binop expr; v = x; }
10201 // { x = expr binop x; v = x; }
10202 // Check that the second expression has form v = x.
10203 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10204 llvm::FoldingSetNodeID XId, PossibleXId;
10205 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10206 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10207 IsUpdateExprFound = XId == PossibleXId;
10208 if (IsUpdateExprFound) {
10209 V = BinOp->getLHS();
10210 X = Checker.getX();
10211 E = Checker.getExpr();
10212 UE = Checker.getUpdateExpr();
10213 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10214 IsPostfixUpdate = false;
10215 }
10216 }
10217 }
10218 if (!IsUpdateExprFound) {
10219 // { v = x; x = expr; }
10220 auto *FirstExpr = dyn_cast<Expr>(First);
10221 auto *SecondExpr = dyn_cast<Expr>(Second);
10222 if (!FirstExpr || !SecondExpr ||
10223 !(FirstExpr->isInstantiationDependent() ||
10224 SecondExpr->isInstantiationDependent())) {
10225 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10226 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10227 ErrorFound = NotAnAssignmentOp;
10228 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10229 : First->getBeginLoc();
10230 NoteRange = ErrorRange = FirstBinOp
10231 ? FirstBinOp->getSourceRange()
10232 : SourceRange(ErrorLoc, ErrorLoc);
10233 } else {
10234 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10235 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10236 ErrorFound = NotAnAssignmentOp;
10237 NoteLoc = ErrorLoc = SecondBinOp
10238 ? SecondBinOp->getOperatorLoc()
10239 : Second->getBeginLoc();
10240 NoteRange = ErrorRange =
10241 SecondBinOp ? SecondBinOp->getSourceRange()
10242 : SourceRange(ErrorLoc, ErrorLoc);
10243 } else {
10244 Expr *PossibleXRHSInFirst =
10245 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10246 Expr *PossibleXLHSInSecond =
10247 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10248 llvm::FoldingSetNodeID X1Id, X2Id;
10249 PossibleXRHSInFirst->Profile(X1Id, Context,
10250 /*Canonical=*/true);
10251 PossibleXLHSInSecond->Profile(X2Id, Context,
10252 /*Canonical=*/true);
10253 IsUpdateExprFound = X1Id == X2Id;
10254 if (IsUpdateExprFound) {
10255 V = FirstBinOp->getLHS();
10256 X = SecondBinOp->getLHS();
10257 E = SecondBinOp->getRHS();
10258 UE = nullptr;
10259 IsXLHSInRHSPart = false;
10260 IsPostfixUpdate = true;
10261 } else {
10262 ErrorFound = NotASpecificExpression;
10263 ErrorLoc = FirstBinOp->getExprLoc();
10264 ErrorRange = FirstBinOp->getSourceRange();
10265 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10266 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10267 }
10268 }
10269 }
10270 }
10271 }
10272 } else {
10273 NoteLoc = ErrorLoc = Body->getBeginLoc();
10274 NoteRange = ErrorRange =
10275 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10276 ErrorFound = NotTwoSubstatements;
10277 }
10278 } else {
10279 NoteLoc = ErrorLoc = Body->getBeginLoc();
10280 NoteRange = ErrorRange =
10281 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10282 ErrorFound = NotACompoundStatement;
10283 }
10284 if (ErrorFound != NoError) {
10285 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10286 << ErrorRange;
10287 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10288 return StmtError();
10289 }
10290 if (CurContext->isDependentContext())
10291 UE = V = E = X = nullptr;
10292 }
10293 }
10294
10295 setFunctionHasBranchProtectedScope();
10296
10297 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10298 X, V, E, UE, IsXLHSInRHSPart,
10299 IsPostfixUpdate);
10300 }
10301
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10302 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10303 Stmt *AStmt,
10304 SourceLocation StartLoc,
10305 SourceLocation EndLoc) {
10306 if (!AStmt)
10307 return StmtError();
10308
10309 auto *CS = cast<CapturedStmt>(AStmt);
10310 // 1.2.2 OpenMP Language Terminology
10311 // Structured block - An executable statement with a single entry at the
10312 // top and a single exit at the bottom.
10313 // The point of exit cannot be a branch out of the structured block.
10314 // longjmp() and throw() must not violate the entry/exit criteria.
10315 CS->getCapturedDecl()->setNothrow();
10316 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10317 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10318 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10319 // 1.2.2 OpenMP Language Terminology
10320 // Structured block - An executable statement with a single entry at the
10321 // top and a single exit at the bottom.
10322 // The point of exit cannot be a branch out of the structured block.
10323 // longjmp() and throw() must not violate the entry/exit criteria.
10324 CS->getCapturedDecl()->setNothrow();
10325 }
10326
10327 // OpenMP [2.16, Nesting of Regions]
10328 // If specified, a teams construct must be contained within a target
10329 // construct. That target construct must contain no statements or directives
10330 // outside of the teams construct.
10331 if (DSAStack->hasInnerTeamsRegion()) {
10332 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10333 bool OMPTeamsFound = true;
10334 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10335 auto I = CS->body_begin();
10336 while (I != CS->body_end()) {
10337 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10338 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10339 OMPTeamsFound) {
10340
10341 OMPTeamsFound = false;
10342 break;
10343 }
10344 ++I;
10345 }
10346 assert(I != CS->body_end() && "Not found statement");
10347 S = *I;
10348 } else {
10349 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10350 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10351 }
10352 if (!OMPTeamsFound) {
10353 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10354 Diag(DSAStack->getInnerTeamsRegionLoc(),
10355 diag::note_omp_nested_teams_construct_here);
10356 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10357 << isa<OMPExecutableDirective>(S);
10358 return StmtError();
10359 }
10360 }
10361
10362 setFunctionHasBranchProtectedScope();
10363
10364 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10365 }
10366
10367 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10368 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10369 Stmt *AStmt, SourceLocation StartLoc,
10370 SourceLocation EndLoc) {
10371 if (!AStmt)
10372 return StmtError();
10373
10374 auto *CS = cast<CapturedStmt>(AStmt);
10375 // 1.2.2 OpenMP Language Terminology
10376 // Structured block - An executable statement with a single entry at the
10377 // top and a single exit at the bottom.
10378 // The point of exit cannot be a branch out of the structured block.
10379 // longjmp() and throw() must not violate the entry/exit criteria.
10380 CS->getCapturedDecl()->setNothrow();
10381 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10382 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10383 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10384 // 1.2.2 OpenMP Language Terminology
10385 // Structured block - An executable statement with a single entry at the
10386 // top and a single exit at the bottom.
10387 // The point of exit cannot be a branch out of the structured block.
10388 // longjmp() and throw() must not violate the entry/exit criteria.
10389 CS->getCapturedDecl()->setNothrow();
10390 }
10391
10392 setFunctionHasBranchProtectedScope();
10393
10394 return OMPTargetParallelDirective::Create(
10395 Context, StartLoc, EndLoc, Clauses, AStmt,
10396 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10397 }
10398
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10399 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10400 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10401 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10402 if (!AStmt)
10403 return StmtError();
10404
10405 auto *CS = cast<CapturedStmt>(AStmt);
10406 // 1.2.2 OpenMP Language Terminology
10407 // Structured block - An executable statement with a single entry at the
10408 // top and a single exit at the bottom.
10409 // The point of exit cannot be a branch out of the structured block.
10410 // longjmp() and throw() must not violate the entry/exit criteria.
10411 CS->getCapturedDecl()->setNothrow();
10412 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10413 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10414 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10415 // 1.2.2 OpenMP Language Terminology
10416 // Structured block - An executable statement with a single entry at the
10417 // top and a single exit at the bottom.
10418 // The point of exit cannot be a branch out of the structured block.
10419 // longjmp() and throw() must not violate the entry/exit criteria.
10420 CS->getCapturedDecl()->setNothrow();
10421 }
10422
10423 OMPLoopDirective::HelperExprs B;
10424 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10425 // define the nested loops number.
10426 unsigned NestedLoopCount =
10427 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10428 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10429 VarsWithImplicitDSA, B);
10430 if (NestedLoopCount == 0)
10431 return StmtError();
10432
10433 assert((CurContext->isDependentContext() || B.builtAll()) &&
10434 "omp target parallel for loop exprs were not built");
10435
10436 if (!CurContext->isDependentContext()) {
10437 // Finalize the clauses that need pre-built expressions for CodeGen.
10438 for (OMPClause *C : Clauses) {
10439 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10440 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10441 B.NumIterations, *this, CurScope,
10442 DSAStack))
10443 return StmtError();
10444 }
10445 }
10446
10447 setFunctionHasBranchProtectedScope();
10448 return OMPTargetParallelForDirective::Create(
10449 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10450 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10451 }
10452
10453 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)10454 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10455 const OpenMPClauseKind K) {
10456 return llvm::any_of(
10457 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10458 }
10459
10460 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)10461 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10462 const Params... ClauseTypes) {
10463 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10464 }
10465
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10466 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10467 Stmt *AStmt,
10468 SourceLocation StartLoc,
10469 SourceLocation EndLoc) {
10470 if (!AStmt)
10471 return StmtError();
10472
10473 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10474
10475 // OpenMP [2.12.2, target data Construct, Restrictions]
10476 // At least one map, use_device_addr or use_device_ptr clause must appear on
10477 // the directive.
10478 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10479 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10480 StringRef Expected;
10481 if (LangOpts.OpenMP < 50)
10482 Expected = "'map' or 'use_device_ptr'";
10483 else
10484 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10485 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10486 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10487 return StmtError();
10488 }
10489
10490 setFunctionHasBranchProtectedScope();
10491
10492 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10493 AStmt);
10494 }
10495
10496 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10497 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10498 SourceLocation StartLoc,
10499 SourceLocation EndLoc, Stmt *AStmt) {
10500 if (!AStmt)
10501 return StmtError();
10502
10503 auto *CS = cast<CapturedStmt>(AStmt);
10504 // 1.2.2 OpenMP Language Terminology
10505 // Structured block - An executable statement with a single entry at the
10506 // top and a single exit at the bottom.
10507 // The point of exit cannot be a branch out of the structured block.
10508 // longjmp() and throw() must not violate the entry/exit criteria.
10509 CS->getCapturedDecl()->setNothrow();
10510 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10511 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10512 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10513 // 1.2.2 OpenMP Language Terminology
10514 // Structured block - An executable statement with a single entry at the
10515 // top and a single exit at the bottom.
10516 // The point of exit cannot be a branch out of the structured block.
10517 // longjmp() and throw() must not violate the entry/exit criteria.
10518 CS->getCapturedDecl()->setNothrow();
10519 }
10520
10521 // OpenMP [2.10.2, Restrictions, p. 99]
10522 // At least one map clause must appear on the directive.
10523 if (!hasClauses(Clauses, OMPC_map)) {
10524 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10525 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10526 return StmtError();
10527 }
10528
10529 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10530 AStmt);
10531 }
10532
10533 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10534 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10535 SourceLocation StartLoc,
10536 SourceLocation EndLoc, Stmt *AStmt) {
10537 if (!AStmt)
10538 return StmtError();
10539
10540 auto *CS = cast<CapturedStmt>(AStmt);
10541 // 1.2.2 OpenMP Language Terminology
10542 // Structured block - An executable statement with a single entry at the
10543 // top and a single exit at the bottom.
10544 // The point of exit cannot be a branch out of the structured block.
10545 // longjmp() and throw() must not violate the entry/exit criteria.
10546 CS->getCapturedDecl()->setNothrow();
10547 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10548 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10549 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10550 // 1.2.2 OpenMP Language Terminology
10551 // Structured block - An executable statement with a single entry at the
10552 // top and a single exit at the bottom.
10553 // The point of exit cannot be a branch out of the structured block.
10554 // longjmp() and throw() must not violate the entry/exit criteria.
10555 CS->getCapturedDecl()->setNothrow();
10556 }
10557
10558 // OpenMP [2.10.3, Restrictions, p. 102]
10559 // At least one map clause must appear on the directive.
10560 if (!hasClauses(Clauses, OMPC_map)) {
10561 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10562 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10563 return StmtError();
10564 }
10565
10566 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10567 AStmt);
10568 }
10569
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10570 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10571 SourceLocation StartLoc,
10572 SourceLocation EndLoc,
10573 Stmt *AStmt) {
10574 if (!AStmt)
10575 return StmtError();
10576
10577 auto *CS = cast<CapturedStmt>(AStmt);
10578 // 1.2.2 OpenMP Language Terminology
10579 // Structured block - An executable statement with a single entry at the
10580 // top and a single exit at the bottom.
10581 // The point of exit cannot be a branch out of the structured block.
10582 // longjmp() and throw() must not violate the entry/exit criteria.
10583 CS->getCapturedDecl()->setNothrow();
10584 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10585 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10586 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10587 // 1.2.2 OpenMP Language Terminology
10588 // Structured block - An executable statement with a single entry at the
10589 // top and a single exit at the bottom.
10590 // The point of exit cannot be a branch out of the structured block.
10591 // longjmp() and throw() must not violate the entry/exit criteria.
10592 CS->getCapturedDecl()->setNothrow();
10593 }
10594
10595 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10596 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10597 return StmtError();
10598 }
10599 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10600 AStmt);
10601 }
10602
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10603 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10604 Stmt *AStmt, SourceLocation StartLoc,
10605 SourceLocation EndLoc) {
10606 if (!AStmt)
10607 return StmtError();
10608
10609 auto *CS = cast<CapturedStmt>(AStmt);
10610 // 1.2.2 OpenMP Language Terminology
10611 // Structured block - An executable statement with a single entry at the
10612 // top and a single exit at the bottom.
10613 // The point of exit cannot be a branch out of the structured block.
10614 // longjmp() and throw() must not violate the entry/exit criteria.
10615 CS->getCapturedDecl()->setNothrow();
10616
10617 setFunctionHasBranchProtectedScope();
10618
10619 DSAStack->setParentTeamsRegionLoc(StartLoc);
10620
10621 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10622 }
10623
10624 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)10625 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10626 SourceLocation EndLoc,
10627 OpenMPDirectiveKind CancelRegion) {
10628 if (DSAStack->isParentNowaitRegion()) {
10629 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10630 return StmtError();
10631 }
10632 if (DSAStack->isParentOrderedRegion()) {
10633 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10634 return StmtError();
10635 }
10636 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10637 CancelRegion);
10638 }
10639
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)10640 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10641 SourceLocation StartLoc,
10642 SourceLocation EndLoc,
10643 OpenMPDirectiveKind CancelRegion) {
10644 if (DSAStack->isParentNowaitRegion()) {
10645 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10646 return StmtError();
10647 }
10648 if (DSAStack->isParentOrderedRegion()) {
10649 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10650 return StmtError();
10651 }
10652 DSAStack->setParentCancelRegion(/*Cancel=*/true);
10653 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10654 CancelRegion);
10655 }
10656
checkGrainsizeNumTasksClauses(Sema & S,ArrayRef<OMPClause * > Clauses)10657 static bool checkGrainsizeNumTasksClauses(Sema &S,
10658 ArrayRef<OMPClause *> Clauses) {
10659 const OMPClause *PrevClause = nullptr;
10660 bool ErrorFound = false;
10661 for (const OMPClause *C : Clauses) {
10662 if (C->getClauseKind() == OMPC_grainsize ||
10663 C->getClauseKind() == OMPC_num_tasks) {
10664 if (!PrevClause)
10665 PrevClause = C;
10666 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10667 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10668 << getOpenMPClauseName(C->getClauseKind())
10669 << getOpenMPClauseName(PrevClause->getClauseKind());
10670 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10671 << getOpenMPClauseName(PrevClause->getClauseKind());
10672 ErrorFound = true;
10673 }
10674 }
10675 }
10676 return ErrorFound;
10677 }
10678
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)10679 static bool checkReductionClauseWithNogroup(Sema &S,
10680 ArrayRef<OMPClause *> Clauses) {
10681 const OMPClause *ReductionClause = nullptr;
10682 const OMPClause *NogroupClause = nullptr;
10683 for (const OMPClause *C : Clauses) {
10684 if (C->getClauseKind() == OMPC_reduction) {
10685 ReductionClause = C;
10686 if (NogroupClause)
10687 break;
10688 continue;
10689 }
10690 if (C->getClauseKind() == OMPC_nogroup) {
10691 NogroupClause = C;
10692 if (ReductionClause)
10693 break;
10694 continue;
10695 }
10696 }
10697 if (ReductionClause && NogroupClause) {
10698 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10699 << SourceRange(NogroupClause->getBeginLoc(),
10700 NogroupClause->getEndLoc());
10701 return true;
10702 }
10703 return false;
10704 }
10705
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10706 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10707 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10708 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10709 if (!AStmt)
10710 return StmtError();
10711
10712 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10713 OMPLoopDirective::HelperExprs B;
10714 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10715 // define the nested loops number.
10716 unsigned NestedLoopCount =
10717 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10718 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10719 VarsWithImplicitDSA, B);
10720 if (NestedLoopCount == 0)
10721 return StmtError();
10722
10723 assert((CurContext->isDependentContext() || B.builtAll()) &&
10724 "omp for loop exprs were not built");
10725
10726 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10727 // The grainsize clause and num_tasks clause are mutually exclusive and may
10728 // not appear on the same taskloop directive.
10729 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10730 return StmtError();
10731 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10732 // If a reduction clause is present on the taskloop directive, the nogroup
10733 // clause must not be specified.
10734 if (checkReductionClauseWithNogroup(*this, Clauses))
10735 return StmtError();
10736
10737 setFunctionHasBranchProtectedScope();
10738 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10739 NestedLoopCount, Clauses, AStmt, B,
10740 DSAStack->isCancelRegion());
10741 }
10742
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10743 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10744 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10745 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10746 if (!AStmt)
10747 return StmtError();
10748
10749 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10750 OMPLoopDirective::HelperExprs B;
10751 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10752 // define the nested loops number.
10753 unsigned NestedLoopCount =
10754 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10755 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10756 VarsWithImplicitDSA, B);
10757 if (NestedLoopCount == 0)
10758 return StmtError();
10759
10760 assert((CurContext->isDependentContext() || B.builtAll()) &&
10761 "omp for loop exprs were not built");
10762
10763 if (!CurContext->isDependentContext()) {
10764 // Finalize the clauses that need pre-built expressions for CodeGen.
10765 for (OMPClause *C : Clauses) {
10766 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10767 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10768 B.NumIterations, *this, CurScope,
10769 DSAStack))
10770 return StmtError();
10771 }
10772 }
10773
10774 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10775 // The grainsize clause and num_tasks clause are mutually exclusive and may
10776 // not appear on the same taskloop directive.
10777 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10778 return StmtError();
10779 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10780 // If a reduction clause is present on the taskloop directive, the nogroup
10781 // clause must not be specified.
10782 if (checkReductionClauseWithNogroup(*this, Clauses))
10783 return StmtError();
10784 if (checkSimdlenSafelenSpecified(*this, Clauses))
10785 return StmtError();
10786
10787 setFunctionHasBranchProtectedScope();
10788 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10789 NestedLoopCount, Clauses, AStmt, B);
10790 }
10791
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10792 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10793 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10794 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10795 if (!AStmt)
10796 return StmtError();
10797
10798 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10799 OMPLoopDirective::HelperExprs B;
10800 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10801 // define the nested loops number.
10802 unsigned NestedLoopCount =
10803 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10804 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10805 VarsWithImplicitDSA, B);
10806 if (NestedLoopCount == 0)
10807 return StmtError();
10808
10809 assert((CurContext->isDependentContext() || B.builtAll()) &&
10810 "omp for loop exprs were not built");
10811
10812 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10813 // The grainsize clause and num_tasks clause are mutually exclusive and may
10814 // not appear on the same taskloop directive.
10815 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10816 return StmtError();
10817 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10818 // If a reduction clause is present on the taskloop directive, the nogroup
10819 // clause must not be specified.
10820 if (checkReductionClauseWithNogroup(*this, Clauses))
10821 return StmtError();
10822
10823 setFunctionHasBranchProtectedScope();
10824 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10825 NestedLoopCount, Clauses, AStmt, B,
10826 DSAStack->isCancelRegion());
10827 }
10828
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10829 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10830 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10831 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10832 if (!AStmt)
10833 return StmtError();
10834
10835 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10836 OMPLoopDirective::HelperExprs B;
10837 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10838 // define the nested loops number.
10839 unsigned NestedLoopCount =
10840 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10841 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10842 VarsWithImplicitDSA, B);
10843 if (NestedLoopCount == 0)
10844 return StmtError();
10845
10846 assert((CurContext->isDependentContext() || B.builtAll()) &&
10847 "omp for loop exprs were not built");
10848
10849 if (!CurContext->isDependentContext()) {
10850 // Finalize the clauses that need pre-built expressions for CodeGen.
10851 for (OMPClause *C : Clauses) {
10852 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10853 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10854 B.NumIterations, *this, CurScope,
10855 DSAStack))
10856 return StmtError();
10857 }
10858 }
10859
10860 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10861 // The grainsize clause and num_tasks clause are mutually exclusive and may
10862 // not appear on the same taskloop directive.
10863 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10864 return StmtError();
10865 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10866 // If a reduction clause is present on the taskloop directive, the nogroup
10867 // clause must not be specified.
10868 if (checkReductionClauseWithNogroup(*this, Clauses))
10869 return StmtError();
10870 if (checkSimdlenSafelenSpecified(*this, Clauses))
10871 return StmtError();
10872
10873 setFunctionHasBranchProtectedScope();
10874 return OMPMasterTaskLoopSimdDirective::Create(
10875 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10876 }
10877
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10878 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
10879 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10880 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10881 if (!AStmt)
10882 return StmtError();
10883
10884 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10885 auto *CS = cast<CapturedStmt>(AStmt);
10886 // 1.2.2 OpenMP Language Terminology
10887 // Structured block - An executable statement with a single entry at the
10888 // top and a single exit at the bottom.
10889 // The point of exit cannot be a branch out of the structured block.
10890 // longjmp() and throw() must not violate the entry/exit criteria.
10891 CS->getCapturedDecl()->setNothrow();
10892 for (int ThisCaptureLevel =
10893 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
10894 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10895 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10896 // 1.2.2 OpenMP Language Terminology
10897 // Structured block - An executable statement with a single entry at the
10898 // top and a single exit at the bottom.
10899 // The point of exit cannot be a branch out of the structured block.
10900 // longjmp() and throw() must not violate the entry/exit criteria.
10901 CS->getCapturedDecl()->setNothrow();
10902 }
10903
10904 OMPLoopDirective::HelperExprs B;
10905 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10906 // define the nested loops number.
10907 unsigned NestedLoopCount = checkOpenMPLoop(
10908 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
10909 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10910 VarsWithImplicitDSA, B);
10911 if (NestedLoopCount == 0)
10912 return StmtError();
10913
10914 assert((CurContext->isDependentContext() || B.builtAll()) &&
10915 "omp for loop exprs were not built");
10916
10917 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10918 // The grainsize clause and num_tasks clause are mutually exclusive and may
10919 // not appear on the same taskloop directive.
10920 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10921 return StmtError();
10922 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10923 // If a reduction clause is present on the taskloop directive, the nogroup
10924 // clause must not be specified.
10925 if (checkReductionClauseWithNogroup(*this, Clauses))
10926 return StmtError();
10927
10928 setFunctionHasBranchProtectedScope();
10929 return OMPParallelMasterTaskLoopDirective::Create(
10930 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10931 DSAStack->isCancelRegion());
10932 }
10933
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10934 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
10935 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10936 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10937 if (!AStmt)
10938 return StmtError();
10939
10940 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10941 auto *CS = cast<CapturedStmt>(AStmt);
10942 // 1.2.2 OpenMP Language Terminology
10943 // Structured block - An executable statement with a single entry at the
10944 // top and a single exit at the bottom.
10945 // The point of exit cannot be a branch out of the structured block.
10946 // longjmp() and throw() must not violate the entry/exit criteria.
10947 CS->getCapturedDecl()->setNothrow();
10948 for (int ThisCaptureLevel =
10949 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
10950 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10951 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10952 // 1.2.2 OpenMP Language Terminology
10953 // Structured block - An executable statement with a single entry at the
10954 // top and a single exit at the bottom.
10955 // The point of exit cannot be a branch out of the structured block.
10956 // longjmp() and throw() must not violate the entry/exit criteria.
10957 CS->getCapturedDecl()->setNothrow();
10958 }
10959
10960 OMPLoopDirective::HelperExprs B;
10961 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10962 // define the nested loops number.
10963 unsigned NestedLoopCount = checkOpenMPLoop(
10964 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10965 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10966 VarsWithImplicitDSA, B);
10967 if (NestedLoopCount == 0)
10968 return StmtError();
10969
10970 assert((CurContext->isDependentContext() || B.builtAll()) &&
10971 "omp for loop exprs were not built");
10972
10973 if (!CurContext->isDependentContext()) {
10974 // Finalize the clauses that need pre-built expressions for CodeGen.
10975 for (OMPClause *C : Clauses) {
10976 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10977 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10978 B.NumIterations, *this, CurScope,
10979 DSAStack))
10980 return StmtError();
10981 }
10982 }
10983
10984 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10985 // The grainsize clause and num_tasks clause are mutually exclusive and may
10986 // not appear on the same taskloop directive.
10987 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10988 return StmtError();
10989 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10990 // If a reduction clause is present on the taskloop directive, the nogroup
10991 // clause must not be specified.
10992 if (checkReductionClauseWithNogroup(*this, Clauses))
10993 return StmtError();
10994 if (checkSimdlenSafelenSpecified(*this, Clauses))
10995 return StmtError();
10996
10997 setFunctionHasBranchProtectedScope();
10998 return OMPParallelMasterTaskLoopSimdDirective::Create(
10999 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11000 }
11001
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11002 StmtResult Sema::ActOnOpenMPDistributeDirective(
11003 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11004 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11005 if (!AStmt)
11006 return StmtError();
11007
11008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11009 OMPLoopDirective::HelperExprs B;
11010 // In presence of clause 'collapse' with number of loops, it will
11011 // define the nested loops number.
11012 unsigned NestedLoopCount =
11013 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11014 nullptr /*ordered not a clause on distribute*/, AStmt,
11015 *this, *DSAStack, VarsWithImplicitDSA, B);
11016 if (NestedLoopCount == 0)
11017 return StmtError();
11018
11019 assert((CurContext->isDependentContext() || B.builtAll()) &&
11020 "omp for loop exprs were not built");
11021
11022 setFunctionHasBranchProtectedScope();
11023 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11024 NestedLoopCount, Clauses, AStmt, B);
11025 }
11026
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11027 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11028 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11029 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11030 if (!AStmt)
11031 return StmtError();
11032
11033 auto *CS = cast<CapturedStmt>(AStmt);
11034 // 1.2.2 OpenMP Language Terminology
11035 // Structured block - An executable statement with a single entry at the
11036 // top and a single exit at the bottom.
11037 // The point of exit cannot be a branch out of the structured block.
11038 // longjmp() and throw() must not violate the entry/exit criteria.
11039 CS->getCapturedDecl()->setNothrow();
11040 for (int ThisCaptureLevel =
11041 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11042 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11043 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11044 // 1.2.2 OpenMP Language Terminology
11045 // Structured block - An executable statement with a single entry at the
11046 // top and a single exit at the bottom.
11047 // The point of exit cannot be a branch out of the structured block.
11048 // longjmp() and throw() must not violate the entry/exit criteria.
11049 CS->getCapturedDecl()->setNothrow();
11050 }
11051
11052 OMPLoopDirective::HelperExprs B;
11053 // In presence of clause 'collapse' with number of loops, it will
11054 // define the nested loops number.
11055 unsigned NestedLoopCount = checkOpenMPLoop(
11056 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11057 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11058 VarsWithImplicitDSA, B);
11059 if (NestedLoopCount == 0)
11060 return StmtError();
11061
11062 assert((CurContext->isDependentContext() || B.builtAll()) &&
11063 "omp for loop exprs were not built");
11064
11065 setFunctionHasBranchProtectedScope();
11066 return OMPDistributeParallelForDirective::Create(
11067 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11068 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11069 }
11070
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11071 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11072 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11073 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11074 if (!AStmt)
11075 return StmtError();
11076
11077 auto *CS = cast<CapturedStmt>(AStmt);
11078 // 1.2.2 OpenMP Language Terminology
11079 // Structured block - An executable statement with a single entry at the
11080 // top and a single exit at the bottom.
11081 // The point of exit cannot be a branch out of the structured block.
11082 // longjmp() and throw() must not violate the entry/exit criteria.
11083 CS->getCapturedDecl()->setNothrow();
11084 for (int ThisCaptureLevel =
11085 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11086 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11087 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11088 // 1.2.2 OpenMP Language Terminology
11089 // Structured block - An executable statement with a single entry at the
11090 // top and a single exit at the bottom.
11091 // The point of exit cannot be a branch out of the structured block.
11092 // longjmp() and throw() must not violate the entry/exit criteria.
11093 CS->getCapturedDecl()->setNothrow();
11094 }
11095
11096 OMPLoopDirective::HelperExprs B;
11097 // In presence of clause 'collapse' with number of loops, it will
11098 // define the nested loops number.
11099 unsigned NestedLoopCount = checkOpenMPLoop(
11100 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11101 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11102 VarsWithImplicitDSA, B);
11103 if (NestedLoopCount == 0)
11104 return StmtError();
11105
11106 assert((CurContext->isDependentContext() || B.builtAll()) &&
11107 "omp for loop exprs were not built");
11108
11109 if (!CurContext->isDependentContext()) {
11110 // Finalize the clauses that need pre-built expressions for CodeGen.
11111 for (OMPClause *C : Clauses) {
11112 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11113 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11114 B.NumIterations, *this, CurScope,
11115 DSAStack))
11116 return StmtError();
11117 }
11118 }
11119
11120 if (checkSimdlenSafelenSpecified(*this, Clauses))
11121 return StmtError();
11122
11123 setFunctionHasBranchProtectedScope();
11124 return OMPDistributeParallelForSimdDirective::Create(
11125 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11126 }
11127
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11128 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11129 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11130 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11131 if (!AStmt)
11132 return StmtError();
11133
11134 auto *CS = cast<CapturedStmt>(AStmt);
11135 // 1.2.2 OpenMP Language Terminology
11136 // Structured block - An executable statement with a single entry at the
11137 // top and a single exit at the bottom.
11138 // The point of exit cannot be a branch out of the structured block.
11139 // longjmp() and throw() must not violate the entry/exit criteria.
11140 CS->getCapturedDecl()->setNothrow();
11141 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11142 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11143 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11144 // 1.2.2 OpenMP Language Terminology
11145 // Structured block - An executable statement with a single entry at the
11146 // top and a single exit at the bottom.
11147 // The point of exit cannot be a branch out of the structured block.
11148 // longjmp() and throw() must not violate the entry/exit criteria.
11149 CS->getCapturedDecl()->setNothrow();
11150 }
11151
11152 OMPLoopDirective::HelperExprs B;
11153 // In presence of clause 'collapse' with number of loops, it will
11154 // define the nested loops number.
11155 unsigned NestedLoopCount =
11156 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11157 nullptr /*ordered not a clause on distribute*/, CS, *this,
11158 *DSAStack, VarsWithImplicitDSA, B);
11159 if (NestedLoopCount == 0)
11160 return StmtError();
11161
11162 assert((CurContext->isDependentContext() || B.builtAll()) &&
11163 "omp for loop exprs were not built");
11164
11165 if (!CurContext->isDependentContext()) {
11166 // Finalize the clauses that need pre-built expressions for CodeGen.
11167 for (OMPClause *C : Clauses) {
11168 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11169 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11170 B.NumIterations, *this, CurScope,
11171 DSAStack))
11172 return StmtError();
11173 }
11174 }
11175
11176 if (checkSimdlenSafelenSpecified(*this, Clauses))
11177 return StmtError();
11178
11179 setFunctionHasBranchProtectedScope();
11180 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11181 NestedLoopCount, Clauses, AStmt, B);
11182 }
11183
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11184 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11185 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11186 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11187 if (!AStmt)
11188 return StmtError();
11189
11190 auto *CS = cast<CapturedStmt>(AStmt);
11191 // 1.2.2 OpenMP Language Terminology
11192 // Structured block - An executable statement with a single entry at the
11193 // top and a single exit at the bottom.
11194 // The point of exit cannot be a branch out of the structured block.
11195 // longjmp() and throw() must not violate the entry/exit criteria.
11196 CS->getCapturedDecl()->setNothrow();
11197 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11198 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11199 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11200 // 1.2.2 OpenMP Language Terminology
11201 // Structured block - An executable statement with a single entry at the
11202 // top and a single exit at the bottom.
11203 // The point of exit cannot be a branch out of the structured block.
11204 // longjmp() and throw() must not violate the entry/exit criteria.
11205 CS->getCapturedDecl()->setNothrow();
11206 }
11207
11208 OMPLoopDirective::HelperExprs B;
11209 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11210 // define the nested loops number.
11211 unsigned NestedLoopCount = checkOpenMPLoop(
11212 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11213 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11214 VarsWithImplicitDSA, B);
11215 if (NestedLoopCount == 0)
11216 return StmtError();
11217
11218 assert((CurContext->isDependentContext() || B.builtAll()) &&
11219 "omp target parallel for simd loop exprs were not built");
11220
11221 if (!CurContext->isDependentContext()) {
11222 // Finalize the clauses that need pre-built expressions for CodeGen.
11223 for (OMPClause *C : Clauses) {
11224 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11225 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11226 B.NumIterations, *this, CurScope,
11227 DSAStack))
11228 return StmtError();
11229 }
11230 }
11231 if (checkSimdlenSafelenSpecified(*this, Clauses))
11232 return StmtError();
11233
11234 setFunctionHasBranchProtectedScope();
11235 return OMPTargetParallelForSimdDirective::Create(
11236 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11237 }
11238
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11239 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11240 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11241 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11242 if (!AStmt)
11243 return StmtError();
11244
11245 auto *CS = cast<CapturedStmt>(AStmt);
11246 // 1.2.2 OpenMP Language Terminology
11247 // Structured block - An executable statement with a single entry at the
11248 // top and a single exit at the bottom.
11249 // The point of exit cannot be a branch out of the structured block.
11250 // longjmp() and throw() must not violate the entry/exit criteria.
11251 CS->getCapturedDecl()->setNothrow();
11252 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11253 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11254 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11255 // 1.2.2 OpenMP Language Terminology
11256 // Structured block - An executable statement with a single entry at the
11257 // top and a single exit at the bottom.
11258 // The point of exit cannot be a branch out of the structured block.
11259 // longjmp() and throw() must not violate the entry/exit criteria.
11260 CS->getCapturedDecl()->setNothrow();
11261 }
11262
11263 OMPLoopDirective::HelperExprs B;
11264 // In presence of clause 'collapse' with number of loops, it will define the
11265 // nested loops number.
11266 unsigned NestedLoopCount =
11267 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11268 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11269 VarsWithImplicitDSA, B);
11270 if (NestedLoopCount == 0)
11271 return StmtError();
11272
11273 assert((CurContext->isDependentContext() || B.builtAll()) &&
11274 "omp target simd loop exprs were not built");
11275
11276 if (!CurContext->isDependentContext()) {
11277 // Finalize the clauses that need pre-built expressions for CodeGen.
11278 for (OMPClause *C : Clauses) {
11279 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11280 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11281 B.NumIterations, *this, CurScope,
11282 DSAStack))
11283 return StmtError();
11284 }
11285 }
11286
11287 if (checkSimdlenSafelenSpecified(*this, Clauses))
11288 return StmtError();
11289
11290 setFunctionHasBranchProtectedScope();
11291 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11292 NestedLoopCount, Clauses, AStmt, B);
11293 }
11294
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11295 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11296 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11297 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11298 if (!AStmt)
11299 return StmtError();
11300
11301 auto *CS = cast<CapturedStmt>(AStmt);
11302 // 1.2.2 OpenMP Language Terminology
11303 // Structured block - An executable statement with a single entry at the
11304 // top and a single exit at the bottom.
11305 // The point of exit cannot be a branch out of the structured block.
11306 // longjmp() and throw() must not violate the entry/exit criteria.
11307 CS->getCapturedDecl()->setNothrow();
11308 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11309 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11310 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11311 // 1.2.2 OpenMP Language Terminology
11312 // Structured block - An executable statement with a single entry at the
11313 // top and a single exit at the bottom.
11314 // The point of exit cannot be a branch out of the structured block.
11315 // longjmp() and throw() must not violate the entry/exit criteria.
11316 CS->getCapturedDecl()->setNothrow();
11317 }
11318
11319 OMPLoopDirective::HelperExprs B;
11320 // In presence of clause 'collapse' with number of loops, it will
11321 // define the nested loops number.
11322 unsigned NestedLoopCount =
11323 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11324 nullptr /*ordered not a clause on distribute*/, CS, *this,
11325 *DSAStack, VarsWithImplicitDSA, B);
11326 if (NestedLoopCount == 0)
11327 return StmtError();
11328
11329 assert((CurContext->isDependentContext() || B.builtAll()) &&
11330 "omp teams distribute loop exprs were not built");
11331
11332 setFunctionHasBranchProtectedScope();
11333
11334 DSAStack->setParentTeamsRegionLoc(StartLoc);
11335
11336 return OMPTeamsDistributeDirective::Create(
11337 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11338 }
11339
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11340 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11341 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11342 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11343 if (!AStmt)
11344 return StmtError();
11345
11346 auto *CS = cast<CapturedStmt>(AStmt);
11347 // 1.2.2 OpenMP Language Terminology
11348 // Structured block - An executable statement with a single entry at the
11349 // top and a single exit at the bottom.
11350 // The point of exit cannot be a branch out of the structured block.
11351 // longjmp() and throw() must not violate the entry/exit criteria.
11352 CS->getCapturedDecl()->setNothrow();
11353 for (int ThisCaptureLevel =
11354 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11355 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11356 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11357 // 1.2.2 OpenMP Language Terminology
11358 // Structured block - An executable statement with a single entry at the
11359 // top and a single exit at the bottom.
11360 // The point of exit cannot be a branch out of the structured block.
11361 // longjmp() and throw() must not violate the entry/exit criteria.
11362 CS->getCapturedDecl()->setNothrow();
11363 }
11364
11365 OMPLoopDirective::HelperExprs B;
11366 // In presence of clause 'collapse' with number of loops, it will
11367 // define the nested loops number.
11368 unsigned NestedLoopCount = checkOpenMPLoop(
11369 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11370 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11371 VarsWithImplicitDSA, B);
11372
11373 if (NestedLoopCount == 0)
11374 return StmtError();
11375
11376 assert((CurContext->isDependentContext() || B.builtAll()) &&
11377 "omp teams distribute simd loop exprs were not built");
11378
11379 if (!CurContext->isDependentContext()) {
11380 // Finalize the clauses that need pre-built expressions for CodeGen.
11381 for (OMPClause *C : Clauses) {
11382 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11383 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11384 B.NumIterations, *this, CurScope,
11385 DSAStack))
11386 return StmtError();
11387 }
11388 }
11389
11390 if (checkSimdlenSafelenSpecified(*this, Clauses))
11391 return StmtError();
11392
11393 setFunctionHasBranchProtectedScope();
11394
11395 DSAStack->setParentTeamsRegionLoc(StartLoc);
11396
11397 return OMPTeamsDistributeSimdDirective::Create(
11398 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11399 }
11400
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11401 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11402 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11403 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11404 if (!AStmt)
11405 return StmtError();
11406
11407 auto *CS = cast<CapturedStmt>(AStmt);
11408 // 1.2.2 OpenMP Language Terminology
11409 // Structured block - An executable statement with a single entry at the
11410 // top and a single exit at the bottom.
11411 // The point of exit cannot be a branch out of the structured block.
11412 // longjmp() and throw() must not violate the entry/exit criteria.
11413 CS->getCapturedDecl()->setNothrow();
11414
11415 for (int ThisCaptureLevel =
11416 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11417 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11418 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11419 // 1.2.2 OpenMP Language Terminology
11420 // Structured block - An executable statement with a single entry at the
11421 // top and a single exit at the bottom.
11422 // The point of exit cannot be a branch out of the structured block.
11423 // longjmp() and throw() must not violate the entry/exit criteria.
11424 CS->getCapturedDecl()->setNothrow();
11425 }
11426
11427 OMPLoopDirective::HelperExprs B;
11428 // In presence of clause 'collapse' with number of loops, it will
11429 // define the nested loops number.
11430 unsigned NestedLoopCount = checkOpenMPLoop(
11431 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11432 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11433 VarsWithImplicitDSA, B);
11434
11435 if (NestedLoopCount == 0)
11436 return StmtError();
11437
11438 assert((CurContext->isDependentContext() || B.builtAll()) &&
11439 "omp for loop exprs were not built");
11440
11441 if (!CurContext->isDependentContext()) {
11442 // Finalize the clauses that need pre-built expressions for CodeGen.
11443 for (OMPClause *C : Clauses) {
11444 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11445 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11446 B.NumIterations, *this, CurScope,
11447 DSAStack))
11448 return StmtError();
11449 }
11450 }
11451
11452 if (checkSimdlenSafelenSpecified(*this, Clauses))
11453 return StmtError();
11454
11455 setFunctionHasBranchProtectedScope();
11456
11457 DSAStack->setParentTeamsRegionLoc(StartLoc);
11458
11459 return OMPTeamsDistributeParallelForSimdDirective::Create(
11460 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11461 }
11462
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11463 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11464 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11465 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11466 if (!AStmt)
11467 return StmtError();
11468
11469 auto *CS = cast<CapturedStmt>(AStmt);
11470 // 1.2.2 OpenMP Language Terminology
11471 // Structured block - An executable statement with a single entry at the
11472 // top and a single exit at the bottom.
11473 // The point of exit cannot be a branch out of the structured block.
11474 // longjmp() and throw() must not violate the entry/exit criteria.
11475 CS->getCapturedDecl()->setNothrow();
11476
11477 for (int ThisCaptureLevel =
11478 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11479 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11480 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11481 // 1.2.2 OpenMP Language Terminology
11482 // Structured block - An executable statement with a single entry at the
11483 // top and a single exit at the bottom.
11484 // The point of exit cannot be a branch out of the structured block.
11485 // longjmp() and throw() must not violate the entry/exit criteria.
11486 CS->getCapturedDecl()->setNothrow();
11487 }
11488
11489 OMPLoopDirective::HelperExprs B;
11490 // In presence of clause 'collapse' with number of loops, it will
11491 // define the nested loops number.
11492 unsigned NestedLoopCount = checkOpenMPLoop(
11493 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11494 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11495 VarsWithImplicitDSA, B);
11496
11497 if (NestedLoopCount == 0)
11498 return StmtError();
11499
11500 assert((CurContext->isDependentContext() || B.builtAll()) &&
11501 "omp for loop exprs were not built");
11502
11503 setFunctionHasBranchProtectedScope();
11504
11505 DSAStack->setParentTeamsRegionLoc(StartLoc);
11506
11507 return OMPTeamsDistributeParallelForDirective::Create(
11508 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11509 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11510 }
11511
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11512 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11513 Stmt *AStmt,
11514 SourceLocation StartLoc,
11515 SourceLocation EndLoc) {
11516 if (!AStmt)
11517 return StmtError();
11518
11519 auto *CS = cast<CapturedStmt>(AStmt);
11520 // 1.2.2 OpenMP Language Terminology
11521 // Structured block - An executable statement with a single entry at the
11522 // top and a single exit at the bottom.
11523 // The point of exit cannot be a branch out of the structured block.
11524 // longjmp() and throw() must not violate the entry/exit criteria.
11525 CS->getCapturedDecl()->setNothrow();
11526
11527 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11528 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11529 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11530 // 1.2.2 OpenMP Language Terminology
11531 // Structured block - An executable statement with a single entry at the
11532 // top and a single exit at the bottom.
11533 // The point of exit cannot be a branch out of the structured block.
11534 // longjmp() and throw() must not violate the entry/exit criteria.
11535 CS->getCapturedDecl()->setNothrow();
11536 }
11537 setFunctionHasBranchProtectedScope();
11538
11539 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11540 AStmt);
11541 }
11542
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11543 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11544 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11545 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11546 if (!AStmt)
11547 return StmtError();
11548
11549 auto *CS = cast<CapturedStmt>(AStmt);
11550 // 1.2.2 OpenMP Language Terminology
11551 // Structured block - An executable statement with a single entry at the
11552 // top and a single exit at the bottom.
11553 // The point of exit cannot be a branch out of the structured block.
11554 // longjmp() and throw() must not violate the entry/exit criteria.
11555 CS->getCapturedDecl()->setNothrow();
11556 for (int ThisCaptureLevel =
11557 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11558 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11559 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11560 // 1.2.2 OpenMP Language Terminology
11561 // Structured block - An executable statement with a single entry at the
11562 // top and a single exit at the bottom.
11563 // The point of exit cannot be a branch out of the structured block.
11564 // longjmp() and throw() must not violate the entry/exit criteria.
11565 CS->getCapturedDecl()->setNothrow();
11566 }
11567
11568 OMPLoopDirective::HelperExprs B;
11569 // In presence of clause 'collapse' with number of loops, it will
11570 // define the nested loops number.
11571 unsigned NestedLoopCount = checkOpenMPLoop(
11572 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11573 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11574 VarsWithImplicitDSA, B);
11575 if (NestedLoopCount == 0)
11576 return StmtError();
11577
11578 assert((CurContext->isDependentContext() || B.builtAll()) &&
11579 "omp target teams distribute loop exprs were not built");
11580
11581 setFunctionHasBranchProtectedScope();
11582 return OMPTargetTeamsDistributeDirective::Create(
11583 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11584 }
11585
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11586 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11587 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11588 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11589 if (!AStmt)
11590 return StmtError();
11591
11592 auto *CS = cast<CapturedStmt>(AStmt);
11593 // 1.2.2 OpenMP Language Terminology
11594 // Structured block - An executable statement with a single entry at the
11595 // top and a single exit at the bottom.
11596 // The point of exit cannot be a branch out of the structured block.
11597 // longjmp() and throw() must not violate the entry/exit criteria.
11598 CS->getCapturedDecl()->setNothrow();
11599 for (int ThisCaptureLevel =
11600 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11601 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11602 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11603 // 1.2.2 OpenMP Language Terminology
11604 // Structured block - An executable statement with a single entry at the
11605 // top and a single exit at the bottom.
11606 // The point of exit cannot be a branch out of the structured block.
11607 // longjmp() and throw() must not violate the entry/exit criteria.
11608 CS->getCapturedDecl()->setNothrow();
11609 }
11610
11611 OMPLoopDirective::HelperExprs B;
11612 // In presence of clause 'collapse' with number of loops, it will
11613 // define the nested loops number.
11614 unsigned NestedLoopCount = checkOpenMPLoop(
11615 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11616 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11617 VarsWithImplicitDSA, B);
11618 if (NestedLoopCount == 0)
11619 return StmtError();
11620
11621 assert((CurContext->isDependentContext() || B.builtAll()) &&
11622 "omp target teams distribute parallel for loop exprs were not built");
11623
11624 if (!CurContext->isDependentContext()) {
11625 // Finalize the clauses that need pre-built expressions for CodeGen.
11626 for (OMPClause *C : Clauses) {
11627 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11628 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11629 B.NumIterations, *this, CurScope,
11630 DSAStack))
11631 return StmtError();
11632 }
11633 }
11634
11635 setFunctionHasBranchProtectedScope();
11636 return OMPTargetTeamsDistributeParallelForDirective::Create(
11637 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11638 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11639 }
11640
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11641 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11642 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11643 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11644 if (!AStmt)
11645 return StmtError();
11646
11647 auto *CS = cast<CapturedStmt>(AStmt);
11648 // 1.2.2 OpenMP Language Terminology
11649 // Structured block - An executable statement with a single entry at the
11650 // top and a single exit at the bottom.
11651 // The point of exit cannot be a branch out of the structured block.
11652 // longjmp() and throw() must not violate the entry/exit criteria.
11653 CS->getCapturedDecl()->setNothrow();
11654 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11655 OMPD_target_teams_distribute_parallel_for_simd);
11656 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11657 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11658 // 1.2.2 OpenMP Language Terminology
11659 // Structured block - An executable statement with a single entry at the
11660 // top and a single exit at the bottom.
11661 // The point of exit cannot be a branch out of the structured block.
11662 // longjmp() and throw() must not violate the entry/exit criteria.
11663 CS->getCapturedDecl()->setNothrow();
11664 }
11665
11666 OMPLoopDirective::HelperExprs B;
11667 // In presence of clause 'collapse' with number of loops, it will
11668 // define the nested loops number.
11669 unsigned NestedLoopCount =
11670 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11671 getCollapseNumberExpr(Clauses),
11672 nullptr /*ordered not a clause on distribute*/, CS, *this,
11673 *DSAStack, VarsWithImplicitDSA, B);
11674 if (NestedLoopCount == 0)
11675 return StmtError();
11676
11677 assert((CurContext->isDependentContext() || B.builtAll()) &&
11678 "omp target teams distribute parallel for simd loop exprs were not "
11679 "built");
11680
11681 if (!CurContext->isDependentContext()) {
11682 // Finalize the clauses that need pre-built expressions for CodeGen.
11683 for (OMPClause *C : Clauses) {
11684 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11685 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11686 B.NumIterations, *this, CurScope,
11687 DSAStack))
11688 return StmtError();
11689 }
11690 }
11691
11692 if (checkSimdlenSafelenSpecified(*this, Clauses))
11693 return StmtError();
11694
11695 setFunctionHasBranchProtectedScope();
11696 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11697 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11698 }
11699
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11700 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11701 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11702 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11703 if (!AStmt)
11704 return StmtError();
11705
11706 auto *CS = cast<CapturedStmt>(AStmt);
11707 // 1.2.2 OpenMP Language Terminology
11708 // Structured block - An executable statement with a single entry at the
11709 // top and a single exit at the bottom.
11710 // The point of exit cannot be a branch out of the structured block.
11711 // longjmp() and throw() must not violate the entry/exit criteria.
11712 CS->getCapturedDecl()->setNothrow();
11713 for (int ThisCaptureLevel =
11714 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11715 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11716 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11717 // 1.2.2 OpenMP Language Terminology
11718 // Structured block - An executable statement with a single entry at the
11719 // top and a single exit at the bottom.
11720 // The point of exit cannot be a branch out of the structured block.
11721 // longjmp() and throw() must not violate the entry/exit criteria.
11722 CS->getCapturedDecl()->setNothrow();
11723 }
11724
11725 OMPLoopDirective::HelperExprs B;
11726 // In presence of clause 'collapse' with number of loops, it will
11727 // define the nested loops number.
11728 unsigned NestedLoopCount = checkOpenMPLoop(
11729 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11730 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11731 VarsWithImplicitDSA, B);
11732 if (NestedLoopCount == 0)
11733 return StmtError();
11734
11735 assert((CurContext->isDependentContext() || B.builtAll()) &&
11736 "omp target teams distribute simd loop exprs were not built");
11737
11738 if (!CurContext->isDependentContext()) {
11739 // Finalize the clauses that need pre-built expressions for CodeGen.
11740 for (OMPClause *C : Clauses) {
11741 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11742 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11743 B.NumIterations, *this, CurScope,
11744 DSAStack))
11745 return StmtError();
11746 }
11747 }
11748
11749 if (checkSimdlenSafelenSpecified(*this, Clauses))
11750 return StmtError();
11751
11752 setFunctionHasBranchProtectedScope();
11753 return OMPTargetTeamsDistributeSimdDirective::Create(
11754 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11755 }
11756
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11757 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11758 SourceLocation StartLoc,
11759 SourceLocation LParenLoc,
11760 SourceLocation EndLoc) {
11761 OMPClause *Res = nullptr;
11762 switch (Kind) {
11763 case OMPC_final:
11764 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11765 break;
11766 case OMPC_num_threads:
11767 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11768 break;
11769 case OMPC_safelen:
11770 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11771 break;
11772 case OMPC_simdlen:
11773 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11774 break;
11775 case OMPC_allocator:
11776 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11777 break;
11778 case OMPC_collapse:
11779 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11780 break;
11781 case OMPC_ordered:
11782 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11783 break;
11784 case OMPC_num_teams:
11785 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11786 break;
11787 case OMPC_thread_limit:
11788 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11789 break;
11790 case OMPC_priority:
11791 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11792 break;
11793 case OMPC_grainsize:
11794 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11795 break;
11796 case OMPC_num_tasks:
11797 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11798 break;
11799 case OMPC_hint:
11800 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11801 break;
11802 case OMPC_depobj:
11803 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11804 break;
11805 case OMPC_detach:
11806 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11807 break;
11808 case OMPC_device:
11809 case OMPC_if:
11810 case OMPC_default:
11811 case OMPC_proc_bind:
11812 case OMPC_schedule:
11813 case OMPC_private:
11814 case OMPC_firstprivate:
11815 case OMPC_lastprivate:
11816 case OMPC_shared:
11817 case OMPC_reduction:
11818 case OMPC_task_reduction:
11819 case OMPC_in_reduction:
11820 case OMPC_linear:
11821 case OMPC_aligned:
11822 case OMPC_copyin:
11823 case OMPC_copyprivate:
11824 case OMPC_nowait:
11825 case OMPC_untied:
11826 case OMPC_mergeable:
11827 case OMPC_threadprivate:
11828 case OMPC_allocate:
11829 case OMPC_flush:
11830 case OMPC_read:
11831 case OMPC_write:
11832 case OMPC_update:
11833 case OMPC_capture:
11834 case OMPC_seq_cst:
11835 case OMPC_acq_rel:
11836 case OMPC_acquire:
11837 case OMPC_release:
11838 case OMPC_relaxed:
11839 case OMPC_depend:
11840 case OMPC_threads:
11841 case OMPC_simd:
11842 case OMPC_map:
11843 case OMPC_nogroup:
11844 case OMPC_dist_schedule:
11845 case OMPC_defaultmap:
11846 case OMPC_unknown:
11847 case OMPC_uniform:
11848 case OMPC_to:
11849 case OMPC_from:
11850 case OMPC_use_device_ptr:
11851 case OMPC_use_device_addr:
11852 case OMPC_is_device_ptr:
11853 case OMPC_unified_address:
11854 case OMPC_unified_shared_memory:
11855 case OMPC_reverse_offload:
11856 case OMPC_dynamic_allocators:
11857 case OMPC_atomic_default_mem_order:
11858 case OMPC_device_type:
11859 case OMPC_match:
11860 case OMPC_nontemporal:
11861 case OMPC_order:
11862 case OMPC_destroy:
11863 case OMPC_inclusive:
11864 case OMPC_exclusive:
11865 case OMPC_uses_allocators:
11866 case OMPC_affinity:
11867 default:
11868 llvm_unreachable("Clause is not allowed.");
11869 }
11870 return Res;
11871 }
11872
11873 // An OpenMP directive such as 'target parallel' has two captured regions:
11874 // for the 'target' and 'parallel' respectively. This function returns
11875 // the region in which to capture expressions associated with a clause.
11876 // A return value of OMPD_unknown signifies that the expression should not
11877 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)11878 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
11879 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
11880 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
11881 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11882 switch (CKind) {
11883 case OMPC_if:
11884 switch (DKind) {
11885 case OMPD_target_parallel_for_simd:
11886 if (OpenMPVersion >= 50 &&
11887 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11888 CaptureRegion = OMPD_parallel;
11889 break;
11890 }
11891 LLVM_FALLTHROUGH;
11892 case OMPD_target_parallel:
11893 case OMPD_target_parallel_for:
11894 // If this clause applies to the nested 'parallel' region, capture within
11895 // the 'target' region, otherwise do not capture.
11896 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11897 CaptureRegion = OMPD_target;
11898 break;
11899 case OMPD_target_teams_distribute_parallel_for_simd:
11900 if (OpenMPVersion >= 50 &&
11901 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11902 CaptureRegion = OMPD_parallel;
11903 break;
11904 }
11905 LLVM_FALLTHROUGH;
11906 case OMPD_target_teams_distribute_parallel_for:
11907 // If this clause applies to the nested 'parallel' region, capture within
11908 // the 'teams' region, otherwise do not capture.
11909 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11910 CaptureRegion = OMPD_teams;
11911 break;
11912 case OMPD_teams_distribute_parallel_for_simd:
11913 if (OpenMPVersion >= 50 &&
11914 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11915 CaptureRegion = OMPD_parallel;
11916 break;
11917 }
11918 LLVM_FALLTHROUGH;
11919 case OMPD_teams_distribute_parallel_for:
11920 CaptureRegion = OMPD_teams;
11921 break;
11922 case OMPD_target_update:
11923 case OMPD_target_enter_data:
11924 case OMPD_target_exit_data:
11925 CaptureRegion = OMPD_task;
11926 break;
11927 case OMPD_parallel_master_taskloop:
11928 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
11929 CaptureRegion = OMPD_parallel;
11930 break;
11931 case OMPD_parallel_master_taskloop_simd:
11932 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
11933 NameModifier == OMPD_taskloop) {
11934 CaptureRegion = OMPD_parallel;
11935 break;
11936 }
11937 if (OpenMPVersion <= 45)
11938 break;
11939 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11940 CaptureRegion = OMPD_taskloop;
11941 break;
11942 case OMPD_parallel_for_simd:
11943 if (OpenMPVersion <= 45)
11944 break;
11945 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11946 CaptureRegion = OMPD_parallel;
11947 break;
11948 case OMPD_taskloop_simd:
11949 case OMPD_master_taskloop_simd:
11950 if (OpenMPVersion <= 45)
11951 break;
11952 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11953 CaptureRegion = OMPD_taskloop;
11954 break;
11955 case OMPD_distribute_parallel_for_simd:
11956 if (OpenMPVersion <= 45)
11957 break;
11958 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11959 CaptureRegion = OMPD_parallel;
11960 break;
11961 case OMPD_target_simd:
11962 if (OpenMPVersion >= 50 &&
11963 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11964 CaptureRegion = OMPD_target;
11965 break;
11966 case OMPD_teams_distribute_simd:
11967 case OMPD_target_teams_distribute_simd:
11968 if (OpenMPVersion >= 50 &&
11969 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11970 CaptureRegion = OMPD_teams;
11971 break;
11972 case OMPD_cancel:
11973 case OMPD_parallel:
11974 case OMPD_parallel_master:
11975 case OMPD_parallel_sections:
11976 case OMPD_parallel_for:
11977 case OMPD_target:
11978 case OMPD_target_teams:
11979 case OMPD_target_teams_distribute:
11980 case OMPD_distribute_parallel_for:
11981 case OMPD_task:
11982 case OMPD_taskloop:
11983 case OMPD_master_taskloop:
11984 case OMPD_target_data:
11985 case OMPD_simd:
11986 case OMPD_for_simd:
11987 case OMPD_distribute_simd:
11988 // Do not capture if-clause expressions.
11989 break;
11990 case OMPD_threadprivate:
11991 case OMPD_allocate:
11992 case OMPD_taskyield:
11993 case OMPD_barrier:
11994 case OMPD_taskwait:
11995 case OMPD_cancellation_point:
11996 case OMPD_flush:
11997 case OMPD_depobj:
11998 case OMPD_scan:
11999 case OMPD_declare_reduction:
12000 case OMPD_declare_mapper:
12001 case OMPD_declare_simd:
12002 case OMPD_declare_variant:
12003 case OMPD_begin_declare_variant:
12004 case OMPD_end_declare_variant:
12005 case OMPD_declare_target:
12006 case OMPD_end_declare_target:
12007 case OMPD_teams:
12008 case OMPD_for:
12009 case OMPD_sections:
12010 case OMPD_section:
12011 case OMPD_single:
12012 case OMPD_master:
12013 case OMPD_critical:
12014 case OMPD_taskgroup:
12015 case OMPD_distribute:
12016 case OMPD_ordered:
12017 case OMPD_atomic:
12018 case OMPD_teams_distribute:
12019 case OMPD_requires:
12020 llvm_unreachable("Unexpected OpenMP directive with if-clause");
12021 case OMPD_unknown:
12022 default:
12023 llvm_unreachable("Unknown OpenMP directive");
12024 }
12025 break;
12026 case OMPC_num_threads:
12027 switch (DKind) {
12028 case OMPD_target_parallel:
12029 case OMPD_target_parallel_for:
12030 case OMPD_target_parallel_for_simd:
12031 CaptureRegion = OMPD_target;
12032 break;
12033 case OMPD_teams_distribute_parallel_for:
12034 case OMPD_teams_distribute_parallel_for_simd:
12035 case OMPD_target_teams_distribute_parallel_for:
12036 case OMPD_target_teams_distribute_parallel_for_simd:
12037 CaptureRegion = OMPD_teams;
12038 break;
12039 case OMPD_parallel:
12040 case OMPD_parallel_master:
12041 case OMPD_parallel_sections:
12042 case OMPD_parallel_for:
12043 case OMPD_parallel_for_simd:
12044 case OMPD_distribute_parallel_for:
12045 case OMPD_distribute_parallel_for_simd:
12046 case OMPD_parallel_master_taskloop:
12047 case OMPD_parallel_master_taskloop_simd:
12048 // Do not capture num_threads-clause expressions.
12049 break;
12050 case OMPD_target_data:
12051 case OMPD_target_enter_data:
12052 case OMPD_target_exit_data:
12053 case OMPD_target_update:
12054 case OMPD_target:
12055 case OMPD_target_simd:
12056 case OMPD_target_teams:
12057 case OMPD_target_teams_distribute:
12058 case OMPD_target_teams_distribute_simd:
12059 case OMPD_cancel:
12060 case OMPD_task:
12061 case OMPD_taskloop:
12062 case OMPD_taskloop_simd:
12063 case OMPD_master_taskloop:
12064 case OMPD_master_taskloop_simd:
12065 case OMPD_threadprivate:
12066 case OMPD_allocate:
12067 case OMPD_taskyield:
12068 case OMPD_barrier:
12069 case OMPD_taskwait:
12070 case OMPD_cancellation_point:
12071 case OMPD_flush:
12072 case OMPD_depobj:
12073 case OMPD_scan:
12074 case OMPD_declare_reduction:
12075 case OMPD_declare_mapper:
12076 case OMPD_declare_simd:
12077 case OMPD_declare_variant:
12078 case OMPD_begin_declare_variant:
12079 case OMPD_end_declare_variant:
12080 case OMPD_declare_target:
12081 case OMPD_end_declare_target:
12082 case OMPD_teams:
12083 case OMPD_simd:
12084 case OMPD_for:
12085 case OMPD_for_simd:
12086 case OMPD_sections:
12087 case OMPD_section:
12088 case OMPD_single:
12089 case OMPD_master:
12090 case OMPD_critical:
12091 case OMPD_taskgroup:
12092 case OMPD_distribute:
12093 case OMPD_ordered:
12094 case OMPD_atomic:
12095 case OMPD_distribute_simd:
12096 case OMPD_teams_distribute:
12097 case OMPD_teams_distribute_simd:
12098 case OMPD_requires:
12099 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
12100 case OMPD_unknown:
12101 default:
12102 llvm_unreachable("Unknown OpenMP directive");
12103 }
12104 break;
12105 case OMPC_num_teams:
12106 switch (DKind) {
12107 case OMPD_target_teams:
12108 case OMPD_target_teams_distribute:
12109 case OMPD_target_teams_distribute_simd:
12110 case OMPD_target_teams_distribute_parallel_for:
12111 case OMPD_target_teams_distribute_parallel_for_simd:
12112 CaptureRegion = OMPD_target;
12113 break;
12114 case OMPD_teams_distribute_parallel_for:
12115 case OMPD_teams_distribute_parallel_for_simd:
12116 case OMPD_teams:
12117 case OMPD_teams_distribute:
12118 case OMPD_teams_distribute_simd:
12119 // Do not capture num_teams-clause expressions.
12120 break;
12121 case OMPD_distribute_parallel_for:
12122 case OMPD_distribute_parallel_for_simd:
12123 case OMPD_task:
12124 case OMPD_taskloop:
12125 case OMPD_taskloop_simd:
12126 case OMPD_master_taskloop:
12127 case OMPD_master_taskloop_simd:
12128 case OMPD_parallel_master_taskloop:
12129 case OMPD_parallel_master_taskloop_simd:
12130 case OMPD_target_data:
12131 case OMPD_target_enter_data:
12132 case OMPD_target_exit_data:
12133 case OMPD_target_update:
12134 case OMPD_cancel:
12135 case OMPD_parallel:
12136 case OMPD_parallel_master:
12137 case OMPD_parallel_sections:
12138 case OMPD_parallel_for:
12139 case OMPD_parallel_for_simd:
12140 case OMPD_target:
12141 case OMPD_target_simd:
12142 case OMPD_target_parallel:
12143 case OMPD_target_parallel_for:
12144 case OMPD_target_parallel_for_simd:
12145 case OMPD_threadprivate:
12146 case OMPD_allocate:
12147 case OMPD_taskyield:
12148 case OMPD_barrier:
12149 case OMPD_taskwait:
12150 case OMPD_cancellation_point:
12151 case OMPD_flush:
12152 case OMPD_depobj:
12153 case OMPD_scan:
12154 case OMPD_declare_reduction:
12155 case OMPD_declare_mapper:
12156 case OMPD_declare_simd:
12157 case OMPD_declare_variant:
12158 case OMPD_begin_declare_variant:
12159 case OMPD_end_declare_variant:
12160 case OMPD_declare_target:
12161 case OMPD_end_declare_target:
12162 case OMPD_simd:
12163 case OMPD_for:
12164 case OMPD_for_simd:
12165 case OMPD_sections:
12166 case OMPD_section:
12167 case OMPD_single:
12168 case OMPD_master:
12169 case OMPD_critical:
12170 case OMPD_taskgroup:
12171 case OMPD_distribute:
12172 case OMPD_ordered:
12173 case OMPD_atomic:
12174 case OMPD_distribute_simd:
12175 case OMPD_requires:
12176 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12177 case OMPD_unknown:
12178 default:
12179 llvm_unreachable("Unknown OpenMP directive");
12180 }
12181 break;
12182 case OMPC_thread_limit:
12183 switch (DKind) {
12184 case OMPD_target_teams:
12185 case OMPD_target_teams_distribute:
12186 case OMPD_target_teams_distribute_simd:
12187 case OMPD_target_teams_distribute_parallel_for:
12188 case OMPD_target_teams_distribute_parallel_for_simd:
12189 CaptureRegion = OMPD_target;
12190 break;
12191 case OMPD_teams_distribute_parallel_for:
12192 case OMPD_teams_distribute_parallel_for_simd:
12193 case OMPD_teams:
12194 case OMPD_teams_distribute:
12195 case OMPD_teams_distribute_simd:
12196 // Do not capture thread_limit-clause expressions.
12197 break;
12198 case OMPD_distribute_parallel_for:
12199 case OMPD_distribute_parallel_for_simd:
12200 case OMPD_task:
12201 case OMPD_taskloop:
12202 case OMPD_taskloop_simd:
12203 case OMPD_master_taskloop:
12204 case OMPD_master_taskloop_simd:
12205 case OMPD_parallel_master_taskloop:
12206 case OMPD_parallel_master_taskloop_simd:
12207 case OMPD_target_data:
12208 case OMPD_target_enter_data:
12209 case OMPD_target_exit_data:
12210 case OMPD_target_update:
12211 case OMPD_cancel:
12212 case OMPD_parallel:
12213 case OMPD_parallel_master:
12214 case OMPD_parallel_sections:
12215 case OMPD_parallel_for:
12216 case OMPD_parallel_for_simd:
12217 case OMPD_target:
12218 case OMPD_target_simd:
12219 case OMPD_target_parallel:
12220 case OMPD_target_parallel_for:
12221 case OMPD_target_parallel_for_simd:
12222 case OMPD_threadprivate:
12223 case OMPD_allocate:
12224 case OMPD_taskyield:
12225 case OMPD_barrier:
12226 case OMPD_taskwait:
12227 case OMPD_cancellation_point:
12228 case OMPD_flush:
12229 case OMPD_depobj:
12230 case OMPD_scan:
12231 case OMPD_declare_reduction:
12232 case OMPD_declare_mapper:
12233 case OMPD_declare_simd:
12234 case OMPD_declare_variant:
12235 case OMPD_begin_declare_variant:
12236 case OMPD_end_declare_variant:
12237 case OMPD_declare_target:
12238 case OMPD_end_declare_target:
12239 case OMPD_simd:
12240 case OMPD_for:
12241 case OMPD_for_simd:
12242 case OMPD_sections:
12243 case OMPD_section:
12244 case OMPD_single:
12245 case OMPD_master:
12246 case OMPD_critical:
12247 case OMPD_taskgroup:
12248 case OMPD_distribute:
12249 case OMPD_ordered:
12250 case OMPD_atomic:
12251 case OMPD_distribute_simd:
12252 case OMPD_requires:
12253 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
12254 case OMPD_unknown:
12255 default:
12256 llvm_unreachable("Unknown OpenMP directive");
12257 }
12258 break;
12259 case OMPC_schedule:
12260 switch (DKind) {
12261 case OMPD_parallel_for:
12262 case OMPD_parallel_for_simd:
12263 case OMPD_distribute_parallel_for:
12264 case OMPD_distribute_parallel_for_simd:
12265 case OMPD_teams_distribute_parallel_for:
12266 case OMPD_teams_distribute_parallel_for_simd:
12267 case OMPD_target_parallel_for:
12268 case OMPD_target_parallel_for_simd:
12269 case OMPD_target_teams_distribute_parallel_for:
12270 case OMPD_target_teams_distribute_parallel_for_simd:
12271 CaptureRegion = OMPD_parallel;
12272 break;
12273 case OMPD_for:
12274 case OMPD_for_simd:
12275 // Do not capture schedule-clause expressions.
12276 break;
12277 case OMPD_task:
12278 case OMPD_taskloop:
12279 case OMPD_taskloop_simd:
12280 case OMPD_master_taskloop:
12281 case OMPD_master_taskloop_simd:
12282 case OMPD_parallel_master_taskloop:
12283 case OMPD_parallel_master_taskloop_simd:
12284 case OMPD_target_data:
12285 case OMPD_target_enter_data:
12286 case OMPD_target_exit_data:
12287 case OMPD_target_update:
12288 case OMPD_teams:
12289 case OMPD_teams_distribute:
12290 case OMPD_teams_distribute_simd:
12291 case OMPD_target_teams_distribute:
12292 case OMPD_target_teams_distribute_simd:
12293 case OMPD_target:
12294 case OMPD_target_simd:
12295 case OMPD_target_parallel:
12296 case OMPD_cancel:
12297 case OMPD_parallel:
12298 case OMPD_parallel_master:
12299 case OMPD_parallel_sections:
12300 case OMPD_threadprivate:
12301 case OMPD_allocate:
12302 case OMPD_taskyield:
12303 case OMPD_barrier:
12304 case OMPD_taskwait:
12305 case OMPD_cancellation_point:
12306 case OMPD_flush:
12307 case OMPD_depobj:
12308 case OMPD_scan:
12309 case OMPD_declare_reduction:
12310 case OMPD_declare_mapper:
12311 case OMPD_declare_simd:
12312 case OMPD_declare_variant:
12313 case OMPD_begin_declare_variant:
12314 case OMPD_end_declare_variant:
12315 case OMPD_declare_target:
12316 case OMPD_end_declare_target:
12317 case OMPD_simd:
12318 case OMPD_sections:
12319 case OMPD_section:
12320 case OMPD_single:
12321 case OMPD_master:
12322 case OMPD_critical:
12323 case OMPD_taskgroup:
12324 case OMPD_distribute:
12325 case OMPD_ordered:
12326 case OMPD_atomic:
12327 case OMPD_distribute_simd:
12328 case OMPD_target_teams:
12329 case OMPD_requires:
12330 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12331 case OMPD_unknown:
12332 default:
12333 llvm_unreachable("Unknown OpenMP directive");
12334 }
12335 break;
12336 case OMPC_dist_schedule:
12337 switch (DKind) {
12338 case OMPD_teams_distribute_parallel_for:
12339 case OMPD_teams_distribute_parallel_for_simd:
12340 case OMPD_teams_distribute:
12341 case OMPD_teams_distribute_simd:
12342 case OMPD_target_teams_distribute_parallel_for:
12343 case OMPD_target_teams_distribute_parallel_for_simd:
12344 case OMPD_target_teams_distribute:
12345 case OMPD_target_teams_distribute_simd:
12346 CaptureRegion = OMPD_teams;
12347 break;
12348 case OMPD_distribute_parallel_for:
12349 case OMPD_distribute_parallel_for_simd:
12350 case OMPD_distribute:
12351 case OMPD_distribute_simd:
12352 // Do not capture thread_limit-clause expressions.
12353 break;
12354 case OMPD_parallel_for:
12355 case OMPD_parallel_for_simd:
12356 case OMPD_target_parallel_for_simd:
12357 case OMPD_target_parallel_for:
12358 case OMPD_task:
12359 case OMPD_taskloop:
12360 case OMPD_taskloop_simd:
12361 case OMPD_master_taskloop:
12362 case OMPD_master_taskloop_simd:
12363 case OMPD_parallel_master_taskloop:
12364 case OMPD_parallel_master_taskloop_simd:
12365 case OMPD_target_data:
12366 case OMPD_target_enter_data:
12367 case OMPD_target_exit_data:
12368 case OMPD_target_update:
12369 case OMPD_teams:
12370 case OMPD_target:
12371 case OMPD_target_simd:
12372 case OMPD_target_parallel:
12373 case OMPD_cancel:
12374 case OMPD_parallel:
12375 case OMPD_parallel_master:
12376 case OMPD_parallel_sections:
12377 case OMPD_threadprivate:
12378 case OMPD_allocate:
12379 case OMPD_taskyield:
12380 case OMPD_barrier:
12381 case OMPD_taskwait:
12382 case OMPD_cancellation_point:
12383 case OMPD_flush:
12384 case OMPD_depobj:
12385 case OMPD_scan:
12386 case OMPD_declare_reduction:
12387 case OMPD_declare_mapper:
12388 case OMPD_declare_simd:
12389 case OMPD_declare_variant:
12390 case OMPD_begin_declare_variant:
12391 case OMPD_end_declare_variant:
12392 case OMPD_declare_target:
12393 case OMPD_end_declare_target:
12394 case OMPD_simd:
12395 case OMPD_for:
12396 case OMPD_for_simd:
12397 case OMPD_sections:
12398 case OMPD_section:
12399 case OMPD_single:
12400 case OMPD_master:
12401 case OMPD_critical:
12402 case OMPD_taskgroup:
12403 case OMPD_ordered:
12404 case OMPD_atomic:
12405 case OMPD_target_teams:
12406 case OMPD_requires:
12407 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12408 case OMPD_unknown:
12409 default:
12410 llvm_unreachable("Unknown OpenMP directive");
12411 }
12412 break;
12413 case OMPC_device:
12414 switch (DKind) {
12415 case OMPD_target_update:
12416 case OMPD_target_enter_data:
12417 case OMPD_target_exit_data:
12418 case OMPD_target:
12419 case OMPD_target_simd:
12420 case OMPD_target_teams:
12421 case OMPD_target_parallel:
12422 case OMPD_target_teams_distribute:
12423 case OMPD_target_teams_distribute_simd:
12424 case OMPD_target_parallel_for:
12425 case OMPD_target_parallel_for_simd:
12426 case OMPD_target_teams_distribute_parallel_for:
12427 case OMPD_target_teams_distribute_parallel_for_simd:
12428 CaptureRegion = OMPD_task;
12429 break;
12430 case OMPD_target_data:
12431 // Do not capture device-clause expressions.
12432 break;
12433 case OMPD_teams_distribute_parallel_for:
12434 case OMPD_teams_distribute_parallel_for_simd:
12435 case OMPD_teams:
12436 case OMPD_teams_distribute:
12437 case OMPD_teams_distribute_simd:
12438 case OMPD_distribute_parallel_for:
12439 case OMPD_distribute_parallel_for_simd:
12440 case OMPD_task:
12441 case OMPD_taskloop:
12442 case OMPD_taskloop_simd:
12443 case OMPD_master_taskloop:
12444 case OMPD_master_taskloop_simd:
12445 case OMPD_parallel_master_taskloop:
12446 case OMPD_parallel_master_taskloop_simd:
12447 case OMPD_cancel:
12448 case OMPD_parallel:
12449 case OMPD_parallel_master:
12450 case OMPD_parallel_sections:
12451 case OMPD_parallel_for:
12452 case OMPD_parallel_for_simd:
12453 case OMPD_threadprivate:
12454 case OMPD_allocate:
12455 case OMPD_taskyield:
12456 case OMPD_barrier:
12457 case OMPD_taskwait:
12458 case OMPD_cancellation_point:
12459 case OMPD_flush:
12460 case OMPD_depobj:
12461 case OMPD_scan:
12462 case OMPD_declare_reduction:
12463 case OMPD_declare_mapper:
12464 case OMPD_declare_simd:
12465 case OMPD_declare_variant:
12466 case OMPD_begin_declare_variant:
12467 case OMPD_end_declare_variant:
12468 case OMPD_declare_target:
12469 case OMPD_end_declare_target:
12470 case OMPD_simd:
12471 case OMPD_for:
12472 case OMPD_for_simd:
12473 case OMPD_sections:
12474 case OMPD_section:
12475 case OMPD_single:
12476 case OMPD_master:
12477 case OMPD_critical:
12478 case OMPD_taskgroup:
12479 case OMPD_distribute:
12480 case OMPD_ordered:
12481 case OMPD_atomic:
12482 case OMPD_distribute_simd:
12483 case OMPD_requires:
12484 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12485 case OMPD_unknown:
12486 default:
12487 llvm_unreachable("Unknown OpenMP directive");
12488 }
12489 break;
12490 case OMPC_grainsize:
12491 case OMPC_num_tasks:
12492 case OMPC_final:
12493 case OMPC_priority:
12494 switch (DKind) {
12495 case OMPD_task:
12496 case OMPD_taskloop:
12497 case OMPD_taskloop_simd:
12498 case OMPD_master_taskloop:
12499 case OMPD_master_taskloop_simd:
12500 break;
12501 case OMPD_parallel_master_taskloop:
12502 case OMPD_parallel_master_taskloop_simd:
12503 CaptureRegion = OMPD_parallel;
12504 break;
12505 case OMPD_target_update:
12506 case OMPD_target_enter_data:
12507 case OMPD_target_exit_data:
12508 case OMPD_target:
12509 case OMPD_target_simd:
12510 case OMPD_target_teams:
12511 case OMPD_target_parallel:
12512 case OMPD_target_teams_distribute:
12513 case OMPD_target_teams_distribute_simd:
12514 case OMPD_target_parallel_for:
12515 case OMPD_target_parallel_for_simd:
12516 case OMPD_target_teams_distribute_parallel_for:
12517 case OMPD_target_teams_distribute_parallel_for_simd:
12518 case OMPD_target_data:
12519 case OMPD_teams_distribute_parallel_for:
12520 case OMPD_teams_distribute_parallel_for_simd:
12521 case OMPD_teams:
12522 case OMPD_teams_distribute:
12523 case OMPD_teams_distribute_simd:
12524 case OMPD_distribute_parallel_for:
12525 case OMPD_distribute_parallel_for_simd:
12526 case OMPD_cancel:
12527 case OMPD_parallel:
12528 case OMPD_parallel_master:
12529 case OMPD_parallel_sections:
12530 case OMPD_parallel_for:
12531 case OMPD_parallel_for_simd:
12532 case OMPD_threadprivate:
12533 case OMPD_allocate:
12534 case OMPD_taskyield:
12535 case OMPD_barrier:
12536 case OMPD_taskwait:
12537 case OMPD_cancellation_point:
12538 case OMPD_flush:
12539 case OMPD_depobj:
12540 case OMPD_scan:
12541 case OMPD_declare_reduction:
12542 case OMPD_declare_mapper:
12543 case OMPD_declare_simd:
12544 case OMPD_declare_variant:
12545 case OMPD_begin_declare_variant:
12546 case OMPD_end_declare_variant:
12547 case OMPD_declare_target:
12548 case OMPD_end_declare_target:
12549 case OMPD_simd:
12550 case OMPD_for:
12551 case OMPD_for_simd:
12552 case OMPD_sections:
12553 case OMPD_section:
12554 case OMPD_single:
12555 case OMPD_master:
12556 case OMPD_critical:
12557 case OMPD_taskgroup:
12558 case OMPD_distribute:
12559 case OMPD_ordered:
12560 case OMPD_atomic:
12561 case OMPD_distribute_simd:
12562 case OMPD_requires:
12563 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
12564 case OMPD_unknown:
12565 default:
12566 llvm_unreachable("Unknown OpenMP directive");
12567 }
12568 break;
12569 case OMPC_firstprivate:
12570 case OMPC_lastprivate:
12571 case OMPC_reduction:
12572 case OMPC_task_reduction:
12573 case OMPC_in_reduction:
12574 case OMPC_linear:
12575 case OMPC_default:
12576 case OMPC_proc_bind:
12577 case OMPC_safelen:
12578 case OMPC_simdlen:
12579 case OMPC_allocator:
12580 case OMPC_collapse:
12581 case OMPC_private:
12582 case OMPC_shared:
12583 case OMPC_aligned:
12584 case OMPC_copyin:
12585 case OMPC_copyprivate:
12586 case OMPC_ordered:
12587 case OMPC_nowait:
12588 case OMPC_untied:
12589 case OMPC_mergeable:
12590 case OMPC_threadprivate:
12591 case OMPC_allocate:
12592 case OMPC_flush:
12593 case OMPC_depobj:
12594 case OMPC_read:
12595 case OMPC_write:
12596 case OMPC_update:
12597 case OMPC_capture:
12598 case OMPC_seq_cst:
12599 case OMPC_acq_rel:
12600 case OMPC_acquire:
12601 case OMPC_release:
12602 case OMPC_relaxed:
12603 case OMPC_depend:
12604 case OMPC_threads:
12605 case OMPC_simd:
12606 case OMPC_map:
12607 case OMPC_nogroup:
12608 case OMPC_hint:
12609 case OMPC_defaultmap:
12610 case OMPC_unknown:
12611 case OMPC_uniform:
12612 case OMPC_to:
12613 case OMPC_from:
12614 case OMPC_use_device_ptr:
12615 case OMPC_use_device_addr:
12616 case OMPC_is_device_ptr:
12617 case OMPC_unified_address:
12618 case OMPC_unified_shared_memory:
12619 case OMPC_reverse_offload:
12620 case OMPC_dynamic_allocators:
12621 case OMPC_atomic_default_mem_order:
12622 case OMPC_device_type:
12623 case OMPC_match:
12624 case OMPC_nontemporal:
12625 case OMPC_order:
12626 case OMPC_destroy:
12627 case OMPC_detach:
12628 case OMPC_inclusive:
12629 case OMPC_exclusive:
12630 case OMPC_uses_allocators:
12631 case OMPC_affinity:
12632 default:
12633 llvm_unreachable("Unexpected OpenMP clause.");
12634 }
12635 return CaptureRegion;
12636 }
12637
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)12638 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12639 Expr *Condition, SourceLocation StartLoc,
12640 SourceLocation LParenLoc,
12641 SourceLocation NameModifierLoc,
12642 SourceLocation ColonLoc,
12643 SourceLocation EndLoc) {
12644 Expr *ValExpr = Condition;
12645 Stmt *HelperValStmt = nullptr;
12646 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12647 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12648 !Condition->isInstantiationDependent() &&
12649 !Condition->containsUnexpandedParameterPack()) {
12650 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12651 if (Val.isInvalid())
12652 return nullptr;
12653
12654 ValExpr = Val.get();
12655
12656 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12657 CaptureRegion = getOpenMPCaptureRegionForClause(
12658 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12659 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12660 ValExpr = MakeFullExpr(ValExpr).get();
12661 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12662 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12663 HelperValStmt = buildPreInits(Context, Captures);
12664 }
12665 }
12666
12667 return new (Context)
12668 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12669 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12670 }
12671
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12672 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12673 SourceLocation StartLoc,
12674 SourceLocation LParenLoc,
12675 SourceLocation EndLoc) {
12676 Expr *ValExpr = Condition;
12677 Stmt *HelperValStmt = nullptr;
12678 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12679 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12680 !Condition->isInstantiationDependent() &&
12681 !Condition->containsUnexpandedParameterPack()) {
12682 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12683 if (Val.isInvalid())
12684 return nullptr;
12685
12686 ValExpr = MakeFullExpr(Val.get()).get();
12687
12688 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12689 CaptureRegion =
12690 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12691 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12692 ValExpr = MakeFullExpr(ValExpr).get();
12693 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12694 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12695 HelperValStmt = buildPreInits(Context, Captures);
12696 }
12697 }
12698
12699 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12700 StartLoc, LParenLoc, EndLoc);
12701 }
12702
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)12703 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12704 Expr *Op) {
12705 if (!Op)
12706 return ExprError();
12707
12708 class IntConvertDiagnoser : public ICEConvertDiagnoser {
12709 public:
12710 IntConvertDiagnoser()
12711 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12712 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12713 QualType T) override {
12714 return S.Diag(Loc, diag::err_omp_not_integral) << T;
12715 }
12716 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12717 QualType T) override {
12718 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12719 }
12720 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12721 QualType T,
12722 QualType ConvTy) override {
12723 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12724 }
12725 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12726 QualType ConvTy) override {
12727 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12728 << ConvTy->isEnumeralType() << ConvTy;
12729 }
12730 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12731 QualType T) override {
12732 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12733 }
12734 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12735 QualType ConvTy) override {
12736 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12737 << ConvTy->isEnumeralType() << ConvTy;
12738 }
12739 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12740 QualType) override {
12741 llvm_unreachable("conversion functions are permitted");
12742 }
12743 } ConvertDiagnoser;
12744 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12745 }
12746
12747 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)12748 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12749 bool StrictlyPositive, bool BuildCapture = false,
12750 OpenMPDirectiveKind DKind = OMPD_unknown,
12751 OpenMPDirectiveKind *CaptureRegion = nullptr,
12752 Stmt **HelperValStmt = nullptr) {
12753 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12754 !ValExpr->isInstantiationDependent()) {
12755 SourceLocation Loc = ValExpr->getExprLoc();
12756 ExprResult Value =
12757 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12758 if (Value.isInvalid())
12759 return false;
12760
12761 ValExpr = Value.get();
12762 // The expression must evaluate to a non-negative integer value.
12763 if (Optional<llvm::APSInt> Result =
12764 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
12765 if (Result->isSigned() &&
12766 !((!StrictlyPositive && Result->isNonNegative()) ||
12767 (StrictlyPositive && Result->isStrictlyPositive()))) {
12768 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12769 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12770 << ValExpr->getSourceRange();
12771 return false;
12772 }
12773 }
12774 if (!BuildCapture)
12775 return true;
12776 *CaptureRegion =
12777 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12778 if (*CaptureRegion != OMPD_unknown &&
12779 !SemaRef.CurContext->isDependentContext()) {
12780 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12781 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12782 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12783 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12784 }
12785 }
12786 return true;
12787 }
12788
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12789 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12790 SourceLocation StartLoc,
12791 SourceLocation LParenLoc,
12792 SourceLocation EndLoc) {
12793 Expr *ValExpr = NumThreads;
12794 Stmt *HelperValStmt = nullptr;
12795
12796 // OpenMP [2.5, Restrictions]
12797 // The num_threads expression must evaluate to a positive integer value.
12798 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12799 /*StrictlyPositive=*/true))
12800 return nullptr;
12801
12802 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12803 OpenMPDirectiveKind CaptureRegion =
12804 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12805 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12806 ValExpr = MakeFullExpr(ValExpr).get();
12807 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12808 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12809 HelperValStmt = buildPreInits(Context, Captures);
12810 }
12811
12812 return new (Context) OMPNumThreadsClause(
12813 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12814 }
12815
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive)12816 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12817 OpenMPClauseKind CKind,
12818 bool StrictlyPositive) {
12819 if (!E)
12820 return ExprError();
12821 if (E->isValueDependent() || E->isTypeDependent() ||
12822 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12823 return E;
12824 llvm::APSInt Result;
12825 ExprResult ICE =
12826 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
12827 if (ICE.isInvalid())
12828 return ExprError();
12829 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12830 (!StrictlyPositive && !Result.isNonNegative())) {
12831 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12832 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12833 << E->getSourceRange();
12834 return ExprError();
12835 }
12836 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12837 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12838 << E->getSourceRange();
12839 return ExprError();
12840 }
12841 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
12842 DSAStack->setAssociatedLoops(Result.getExtValue());
12843 else if (CKind == OMPC_ordered)
12844 DSAStack->setAssociatedLoops(Result.getExtValue());
12845 return ICE;
12846 }
12847
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12848 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12849 SourceLocation LParenLoc,
12850 SourceLocation EndLoc) {
12851 // OpenMP [2.8.1, simd construct, Description]
12852 // The parameter of the safelen clause must be a constant
12853 // positive integer expression.
12854 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12855 if (Safelen.isInvalid())
12856 return nullptr;
12857 return new (Context)
12858 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
12859 }
12860
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12861 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
12862 SourceLocation LParenLoc,
12863 SourceLocation EndLoc) {
12864 // OpenMP [2.8.1, simd construct, Description]
12865 // The parameter of the simdlen clause must be a constant
12866 // positive integer expression.
12867 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
12868 if (Simdlen.isInvalid())
12869 return nullptr;
12870 return new (Context)
12871 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
12872 }
12873
12874 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)12875 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
12876 DSAStackTy *Stack) {
12877 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
12878 if (!OMPAllocatorHandleT.isNull())
12879 return true;
12880 // Build the predefined allocator expressions.
12881 bool ErrorFound = false;
12882 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
12883 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
12884 StringRef Allocator =
12885 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
12886 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
12887 auto *VD = dyn_cast_or_null<ValueDecl>(
12888 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
12889 if (!VD) {
12890 ErrorFound = true;
12891 break;
12892 }
12893 QualType AllocatorType =
12894 VD->getType().getNonLValueExprType(S.getASTContext());
12895 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
12896 if (!Res.isUsable()) {
12897 ErrorFound = true;
12898 break;
12899 }
12900 if (OMPAllocatorHandleT.isNull())
12901 OMPAllocatorHandleT = AllocatorType;
12902 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
12903 ErrorFound = true;
12904 break;
12905 }
12906 Stack->setAllocator(AllocatorKind, Res.get());
12907 }
12908 if (ErrorFound) {
12909 S.Diag(Loc, diag::err_omp_implied_type_not_found)
12910 << "omp_allocator_handle_t";
12911 return false;
12912 }
12913 OMPAllocatorHandleT.addConst();
12914 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
12915 return true;
12916 }
12917
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12918 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
12919 SourceLocation LParenLoc,
12920 SourceLocation EndLoc) {
12921 // OpenMP [2.11.3, allocate Directive, Description]
12922 // allocator is an expression of omp_allocator_handle_t type.
12923 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
12924 return nullptr;
12925
12926 ExprResult Allocator = DefaultLvalueConversion(A);
12927 if (Allocator.isInvalid())
12928 return nullptr;
12929 Allocator = PerformImplicitConversion(Allocator.get(),
12930 DSAStack->getOMPAllocatorHandleT(),
12931 Sema::AA_Initializing,
12932 /*AllowExplicit=*/true);
12933 if (Allocator.isInvalid())
12934 return nullptr;
12935 return new (Context)
12936 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
12937 }
12938
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12939 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
12940 SourceLocation StartLoc,
12941 SourceLocation LParenLoc,
12942 SourceLocation EndLoc) {
12943 // OpenMP [2.7.1, loop construct, Description]
12944 // OpenMP [2.8.1, simd construct, Description]
12945 // OpenMP [2.9.6, distribute construct, Description]
12946 // The parameter of the collapse clause must be a constant
12947 // positive integer expression.
12948 ExprResult NumForLoopsResult =
12949 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
12950 if (NumForLoopsResult.isInvalid())
12951 return nullptr;
12952 return new (Context)
12953 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
12954 }
12955
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)12956 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
12957 SourceLocation EndLoc,
12958 SourceLocation LParenLoc,
12959 Expr *NumForLoops) {
12960 // OpenMP [2.7.1, loop construct, Description]
12961 // OpenMP [2.8.1, simd construct, Description]
12962 // OpenMP [2.9.6, distribute construct, Description]
12963 // The parameter of the ordered clause must be a constant
12964 // positive integer expression if any.
12965 if (NumForLoops && LParenLoc.isValid()) {
12966 ExprResult NumForLoopsResult =
12967 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
12968 if (NumForLoopsResult.isInvalid())
12969 return nullptr;
12970 NumForLoops = NumForLoopsResult.get();
12971 } else {
12972 NumForLoops = nullptr;
12973 }
12974 auto *Clause = OMPOrderedClause::Create(
12975 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
12976 StartLoc, LParenLoc, EndLoc);
12977 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
12978 return Clause;
12979 }
12980
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12981 OMPClause *Sema::ActOnOpenMPSimpleClause(
12982 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
12983 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12984 OMPClause *Res = nullptr;
12985 switch (Kind) {
12986 case OMPC_default:
12987 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
12988 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12989 break;
12990 case OMPC_proc_bind:
12991 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
12992 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12993 break;
12994 case OMPC_atomic_default_mem_order:
12995 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
12996 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
12997 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12998 break;
12999 case OMPC_order:
13000 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
13001 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13002 break;
13003 case OMPC_update:
13004 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
13005 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13006 break;
13007 case OMPC_if:
13008 case OMPC_final:
13009 case OMPC_num_threads:
13010 case OMPC_safelen:
13011 case OMPC_simdlen:
13012 case OMPC_allocator:
13013 case OMPC_collapse:
13014 case OMPC_schedule:
13015 case OMPC_private:
13016 case OMPC_firstprivate:
13017 case OMPC_lastprivate:
13018 case OMPC_shared:
13019 case OMPC_reduction:
13020 case OMPC_task_reduction:
13021 case OMPC_in_reduction:
13022 case OMPC_linear:
13023 case OMPC_aligned:
13024 case OMPC_copyin:
13025 case OMPC_copyprivate:
13026 case OMPC_ordered:
13027 case OMPC_nowait:
13028 case OMPC_untied:
13029 case OMPC_mergeable:
13030 case OMPC_threadprivate:
13031 case OMPC_allocate:
13032 case OMPC_flush:
13033 case OMPC_depobj:
13034 case OMPC_read:
13035 case OMPC_write:
13036 case OMPC_capture:
13037 case OMPC_seq_cst:
13038 case OMPC_acq_rel:
13039 case OMPC_acquire:
13040 case OMPC_release:
13041 case OMPC_relaxed:
13042 case OMPC_depend:
13043 case OMPC_device:
13044 case OMPC_threads:
13045 case OMPC_simd:
13046 case OMPC_map:
13047 case OMPC_num_teams:
13048 case OMPC_thread_limit:
13049 case OMPC_priority:
13050 case OMPC_grainsize:
13051 case OMPC_nogroup:
13052 case OMPC_num_tasks:
13053 case OMPC_hint:
13054 case OMPC_dist_schedule:
13055 case OMPC_defaultmap:
13056 case OMPC_unknown:
13057 case OMPC_uniform:
13058 case OMPC_to:
13059 case OMPC_from:
13060 case OMPC_use_device_ptr:
13061 case OMPC_use_device_addr:
13062 case OMPC_is_device_ptr:
13063 case OMPC_unified_address:
13064 case OMPC_unified_shared_memory:
13065 case OMPC_reverse_offload:
13066 case OMPC_dynamic_allocators:
13067 case OMPC_device_type:
13068 case OMPC_match:
13069 case OMPC_nontemporal:
13070 case OMPC_destroy:
13071 case OMPC_detach:
13072 case OMPC_inclusive:
13073 case OMPC_exclusive:
13074 case OMPC_uses_allocators:
13075 case OMPC_affinity:
13076 default:
13077 llvm_unreachable("Clause is not allowed.");
13078 }
13079 return Res;
13080 }
13081
13082 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)13083 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
13084 ArrayRef<unsigned> Exclude = llvm::None) {
13085 SmallString<256> Buffer;
13086 llvm::raw_svector_ostream Out(Buffer);
13087 unsigned Skipped = Exclude.size();
13088 auto S = Exclude.begin(), E = Exclude.end();
13089 for (unsigned I = First; I < Last; ++I) {
13090 if (std::find(S, E, I) != E) {
13091 --Skipped;
13092 continue;
13093 }
13094 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
13095 if (I + Skipped + 2 == Last)
13096 Out << " or ";
13097 else if (I + Skipped + 1 != Last)
13098 Out << ", ";
13099 }
13100 return std::string(Out.str());
13101 }
13102
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13103 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
13104 SourceLocation KindKwLoc,
13105 SourceLocation StartLoc,
13106 SourceLocation LParenLoc,
13107 SourceLocation EndLoc) {
13108 if (Kind == OMP_DEFAULT_unknown) {
13109 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13110 << getListOfPossibleValues(OMPC_default, /*First=*/0,
13111 /*Last=*/unsigned(OMP_DEFAULT_unknown))
13112 << getOpenMPClauseName(OMPC_default);
13113 return nullptr;
13114 }
13115
13116 switch (Kind) {
13117 case OMP_DEFAULT_none:
13118 DSAStack->setDefaultDSANone(KindKwLoc);
13119 break;
13120 case OMP_DEFAULT_shared:
13121 DSAStack->setDefaultDSAShared(KindKwLoc);
13122 break;
13123 case OMP_DEFAULT_firstprivate:
13124 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
13125 break;
13126 default:
13127 llvm_unreachable("DSA unexpected in OpenMP default clause");
13128 }
13129
13130 return new (Context)
13131 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13132 }
13133
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13134 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13135 SourceLocation KindKwLoc,
13136 SourceLocation StartLoc,
13137 SourceLocation LParenLoc,
13138 SourceLocation EndLoc) {
13139 if (Kind == OMP_PROC_BIND_unknown) {
13140 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13141 << getListOfPossibleValues(OMPC_proc_bind,
13142 /*First=*/unsigned(OMP_PROC_BIND_master),
13143 /*Last=*/5)
13144 << getOpenMPClauseName(OMPC_proc_bind);
13145 return nullptr;
13146 }
13147 return new (Context)
13148 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13149 }
13150
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13151 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13152 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13153 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13154 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13155 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13156 << getListOfPossibleValues(
13157 OMPC_atomic_default_mem_order, /*First=*/0,
13158 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13159 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13160 return nullptr;
13161 }
13162 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13163 LParenLoc, EndLoc);
13164 }
13165
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13166 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13167 SourceLocation KindKwLoc,
13168 SourceLocation StartLoc,
13169 SourceLocation LParenLoc,
13170 SourceLocation EndLoc) {
13171 if (Kind == OMPC_ORDER_unknown) {
13172 static_assert(OMPC_ORDER_unknown > 0,
13173 "OMPC_ORDER_unknown not greater than 0");
13174 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13175 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13176 /*Last=*/OMPC_ORDER_unknown)
13177 << getOpenMPClauseName(OMPC_order);
13178 return nullptr;
13179 }
13180 return new (Context)
13181 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13182 }
13183
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13184 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13185 SourceLocation KindKwLoc,
13186 SourceLocation StartLoc,
13187 SourceLocation LParenLoc,
13188 SourceLocation EndLoc) {
13189 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13190 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13191 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13192 OMPC_DEPEND_depobj};
13193 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13194 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13195 /*Last=*/OMPC_DEPEND_unknown, Except)
13196 << getOpenMPClauseName(OMPC_update);
13197 return nullptr;
13198 }
13199 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13200 EndLoc);
13201 }
13202
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)13203 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13204 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13205 SourceLocation StartLoc, SourceLocation LParenLoc,
13206 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13207 SourceLocation EndLoc) {
13208 OMPClause *Res = nullptr;
13209 switch (Kind) {
13210 case OMPC_schedule:
13211 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13212 assert(Argument.size() == NumberOfElements &&
13213 ArgumentLoc.size() == NumberOfElements);
13214 Res = ActOnOpenMPScheduleClause(
13215 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13216 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13217 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13218 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13219 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13220 break;
13221 case OMPC_if:
13222 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13223 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13224 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13225 DelimLoc, EndLoc);
13226 break;
13227 case OMPC_dist_schedule:
13228 Res = ActOnOpenMPDistScheduleClause(
13229 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13230 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13231 break;
13232 case OMPC_defaultmap:
13233 enum { Modifier, DefaultmapKind };
13234 Res = ActOnOpenMPDefaultmapClause(
13235 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13236 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13237 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13238 EndLoc);
13239 break;
13240 case OMPC_device:
13241 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13242 Res = ActOnOpenMPDeviceClause(
13243 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13244 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13245 break;
13246 case OMPC_final:
13247 case OMPC_num_threads:
13248 case OMPC_safelen:
13249 case OMPC_simdlen:
13250 case OMPC_allocator:
13251 case OMPC_collapse:
13252 case OMPC_default:
13253 case OMPC_proc_bind:
13254 case OMPC_private:
13255 case OMPC_firstprivate:
13256 case OMPC_lastprivate:
13257 case OMPC_shared:
13258 case OMPC_reduction:
13259 case OMPC_task_reduction:
13260 case OMPC_in_reduction:
13261 case OMPC_linear:
13262 case OMPC_aligned:
13263 case OMPC_copyin:
13264 case OMPC_copyprivate:
13265 case OMPC_ordered:
13266 case OMPC_nowait:
13267 case OMPC_untied:
13268 case OMPC_mergeable:
13269 case OMPC_threadprivate:
13270 case OMPC_allocate:
13271 case OMPC_flush:
13272 case OMPC_depobj:
13273 case OMPC_read:
13274 case OMPC_write:
13275 case OMPC_update:
13276 case OMPC_capture:
13277 case OMPC_seq_cst:
13278 case OMPC_acq_rel:
13279 case OMPC_acquire:
13280 case OMPC_release:
13281 case OMPC_relaxed:
13282 case OMPC_depend:
13283 case OMPC_threads:
13284 case OMPC_simd:
13285 case OMPC_map:
13286 case OMPC_num_teams:
13287 case OMPC_thread_limit:
13288 case OMPC_priority:
13289 case OMPC_grainsize:
13290 case OMPC_nogroup:
13291 case OMPC_num_tasks:
13292 case OMPC_hint:
13293 case OMPC_unknown:
13294 case OMPC_uniform:
13295 case OMPC_to:
13296 case OMPC_from:
13297 case OMPC_use_device_ptr:
13298 case OMPC_use_device_addr:
13299 case OMPC_is_device_ptr:
13300 case OMPC_unified_address:
13301 case OMPC_unified_shared_memory:
13302 case OMPC_reverse_offload:
13303 case OMPC_dynamic_allocators:
13304 case OMPC_atomic_default_mem_order:
13305 case OMPC_device_type:
13306 case OMPC_match:
13307 case OMPC_nontemporal:
13308 case OMPC_order:
13309 case OMPC_destroy:
13310 case OMPC_detach:
13311 case OMPC_inclusive:
13312 case OMPC_exclusive:
13313 case OMPC_uses_allocators:
13314 case OMPC_affinity:
13315 default:
13316 llvm_unreachable("Clause is not allowed.");
13317 }
13318 return Res;
13319 }
13320
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)13321 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13322 OpenMPScheduleClauseModifier M2,
13323 SourceLocation M1Loc, SourceLocation M2Loc) {
13324 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13325 SmallVector<unsigned, 2> Excluded;
13326 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13327 Excluded.push_back(M2);
13328 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13329 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13330 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13331 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13332 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13333 << getListOfPossibleValues(OMPC_schedule,
13334 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13335 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13336 Excluded)
13337 << getOpenMPClauseName(OMPC_schedule);
13338 return true;
13339 }
13340 return false;
13341 }
13342
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)13343 OMPClause *Sema::ActOnOpenMPScheduleClause(
13344 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13345 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13346 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13347 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13348 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13349 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13350 return nullptr;
13351 // OpenMP, 2.7.1, Loop Construct, Restrictions
13352 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13353 // but not both.
13354 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13355 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13356 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13357 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13358 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13359 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13360 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13361 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13362 return nullptr;
13363 }
13364 if (Kind == OMPC_SCHEDULE_unknown) {
13365 std::string Values;
13366 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13367 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13368 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13369 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13370 Exclude);
13371 } else {
13372 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13373 /*Last=*/OMPC_SCHEDULE_unknown);
13374 }
13375 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13376 << Values << getOpenMPClauseName(OMPC_schedule);
13377 return nullptr;
13378 }
13379 // OpenMP, 2.7.1, Loop Construct, Restrictions
13380 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13381 // schedule(guided).
13382 // OpenMP 5.0 does not have this restriction.
13383 if (LangOpts.OpenMP < 50 &&
13384 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13385 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13386 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13387 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13388 diag::err_omp_schedule_nonmonotonic_static);
13389 return nullptr;
13390 }
13391 Expr *ValExpr = ChunkSize;
13392 Stmt *HelperValStmt = nullptr;
13393 if (ChunkSize) {
13394 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13395 !ChunkSize->isInstantiationDependent() &&
13396 !ChunkSize->containsUnexpandedParameterPack()) {
13397 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13398 ExprResult Val =
13399 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13400 if (Val.isInvalid())
13401 return nullptr;
13402
13403 ValExpr = Val.get();
13404
13405 // OpenMP [2.7.1, Restrictions]
13406 // chunk_size must be a loop invariant integer expression with a positive
13407 // value.
13408 if (Optional<llvm::APSInt> Result =
13409 ValExpr->getIntegerConstantExpr(Context)) {
13410 if (Result->isSigned() && !Result->isStrictlyPositive()) {
13411 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13412 << "schedule" << 1 << ChunkSize->getSourceRange();
13413 return nullptr;
13414 }
13415 } else if (getOpenMPCaptureRegionForClause(
13416 DSAStack->getCurrentDirective(), OMPC_schedule,
13417 LangOpts.OpenMP) != OMPD_unknown &&
13418 !CurContext->isDependentContext()) {
13419 ValExpr = MakeFullExpr(ValExpr).get();
13420 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13421 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13422 HelperValStmt = buildPreInits(Context, Captures);
13423 }
13424 }
13425 }
13426
13427 return new (Context)
13428 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13429 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13430 }
13431
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)13432 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13433 SourceLocation StartLoc,
13434 SourceLocation EndLoc) {
13435 OMPClause *Res = nullptr;
13436 switch (Kind) {
13437 case OMPC_ordered:
13438 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13439 break;
13440 case OMPC_nowait:
13441 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13442 break;
13443 case OMPC_untied:
13444 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13445 break;
13446 case OMPC_mergeable:
13447 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13448 break;
13449 case OMPC_read:
13450 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13451 break;
13452 case OMPC_write:
13453 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13454 break;
13455 case OMPC_update:
13456 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13457 break;
13458 case OMPC_capture:
13459 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13460 break;
13461 case OMPC_seq_cst:
13462 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13463 break;
13464 case OMPC_acq_rel:
13465 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13466 break;
13467 case OMPC_acquire:
13468 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13469 break;
13470 case OMPC_release:
13471 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13472 break;
13473 case OMPC_relaxed:
13474 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13475 break;
13476 case OMPC_threads:
13477 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13478 break;
13479 case OMPC_simd:
13480 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13481 break;
13482 case OMPC_nogroup:
13483 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13484 break;
13485 case OMPC_unified_address:
13486 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13487 break;
13488 case OMPC_unified_shared_memory:
13489 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13490 break;
13491 case OMPC_reverse_offload:
13492 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13493 break;
13494 case OMPC_dynamic_allocators:
13495 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13496 break;
13497 case OMPC_destroy:
13498 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13499 break;
13500 case OMPC_if:
13501 case OMPC_final:
13502 case OMPC_num_threads:
13503 case OMPC_safelen:
13504 case OMPC_simdlen:
13505 case OMPC_allocator:
13506 case OMPC_collapse:
13507 case OMPC_schedule:
13508 case OMPC_private:
13509 case OMPC_firstprivate:
13510 case OMPC_lastprivate:
13511 case OMPC_shared:
13512 case OMPC_reduction:
13513 case OMPC_task_reduction:
13514 case OMPC_in_reduction:
13515 case OMPC_linear:
13516 case OMPC_aligned:
13517 case OMPC_copyin:
13518 case OMPC_copyprivate:
13519 case OMPC_default:
13520 case OMPC_proc_bind:
13521 case OMPC_threadprivate:
13522 case OMPC_allocate:
13523 case OMPC_flush:
13524 case OMPC_depobj:
13525 case OMPC_depend:
13526 case OMPC_device:
13527 case OMPC_map:
13528 case OMPC_num_teams:
13529 case OMPC_thread_limit:
13530 case OMPC_priority:
13531 case OMPC_grainsize:
13532 case OMPC_num_tasks:
13533 case OMPC_hint:
13534 case OMPC_dist_schedule:
13535 case OMPC_defaultmap:
13536 case OMPC_unknown:
13537 case OMPC_uniform:
13538 case OMPC_to:
13539 case OMPC_from:
13540 case OMPC_use_device_ptr:
13541 case OMPC_use_device_addr:
13542 case OMPC_is_device_ptr:
13543 case OMPC_atomic_default_mem_order:
13544 case OMPC_device_type:
13545 case OMPC_match:
13546 case OMPC_nontemporal:
13547 case OMPC_order:
13548 case OMPC_detach:
13549 case OMPC_inclusive:
13550 case OMPC_exclusive:
13551 case OMPC_uses_allocators:
13552 case OMPC_affinity:
13553 default:
13554 llvm_unreachable("Clause is not allowed.");
13555 }
13556 return Res;
13557 }
13558
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)13559 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13560 SourceLocation EndLoc) {
13561 DSAStack->setNowaitRegion();
13562 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13563 }
13564
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)13565 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13566 SourceLocation EndLoc) {
13567 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13568 }
13569
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)13570 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13571 SourceLocation EndLoc) {
13572 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13573 }
13574
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)13575 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13576 SourceLocation EndLoc) {
13577 return new (Context) OMPReadClause(StartLoc, EndLoc);
13578 }
13579
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)13580 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13581 SourceLocation EndLoc) {
13582 return new (Context) OMPWriteClause(StartLoc, EndLoc);
13583 }
13584
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)13585 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13586 SourceLocation EndLoc) {
13587 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13588 }
13589
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)13590 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13591 SourceLocation EndLoc) {
13592 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13593 }
13594
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)13595 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13596 SourceLocation EndLoc) {
13597 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13598 }
13599
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)13600 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13601 SourceLocation EndLoc) {
13602 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13603 }
13604
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)13605 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13606 SourceLocation EndLoc) {
13607 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13608 }
13609
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)13610 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13611 SourceLocation EndLoc) {
13612 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13613 }
13614
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)13615 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13616 SourceLocation EndLoc) {
13617 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13618 }
13619
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)13620 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13621 SourceLocation EndLoc) {
13622 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13623 }
13624
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)13625 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13626 SourceLocation EndLoc) {
13627 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13628 }
13629
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)13630 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13631 SourceLocation EndLoc) {
13632 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13633 }
13634
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)13635 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13636 SourceLocation EndLoc) {
13637 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13638 }
13639
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)13640 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13641 SourceLocation EndLoc) {
13642 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13643 }
13644
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)13645 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13646 SourceLocation EndLoc) {
13647 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13648 }
13649
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)13650 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13651 SourceLocation EndLoc) {
13652 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13653 }
13654
ActOnOpenMPDestroyClause(SourceLocation StartLoc,SourceLocation EndLoc)13655 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13656 SourceLocation EndLoc) {
13657 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13658 }
13659
ActOnOpenMPVarListClause(OpenMPClauseKind Kind,ArrayRef<Expr * > VarList,Expr * DepModOrTailExpr,const OMPVarListLocTy & Locs,SourceLocation ColonLoc,CXXScopeSpec & ReductionOrMapperIdScopeSpec,DeclarationNameInfo & ReductionOrMapperId,int ExtraModifier,ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,bool IsMapTypeImplicit,SourceLocation ExtraModifierLoc,ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc)13660 OMPClause *Sema::ActOnOpenMPVarListClause(
13661 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13662 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13663 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13664 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13665 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13666 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13667 SourceLocation ExtraModifierLoc,
13668 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
13669 ArrayRef<SourceLocation> MotionModifiersLoc) {
13670 SourceLocation StartLoc = Locs.StartLoc;
13671 SourceLocation LParenLoc = Locs.LParenLoc;
13672 SourceLocation EndLoc = Locs.EndLoc;
13673 OMPClause *Res = nullptr;
13674 switch (Kind) {
13675 case OMPC_private:
13676 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13677 break;
13678 case OMPC_firstprivate:
13679 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13680 break;
13681 case OMPC_lastprivate:
13682 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
13683 "Unexpected lastprivate modifier.");
13684 Res = ActOnOpenMPLastprivateClause(
13685 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13686 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13687 break;
13688 case OMPC_shared:
13689 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13690 break;
13691 case OMPC_reduction:
13692 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
13693 "Unexpected lastprivate modifier.");
13694 Res = ActOnOpenMPReductionClause(
13695 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13696 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13697 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13698 break;
13699 case OMPC_task_reduction:
13700 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13701 EndLoc, ReductionOrMapperIdScopeSpec,
13702 ReductionOrMapperId);
13703 break;
13704 case OMPC_in_reduction:
13705 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13706 EndLoc, ReductionOrMapperIdScopeSpec,
13707 ReductionOrMapperId);
13708 break;
13709 case OMPC_linear:
13710 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
13711 "Unexpected linear modifier.");
13712 Res = ActOnOpenMPLinearClause(
13713 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13714 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13715 ColonLoc, EndLoc);
13716 break;
13717 case OMPC_aligned:
13718 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13719 LParenLoc, ColonLoc, EndLoc);
13720 break;
13721 case OMPC_copyin:
13722 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13723 break;
13724 case OMPC_copyprivate:
13725 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13726 break;
13727 case OMPC_flush:
13728 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13729 break;
13730 case OMPC_depend:
13731 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
13732 "Unexpected depend modifier.");
13733 Res = ActOnOpenMPDependClause(
13734 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13735 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13736 break;
13737 case OMPC_map:
13738 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
13739 "Unexpected map modifier.");
13740 Res = ActOnOpenMPMapClause(
13741 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13742 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13743 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13744 break;
13745 case OMPC_to:
13746 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
13747 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
13748 ColonLoc, VarList, Locs);
13749 break;
13750 case OMPC_from:
13751 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
13752 ReductionOrMapperIdScopeSpec,
13753 ReductionOrMapperId, ColonLoc, VarList, Locs);
13754 break;
13755 case OMPC_use_device_ptr:
13756 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13757 break;
13758 case OMPC_use_device_addr:
13759 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13760 break;
13761 case OMPC_is_device_ptr:
13762 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13763 break;
13764 case OMPC_allocate:
13765 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13766 LParenLoc, ColonLoc, EndLoc);
13767 break;
13768 case OMPC_nontemporal:
13769 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13770 break;
13771 case OMPC_inclusive:
13772 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13773 break;
13774 case OMPC_exclusive:
13775 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13776 break;
13777 case OMPC_affinity:
13778 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13779 DepModOrTailExpr, VarList);
13780 break;
13781 case OMPC_if:
13782 case OMPC_depobj:
13783 case OMPC_final:
13784 case OMPC_num_threads:
13785 case OMPC_safelen:
13786 case OMPC_simdlen:
13787 case OMPC_allocator:
13788 case OMPC_collapse:
13789 case OMPC_default:
13790 case OMPC_proc_bind:
13791 case OMPC_schedule:
13792 case OMPC_ordered:
13793 case OMPC_nowait:
13794 case OMPC_untied:
13795 case OMPC_mergeable:
13796 case OMPC_threadprivate:
13797 case OMPC_read:
13798 case OMPC_write:
13799 case OMPC_update:
13800 case OMPC_capture:
13801 case OMPC_seq_cst:
13802 case OMPC_acq_rel:
13803 case OMPC_acquire:
13804 case OMPC_release:
13805 case OMPC_relaxed:
13806 case OMPC_device:
13807 case OMPC_threads:
13808 case OMPC_simd:
13809 case OMPC_num_teams:
13810 case OMPC_thread_limit:
13811 case OMPC_priority:
13812 case OMPC_grainsize:
13813 case OMPC_nogroup:
13814 case OMPC_num_tasks:
13815 case OMPC_hint:
13816 case OMPC_dist_schedule:
13817 case OMPC_defaultmap:
13818 case OMPC_unknown:
13819 case OMPC_uniform:
13820 case OMPC_unified_address:
13821 case OMPC_unified_shared_memory:
13822 case OMPC_reverse_offload:
13823 case OMPC_dynamic_allocators:
13824 case OMPC_atomic_default_mem_order:
13825 case OMPC_device_type:
13826 case OMPC_match:
13827 case OMPC_order:
13828 case OMPC_destroy:
13829 case OMPC_detach:
13830 case OMPC_uses_allocators:
13831 default:
13832 llvm_unreachable("Clause is not allowed.");
13833 }
13834 return Res;
13835 }
13836
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)13837 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13838 ExprObjectKind OK, SourceLocation Loc) {
13839 ExprResult Res = BuildDeclRefExpr(
13840 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13841 if (!Res.isUsable())
13842 return ExprError();
13843 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13844 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13845 if (!Res.isUsable())
13846 return ExprError();
13847 }
13848 if (VK != VK_LValue && Res.get()->isGLValue()) {
13849 Res = DefaultLvalueConversion(Res.get());
13850 if (!Res.isUsable())
13851 return ExprError();
13852 }
13853 return Res;
13854 }
13855
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13856 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13857 SourceLocation StartLoc,
13858 SourceLocation LParenLoc,
13859 SourceLocation EndLoc) {
13860 SmallVector<Expr *, 8> Vars;
13861 SmallVector<Expr *, 8> PrivateCopies;
13862 for (Expr *RefExpr : VarList) {
13863 assert(RefExpr && "NULL expr in OpenMP private clause.");
13864 SourceLocation ELoc;
13865 SourceRange ERange;
13866 Expr *SimpleRefExpr = RefExpr;
13867 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13868 if (Res.second) {
13869 // It will be analyzed later.
13870 Vars.push_back(RefExpr);
13871 PrivateCopies.push_back(nullptr);
13872 }
13873 ValueDecl *D = Res.first;
13874 if (!D)
13875 continue;
13876
13877 QualType Type = D->getType();
13878 auto *VD = dyn_cast<VarDecl>(D);
13879
13880 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13881 // A variable that appears in a private clause must not have an incomplete
13882 // type or a reference type.
13883 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
13884 continue;
13885 Type = Type.getNonReferenceType();
13886
13887 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13888 // A variable that is privatized must not have a const-qualified type
13889 // unless it is of class type with a mutable member. This restriction does
13890 // not apply to the firstprivate clause.
13891 //
13892 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
13893 // A variable that appears in a private clause must not have a
13894 // const-qualified type unless it is of class type with a mutable member.
13895 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
13896 continue;
13897
13898 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13899 // in a Construct]
13900 // Variables with the predetermined data-sharing attributes may not be
13901 // listed in data-sharing attributes clauses, except for the cases
13902 // listed below. For these exceptions only, listing a predetermined
13903 // variable in a data-sharing attribute clause is allowed and overrides
13904 // the variable's predetermined data-sharing attributes.
13905 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13906 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
13907 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13908 << getOpenMPClauseName(OMPC_private);
13909 reportOriginalDsa(*this, DSAStack, D, DVar);
13910 continue;
13911 }
13912
13913 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
13914 // Variably modified types are not supported for tasks.
13915 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
13916 isOpenMPTaskingDirective(CurrDir)) {
13917 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13918 << getOpenMPClauseName(OMPC_private) << Type
13919 << getOpenMPDirectiveName(CurrDir);
13920 bool IsDecl =
13921 !VD ||
13922 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13923 Diag(D->getLocation(),
13924 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13925 << D;
13926 continue;
13927 }
13928
13929 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13930 // A list item cannot appear in both a map clause and a data-sharing
13931 // attribute clause on the same construct
13932 //
13933 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
13934 // A list item cannot appear in both a map clause and a data-sharing
13935 // attribute clause on the same construct unless the construct is a
13936 // combined construct.
13937 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
13938 CurrDir == OMPD_target) {
13939 OpenMPClauseKind ConflictKind;
13940 if (DSAStack->checkMappableExprComponentListsForDecl(
13941 VD, /*CurrentRegionOnly=*/true,
13942 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
13943 OpenMPClauseKind WhereFoundClauseKind) -> bool {
13944 ConflictKind = WhereFoundClauseKind;
13945 return true;
13946 })) {
13947 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13948 << getOpenMPClauseName(OMPC_private)
13949 << getOpenMPClauseName(ConflictKind)
13950 << getOpenMPDirectiveName(CurrDir);
13951 reportOriginalDsa(*this, DSAStack, D, DVar);
13952 continue;
13953 }
13954 }
13955
13956 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
13957 // A variable of class type (or array thereof) that appears in a private
13958 // clause requires an accessible, unambiguous default constructor for the
13959 // class type.
13960 // Generate helper private variable and initialize it with the default
13961 // value. The address of the original variable is replaced by the address of
13962 // the new private variable in CodeGen. This new variable is not added to
13963 // IdResolver, so the code in the OpenMP region uses original variable for
13964 // proper diagnostics.
13965 Type = Type.getUnqualifiedType();
13966 VarDecl *VDPrivate =
13967 buildVarDecl(*this, ELoc, Type, D->getName(),
13968 D->hasAttrs() ? &D->getAttrs() : nullptr,
13969 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13970 ActOnUninitializedDecl(VDPrivate);
13971 if (VDPrivate->isInvalidDecl())
13972 continue;
13973 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13974 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13975
13976 DeclRefExpr *Ref = nullptr;
13977 if (!VD && !CurContext->isDependentContext())
13978 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13979 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
13980 Vars.push_back((VD || CurContext->isDependentContext())
13981 ? RefExpr->IgnoreParens()
13982 : Ref);
13983 PrivateCopies.push_back(VDPrivateRefExpr);
13984 }
13985
13986 if (Vars.empty())
13987 return nullptr;
13988
13989 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
13990 PrivateCopies);
13991 }
13992
13993 namespace {
13994 class DiagsUninitializedSeveretyRAII {
13995 private:
13996 DiagnosticsEngine &Diags;
13997 SourceLocation SavedLoc;
13998 bool IsIgnored = false;
13999
14000 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)14001 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
14002 bool IsIgnored)
14003 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
14004 if (!IsIgnored) {
14005 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
14006 /*Map*/ diag::Severity::Ignored, Loc);
14007 }
14008 }
~DiagsUninitializedSeveretyRAII()14009 ~DiagsUninitializedSeveretyRAII() {
14010 if (!IsIgnored)
14011 Diags.popMappings(SavedLoc);
14012 }
14013 };
14014 }
14015
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14016 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
14017 SourceLocation StartLoc,
14018 SourceLocation LParenLoc,
14019 SourceLocation EndLoc) {
14020 SmallVector<Expr *, 8> Vars;
14021 SmallVector<Expr *, 8> PrivateCopies;
14022 SmallVector<Expr *, 8> Inits;
14023 SmallVector<Decl *, 4> ExprCaptures;
14024 bool IsImplicitClause =
14025 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
14026 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
14027
14028 for (Expr *RefExpr : VarList) {
14029 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
14030 SourceLocation ELoc;
14031 SourceRange ERange;
14032 Expr *SimpleRefExpr = RefExpr;
14033 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14034 if (Res.second) {
14035 // It will be analyzed later.
14036 Vars.push_back(RefExpr);
14037 PrivateCopies.push_back(nullptr);
14038 Inits.push_back(nullptr);
14039 }
14040 ValueDecl *D = Res.first;
14041 if (!D)
14042 continue;
14043
14044 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
14045 QualType Type = D->getType();
14046 auto *VD = dyn_cast<VarDecl>(D);
14047
14048 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14049 // A variable that appears in a private clause must not have an incomplete
14050 // type or a reference type.
14051 if (RequireCompleteType(ELoc, Type,
14052 diag::err_omp_firstprivate_incomplete_type))
14053 continue;
14054 Type = Type.getNonReferenceType();
14055
14056 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
14057 // A variable of class type (or array thereof) that appears in a private
14058 // clause requires an accessible, unambiguous copy constructor for the
14059 // class type.
14060 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14061
14062 // If an implicit firstprivate variable found it was checked already.
14063 DSAStackTy::DSAVarData TopDVar;
14064 if (!IsImplicitClause) {
14065 DSAStackTy::DSAVarData DVar =
14066 DSAStack->getTopDSA(D, /*FromParent=*/false);
14067 TopDVar = DVar;
14068 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14069 bool IsConstant = ElemType.isConstant(Context);
14070 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
14071 // A list item that specifies a given variable may not appear in more
14072 // than one clause on the same directive, except that a variable may be
14073 // specified in both firstprivate and lastprivate clauses.
14074 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14075 // A list item may appear in a firstprivate or lastprivate clause but not
14076 // both.
14077 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
14078 (isOpenMPDistributeDirective(CurrDir) ||
14079 DVar.CKind != OMPC_lastprivate) &&
14080 DVar.RefExpr) {
14081 Diag(ELoc, diag::err_omp_wrong_dsa)
14082 << getOpenMPClauseName(DVar.CKind)
14083 << getOpenMPClauseName(OMPC_firstprivate);
14084 reportOriginalDsa(*this, DSAStack, D, DVar);
14085 continue;
14086 }
14087
14088 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14089 // in a Construct]
14090 // Variables with the predetermined data-sharing attributes may not be
14091 // listed in data-sharing attributes clauses, except for the cases
14092 // listed below. For these exceptions only, listing a predetermined
14093 // variable in a data-sharing attribute clause is allowed and overrides
14094 // the variable's predetermined data-sharing attributes.
14095 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14096 // in a Construct, C/C++, p.2]
14097 // Variables with const-qualified type having no mutable member may be
14098 // listed in a firstprivate clause, even if they are static data members.
14099 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
14100 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
14101 Diag(ELoc, diag::err_omp_wrong_dsa)
14102 << getOpenMPClauseName(DVar.CKind)
14103 << getOpenMPClauseName(OMPC_firstprivate);
14104 reportOriginalDsa(*this, DSAStack, D, DVar);
14105 continue;
14106 }
14107
14108 // OpenMP [2.9.3.4, Restrictions, p.2]
14109 // A list item that is private within a parallel region must not appear
14110 // in a firstprivate clause on a worksharing construct if any of the
14111 // worksharing regions arising from the worksharing construct ever bind
14112 // to any of the parallel regions arising from the parallel construct.
14113 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14114 // A list item that is private within a teams region must not appear in a
14115 // firstprivate clause on a distribute construct if any of the distribute
14116 // regions arising from the distribute construct ever bind to any of the
14117 // teams regions arising from the teams construct.
14118 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14119 // A list item that appears in a reduction clause of a teams construct
14120 // must not appear in a firstprivate clause on a distribute construct if
14121 // any of the distribute regions arising from the distribute construct
14122 // ever bind to any of the teams regions arising from the teams construct.
14123 if ((isOpenMPWorksharingDirective(CurrDir) ||
14124 isOpenMPDistributeDirective(CurrDir)) &&
14125 !isOpenMPParallelDirective(CurrDir) &&
14126 !isOpenMPTeamsDirective(CurrDir)) {
14127 DVar = DSAStack->getImplicitDSA(D, true);
14128 if (DVar.CKind != OMPC_shared &&
14129 (isOpenMPParallelDirective(DVar.DKind) ||
14130 isOpenMPTeamsDirective(DVar.DKind) ||
14131 DVar.DKind == OMPD_unknown)) {
14132 Diag(ELoc, diag::err_omp_required_access)
14133 << getOpenMPClauseName(OMPC_firstprivate)
14134 << getOpenMPClauseName(OMPC_shared);
14135 reportOriginalDsa(*this, DSAStack, D, DVar);
14136 continue;
14137 }
14138 }
14139 // OpenMP [2.9.3.4, Restrictions, p.3]
14140 // A list item that appears in a reduction clause of a parallel construct
14141 // must not appear in a firstprivate clause on a worksharing or task
14142 // construct if any of the worksharing or task regions arising from the
14143 // worksharing or task construct ever bind to any of the parallel regions
14144 // arising from the parallel construct.
14145 // OpenMP [2.9.3.4, Restrictions, p.4]
14146 // A list item that appears in a reduction clause in worksharing
14147 // construct must not appear in a firstprivate clause in a task construct
14148 // encountered during execution of any of the worksharing regions arising
14149 // from the worksharing construct.
14150 if (isOpenMPTaskingDirective(CurrDir)) {
14151 DVar = DSAStack->hasInnermostDSA(
14152 D,
14153 [](OpenMPClauseKind C, bool AppliedToPointee) {
14154 return C == OMPC_reduction && !AppliedToPointee;
14155 },
14156 [](OpenMPDirectiveKind K) {
14157 return isOpenMPParallelDirective(K) ||
14158 isOpenMPWorksharingDirective(K) ||
14159 isOpenMPTeamsDirective(K);
14160 },
14161 /*FromParent=*/true);
14162 if (DVar.CKind == OMPC_reduction &&
14163 (isOpenMPParallelDirective(DVar.DKind) ||
14164 isOpenMPWorksharingDirective(DVar.DKind) ||
14165 isOpenMPTeamsDirective(DVar.DKind))) {
14166 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14167 << getOpenMPDirectiveName(DVar.DKind);
14168 reportOriginalDsa(*this, DSAStack, D, DVar);
14169 continue;
14170 }
14171 }
14172
14173 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14174 // A list item cannot appear in both a map clause and a data-sharing
14175 // attribute clause on the same construct
14176 //
14177 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14178 // A list item cannot appear in both a map clause and a data-sharing
14179 // attribute clause on the same construct unless the construct is a
14180 // combined construct.
14181 if ((LangOpts.OpenMP <= 45 &&
14182 isOpenMPTargetExecutionDirective(CurrDir)) ||
14183 CurrDir == OMPD_target) {
14184 OpenMPClauseKind ConflictKind;
14185 if (DSAStack->checkMappableExprComponentListsForDecl(
14186 VD, /*CurrentRegionOnly=*/true,
14187 [&ConflictKind](
14188 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14189 OpenMPClauseKind WhereFoundClauseKind) {
14190 ConflictKind = WhereFoundClauseKind;
14191 return true;
14192 })) {
14193 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14194 << getOpenMPClauseName(OMPC_firstprivate)
14195 << getOpenMPClauseName(ConflictKind)
14196 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14197 reportOriginalDsa(*this, DSAStack, D, DVar);
14198 continue;
14199 }
14200 }
14201 }
14202
14203 // Variably modified types are not supported for tasks.
14204 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14205 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
14206 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14207 << getOpenMPClauseName(OMPC_firstprivate) << Type
14208 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14209 bool IsDecl =
14210 !VD ||
14211 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14212 Diag(D->getLocation(),
14213 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14214 << D;
14215 continue;
14216 }
14217
14218 Type = Type.getUnqualifiedType();
14219 VarDecl *VDPrivate =
14220 buildVarDecl(*this, ELoc, Type, D->getName(),
14221 D->hasAttrs() ? &D->getAttrs() : nullptr,
14222 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14223 // Generate helper private variable and initialize it with the value of the
14224 // original variable. The address of the original variable is replaced by
14225 // the address of the new private variable in the CodeGen. This new variable
14226 // is not added to IdResolver, so the code in the OpenMP region uses
14227 // original variable for proper diagnostics and variable capturing.
14228 Expr *VDInitRefExpr = nullptr;
14229 // For arrays generate initializer for single element and replace it by the
14230 // original array element in CodeGen.
14231 if (Type->isArrayType()) {
14232 VarDecl *VDInit =
14233 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14234 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14235 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14236 ElemType = ElemType.getUnqualifiedType();
14237 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14238 ".firstprivate.temp");
14239 InitializedEntity Entity =
14240 InitializedEntity::InitializeVariable(VDInitTemp);
14241 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14242
14243 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14244 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14245 if (Result.isInvalid())
14246 VDPrivate->setInvalidDecl();
14247 else
14248 VDPrivate->setInit(Result.getAs<Expr>());
14249 // Remove temp variable declaration.
14250 Context.Deallocate(VDInitTemp);
14251 } else {
14252 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14253 ".firstprivate.temp");
14254 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14255 RefExpr->getExprLoc());
14256 AddInitializerToDecl(VDPrivate,
14257 DefaultLvalueConversion(VDInitRefExpr).get(),
14258 /*DirectInit=*/false);
14259 }
14260 if (VDPrivate->isInvalidDecl()) {
14261 if (IsImplicitClause) {
14262 Diag(RefExpr->getExprLoc(),
14263 diag::note_omp_task_predetermined_firstprivate_here);
14264 }
14265 continue;
14266 }
14267 CurContext->addDecl(VDPrivate);
14268 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14269 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14270 RefExpr->getExprLoc());
14271 DeclRefExpr *Ref = nullptr;
14272 if (!VD && !CurContext->isDependentContext()) {
14273 if (TopDVar.CKind == OMPC_lastprivate) {
14274 Ref = TopDVar.PrivateCopy;
14275 } else {
14276 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14277 if (!isOpenMPCapturedDecl(D))
14278 ExprCaptures.push_back(Ref->getDecl());
14279 }
14280 }
14281 if (!IsImplicitClause)
14282 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14283 Vars.push_back((VD || CurContext->isDependentContext())
14284 ? RefExpr->IgnoreParens()
14285 : Ref);
14286 PrivateCopies.push_back(VDPrivateRefExpr);
14287 Inits.push_back(VDInitRefExpr);
14288 }
14289
14290 if (Vars.empty())
14291 return nullptr;
14292
14293 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14294 Vars, PrivateCopies, Inits,
14295 buildPreInits(Context, ExprCaptures));
14296 }
14297
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14298 OMPClause *Sema::ActOnOpenMPLastprivateClause(
14299 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14300 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14301 SourceLocation LParenLoc, SourceLocation EndLoc) {
14302 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14303 assert(ColonLoc.isValid() && "Colon location must be valid.");
14304 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14305 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14306 /*Last=*/OMPC_LASTPRIVATE_unknown)
14307 << getOpenMPClauseName(OMPC_lastprivate);
14308 return nullptr;
14309 }
14310
14311 SmallVector<Expr *, 8> Vars;
14312 SmallVector<Expr *, 8> SrcExprs;
14313 SmallVector<Expr *, 8> DstExprs;
14314 SmallVector<Expr *, 8> AssignmentOps;
14315 SmallVector<Decl *, 4> ExprCaptures;
14316 SmallVector<Expr *, 4> ExprPostUpdates;
14317 for (Expr *RefExpr : VarList) {
14318 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14319 SourceLocation ELoc;
14320 SourceRange ERange;
14321 Expr *SimpleRefExpr = RefExpr;
14322 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14323 if (Res.second) {
14324 // It will be analyzed later.
14325 Vars.push_back(RefExpr);
14326 SrcExprs.push_back(nullptr);
14327 DstExprs.push_back(nullptr);
14328 AssignmentOps.push_back(nullptr);
14329 }
14330 ValueDecl *D = Res.first;
14331 if (!D)
14332 continue;
14333
14334 QualType Type = D->getType();
14335 auto *VD = dyn_cast<VarDecl>(D);
14336
14337 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14338 // A variable that appears in a lastprivate clause must not have an
14339 // incomplete type or a reference type.
14340 if (RequireCompleteType(ELoc, Type,
14341 diag::err_omp_lastprivate_incomplete_type))
14342 continue;
14343 Type = Type.getNonReferenceType();
14344
14345 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14346 // A variable that is privatized must not have a const-qualified type
14347 // unless it is of class type with a mutable member. This restriction does
14348 // not apply to the firstprivate clause.
14349 //
14350 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14351 // A variable that appears in a lastprivate clause must not have a
14352 // const-qualified type unless it is of class type with a mutable member.
14353 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14354 continue;
14355
14356 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14357 // A list item that appears in a lastprivate clause with the conditional
14358 // modifier must be a scalar variable.
14359 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14360 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14361 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14362 VarDecl::DeclarationOnly;
14363 Diag(D->getLocation(),
14364 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14365 << D;
14366 continue;
14367 }
14368
14369 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14370 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14371 // in a Construct]
14372 // Variables with the predetermined data-sharing attributes may not be
14373 // listed in data-sharing attributes clauses, except for the cases
14374 // listed below.
14375 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14376 // A list item may appear in a firstprivate or lastprivate clause but not
14377 // both.
14378 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14379 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14380 (isOpenMPDistributeDirective(CurrDir) ||
14381 DVar.CKind != OMPC_firstprivate) &&
14382 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14383 Diag(ELoc, diag::err_omp_wrong_dsa)
14384 << getOpenMPClauseName(DVar.CKind)
14385 << getOpenMPClauseName(OMPC_lastprivate);
14386 reportOriginalDsa(*this, DSAStack, D, DVar);
14387 continue;
14388 }
14389
14390 // OpenMP [2.14.3.5, Restrictions, p.2]
14391 // A list item that is private within a parallel region, or that appears in
14392 // the reduction clause of a parallel construct, must not appear in a
14393 // lastprivate clause on a worksharing construct if any of the corresponding
14394 // worksharing regions ever binds to any of the corresponding parallel
14395 // regions.
14396 DSAStackTy::DSAVarData TopDVar = DVar;
14397 if (isOpenMPWorksharingDirective(CurrDir) &&
14398 !isOpenMPParallelDirective(CurrDir) &&
14399 !isOpenMPTeamsDirective(CurrDir)) {
14400 DVar = DSAStack->getImplicitDSA(D, true);
14401 if (DVar.CKind != OMPC_shared) {
14402 Diag(ELoc, diag::err_omp_required_access)
14403 << getOpenMPClauseName(OMPC_lastprivate)
14404 << getOpenMPClauseName(OMPC_shared);
14405 reportOriginalDsa(*this, DSAStack, D, DVar);
14406 continue;
14407 }
14408 }
14409
14410 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14411 // A variable of class type (or array thereof) that appears in a
14412 // lastprivate clause requires an accessible, unambiguous default
14413 // constructor for the class type, unless the list item is also specified
14414 // in a firstprivate clause.
14415 // A variable of class type (or array thereof) that appears in a
14416 // lastprivate clause requires an accessible, unambiguous copy assignment
14417 // operator for the class type.
14418 Type = Context.getBaseElementType(Type).getNonReferenceType();
14419 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14420 Type.getUnqualifiedType(), ".lastprivate.src",
14421 D->hasAttrs() ? &D->getAttrs() : nullptr);
14422 DeclRefExpr *PseudoSrcExpr =
14423 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14424 VarDecl *DstVD =
14425 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14426 D->hasAttrs() ? &D->getAttrs() : nullptr);
14427 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14428 // For arrays generate assignment operation for single element and replace
14429 // it by the original array element in CodeGen.
14430 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14431 PseudoDstExpr, PseudoSrcExpr);
14432 if (AssignmentOp.isInvalid())
14433 continue;
14434 AssignmentOp =
14435 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14436 if (AssignmentOp.isInvalid())
14437 continue;
14438
14439 DeclRefExpr *Ref = nullptr;
14440 if (!VD && !CurContext->isDependentContext()) {
14441 if (TopDVar.CKind == OMPC_firstprivate) {
14442 Ref = TopDVar.PrivateCopy;
14443 } else {
14444 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14445 if (!isOpenMPCapturedDecl(D))
14446 ExprCaptures.push_back(Ref->getDecl());
14447 }
14448 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
14449 (!isOpenMPCapturedDecl(D) &&
14450 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14451 ExprResult RefRes = DefaultLvalueConversion(Ref);
14452 if (!RefRes.isUsable())
14453 continue;
14454 ExprResult PostUpdateRes =
14455 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14456 RefRes.get());
14457 if (!PostUpdateRes.isUsable())
14458 continue;
14459 ExprPostUpdates.push_back(
14460 IgnoredValueConversions(PostUpdateRes.get()).get());
14461 }
14462 }
14463 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14464 Vars.push_back((VD || CurContext->isDependentContext())
14465 ? RefExpr->IgnoreParens()
14466 : Ref);
14467 SrcExprs.push_back(PseudoSrcExpr);
14468 DstExprs.push_back(PseudoDstExpr);
14469 AssignmentOps.push_back(AssignmentOp.get());
14470 }
14471
14472 if (Vars.empty())
14473 return nullptr;
14474
14475 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14476 Vars, SrcExprs, DstExprs, AssignmentOps,
14477 LPKind, LPKindLoc, ColonLoc,
14478 buildPreInits(Context, ExprCaptures),
14479 buildPostUpdate(*this, ExprPostUpdates));
14480 }
14481
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14482 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14483 SourceLocation StartLoc,
14484 SourceLocation LParenLoc,
14485 SourceLocation EndLoc) {
14486 SmallVector<Expr *, 8> Vars;
14487 for (Expr *RefExpr : VarList) {
14488 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14489 SourceLocation ELoc;
14490 SourceRange ERange;
14491 Expr *SimpleRefExpr = RefExpr;
14492 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14493 if (Res.second) {
14494 // It will be analyzed later.
14495 Vars.push_back(RefExpr);
14496 }
14497 ValueDecl *D = Res.first;
14498 if (!D)
14499 continue;
14500
14501 auto *VD = dyn_cast<VarDecl>(D);
14502 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14503 // in a Construct]
14504 // Variables with the predetermined data-sharing attributes may not be
14505 // listed in data-sharing attributes clauses, except for the cases
14506 // listed below. For these exceptions only, listing a predetermined
14507 // variable in a data-sharing attribute clause is allowed and overrides
14508 // the variable's predetermined data-sharing attributes.
14509 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14510 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14511 DVar.RefExpr) {
14512 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14513 << getOpenMPClauseName(OMPC_shared);
14514 reportOriginalDsa(*this, DSAStack, D, DVar);
14515 continue;
14516 }
14517
14518 DeclRefExpr *Ref = nullptr;
14519 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14520 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14521 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14522 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14523 ? RefExpr->IgnoreParens()
14524 : Ref);
14525 }
14526
14527 if (Vars.empty())
14528 return nullptr;
14529
14530 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14531 }
14532
14533 namespace {
14534 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14535 DSAStackTy *Stack;
14536
14537 public:
VisitDeclRefExpr(DeclRefExpr * E)14538 bool VisitDeclRefExpr(DeclRefExpr *E) {
14539 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14540 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14541 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14542 return false;
14543 if (DVar.CKind != OMPC_unknown)
14544 return true;
14545 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14546 VD,
14547 [](OpenMPClauseKind C, bool AppliedToPointee) {
14548 return isOpenMPPrivate(C) && !AppliedToPointee;
14549 },
14550 [](OpenMPDirectiveKind) { return true; },
14551 /*FromParent=*/true);
14552 return DVarPrivate.CKind != OMPC_unknown;
14553 }
14554 return false;
14555 }
VisitStmt(Stmt * S)14556 bool VisitStmt(Stmt *S) {
14557 for (Stmt *Child : S->children()) {
14558 if (Child && Visit(Child))
14559 return true;
14560 }
14561 return false;
14562 }
DSARefChecker(DSAStackTy * S)14563 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14564 };
14565 } // namespace
14566
14567 namespace {
14568 // Transform MemberExpression for specified FieldDecl of current class to
14569 // DeclRefExpr to specified OMPCapturedExprDecl.
14570 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14571 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14572 ValueDecl *Field = nullptr;
14573 DeclRefExpr *CapturedExpr = nullptr;
14574
14575 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)14576 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14577 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14578
TransformMemberExpr(MemberExpr * E)14579 ExprResult TransformMemberExpr(MemberExpr *E) {
14580 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14581 E->getMemberDecl() == Field) {
14582 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14583 return CapturedExpr;
14584 }
14585 return BaseTransform::TransformMemberExpr(E);
14586 }
getCapturedExpr()14587 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14588 };
14589 } // namespace
14590
14591 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)14592 static T filterLookupForUDReductionAndMapper(
14593 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14594 for (U &Set : Lookups) {
14595 for (auto *D : Set) {
14596 if (T Res = Gen(cast<ValueDecl>(D)))
14597 return Res;
14598 }
14599 }
14600 return T();
14601 }
14602
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)14603 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14604 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
14605
14606 for (auto RD : D->redecls()) {
14607 // Don't bother with extra checks if we already know this one isn't visible.
14608 if (RD == D)
14609 continue;
14610
14611 auto ND = cast<NamedDecl>(RD);
14612 if (LookupResult::isVisible(SemaRef, ND))
14613 return ND;
14614 }
14615
14616 return nullptr;
14617 }
14618
14619 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)14620 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14621 SourceLocation Loc, QualType Ty,
14622 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14623 // Find all of the associated namespaces and classes based on the
14624 // arguments we have.
14625 Sema::AssociatedNamespaceSet AssociatedNamespaces;
14626 Sema::AssociatedClassSet AssociatedClasses;
14627 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14628 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14629 AssociatedClasses);
14630
14631 // C++ [basic.lookup.argdep]p3:
14632 // Let X be the lookup set produced by unqualified lookup (3.4.1)
14633 // and let Y be the lookup set produced by argument dependent
14634 // lookup (defined as follows). If X contains [...] then Y is
14635 // empty. Otherwise Y is the set of declarations found in the
14636 // namespaces associated with the argument types as described
14637 // below. The set of declarations found by the lookup of the name
14638 // is the union of X and Y.
14639 //
14640 // Here, we compute Y and add its members to the overloaded
14641 // candidate set.
14642 for (auto *NS : AssociatedNamespaces) {
14643 // When considering an associated namespace, the lookup is the
14644 // same as the lookup performed when the associated namespace is
14645 // used as a qualifier (3.4.3.2) except that:
14646 //
14647 // -- Any using-directives in the associated namespace are
14648 // ignored.
14649 //
14650 // -- Any namespace-scope friend functions declared in
14651 // associated classes are visible within their respective
14652 // namespaces even if they are not visible during an ordinary
14653 // lookup (11.4).
14654 DeclContext::lookup_result R = NS->lookup(Id.getName());
14655 for (auto *D : R) {
14656 auto *Underlying = D;
14657 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14658 Underlying = USD->getTargetDecl();
14659
14660 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14661 !isa<OMPDeclareMapperDecl>(Underlying))
14662 continue;
14663
14664 if (!SemaRef.isVisible(D)) {
14665 D = findAcceptableDecl(SemaRef, D);
14666 if (!D)
14667 continue;
14668 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14669 Underlying = USD->getTargetDecl();
14670 }
14671 Lookups.emplace_back();
14672 Lookups.back().addDecl(Underlying);
14673 }
14674 }
14675 }
14676
14677 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)14678 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14679 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14680 const DeclarationNameInfo &ReductionId, QualType Ty,
14681 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14682 if (ReductionIdScopeSpec.isInvalid())
14683 return ExprError();
14684 SmallVector<UnresolvedSet<8>, 4> Lookups;
14685 if (S) {
14686 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14687 Lookup.suppressDiagnostics();
14688 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14689 NamedDecl *D = Lookup.getRepresentativeDecl();
14690 do {
14691 S = S->getParent();
14692 } while (S && !S->isDeclScope(D));
14693 if (S)
14694 S = S->getParent();
14695 Lookups.emplace_back();
14696 Lookups.back().append(Lookup.begin(), Lookup.end());
14697 Lookup.clear();
14698 }
14699 } else if (auto *ULE =
14700 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14701 Lookups.push_back(UnresolvedSet<8>());
14702 Decl *PrevD = nullptr;
14703 for (NamedDecl *D : ULE->decls()) {
14704 if (D == PrevD)
14705 Lookups.push_back(UnresolvedSet<8>());
14706 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14707 Lookups.back().addDecl(DRD);
14708 PrevD = D;
14709 }
14710 }
14711 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14712 Ty->isInstantiationDependentType() ||
14713 Ty->containsUnexpandedParameterPack() ||
14714 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14715 return !D->isInvalidDecl() &&
14716 (D->getType()->isDependentType() ||
14717 D->getType()->isInstantiationDependentType() ||
14718 D->getType()->containsUnexpandedParameterPack());
14719 })) {
14720 UnresolvedSet<8> ResSet;
14721 for (const UnresolvedSet<8> &Set : Lookups) {
14722 if (Set.empty())
14723 continue;
14724 ResSet.append(Set.begin(), Set.end());
14725 // The last item marks the end of all declarations at the specified scope.
14726 ResSet.addDecl(Set[Set.size() - 1]);
14727 }
14728 return UnresolvedLookupExpr::Create(
14729 SemaRef.Context, /*NamingClass=*/nullptr,
14730 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14731 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14732 }
14733 // Lookup inside the classes.
14734 // C++ [over.match.oper]p3:
14735 // For a unary operator @ with an operand of a type whose
14736 // cv-unqualified version is T1, and for a binary operator @ with
14737 // a left operand of a type whose cv-unqualified version is T1 and
14738 // a right operand of a type whose cv-unqualified version is T2,
14739 // three sets of candidate functions, designated member
14740 // candidates, non-member candidates and built-in candidates, are
14741 // constructed as follows:
14742 // -- If T1 is a complete class type or a class currently being
14743 // defined, the set of member candidates is the result of the
14744 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14745 // the set of member candidates is empty.
14746 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14747 Lookup.suppressDiagnostics();
14748 if (const auto *TyRec = Ty->getAs<RecordType>()) {
14749 // Complete the type if it can be completed.
14750 // If the type is neither complete nor being defined, bail out now.
14751 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14752 TyRec->getDecl()->getDefinition()) {
14753 Lookup.clear();
14754 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14755 if (Lookup.empty()) {
14756 Lookups.emplace_back();
14757 Lookups.back().append(Lookup.begin(), Lookup.end());
14758 }
14759 }
14760 }
14761 // Perform ADL.
14762 if (SemaRef.getLangOpts().CPlusPlus)
14763 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14764 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14765 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14766 if (!D->isInvalidDecl() &&
14767 SemaRef.Context.hasSameType(D->getType(), Ty))
14768 return D;
14769 return nullptr;
14770 }))
14771 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14772 VK_LValue, Loc);
14773 if (SemaRef.getLangOpts().CPlusPlus) {
14774 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14775 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14776 if (!D->isInvalidDecl() &&
14777 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14778 !Ty.isMoreQualifiedThan(D->getType()))
14779 return D;
14780 return nullptr;
14781 })) {
14782 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14783 /*DetectVirtual=*/false);
14784 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14785 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14786 VD->getType().getUnqualifiedType()))) {
14787 if (SemaRef.CheckBaseClassAccess(
14788 Loc, VD->getType(), Ty, Paths.front(),
14789 /*DiagID=*/0) != Sema::AR_inaccessible) {
14790 SemaRef.BuildBasePathArray(Paths, BasePath);
14791 return SemaRef.BuildDeclRefExpr(
14792 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14793 }
14794 }
14795 }
14796 }
14797 }
14798 if (ReductionIdScopeSpec.isSet()) {
14799 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14800 << Ty << Range;
14801 return ExprError();
14802 }
14803 return ExprEmpty();
14804 }
14805
14806 namespace {
14807 /// Data for the reduction-based clauses.
14808 struct ReductionData {
14809 /// List of original reduction items.
14810 SmallVector<Expr *, 8> Vars;
14811 /// List of private copies of the reduction items.
14812 SmallVector<Expr *, 8> Privates;
14813 /// LHS expressions for the reduction_op expressions.
14814 SmallVector<Expr *, 8> LHSs;
14815 /// RHS expressions for the reduction_op expressions.
14816 SmallVector<Expr *, 8> RHSs;
14817 /// Reduction operation expression.
14818 SmallVector<Expr *, 8> ReductionOps;
14819 /// inscan copy operation expressions.
14820 SmallVector<Expr *, 8> InscanCopyOps;
14821 /// inscan copy temp array expressions for prefix sums.
14822 SmallVector<Expr *, 8> InscanCopyArrayTemps;
14823 /// inscan copy temp array element expressions for prefix sums.
14824 SmallVector<Expr *, 8> InscanCopyArrayElems;
14825 /// Taskgroup descriptors for the corresponding reduction items in
14826 /// in_reduction clauses.
14827 SmallVector<Expr *, 8> TaskgroupDescriptors;
14828 /// List of captures for clause.
14829 SmallVector<Decl *, 4> ExprCaptures;
14830 /// List of postupdate expressions.
14831 SmallVector<Expr *, 4> ExprPostUpdates;
14832 /// Reduction modifier.
14833 unsigned RedModifier = 0;
14834 ReductionData() = delete;
14835 /// Reserves required memory for the reduction data.
ReductionData__anon0bb9e2bb4811::ReductionData14836 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14837 Vars.reserve(Size);
14838 Privates.reserve(Size);
14839 LHSs.reserve(Size);
14840 RHSs.reserve(Size);
14841 ReductionOps.reserve(Size);
14842 if (RedModifier == OMPC_REDUCTION_inscan) {
14843 InscanCopyOps.reserve(Size);
14844 InscanCopyArrayTemps.reserve(Size);
14845 InscanCopyArrayElems.reserve(Size);
14846 }
14847 TaskgroupDescriptors.reserve(Size);
14848 ExprCaptures.reserve(Size);
14849 ExprPostUpdates.reserve(Size);
14850 }
14851 /// Stores reduction item and reduction operation only (required for dependent
14852 /// reduction item).
push__anon0bb9e2bb4811::ReductionData14853 void push(Expr *Item, Expr *ReductionOp) {
14854 Vars.emplace_back(Item);
14855 Privates.emplace_back(nullptr);
14856 LHSs.emplace_back(nullptr);
14857 RHSs.emplace_back(nullptr);
14858 ReductionOps.emplace_back(ReductionOp);
14859 TaskgroupDescriptors.emplace_back(nullptr);
14860 if (RedModifier == OMPC_REDUCTION_inscan) {
14861 InscanCopyOps.push_back(nullptr);
14862 InscanCopyArrayTemps.push_back(nullptr);
14863 InscanCopyArrayElems.push_back(nullptr);
14864 }
14865 }
14866 /// Stores reduction data.
push__anon0bb9e2bb4811::ReductionData14867 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
14868 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
14869 Expr *CopyArrayElem) {
14870 Vars.emplace_back(Item);
14871 Privates.emplace_back(Private);
14872 LHSs.emplace_back(LHS);
14873 RHSs.emplace_back(RHS);
14874 ReductionOps.emplace_back(ReductionOp);
14875 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
14876 if (RedModifier == OMPC_REDUCTION_inscan) {
14877 InscanCopyOps.push_back(CopyOp);
14878 InscanCopyArrayTemps.push_back(CopyArrayTemp);
14879 InscanCopyArrayElems.push_back(CopyArrayElem);
14880 } else {
14881 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
14882 CopyArrayElem == nullptr &&
14883 "Copy operation must be used for inscan reductions only.");
14884 }
14885 }
14886 };
14887 } // namespace
14888
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)14889 static bool checkOMPArraySectionConstantForReduction(
14890 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
14891 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
14892 const Expr *Length = OASE->getLength();
14893 if (Length == nullptr) {
14894 // For array sections of the form [1:] or [:], we would need to analyze
14895 // the lower bound...
14896 if (OASE->getColonLocFirst().isValid())
14897 return false;
14898
14899 // This is an array subscript which has implicit length 1!
14900 SingleElement = true;
14901 ArraySizes.push_back(llvm::APSInt::get(1));
14902 } else {
14903 Expr::EvalResult Result;
14904 if (!Length->EvaluateAsInt(Result, Context))
14905 return false;
14906
14907 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14908 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
14909 ArraySizes.push_back(ConstantLengthValue);
14910 }
14911
14912 // Get the base of this array section and walk up from there.
14913 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
14914
14915 // We require length = 1 for all array sections except the right-most to
14916 // guarantee that the memory region is contiguous and has no holes in it.
14917 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
14918 Length = TempOASE->getLength();
14919 if (Length == nullptr) {
14920 // For array sections of the form [1:] or [:], we would need to analyze
14921 // the lower bound...
14922 if (OASE->getColonLocFirst().isValid())
14923 return false;
14924
14925 // This is an array subscript which has implicit length 1!
14926 ArraySizes.push_back(llvm::APSInt::get(1));
14927 } else {
14928 Expr::EvalResult Result;
14929 if (!Length->EvaluateAsInt(Result, Context))
14930 return false;
14931
14932 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14933 if (ConstantLengthValue.getSExtValue() != 1)
14934 return false;
14935
14936 ArraySizes.push_back(ConstantLengthValue);
14937 }
14938 Base = TempOASE->getBase()->IgnoreParenImpCasts();
14939 }
14940
14941 // If we have a single element, we don't need to add the implicit lengths.
14942 if (!SingleElement) {
14943 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
14944 // Has implicit length 1!
14945 ArraySizes.push_back(llvm::APSInt::get(1));
14946 Base = TempASE->getBase()->IgnoreParenImpCasts();
14947 }
14948 }
14949
14950 // This array section can be privatized as a single value or as a constant
14951 // sized array.
14952 return true;
14953 }
14954
actOnOMPReductionKindClause(Sema & S,DSAStackTy * Stack,OpenMPClauseKind ClauseKind,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions,ReductionData & RD)14955 static bool actOnOMPReductionKindClause(
14956 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
14957 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14958 SourceLocation ColonLoc, SourceLocation EndLoc,
14959 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14960 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
14961 DeclarationName DN = ReductionId.getName();
14962 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
14963 BinaryOperatorKind BOK = BO_Comma;
14964
14965 ASTContext &Context = S.Context;
14966 // OpenMP [2.14.3.6, reduction clause]
14967 // C
14968 // reduction-identifier is either an identifier or one of the following
14969 // operators: +, -, *, &, |, ^, && and ||
14970 // C++
14971 // reduction-identifier is either an id-expression or one of the following
14972 // operators: +, -, *, &, |, ^, && and ||
14973 switch (OOK) {
14974 case OO_Plus:
14975 case OO_Minus:
14976 BOK = BO_Add;
14977 break;
14978 case OO_Star:
14979 BOK = BO_Mul;
14980 break;
14981 case OO_Amp:
14982 BOK = BO_And;
14983 break;
14984 case OO_Pipe:
14985 BOK = BO_Or;
14986 break;
14987 case OO_Caret:
14988 BOK = BO_Xor;
14989 break;
14990 case OO_AmpAmp:
14991 BOK = BO_LAnd;
14992 break;
14993 case OO_PipePipe:
14994 BOK = BO_LOr;
14995 break;
14996 case OO_New:
14997 case OO_Delete:
14998 case OO_Array_New:
14999 case OO_Array_Delete:
15000 case OO_Slash:
15001 case OO_Percent:
15002 case OO_Tilde:
15003 case OO_Exclaim:
15004 case OO_Equal:
15005 case OO_Less:
15006 case OO_Greater:
15007 case OO_LessEqual:
15008 case OO_GreaterEqual:
15009 case OO_PlusEqual:
15010 case OO_MinusEqual:
15011 case OO_StarEqual:
15012 case OO_SlashEqual:
15013 case OO_PercentEqual:
15014 case OO_CaretEqual:
15015 case OO_AmpEqual:
15016 case OO_PipeEqual:
15017 case OO_LessLess:
15018 case OO_GreaterGreater:
15019 case OO_LessLessEqual:
15020 case OO_GreaterGreaterEqual:
15021 case OO_EqualEqual:
15022 case OO_ExclaimEqual:
15023 case OO_Spaceship:
15024 case OO_PlusPlus:
15025 case OO_MinusMinus:
15026 case OO_Comma:
15027 case OO_ArrowStar:
15028 case OO_Arrow:
15029 case OO_Call:
15030 case OO_Subscript:
15031 case OO_Conditional:
15032 case OO_Coawait:
15033 case NUM_OVERLOADED_OPERATORS:
15034 llvm_unreachable("Unexpected reduction identifier");
15035 case OO_None:
15036 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
15037 if (II->isStr("max"))
15038 BOK = BO_GT;
15039 else if (II->isStr("min"))
15040 BOK = BO_LT;
15041 }
15042 break;
15043 }
15044 SourceRange ReductionIdRange;
15045 if (ReductionIdScopeSpec.isValid())
15046 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
15047 else
15048 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
15049 ReductionIdRange.setEnd(ReductionId.getEndLoc());
15050
15051 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
15052 bool FirstIter = true;
15053 for (Expr *RefExpr : VarList) {
15054 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
15055 // OpenMP [2.1, C/C++]
15056 // A list item is a variable or array section, subject to the restrictions
15057 // specified in Section 2.4 on page 42 and in each of the sections
15058 // describing clauses and directives for which a list appears.
15059 // OpenMP [2.14.3.3, Restrictions, p.1]
15060 // A variable that is part of another variable (as an array or
15061 // structure element) cannot appear in a private clause.
15062 if (!FirstIter && IR != ER)
15063 ++IR;
15064 FirstIter = false;
15065 SourceLocation ELoc;
15066 SourceRange ERange;
15067 Expr *SimpleRefExpr = RefExpr;
15068 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
15069 /*AllowArraySection=*/true);
15070 if (Res.second) {
15071 // Try to find 'declare reduction' corresponding construct before using
15072 // builtin/overloaded operators.
15073 QualType Type = Context.DependentTy;
15074 CXXCastPath BasePath;
15075 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15076 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15077 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15078 Expr *ReductionOp = nullptr;
15079 if (S.CurContext->isDependentContext() &&
15080 (DeclareReductionRef.isUnset() ||
15081 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
15082 ReductionOp = DeclareReductionRef.get();
15083 // It will be analyzed later.
15084 RD.push(RefExpr, ReductionOp);
15085 }
15086 ValueDecl *D = Res.first;
15087 if (!D)
15088 continue;
15089
15090 Expr *TaskgroupDescriptor = nullptr;
15091 QualType Type;
15092 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
15093 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
15094 if (ASE) {
15095 Type = ASE->getType().getNonReferenceType();
15096 } else if (OASE) {
15097 QualType BaseType =
15098 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15099 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15100 Type = ATy->getElementType();
15101 else
15102 Type = BaseType->getPointeeType();
15103 Type = Type.getNonReferenceType();
15104 } else {
15105 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
15106 }
15107 auto *VD = dyn_cast<VarDecl>(D);
15108
15109 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15110 // A variable that appears in a private clause must not have an incomplete
15111 // type or a reference type.
15112 if (S.RequireCompleteType(ELoc, D->getType(),
15113 diag::err_omp_reduction_incomplete_type))
15114 continue;
15115 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15116 // A list item that appears in a reduction clause must not be
15117 // const-qualified.
15118 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
15119 /*AcceptIfMutable*/ false, ASE || OASE))
15120 continue;
15121
15122 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
15123 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
15124 // If a list-item is a reference type then it must bind to the same object
15125 // for all threads of the team.
15126 if (!ASE && !OASE) {
15127 if (VD) {
15128 VarDecl *VDDef = VD->getDefinition();
15129 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15130 DSARefChecker Check(Stack);
15131 if (Check.Visit(VDDef->getInit())) {
15132 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15133 << getOpenMPClauseName(ClauseKind) << ERange;
15134 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15135 continue;
15136 }
15137 }
15138 }
15139
15140 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15141 // in a Construct]
15142 // Variables with the predetermined data-sharing attributes may not be
15143 // listed in data-sharing attributes clauses, except for the cases
15144 // listed below. For these exceptions only, listing a predetermined
15145 // variable in a data-sharing attribute clause is allowed and overrides
15146 // the variable's predetermined data-sharing attributes.
15147 // OpenMP [2.14.3.6, Restrictions, p.3]
15148 // Any number of reduction clauses can be specified on the directive,
15149 // but a list item can appear only once in the reduction clauses for that
15150 // directive.
15151 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15152 if (DVar.CKind == OMPC_reduction) {
15153 S.Diag(ELoc, diag::err_omp_once_referenced)
15154 << getOpenMPClauseName(ClauseKind);
15155 if (DVar.RefExpr)
15156 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15157 continue;
15158 }
15159 if (DVar.CKind != OMPC_unknown) {
15160 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15161 << getOpenMPClauseName(DVar.CKind)
15162 << getOpenMPClauseName(OMPC_reduction);
15163 reportOriginalDsa(S, Stack, D, DVar);
15164 continue;
15165 }
15166
15167 // OpenMP [2.14.3.6, Restrictions, p.1]
15168 // A list item that appears in a reduction clause of a worksharing
15169 // construct must be shared in the parallel regions to which any of the
15170 // worksharing regions arising from the worksharing construct bind.
15171 if (isOpenMPWorksharingDirective(CurrDir) &&
15172 !isOpenMPParallelDirective(CurrDir) &&
15173 !isOpenMPTeamsDirective(CurrDir)) {
15174 DVar = Stack->getImplicitDSA(D, true);
15175 if (DVar.CKind != OMPC_shared) {
15176 S.Diag(ELoc, diag::err_omp_required_access)
15177 << getOpenMPClauseName(OMPC_reduction)
15178 << getOpenMPClauseName(OMPC_shared);
15179 reportOriginalDsa(S, Stack, D, DVar);
15180 continue;
15181 }
15182 }
15183 } else {
15184 // Threadprivates cannot be shared between threads, so dignose if the base
15185 // is a threadprivate variable.
15186 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15187 if (DVar.CKind == OMPC_threadprivate) {
15188 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15189 << getOpenMPClauseName(DVar.CKind)
15190 << getOpenMPClauseName(OMPC_reduction);
15191 reportOriginalDsa(S, Stack, D, DVar);
15192 continue;
15193 }
15194 }
15195
15196 // Try to find 'declare reduction' corresponding construct before using
15197 // builtin/overloaded operators.
15198 CXXCastPath BasePath;
15199 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15200 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15201 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15202 if (DeclareReductionRef.isInvalid())
15203 continue;
15204 if (S.CurContext->isDependentContext() &&
15205 (DeclareReductionRef.isUnset() ||
15206 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15207 RD.push(RefExpr, DeclareReductionRef.get());
15208 continue;
15209 }
15210 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15211 // Not allowed reduction identifier is found.
15212 S.Diag(ReductionId.getBeginLoc(),
15213 diag::err_omp_unknown_reduction_identifier)
15214 << Type << ReductionIdRange;
15215 continue;
15216 }
15217
15218 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15219 // The type of a list item that appears in a reduction clause must be valid
15220 // for the reduction-identifier. For a max or min reduction in C, the type
15221 // of the list item must be an allowed arithmetic data type: char, int,
15222 // float, double, or _Bool, possibly modified with long, short, signed, or
15223 // unsigned. For a max or min reduction in C++, the type of the list item
15224 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15225 // double, or bool, possibly modified with long, short, signed, or unsigned.
15226 if (DeclareReductionRef.isUnset()) {
15227 if ((BOK == BO_GT || BOK == BO_LT) &&
15228 !(Type->isScalarType() ||
15229 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15230 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15231 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15232 if (!ASE && !OASE) {
15233 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15234 VarDecl::DeclarationOnly;
15235 S.Diag(D->getLocation(),
15236 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15237 << D;
15238 }
15239 continue;
15240 }
15241 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15242 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15243 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15244 << getOpenMPClauseName(ClauseKind);
15245 if (!ASE && !OASE) {
15246 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15247 VarDecl::DeclarationOnly;
15248 S.Diag(D->getLocation(),
15249 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15250 << D;
15251 }
15252 continue;
15253 }
15254 }
15255
15256 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15257 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15258 D->hasAttrs() ? &D->getAttrs() : nullptr);
15259 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15260 D->hasAttrs() ? &D->getAttrs() : nullptr);
15261 QualType PrivateTy = Type;
15262
15263 // Try if we can determine constant lengths for all array sections and avoid
15264 // the VLA.
15265 bool ConstantLengthOASE = false;
15266 if (OASE) {
15267 bool SingleElement;
15268 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15269 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15270 Context, OASE, SingleElement, ArraySizes);
15271
15272 // If we don't have a single element, we must emit a constant array type.
15273 if (ConstantLengthOASE && !SingleElement) {
15274 for (llvm::APSInt &Size : ArraySizes)
15275 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15276 ArrayType::Normal,
15277 /*IndexTypeQuals=*/0);
15278 }
15279 }
15280
15281 if ((OASE && !ConstantLengthOASE) ||
15282 (!OASE && !ASE &&
15283 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15284 if (!Context.getTargetInfo().isVLASupported()) {
15285 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15286 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15287 S.Diag(ELoc, diag::note_vla_unsupported);
15288 continue;
15289 } else {
15290 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15291 S.targetDiag(ELoc, diag::note_vla_unsupported);
15292 }
15293 }
15294 // For arrays/array sections only:
15295 // Create pseudo array type for private copy. The size for this array will
15296 // be generated during codegen.
15297 // For array subscripts or single variables Private Ty is the same as Type
15298 // (type of the variable or single array element).
15299 PrivateTy = Context.getVariableArrayType(
15300 Type,
15301 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15302 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15303 } else if (!ASE && !OASE &&
15304 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15305 PrivateTy = D->getType().getNonReferenceType();
15306 }
15307 // Private copy.
15308 VarDecl *PrivateVD =
15309 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15310 D->hasAttrs() ? &D->getAttrs() : nullptr,
15311 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15312 // Add initializer for private variable.
15313 Expr *Init = nullptr;
15314 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15315 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15316 if (DeclareReductionRef.isUsable()) {
15317 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15318 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15319 if (DRD->getInitializer()) {
15320 S.ActOnUninitializedDecl(PrivateVD);
15321 Init = DRDRef;
15322 RHSVD->setInit(DRDRef);
15323 RHSVD->setInitStyle(VarDecl::CallInit);
15324 }
15325 } else {
15326 switch (BOK) {
15327 case BO_Add:
15328 case BO_Xor:
15329 case BO_Or:
15330 case BO_LOr:
15331 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15332 if (Type->isScalarType() || Type->isAnyComplexType())
15333 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15334 break;
15335 case BO_Mul:
15336 case BO_LAnd:
15337 if (Type->isScalarType() || Type->isAnyComplexType()) {
15338 // '*' and '&&' reduction ops - initializer is '1'.
15339 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15340 }
15341 break;
15342 case BO_And: {
15343 // '&' reduction op - initializer is '~0'.
15344 QualType OrigType = Type;
15345 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15346 Type = ComplexTy->getElementType();
15347 if (Type->isRealFloatingType()) {
15348 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15349 Context.getFloatTypeSemantics(Type),
15350 Context.getTypeSize(Type));
15351 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15352 Type, ELoc);
15353 } else if (Type->isScalarType()) {
15354 uint64_t Size = Context.getTypeSize(Type);
15355 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15356 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15357 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15358 }
15359 if (Init && OrigType->isAnyComplexType()) {
15360 // Init = 0xFFFF + 0xFFFFi;
15361 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15362 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15363 }
15364 Type = OrigType;
15365 break;
15366 }
15367 case BO_LT:
15368 case BO_GT: {
15369 // 'min' reduction op - initializer is 'Largest representable number in
15370 // the reduction list item type'.
15371 // 'max' reduction op - initializer is 'Least representable number in
15372 // the reduction list item type'.
15373 if (Type->isIntegerType() || Type->isPointerType()) {
15374 bool IsSigned = Type->hasSignedIntegerRepresentation();
15375 uint64_t Size = Context.getTypeSize(Type);
15376 QualType IntTy =
15377 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15378 llvm::APInt InitValue =
15379 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15380 : llvm::APInt::getMinValue(Size)
15381 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15382 : llvm::APInt::getMaxValue(Size);
15383 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15384 if (Type->isPointerType()) {
15385 // Cast to pointer type.
15386 ExprResult CastExpr = S.BuildCStyleCastExpr(
15387 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15388 if (CastExpr.isInvalid())
15389 continue;
15390 Init = CastExpr.get();
15391 }
15392 } else if (Type->isRealFloatingType()) {
15393 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15394 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15395 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15396 Type, ELoc);
15397 }
15398 break;
15399 }
15400 case BO_PtrMemD:
15401 case BO_PtrMemI:
15402 case BO_MulAssign:
15403 case BO_Div:
15404 case BO_Rem:
15405 case BO_Sub:
15406 case BO_Shl:
15407 case BO_Shr:
15408 case BO_LE:
15409 case BO_GE:
15410 case BO_EQ:
15411 case BO_NE:
15412 case BO_Cmp:
15413 case BO_AndAssign:
15414 case BO_XorAssign:
15415 case BO_OrAssign:
15416 case BO_Assign:
15417 case BO_AddAssign:
15418 case BO_SubAssign:
15419 case BO_DivAssign:
15420 case BO_RemAssign:
15421 case BO_ShlAssign:
15422 case BO_ShrAssign:
15423 case BO_Comma:
15424 llvm_unreachable("Unexpected reduction operation");
15425 }
15426 }
15427 if (Init && DeclareReductionRef.isUnset()) {
15428 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15429 // Store initializer for single element in private copy. Will be used
15430 // during codegen.
15431 PrivateVD->setInit(RHSVD->getInit());
15432 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15433 } else if (!Init) {
15434 S.ActOnUninitializedDecl(RHSVD);
15435 // Store initializer for single element in private copy. Will be used
15436 // during codegen.
15437 PrivateVD->setInit(RHSVD->getInit());
15438 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15439 }
15440 if (RHSVD->isInvalidDecl())
15441 continue;
15442 if (!RHSVD->hasInit() &&
15443 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15444 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15445 << Type << ReductionIdRange;
15446 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15447 VarDecl::DeclarationOnly;
15448 S.Diag(D->getLocation(),
15449 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15450 << D;
15451 continue;
15452 }
15453 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15454 ExprResult ReductionOp;
15455 if (DeclareReductionRef.isUsable()) {
15456 QualType RedTy = DeclareReductionRef.get()->getType();
15457 QualType PtrRedTy = Context.getPointerType(RedTy);
15458 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15459 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15460 if (!BasePath.empty()) {
15461 LHS = S.DefaultLvalueConversion(LHS.get());
15462 RHS = S.DefaultLvalueConversion(RHS.get());
15463 LHS = ImplicitCastExpr::Create(
15464 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
15465 LHS.get()->getValueKind(), FPOptionsOverride());
15466 RHS = ImplicitCastExpr::Create(
15467 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
15468 RHS.get()->getValueKind(), FPOptionsOverride());
15469 }
15470 FunctionProtoType::ExtProtoInfo EPI;
15471 QualType Params[] = {PtrRedTy, PtrRedTy};
15472 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15473 auto *OVE = new (Context) OpaqueValueExpr(
15474 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15475 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15476 Expr *Args[] = {LHS.get(), RHS.get()};
15477 ReductionOp =
15478 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
15479 S.CurFPFeatureOverrides());
15480 } else {
15481 ReductionOp = S.BuildBinOp(
15482 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15483 if (ReductionOp.isUsable()) {
15484 if (BOK != BO_LT && BOK != BO_GT) {
15485 ReductionOp =
15486 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15487 BO_Assign, LHSDRE, ReductionOp.get());
15488 } else {
15489 auto *ConditionalOp = new (Context)
15490 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15491 Type, VK_LValue, OK_Ordinary);
15492 ReductionOp =
15493 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15494 BO_Assign, LHSDRE, ConditionalOp);
15495 }
15496 if (ReductionOp.isUsable())
15497 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15498 /*DiscardedValue*/ false);
15499 }
15500 if (!ReductionOp.isUsable())
15501 continue;
15502 }
15503
15504 // Add copy operations for inscan reductions.
15505 // LHS = RHS;
15506 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15507 if (ClauseKind == OMPC_reduction &&
15508 RD.RedModifier == OMPC_REDUCTION_inscan) {
15509 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15510 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15511 RHS.get());
15512 if (!CopyOpRes.isUsable())
15513 continue;
15514 CopyOpRes =
15515 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15516 if (!CopyOpRes.isUsable())
15517 continue;
15518 // For simd directive and simd-based directives in simd mode no need to
15519 // construct temp array, need just a single temp element.
15520 if (Stack->getCurrentDirective() == OMPD_simd ||
15521 (S.getLangOpts().OpenMPSimd &&
15522 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15523 VarDecl *TempArrayVD =
15524 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15525 D->hasAttrs() ? &D->getAttrs() : nullptr);
15526 // Add a constructor to the temp decl.
15527 S.ActOnUninitializedDecl(TempArrayVD);
15528 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15529 } else {
15530 // Build temp array for prefix sum.
15531 auto *Dim = new (S.Context)
15532 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15533 QualType ArrayTy =
15534 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15535 /*IndexTypeQuals=*/0, {ELoc, ELoc});
15536 VarDecl *TempArrayVD =
15537 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15538 D->hasAttrs() ? &D->getAttrs() : nullptr);
15539 // Add a constructor to the temp decl.
15540 S.ActOnUninitializedDecl(TempArrayVD);
15541 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15542 TempArrayElem =
15543 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15544 auto *Idx = new (S.Context)
15545 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15546 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15547 ELoc, Idx, ELoc);
15548 }
15549 }
15550
15551 // OpenMP [2.15.4.6, Restrictions, p.2]
15552 // A list item that appears in an in_reduction clause of a task construct
15553 // must appear in a task_reduction clause of a construct associated with a
15554 // taskgroup region that includes the participating task in its taskgroup
15555 // set. The construct associated with the innermost region that meets this
15556 // condition must specify the same reduction-identifier as the in_reduction
15557 // clause.
15558 if (ClauseKind == OMPC_in_reduction) {
15559 SourceRange ParentSR;
15560 BinaryOperatorKind ParentBOK;
15561 const Expr *ParentReductionOp = nullptr;
15562 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15563 DSAStackTy::DSAVarData ParentBOKDSA =
15564 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15565 ParentBOKTD);
15566 DSAStackTy::DSAVarData ParentReductionOpDSA =
15567 Stack->getTopMostTaskgroupReductionData(
15568 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15569 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15570 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15571 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15572 (DeclareReductionRef.isUsable() && IsParentBOK) ||
15573 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15574 bool EmitError = true;
15575 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15576 llvm::FoldingSetNodeID RedId, ParentRedId;
15577 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15578 DeclareReductionRef.get()->Profile(RedId, Context,
15579 /*Canonical=*/true);
15580 EmitError = RedId != ParentRedId;
15581 }
15582 if (EmitError) {
15583 S.Diag(ReductionId.getBeginLoc(),
15584 diag::err_omp_reduction_identifier_mismatch)
15585 << ReductionIdRange << RefExpr->getSourceRange();
15586 S.Diag(ParentSR.getBegin(),
15587 diag::note_omp_previous_reduction_identifier)
15588 << ParentSR
15589 << (IsParentBOK ? ParentBOKDSA.RefExpr
15590 : ParentReductionOpDSA.RefExpr)
15591 ->getSourceRange();
15592 continue;
15593 }
15594 }
15595 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15596 }
15597
15598 DeclRefExpr *Ref = nullptr;
15599 Expr *VarsExpr = RefExpr->IgnoreParens();
15600 if (!VD && !S.CurContext->isDependentContext()) {
15601 if (ASE || OASE) {
15602 TransformExprToCaptures RebuildToCapture(S, D);
15603 VarsExpr =
15604 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15605 Ref = RebuildToCapture.getCapturedExpr();
15606 } else {
15607 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15608 }
15609 if (!S.isOpenMPCapturedDecl(D)) {
15610 RD.ExprCaptures.emplace_back(Ref->getDecl());
15611 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15612 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15613 if (!RefRes.isUsable())
15614 continue;
15615 ExprResult PostUpdateRes =
15616 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15617 RefRes.get());
15618 if (!PostUpdateRes.isUsable())
15619 continue;
15620 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15621 Stack->getCurrentDirective() == OMPD_taskgroup) {
15622 S.Diag(RefExpr->getExprLoc(),
15623 diag::err_omp_reduction_non_addressable_expression)
15624 << RefExpr->getSourceRange();
15625 continue;
15626 }
15627 RD.ExprPostUpdates.emplace_back(
15628 S.IgnoredValueConversions(PostUpdateRes.get()).get());
15629 }
15630 }
15631 }
15632 // All reduction items are still marked as reduction (to do not increase
15633 // code base size).
15634 unsigned Modifier = RD.RedModifier;
15635 // Consider task_reductions as reductions with task modifier. Required for
15636 // correct analysis of in_reduction clauses.
15637 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15638 Modifier = OMPC_REDUCTION_task;
15639 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
15640 ASE || OASE);
15641 if (Modifier == OMPC_REDUCTION_task &&
15642 (CurrDir == OMPD_taskgroup ||
15643 ((isOpenMPParallelDirective(CurrDir) ||
15644 isOpenMPWorksharingDirective(CurrDir)) &&
15645 !isOpenMPSimdDirective(CurrDir)))) {
15646 if (DeclareReductionRef.isUsable())
15647 Stack->addTaskgroupReductionData(D, ReductionIdRange,
15648 DeclareReductionRef.get());
15649 else
15650 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15651 }
15652 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15653 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15654 TempArrayElem.get());
15655 }
15656 return RD.Vars.empty();
15657 }
15658
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15659 OMPClause *Sema::ActOnOpenMPReductionClause(
15660 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15661 SourceLocation StartLoc, SourceLocation LParenLoc,
15662 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15663 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15664 ArrayRef<Expr *> UnresolvedReductions) {
15665 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15666 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15667 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15668 /*Last=*/OMPC_REDUCTION_unknown)
15669 << getOpenMPClauseName(OMPC_reduction);
15670 return nullptr;
15671 }
15672 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15673 // A reduction clause with the inscan reduction-modifier may only appear on a
15674 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15675 // construct, a parallel worksharing-loop construct or a parallel
15676 // worksharing-loop SIMD construct.
15677 if (Modifier == OMPC_REDUCTION_inscan &&
15678 (DSAStack->getCurrentDirective() != OMPD_for &&
15679 DSAStack->getCurrentDirective() != OMPD_for_simd &&
15680 DSAStack->getCurrentDirective() != OMPD_simd &&
15681 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
15682 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
15683 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15684 return nullptr;
15685 }
15686
15687 ReductionData RD(VarList.size(), Modifier);
15688 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
15689 StartLoc, LParenLoc, ColonLoc, EndLoc,
15690 ReductionIdScopeSpec, ReductionId,
15691 UnresolvedReductions, RD))
15692 return nullptr;
15693
15694 return OMPReductionClause::Create(
15695 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15696 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15697 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15698 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15699 buildPreInits(Context, RD.ExprCaptures),
15700 buildPostUpdate(*this, RD.ExprPostUpdates));
15701 }
15702
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15703 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15704 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15705 SourceLocation ColonLoc, SourceLocation EndLoc,
15706 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15707 ArrayRef<Expr *> UnresolvedReductions) {
15708 ReductionData RD(VarList.size());
15709 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
15710 StartLoc, LParenLoc, ColonLoc, EndLoc,
15711 ReductionIdScopeSpec, ReductionId,
15712 UnresolvedReductions, RD))
15713 return nullptr;
15714
15715 return OMPTaskReductionClause::Create(
15716 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15717 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15718 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15719 buildPreInits(Context, RD.ExprCaptures),
15720 buildPostUpdate(*this, RD.ExprPostUpdates));
15721 }
15722
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15723 OMPClause *Sema::ActOnOpenMPInReductionClause(
15724 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15725 SourceLocation ColonLoc, SourceLocation EndLoc,
15726 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15727 ArrayRef<Expr *> UnresolvedReductions) {
15728 ReductionData RD(VarList.size());
15729 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
15730 StartLoc, LParenLoc, ColonLoc, EndLoc,
15731 ReductionIdScopeSpec, ReductionId,
15732 UnresolvedReductions, RD))
15733 return nullptr;
15734
15735 return OMPInReductionClause::Create(
15736 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15737 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15738 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15739 buildPreInits(Context, RD.ExprCaptures),
15740 buildPostUpdate(*this, RD.ExprPostUpdates));
15741 }
15742
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)15743 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15744 SourceLocation LinLoc) {
15745 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15746 LinKind == OMPC_LINEAR_unknown) {
15747 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15748 return true;
15749 }
15750 return false;
15751 }
15752
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)15753 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15754 OpenMPLinearClauseKind LinKind, QualType Type,
15755 bool IsDeclareSimd) {
15756 const auto *VD = dyn_cast_or_null<VarDecl>(D);
15757 // A variable must not have an incomplete type or a reference type.
15758 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15759 return true;
15760 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15761 !Type->isReferenceType()) {
15762 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15763 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15764 return true;
15765 }
15766 Type = Type.getNonReferenceType();
15767
15768 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15769 // A variable that is privatized must not have a const-qualified type
15770 // unless it is of class type with a mutable member. This restriction does
15771 // not apply to the firstprivate clause, nor to the linear clause on
15772 // declarative directives (like declare simd).
15773 if (!IsDeclareSimd &&
15774 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15775 return true;
15776
15777 // A list item must be of integral or pointer type.
15778 Type = Type.getUnqualifiedType().getCanonicalType();
15779 const auto *Ty = Type.getTypePtrOrNull();
15780 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15781 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15782 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15783 if (D) {
15784 bool IsDecl =
15785 !VD ||
15786 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15787 Diag(D->getLocation(),
15788 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15789 << D;
15790 }
15791 return true;
15792 }
15793 return false;
15794 }
15795
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)15796 OMPClause *Sema::ActOnOpenMPLinearClause(
15797 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15798 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15799 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15800 SmallVector<Expr *, 8> Vars;
15801 SmallVector<Expr *, 8> Privates;
15802 SmallVector<Expr *, 8> Inits;
15803 SmallVector<Decl *, 4> ExprCaptures;
15804 SmallVector<Expr *, 4> ExprPostUpdates;
15805 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15806 LinKind = OMPC_LINEAR_val;
15807 for (Expr *RefExpr : VarList) {
15808 assert(RefExpr && "NULL expr in OpenMP linear clause.");
15809 SourceLocation ELoc;
15810 SourceRange ERange;
15811 Expr *SimpleRefExpr = RefExpr;
15812 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15813 if (Res.second) {
15814 // It will be analyzed later.
15815 Vars.push_back(RefExpr);
15816 Privates.push_back(nullptr);
15817 Inits.push_back(nullptr);
15818 }
15819 ValueDecl *D = Res.first;
15820 if (!D)
15821 continue;
15822
15823 QualType Type = D->getType();
15824 auto *VD = dyn_cast<VarDecl>(D);
15825
15826 // OpenMP [2.14.3.7, linear clause]
15827 // A list-item cannot appear in more than one linear clause.
15828 // A list-item that appears in a linear clause cannot appear in any
15829 // other data-sharing attribute clause.
15830 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15831 if (DVar.RefExpr) {
15832 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15833 << getOpenMPClauseName(OMPC_linear);
15834 reportOriginalDsa(*this, DSAStack, D, DVar);
15835 continue;
15836 }
15837
15838 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15839 continue;
15840 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15841
15842 // Build private copy of original var.
15843 VarDecl *Private =
15844 buildVarDecl(*this, ELoc, Type, D->getName(),
15845 D->hasAttrs() ? &D->getAttrs() : nullptr,
15846 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15847 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15848 // Build var to save initial value.
15849 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15850 Expr *InitExpr;
15851 DeclRefExpr *Ref = nullptr;
15852 if (!VD && !CurContext->isDependentContext()) {
15853 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15854 if (!isOpenMPCapturedDecl(D)) {
15855 ExprCaptures.push_back(Ref->getDecl());
15856 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15857 ExprResult RefRes = DefaultLvalueConversion(Ref);
15858 if (!RefRes.isUsable())
15859 continue;
15860 ExprResult PostUpdateRes =
15861 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
15862 SimpleRefExpr, RefRes.get());
15863 if (!PostUpdateRes.isUsable())
15864 continue;
15865 ExprPostUpdates.push_back(
15866 IgnoredValueConversions(PostUpdateRes.get()).get());
15867 }
15868 }
15869 }
15870 if (LinKind == OMPC_LINEAR_uval)
15871 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
15872 else
15873 InitExpr = VD ? SimpleRefExpr : Ref;
15874 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
15875 /*DirectInit=*/false);
15876 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
15877
15878 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
15879 Vars.push_back((VD || CurContext->isDependentContext())
15880 ? RefExpr->IgnoreParens()
15881 : Ref);
15882 Privates.push_back(PrivateRef);
15883 Inits.push_back(InitRef);
15884 }
15885
15886 if (Vars.empty())
15887 return nullptr;
15888
15889 Expr *StepExpr = Step;
15890 Expr *CalcStepExpr = nullptr;
15891 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
15892 !Step->isInstantiationDependent() &&
15893 !Step->containsUnexpandedParameterPack()) {
15894 SourceLocation StepLoc = Step->getBeginLoc();
15895 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
15896 if (Val.isInvalid())
15897 return nullptr;
15898 StepExpr = Val.get();
15899
15900 // Build var to save the step value.
15901 VarDecl *SaveVar =
15902 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
15903 ExprResult SaveRef =
15904 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
15905 ExprResult CalcStep =
15906 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
15907 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
15908
15909 // Warn about zero linear step (it would be probably better specified as
15910 // making corresponding variables 'const').
15911 if (Optional<llvm::APSInt> Result =
15912 StepExpr->getIntegerConstantExpr(Context)) {
15913 if (!Result->isNegative() && !Result->isStrictlyPositive())
15914 Diag(StepLoc, diag::warn_omp_linear_step_zero)
15915 << Vars[0] << (Vars.size() > 1);
15916 } else if (CalcStep.isUsable()) {
15917 // Calculate the step beforehand instead of doing this on each iteration.
15918 // (This is not used if the number of iterations may be kfold-ed).
15919 CalcStepExpr = CalcStep.get();
15920 }
15921 }
15922
15923 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
15924 ColonLoc, EndLoc, Vars, Privates, Inits,
15925 StepExpr, CalcStepExpr,
15926 buildPreInits(Context, ExprCaptures),
15927 buildPostUpdate(*this, ExprPostUpdates));
15928 }
15929
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)15930 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
15931 Expr *NumIterations, Sema &SemaRef,
15932 Scope *S, DSAStackTy *Stack) {
15933 // Walk the vars and build update/final expressions for the CodeGen.
15934 SmallVector<Expr *, 8> Updates;
15935 SmallVector<Expr *, 8> Finals;
15936 SmallVector<Expr *, 8> UsedExprs;
15937 Expr *Step = Clause.getStep();
15938 Expr *CalcStep = Clause.getCalcStep();
15939 // OpenMP [2.14.3.7, linear clause]
15940 // If linear-step is not specified it is assumed to be 1.
15941 if (!Step)
15942 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
15943 else if (CalcStep)
15944 Step = cast<BinaryOperator>(CalcStep)->getLHS();
15945 bool HasErrors = false;
15946 auto CurInit = Clause.inits().begin();
15947 auto CurPrivate = Clause.privates().begin();
15948 OpenMPLinearClauseKind LinKind = Clause.getModifier();
15949 for (Expr *RefExpr : Clause.varlists()) {
15950 SourceLocation ELoc;
15951 SourceRange ERange;
15952 Expr *SimpleRefExpr = RefExpr;
15953 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
15954 ValueDecl *D = Res.first;
15955 if (Res.second || !D) {
15956 Updates.push_back(nullptr);
15957 Finals.push_back(nullptr);
15958 HasErrors = true;
15959 continue;
15960 }
15961 auto &&Info = Stack->isLoopControlVariable(D);
15962 // OpenMP [2.15.11, distribute simd Construct]
15963 // A list item may not appear in a linear clause, unless it is the loop
15964 // iteration variable.
15965 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
15966 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
15967 SemaRef.Diag(ELoc,
15968 diag::err_omp_linear_distribute_var_non_loop_iteration);
15969 Updates.push_back(nullptr);
15970 Finals.push_back(nullptr);
15971 HasErrors = true;
15972 continue;
15973 }
15974 Expr *InitExpr = *CurInit;
15975
15976 // Build privatized reference to the current linear var.
15977 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
15978 Expr *CapturedRef;
15979 if (LinKind == OMPC_LINEAR_uval)
15980 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
15981 else
15982 CapturedRef =
15983 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
15984 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
15985 /*RefersToCapture=*/true);
15986
15987 // Build update: Var = InitExpr + IV * Step
15988 ExprResult Update;
15989 if (!Info.first)
15990 Update = buildCounterUpdate(
15991 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
15992 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
15993 else
15994 Update = *CurPrivate;
15995 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
15996 /*DiscardedValue*/ false);
15997
15998 // Build final: Var = InitExpr + NumIterations * Step
15999 ExprResult Final;
16000 if (!Info.first)
16001 Final =
16002 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
16003 InitExpr, NumIterations, Step, /*Subtract=*/false,
16004 /*IsNonRectangularLB=*/false);
16005 else
16006 Final = *CurPrivate;
16007 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
16008 /*DiscardedValue*/ false);
16009
16010 if (!Update.isUsable() || !Final.isUsable()) {
16011 Updates.push_back(nullptr);
16012 Finals.push_back(nullptr);
16013 UsedExprs.push_back(nullptr);
16014 HasErrors = true;
16015 } else {
16016 Updates.push_back(Update.get());
16017 Finals.push_back(Final.get());
16018 if (!Info.first)
16019 UsedExprs.push_back(SimpleRefExpr);
16020 }
16021 ++CurInit;
16022 ++CurPrivate;
16023 }
16024 if (Expr *S = Clause.getStep())
16025 UsedExprs.push_back(S);
16026 // Fill the remaining part with the nullptr.
16027 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
16028 Clause.setUpdates(Updates);
16029 Clause.setFinals(Finals);
16030 Clause.setUsedExprs(UsedExprs);
16031 return HasErrors;
16032 }
16033
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)16034 OMPClause *Sema::ActOnOpenMPAlignedClause(
16035 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
16036 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16037 SmallVector<Expr *, 8> Vars;
16038 for (Expr *RefExpr : VarList) {
16039 assert(RefExpr && "NULL expr in OpenMP linear clause.");
16040 SourceLocation ELoc;
16041 SourceRange ERange;
16042 Expr *SimpleRefExpr = RefExpr;
16043 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16044 if (Res.second) {
16045 // It will be analyzed later.
16046 Vars.push_back(RefExpr);
16047 }
16048 ValueDecl *D = Res.first;
16049 if (!D)
16050 continue;
16051
16052 QualType QType = D->getType();
16053 auto *VD = dyn_cast<VarDecl>(D);
16054
16055 // OpenMP [2.8.1, simd construct, Restrictions]
16056 // The type of list items appearing in the aligned clause must be
16057 // array, pointer, reference to array, or reference to pointer.
16058 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16059 const Type *Ty = QType.getTypePtrOrNull();
16060 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
16061 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
16062 << QType << getLangOpts().CPlusPlus << ERange;
16063 bool IsDecl =
16064 !VD ||
16065 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16066 Diag(D->getLocation(),
16067 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16068 << D;
16069 continue;
16070 }
16071
16072 // OpenMP [2.8.1, simd construct, Restrictions]
16073 // A list-item cannot appear in more than one aligned clause.
16074 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
16075 Diag(ELoc, diag::err_omp_used_in_clause_twice)
16076 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
16077 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
16078 << getOpenMPClauseName(OMPC_aligned);
16079 continue;
16080 }
16081
16082 DeclRefExpr *Ref = nullptr;
16083 if (!VD && isOpenMPCapturedDecl(D))
16084 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16085 Vars.push_back(DefaultFunctionArrayConversion(
16086 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
16087 .get());
16088 }
16089
16090 // OpenMP [2.8.1, simd construct, Description]
16091 // The parameter of the aligned clause, alignment, must be a constant
16092 // positive integer expression.
16093 // If no optional parameter is specified, implementation-defined default
16094 // alignments for SIMD instructions on the target platforms are assumed.
16095 if (Alignment != nullptr) {
16096 ExprResult AlignResult =
16097 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
16098 if (AlignResult.isInvalid())
16099 return nullptr;
16100 Alignment = AlignResult.get();
16101 }
16102 if (Vars.empty())
16103 return nullptr;
16104
16105 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
16106 EndLoc, Vars, Alignment);
16107 }
16108
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16109 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
16110 SourceLocation StartLoc,
16111 SourceLocation LParenLoc,
16112 SourceLocation EndLoc) {
16113 SmallVector<Expr *, 8> Vars;
16114 SmallVector<Expr *, 8> SrcExprs;
16115 SmallVector<Expr *, 8> DstExprs;
16116 SmallVector<Expr *, 8> AssignmentOps;
16117 for (Expr *RefExpr : VarList) {
16118 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
16119 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16120 // It will be analyzed later.
16121 Vars.push_back(RefExpr);
16122 SrcExprs.push_back(nullptr);
16123 DstExprs.push_back(nullptr);
16124 AssignmentOps.push_back(nullptr);
16125 continue;
16126 }
16127
16128 SourceLocation ELoc = RefExpr->getExprLoc();
16129 // OpenMP [2.1, C/C++]
16130 // A list item is a variable name.
16131 // OpenMP [2.14.4.1, Restrictions, p.1]
16132 // A list item that appears in a copyin clause must be threadprivate.
16133 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
16134 if (!DE || !isa<VarDecl>(DE->getDecl())) {
16135 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
16136 << 0 << RefExpr->getSourceRange();
16137 continue;
16138 }
16139
16140 Decl *D = DE->getDecl();
16141 auto *VD = cast<VarDecl>(D);
16142
16143 QualType Type = VD->getType();
16144 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16145 // It will be analyzed later.
16146 Vars.push_back(DE);
16147 SrcExprs.push_back(nullptr);
16148 DstExprs.push_back(nullptr);
16149 AssignmentOps.push_back(nullptr);
16150 continue;
16151 }
16152
16153 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16154 // A list item that appears in a copyin clause must be threadprivate.
16155 if (!DSAStack->isThreadPrivate(VD)) {
16156 Diag(ELoc, diag::err_omp_required_access)
16157 << getOpenMPClauseName(OMPC_copyin)
16158 << getOpenMPDirectiveName(OMPD_threadprivate);
16159 continue;
16160 }
16161
16162 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16163 // A variable of class type (or array thereof) that appears in a
16164 // copyin clause requires an accessible, unambiguous copy assignment
16165 // operator for the class type.
16166 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16167 VarDecl *SrcVD =
16168 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16169 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16170 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16171 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16172 VarDecl *DstVD =
16173 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16174 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16175 DeclRefExpr *PseudoDstExpr =
16176 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16177 // For arrays generate assignment operation for single element and replace
16178 // it by the original array element in CodeGen.
16179 ExprResult AssignmentOp =
16180 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16181 PseudoSrcExpr);
16182 if (AssignmentOp.isInvalid())
16183 continue;
16184 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16185 /*DiscardedValue*/ false);
16186 if (AssignmentOp.isInvalid())
16187 continue;
16188
16189 DSAStack->addDSA(VD, DE, OMPC_copyin);
16190 Vars.push_back(DE);
16191 SrcExprs.push_back(PseudoSrcExpr);
16192 DstExprs.push_back(PseudoDstExpr);
16193 AssignmentOps.push_back(AssignmentOp.get());
16194 }
16195
16196 if (Vars.empty())
16197 return nullptr;
16198
16199 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16200 SrcExprs, DstExprs, AssignmentOps);
16201 }
16202
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16203 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16204 SourceLocation StartLoc,
16205 SourceLocation LParenLoc,
16206 SourceLocation EndLoc) {
16207 SmallVector<Expr *, 8> Vars;
16208 SmallVector<Expr *, 8> SrcExprs;
16209 SmallVector<Expr *, 8> DstExprs;
16210 SmallVector<Expr *, 8> AssignmentOps;
16211 for (Expr *RefExpr : VarList) {
16212 assert(RefExpr && "NULL expr in OpenMP linear clause.");
16213 SourceLocation ELoc;
16214 SourceRange ERange;
16215 Expr *SimpleRefExpr = RefExpr;
16216 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16217 if (Res.second) {
16218 // It will be analyzed later.
16219 Vars.push_back(RefExpr);
16220 SrcExprs.push_back(nullptr);
16221 DstExprs.push_back(nullptr);
16222 AssignmentOps.push_back(nullptr);
16223 }
16224 ValueDecl *D = Res.first;
16225 if (!D)
16226 continue;
16227
16228 QualType Type = D->getType();
16229 auto *VD = dyn_cast<VarDecl>(D);
16230
16231 // OpenMP [2.14.4.2, Restrictions, p.2]
16232 // A list item that appears in a copyprivate clause may not appear in a
16233 // private or firstprivate clause on the single construct.
16234 if (!VD || !DSAStack->isThreadPrivate(VD)) {
16235 DSAStackTy::DSAVarData DVar =
16236 DSAStack->getTopDSA(D, /*FromParent=*/false);
16237 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16238 DVar.RefExpr) {
16239 Diag(ELoc, diag::err_omp_wrong_dsa)
16240 << getOpenMPClauseName(DVar.CKind)
16241 << getOpenMPClauseName(OMPC_copyprivate);
16242 reportOriginalDsa(*this, DSAStack, D, DVar);
16243 continue;
16244 }
16245
16246 // OpenMP [2.11.4.2, Restrictions, p.1]
16247 // All list items that appear in a copyprivate clause must be either
16248 // threadprivate or private in the enclosing context.
16249 if (DVar.CKind == OMPC_unknown) {
16250 DVar = DSAStack->getImplicitDSA(D, false);
16251 if (DVar.CKind == OMPC_shared) {
16252 Diag(ELoc, diag::err_omp_required_access)
16253 << getOpenMPClauseName(OMPC_copyprivate)
16254 << "threadprivate or private in the enclosing context";
16255 reportOriginalDsa(*this, DSAStack, D, DVar);
16256 continue;
16257 }
16258 }
16259 }
16260
16261 // Variably modified types are not supported.
16262 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16263 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16264 << getOpenMPClauseName(OMPC_copyprivate) << Type
16265 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16266 bool IsDecl =
16267 !VD ||
16268 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16269 Diag(D->getLocation(),
16270 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16271 << D;
16272 continue;
16273 }
16274
16275 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16276 // A variable of class type (or array thereof) that appears in a
16277 // copyin clause requires an accessible, unambiguous copy assignment
16278 // operator for the class type.
16279 Type = Context.getBaseElementType(Type.getNonReferenceType())
16280 .getUnqualifiedType();
16281 VarDecl *SrcVD =
16282 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16283 D->hasAttrs() ? &D->getAttrs() : nullptr);
16284 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16285 VarDecl *DstVD =
16286 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16287 D->hasAttrs() ? &D->getAttrs() : nullptr);
16288 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16289 ExprResult AssignmentOp = BuildBinOp(
16290 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16291 if (AssignmentOp.isInvalid())
16292 continue;
16293 AssignmentOp =
16294 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16295 if (AssignmentOp.isInvalid())
16296 continue;
16297
16298 // No need to mark vars as copyprivate, they are already threadprivate or
16299 // implicitly private.
16300 assert(VD || isOpenMPCapturedDecl(D));
16301 Vars.push_back(
16302 VD ? RefExpr->IgnoreParens()
16303 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16304 SrcExprs.push_back(PseudoSrcExpr);
16305 DstExprs.push_back(PseudoDstExpr);
16306 AssignmentOps.push_back(AssignmentOp.get());
16307 }
16308
16309 if (Vars.empty())
16310 return nullptr;
16311
16312 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16313 Vars, SrcExprs, DstExprs, AssignmentOps);
16314 }
16315
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16316 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16317 SourceLocation StartLoc,
16318 SourceLocation LParenLoc,
16319 SourceLocation EndLoc) {
16320 if (VarList.empty())
16321 return nullptr;
16322
16323 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16324 }
16325
16326 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)16327 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16328 bool Diagnose = true) {
16329 QualType OMPDependT = Stack->getOMPDependT();
16330 if (!OMPDependT.isNull())
16331 return true;
16332 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16333 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16334 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16335 if (Diagnose)
16336 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16337 return false;
16338 }
16339 Stack->setOMPDependT(PT.get());
16340 return true;
16341 }
16342
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16343 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16344 SourceLocation LParenLoc,
16345 SourceLocation EndLoc) {
16346 if (!Depobj)
16347 return nullptr;
16348
16349 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
16350
16351 // OpenMP 5.0, 2.17.10.1 depobj Construct
16352 // depobj is an lvalue expression of type omp_depend_t.
16353 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16354 !Depobj->isInstantiationDependent() &&
16355 !Depobj->containsUnexpandedParameterPack() &&
16356 (OMPDependTFound &&
16357 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
16358 /*CompareUnqualified=*/true))) {
16359 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16360 << 0 << Depobj->getType() << Depobj->getSourceRange();
16361 }
16362
16363 if (!Depobj->isLValue()) {
16364 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16365 << 1 << Depobj->getSourceRange();
16366 }
16367
16368 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16369 }
16370
16371 OMPClause *
ActOnOpenMPDependClause(Expr * DepModifier,OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16372 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16373 SourceLocation DepLoc, SourceLocation ColonLoc,
16374 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16375 SourceLocation LParenLoc, SourceLocation EndLoc) {
16376 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
16377 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16378 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16379 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16380 return nullptr;
16381 }
16382 if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
16383 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16384 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16385 DepKind == OMPC_DEPEND_sink ||
16386 ((LangOpts.OpenMP < 50 ||
16387 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16388 DepKind == OMPC_DEPEND_depobj))) {
16389 SmallVector<unsigned, 3> Except;
16390 Except.push_back(OMPC_DEPEND_source);
16391 Except.push_back(OMPC_DEPEND_sink);
16392 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
16393 Except.push_back(OMPC_DEPEND_depobj);
16394 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16395 ? "depend modifier(iterator) or "
16396 : "";
16397 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16398 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16399 /*Last=*/OMPC_DEPEND_unknown,
16400 Except)
16401 << getOpenMPClauseName(OMPC_depend);
16402 return nullptr;
16403 }
16404 if (DepModifier &&
16405 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16406 Diag(DepModifier->getExprLoc(),
16407 diag::err_omp_depend_sink_source_with_modifier);
16408 return nullptr;
16409 }
16410 if (DepModifier &&
16411 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16412 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16413
16414 SmallVector<Expr *, 8> Vars;
16415 DSAStackTy::OperatorOffsetTy OpsOffs;
16416 llvm::APSInt DepCounter(/*BitWidth=*/32);
16417 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16418 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16419 if (const Expr *OrderedCountExpr =
16420 DSAStack->getParentOrderedRegionParam().first) {
16421 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16422 TotalDepCount.setIsUnsigned(/*Val=*/true);
16423 }
16424 }
16425 for (Expr *RefExpr : VarList) {
16426 assert(RefExpr && "NULL expr in OpenMP shared clause.");
16427 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16428 // It will be analyzed later.
16429 Vars.push_back(RefExpr);
16430 continue;
16431 }
16432
16433 SourceLocation ELoc = RefExpr->getExprLoc();
16434 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16435 if (DepKind == OMPC_DEPEND_sink) {
16436 if (DSAStack->getParentOrderedRegionParam().first &&
16437 DepCounter >= TotalDepCount) {
16438 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16439 continue;
16440 }
16441 ++DepCounter;
16442 // OpenMP [2.13.9, Summary]
16443 // depend(dependence-type : vec), where dependence-type is:
16444 // 'sink' and where vec is the iteration vector, which has the form:
16445 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16446 // where n is the value specified by the ordered clause in the loop
16447 // directive, xi denotes the loop iteration variable of the i-th nested
16448 // loop associated with the loop directive, and di is a constant
16449 // non-negative integer.
16450 if (CurContext->isDependentContext()) {
16451 // It will be analyzed later.
16452 Vars.push_back(RefExpr);
16453 continue;
16454 }
16455 SimpleExpr = SimpleExpr->IgnoreImplicit();
16456 OverloadedOperatorKind OOK = OO_None;
16457 SourceLocation OOLoc;
16458 Expr *LHS = SimpleExpr;
16459 Expr *RHS = nullptr;
16460 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16461 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16462 OOLoc = BO->getOperatorLoc();
16463 LHS = BO->getLHS()->IgnoreParenImpCasts();
16464 RHS = BO->getRHS()->IgnoreParenImpCasts();
16465 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16466 OOK = OCE->getOperator();
16467 OOLoc = OCE->getOperatorLoc();
16468 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16469 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16470 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16471 OOK = MCE->getMethodDecl()
16472 ->getNameInfo()
16473 .getName()
16474 .getCXXOverloadedOperator();
16475 OOLoc = MCE->getCallee()->getExprLoc();
16476 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16477 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16478 }
16479 SourceLocation ELoc;
16480 SourceRange ERange;
16481 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16482 if (Res.second) {
16483 // It will be analyzed later.
16484 Vars.push_back(RefExpr);
16485 }
16486 ValueDecl *D = Res.first;
16487 if (!D)
16488 continue;
16489
16490 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16491 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16492 continue;
16493 }
16494 if (RHS) {
16495 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16496 RHS, OMPC_depend, /*StrictlyPositive=*/false);
16497 if (RHSRes.isInvalid())
16498 continue;
16499 }
16500 if (!CurContext->isDependentContext() &&
16501 DSAStack->getParentOrderedRegionParam().first &&
16502 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
16503 const ValueDecl *VD =
16504 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
16505 if (VD)
16506 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16507 << 1 << VD;
16508 else
16509 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16510 continue;
16511 }
16512 OpsOffs.emplace_back(RHS, OOK);
16513 } else {
16514 bool OMPDependTFound = LangOpts.OpenMP >= 50;
16515 if (OMPDependTFound)
16516 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
16517 DepKind == OMPC_DEPEND_depobj);
16518 if (DepKind == OMPC_DEPEND_depobj) {
16519 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16520 // List items used in depend clauses with the depobj dependence type
16521 // must be expressions of the omp_depend_t type.
16522 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16523 !RefExpr->isInstantiationDependent() &&
16524 !RefExpr->containsUnexpandedParameterPack() &&
16525 (OMPDependTFound &&
16526 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
16527 RefExpr->getType()))) {
16528 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16529 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16530 continue;
16531 }
16532 if (!RefExpr->isLValue()) {
16533 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16534 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16535 continue;
16536 }
16537 } else {
16538 // OpenMP 5.0 [2.17.11, Restrictions]
16539 // List items used in depend clauses cannot be zero-length array
16540 // sections.
16541 QualType ExprTy = RefExpr->getType().getNonReferenceType();
16542 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16543 if (OASE) {
16544 QualType BaseType =
16545 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16546 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16547 ExprTy = ATy->getElementType();
16548 else
16549 ExprTy = BaseType->getPointeeType();
16550 ExprTy = ExprTy.getNonReferenceType();
16551 const Expr *Length = OASE->getLength();
16552 Expr::EvalResult Result;
16553 if (Length && !Length->isValueDependent() &&
16554 Length->EvaluateAsInt(Result, Context) &&
16555 Result.Val.getInt().isNullValue()) {
16556 Diag(ELoc,
16557 diag::err_omp_depend_zero_length_array_section_not_allowed)
16558 << SimpleExpr->getSourceRange();
16559 continue;
16560 }
16561 }
16562
16563 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16564 // List items used in depend clauses with the in, out, inout or
16565 // mutexinoutset dependence types cannot be expressions of the
16566 // omp_depend_t type.
16567 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16568 !RefExpr->isInstantiationDependent() &&
16569 !RefExpr->containsUnexpandedParameterPack() &&
16570 (OMPDependTFound &&
16571 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16572 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16573 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16574 << RefExpr->getSourceRange();
16575 continue;
16576 }
16577
16578 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16579 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16580 (ASE && !ASE->getBase()->isTypeDependent() &&
16581 !ASE->getBase()
16582 ->getType()
16583 .getNonReferenceType()
16584 ->isPointerType() &&
16585 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16586 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16587 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16588 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16589 continue;
16590 }
16591
16592 ExprResult Res;
16593 {
16594 Sema::TentativeAnalysisScope Trap(*this);
16595 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16596 RefExpr->IgnoreParenImpCasts());
16597 }
16598 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16599 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16600 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16601 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16602 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16603 continue;
16604 }
16605 }
16606 }
16607 Vars.push_back(RefExpr->IgnoreParenImpCasts());
16608 }
16609
16610 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16611 TotalDepCount > VarList.size() &&
16612 DSAStack->getParentOrderedRegionParam().first &&
16613 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
16614 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16615 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
16616 }
16617 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16618 Vars.empty())
16619 return nullptr;
16620
16621 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16622 DepModifier, DepKind, DepLoc, ColonLoc,
16623 Vars, TotalDepCount.getZExtValue());
16624 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16625 DSAStack->isParentOrderedRegion())
16626 DSAStack->addDoacrossDependClause(C, OpsOffs);
16627 return C;
16628 }
16629
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)16630 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16631 Expr *Device, SourceLocation StartLoc,
16632 SourceLocation LParenLoc,
16633 SourceLocation ModifierLoc,
16634 SourceLocation EndLoc) {
16635 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
16636 "Unexpected device modifier in OpenMP < 50.");
16637
16638 bool ErrorFound = false;
16639 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16640 std::string Values =
16641 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16642 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16643 << Values << getOpenMPClauseName(OMPC_device);
16644 ErrorFound = true;
16645 }
16646
16647 Expr *ValExpr = Device;
16648 Stmt *HelperValStmt = nullptr;
16649
16650 // OpenMP [2.9.1, Restrictions]
16651 // The device expression must evaluate to a non-negative integer value.
16652 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16653 /*StrictlyPositive=*/false) ||
16654 ErrorFound;
16655 if (ErrorFound)
16656 return nullptr;
16657
16658 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16659 OpenMPDirectiveKind CaptureRegion =
16660 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16661 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16662 ValExpr = MakeFullExpr(ValExpr).get();
16663 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16664 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16665 HelperValStmt = buildPreInits(Context, Captures);
16666 }
16667
16668 return new (Context)
16669 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16670 LParenLoc, ModifierLoc, EndLoc);
16671 }
16672
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)16673 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16674 DSAStackTy *Stack, QualType QTy,
16675 bool FullCheck = true) {
16676 NamedDecl *ND;
16677 if (QTy->isIncompleteType(&ND)) {
16678 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16679 return false;
16680 }
16681 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16682 !QTy.isTriviallyCopyableType(SemaRef.Context))
16683 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16684 return true;
16685 }
16686
16687 /// Return true if it can be proven that the provided array expression
16688 /// (array section or array subscript) does NOT specify the whole size of the
16689 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)16690 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16691 const Expr *E,
16692 QualType BaseQTy) {
16693 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16694
16695 // If this is an array subscript, it refers to the whole size if the size of
16696 // the dimension is constant and equals 1. Also, an array section assumes the
16697 // format of an array subscript if no colon is used.
16698 if (isa<ArraySubscriptExpr>(E) ||
16699 (OASE && OASE->getColonLocFirst().isInvalid())) {
16700 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16701 return ATy->getSize().getSExtValue() != 1;
16702 // Size can't be evaluated statically.
16703 return false;
16704 }
16705
16706 assert(OASE && "Expecting array section if not an array subscript.");
16707 const Expr *LowerBound = OASE->getLowerBound();
16708 const Expr *Length = OASE->getLength();
16709
16710 // If there is a lower bound that does not evaluates to zero, we are not
16711 // covering the whole dimension.
16712 if (LowerBound) {
16713 Expr::EvalResult Result;
16714 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16715 return false; // Can't get the integer value as a constant.
16716
16717 llvm::APSInt ConstLowerBound = Result.Val.getInt();
16718 if (ConstLowerBound.getSExtValue())
16719 return true;
16720 }
16721
16722 // If we don't have a length we covering the whole dimension.
16723 if (!Length)
16724 return false;
16725
16726 // If the base is a pointer, we don't have a way to get the size of the
16727 // pointee.
16728 if (BaseQTy->isPointerType())
16729 return false;
16730
16731 // We can only check if the length is the same as the size of the dimension
16732 // if we have a constant array.
16733 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16734 if (!CATy)
16735 return false;
16736
16737 Expr::EvalResult Result;
16738 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16739 return false; // Can't get the integer value as a constant.
16740
16741 llvm::APSInt ConstLength = Result.Val.getInt();
16742 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16743 }
16744
16745 // Return true if it can be proven that the provided array expression (array
16746 // section or array subscript) does NOT specify a single element of the array
16747 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)16748 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16749 const Expr *E,
16750 QualType BaseQTy) {
16751 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16752
16753 // An array subscript always refer to a single element. Also, an array section
16754 // assumes the format of an array subscript if no colon is used.
16755 if (isa<ArraySubscriptExpr>(E) ||
16756 (OASE && OASE->getColonLocFirst().isInvalid()))
16757 return false;
16758
16759 assert(OASE && "Expecting array section if not an array subscript.");
16760 const Expr *Length = OASE->getLength();
16761
16762 // If we don't have a length we have to check if the array has unitary size
16763 // for this dimension. Also, we should always expect a length if the base type
16764 // is pointer.
16765 if (!Length) {
16766 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16767 return ATy->getSize().getSExtValue() != 1;
16768 // We cannot assume anything.
16769 return false;
16770 }
16771
16772 // Check if the length evaluates to 1.
16773 Expr::EvalResult Result;
16774 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16775 return false; // Can't get the integer value as a constant.
16776
16777 llvm::APSInt ConstLength = Result.Val.getInt();
16778 return ConstLength.getSExtValue() != 1;
16779 }
16780
16781 // The base of elements of list in a map clause have to be either:
16782 // - a reference to variable or field.
16783 // - a member expression.
16784 // - an array expression.
16785 //
16786 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16787 // reference to 'r'.
16788 //
16789 // If we have:
16790 //
16791 // struct SS {
16792 // Bla S;
16793 // foo() {
16794 // #pragma omp target map (S.Arr[:12]);
16795 // }
16796 // }
16797 //
16798 // We want to retrieve the member expression 'this->S';
16799
16800 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16801 // If a list item is an array section, it must specify contiguous storage.
16802 //
16803 // For this restriction it is sufficient that we make sure only references
16804 // to variables or fields and array expressions, and that no array sections
16805 // exist except in the rightmost expression (unless they cover the whole
16806 // dimension of the array). E.g. these would be invalid:
16807 //
16808 // r.ArrS[3:5].Arr[6:7]
16809 //
16810 // r.ArrS[3:5].x
16811 //
16812 // but these would be valid:
16813 // r.ArrS[3].Arr[6:7]
16814 //
16815 // r.ArrS[3].x
16816 namespace {
16817 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16818 Sema &SemaRef;
16819 OpenMPClauseKind CKind = OMPC_unknown;
16820 OpenMPDirectiveKind DKind = OMPD_unknown;
16821 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16822 bool IsNonContiguous = false;
16823 bool NoDiagnose = false;
16824 const Expr *RelevantExpr = nullptr;
16825 bool AllowUnitySizeArraySection = true;
16826 bool AllowWholeSizeArraySection = true;
16827 bool AllowAnotherPtr = true;
16828 SourceLocation ELoc;
16829 SourceRange ERange;
16830
emitErrorMsg()16831 void emitErrorMsg() {
16832 // If nothing else worked, this is not a valid map clause expression.
16833 if (SemaRef.getLangOpts().OpenMP < 50) {
16834 SemaRef.Diag(ELoc,
16835 diag::err_omp_expected_named_var_member_or_array_expression)
16836 << ERange;
16837 } else {
16838 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16839 << getOpenMPClauseName(CKind) << ERange;
16840 }
16841 }
16842
16843 public:
VisitDeclRefExpr(DeclRefExpr * DRE)16844 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16845 if (!isa<VarDecl>(DRE->getDecl())) {
16846 emitErrorMsg();
16847 return false;
16848 }
16849 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16850 RelevantExpr = DRE;
16851 // Record the component.
16852 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
16853 return true;
16854 }
16855
VisitMemberExpr(MemberExpr * ME)16856 bool VisitMemberExpr(MemberExpr *ME) {
16857 Expr *E = ME;
16858 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
16859
16860 if (isa<CXXThisExpr>(BaseE)) {
16861 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16862 // We found a base expression: this->Val.
16863 RelevantExpr = ME;
16864 } else {
16865 E = BaseE;
16866 }
16867
16868 if (!isa<FieldDecl>(ME->getMemberDecl())) {
16869 if (!NoDiagnose) {
16870 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
16871 << ME->getSourceRange();
16872 return false;
16873 }
16874 if (RelevantExpr)
16875 return false;
16876 return Visit(E);
16877 }
16878
16879 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
16880
16881 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
16882 // A bit-field cannot appear in a map clause.
16883 //
16884 if (FD->isBitField()) {
16885 if (!NoDiagnose) {
16886 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
16887 << ME->getSourceRange() << getOpenMPClauseName(CKind);
16888 return false;
16889 }
16890 if (RelevantExpr)
16891 return false;
16892 return Visit(E);
16893 }
16894
16895 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16896 // If the type of a list item is a reference to a type T then the type
16897 // will be considered to be T for all purposes of this clause.
16898 QualType CurType = BaseE->getType().getNonReferenceType();
16899
16900 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
16901 // A list item cannot be a variable that is a member of a structure with
16902 // a union type.
16903 //
16904 if (CurType->isUnionType()) {
16905 if (!NoDiagnose) {
16906 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
16907 << ME->getSourceRange();
16908 return false;
16909 }
16910 return RelevantExpr || Visit(E);
16911 }
16912
16913 // If we got a member expression, we should not expect any array section
16914 // before that:
16915 //
16916 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
16917 // If a list item is an element of a structure, only the rightmost symbol
16918 // of the variable reference can be an array section.
16919 //
16920 AllowUnitySizeArraySection = false;
16921 AllowWholeSizeArraySection = false;
16922
16923 // Record the component.
16924 Components.emplace_back(ME, FD, IsNonContiguous);
16925 return RelevantExpr || Visit(E);
16926 }
16927
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)16928 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
16929 Expr *E = AE->getBase()->IgnoreParenImpCasts();
16930
16931 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
16932 if (!NoDiagnose) {
16933 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16934 << 0 << AE->getSourceRange();
16935 return false;
16936 }
16937 return RelevantExpr || Visit(E);
16938 }
16939
16940 // If we got an array subscript that express the whole dimension we
16941 // can have any array expressions before. If it only expressing part of
16942 // the dimension, we can only have unitary-size array expressions.
16943 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
16944 E->getType()))
16945 AllowWholeSizeArraySection = false;
16946
16947 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
16948 Expr::EvalResult Result;
16949 if (!AE->getIdx()->isValueDependent() &&
16950 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
16951 !Result.Val.getInt().isNullValue()) {
16952 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16953 diag::err_omp_invalid_map_this_expr);
16954 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16955 diag::note_omp_invalid_subscript_on_this_ptr_map);
16956 }
16957 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16958 RelevantExpr = TE;
16959 }
16960
16961 // Record the component - we don't have any declaration associated.
16962 Components.emplace_back(AE, nullptr, IsNonContiguous);
16963
16964 return RelevantExpr || Visit(E);
16965 }
16966
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)16967 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
16968 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
16969 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
16970 QualType CurType =
16971 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
16972
16973 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16974 // If the type of a list item is a reference to a type T then the type
16975 // will be considered to be T for all purposes of this clause.
16976 if (CurType->isReferenceType())
16977 CurType = CurType->getPointeeType();
16978
16979 bool IsPointer = CurType->isAnyPointerType();
16980
16981 if (!IsPointer && !CurType->isArrayType()) {
16982 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16983 << 0 << OASE->getSourceRange();
16984 return false;
16985 }
16986
16987 bool NotWhole =
16988 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
16989 bool NotUnity =
16990 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
16991
16992 if (AllowWholeSizeArraySection) {
16993 // Any array section is currently allowed. Allowing a whole size array
16994 // section implies allowing a unity array section as well.
16995 //
16996 // If this array section refers to the whole dimension we can still
16997 // accept other array sections before this one, except if the base is a
16998 // pointer. Otherwise, only unitary sections are accepted.
16999 if (NotWhole || IsPointer)
17000 AllowWholeSizeArraySection = false;
17001 } else if (DKind == OMPD_target_update &&
17002 SemaRef.getLangOpts().OpenMP >= 50) {
17003 if (IsPointer && !AllowAnotherPtr)
17004 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
17005 << /*array of unknown bound */ 1;
17006 else
17007 IsNonContiguous = true;
17008 } else if (AllowUnitySizeArraySection && NotUnity) {
17009 // A unity or whole array section is not allowed and that is not
17010 // compatible with the properties of the current array section.
17011 SemaRef.Diag(
17012 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
17013 << OASE->getSourceRange();
17014 return false;
17015 }
17016
17017 if (IsPointer)
17018 AllowAnotherPtr = false;
17019
17020 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
17021 Expr::EvalResult ResultR;
17022 Expr::EvalResult ResultL;
17023 if (!OASE->getLength()->isValueDependent() &&
17024 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
17025 !ResultR.Val.getInt().isOneValue()) {
17026 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17027 diag::err_omp_invalid_map_this_expr);
17028 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17029 diag::note_omp_invalid_length_on_this_ptr_mapping);
17030 }
17031 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
17032 OASE->getLowerBound()->EvaluateAsInt(ResultL,
17033 SemaRef.getASTContext()) &&
17034 !ResultL.Val.getInt().isNullValue()) {
17035 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17036 diag::err_omp_invalid_map_this_expr);
17037 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17038 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
17039 }
17040 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17041 RelevantExpr = TE;
17042 }
17043
17044 // Record the component - we don't have any declaration associated.
17045 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
17046 return RelevantExpr || Visit(E);
17047 }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)17048 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
17049 Expr *Base = E->getBase();
17050
17051 // Record the component - we don't have any declaration associated.
17052 Components.emplace_back(E, nullptr, IsNonContiguous);
17053
17054 return Visit(Base->IgnoreParenImpCasts());
17055 }
17056
VisitUnaryOperator(UnaryOperator * UO)17057 bool VisitUnaryOperator(UnaryOperator *UO) {
17058 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
17059 UO->getOpcode() != UO_Deref) {
17060 emitErrorMsg();
17061 return false;
17062 }
17063 if (!RelevantExpr) {
17064 // Record the component if haven't found base decl.
17065 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
17066 }
17067 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
17068 }
VisitBinaryOperator(BinaryOperator * BO)17069 bool VisitBinaryOperator(BinaryOperator *BO) {
17070 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
17071 emitErrorMsg();
17072 return false;
17073 }
17074
17075 // Pointer arithmetic is the only thing we expect to happen here so after we
17076 // make sure the binary operator is a pointer type, the we only thing need
17077 // to to is to visit the subtree that has the same type as root (so that we
17078 // know the other subtree is just an offset)
17079 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
17080 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
17081 Components.emplace_back(BO, nullptr, false);
17082 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
17083 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
17084 "Either LHS or RHS have base decl inside");
17085 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
17086 return RelevantExpr || Visit(LE);
17087 return RelevantExpr || Visit(RE);
17088 }
VisitCXXThisExpr(CXXThisExpr * CTE)17089 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
17090 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17091 RelevantExpr = CTE;
17092 Components.emplace_back(CTE, nullptr, IsNonContiguous);
17093 return true;
17094 }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)17095 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
17096 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17097 Components.emplace_back(COCE, nullptr, IsNonContiguous);
17098 return true;
17099 }
VisitStmt(Stmt *)17100 bool VisitStmt(Stmt *) {
17101 emitErrorMsg();
17102 return false;
17103 }
getFoundBase() const17104 const Expr *getFoundBase() const {
17105 return RelevantExpr;
17106 }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)17107 explicit MapBaseChecker(
17108 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
17109 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
17110 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
17111 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
17112 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
17113 };
17114 } // namespace
17115
17116 /// Return the expression of the base of the mappable expression or null if it
17117 /// cannot be determined and do all the necessary checks to see if the expression
17118 /// is valid as a standalone mappable expression. In the process, record all the
17119 /// components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)17120 static const Expr *checkMapClauseExpressionBase(
17121 Sema &SemaRef, Expr *E,
17122 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
17123 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
17124 SourceLocation ELoc = E->getExprLoc();
17125 SourceRange ERange = E->getSourceRange();
17126 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
17127 ERange);
17128 if (Checker.Visit(E->IgnoreParens())) {
17129 // Check if the highest dimension array section has length specified
17130 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
17131 (CKind == OMPC_to || CKind == OMPC_from)) {
17132 auto CI = CurComponents.rbegin();
17133 auto CE = CurComponents.rend();
17134 for (; CI != CE; ++CI) {
17135 const auto *OASE =
17136 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
17137 if (!OASE)
17138 continue;
17139 if (OASE && OASE->getLength())
17140 break;
17141 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
17142 << ERange;
17143 }
17144 }
17145 return Checker.getFoundBase();
17146 }
17147 return nullptr;
17148 }
17149
17150 // Return true if expression E associated with value VD has conflicts with other
17151 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)17152 static bool checkMapConflicts(
17153 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
17154 bool CurrentRegionOnly,
17155 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
17156 OpenMPClauseKind CKind) {
17157 assert(VD && E);
17158 SourceLocation ELoc = E->getExprLoc();
17159 SourceRange ERange = E->getSourceRange();
17160
17161 // In order to easily check the conflicts we need to match each component of
17162 // the expression under test with the components of the expressions that are
17163 // already in the stack.
17164
17165 assert(!CurComponents.empty() && "Map clause expression with no components!");
17166 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
17167 "Map clause expression with unexpected base!");
17168
17169 // Variables to help detecting enclosing problems in data environment nests.
17170 bool IsEnclosedByDataEnvironmentExpr = false;
17171 const Expr *EnclosingExpr = nullptr;
17172
17173 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17174 VD, CurrentRegionOnly,
17175 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17176 ERange, CKind, &EnclosingExpr,
17177 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17178 StackComponents,
17179 OpenMPClauseKind) {
17180 assert(!StackComponents.empty() &&
17181 "Map clause expression with no components!");
17182 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
17183 "Map clause expression with unexpected base!");
17184 (void)VD;
17185
17186 // The whole expression in the stack.
17187 const Expr *RE = StackComponents.front().getAssociatedExpression();
17188
17189 // Expressions must start from the same base. Here we detect at which
17190 // point both expressions diverge from each other and see if we can
17191 // detect if the memory referred to both expressions is contiguous and
17192 // do not overlap.
17193 auto CI = CurComponents.rbegin();
17194 auto CE = CurComponents.rend();
17195 auto SI = StackComponents.rbegin();
17196 auto SE = StackComponents.rend();
17197 for (; CI != CE && SI != SE; ++CI, ++SI) {
17198
17199 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17200 // At most one list item can be an array item derived from a given
17201 // variable in map clauses of the same construct.
17202 if (CurrentRegionOnly &&
17203 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17204 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17205 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17206 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17207 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17208 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17209 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17210 diag::err_omp_multiple_array_items_in_map_clause)
17211 << CI->getAssociatedExpression()->getSourceRange();
17212 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17213 diag::note_used_here)
17214 << SI->getAssociatedExpression()->getSourceRange();
17215 return true;
17216 }
17217
17218 // Do both expressions have the same kind?
17219 if (CI->getAssociatedExpression()->getStmtClass() !=
17220 SI->getAssociatedExpression()->getStmtClass())
17221 break;
17222
17223 // Are we dealing with different variables/fields?
17224 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17225 break;
17226 }
17227 // Check if the extra components of the expressions in the enclosing
17228 // data environment are redundant for the current base declaration.
17229 // If they are, the maps completely overlap, which is legal.
17230 for (; SI != SE; ++SI) {
17231 QualType Type;
17232 if (const auto *ASE =
17233 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17234 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17235 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17236 SI->getAssociatedExpression())) {
17237 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17238 Type =
17239 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17240 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17241 SI->getAssociatedExpression())) {
17242 Type = OASE->getBase()->getType()->getPointeeType();
17243 }
17244 if (Type.isNull() || Type->isAnyPointerType() ||
17245 checkArrayExpressionDoesNotReferToWholeSize(
17246 SemaRef, SI->getAssociatedExpression(), Type))
17247 break;
17248 }
17249
17250 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17251 // List items of map clauses in the same construct must not share
17252 // original storage.
17253 //
17254 // If the expressions are exactly the same or one is a subset of the
17255 // other, it means they are sharing storage.
17256 if (CI == CE && SI == SE) {
17257 if (CurrentRegionOnly) {
17258 if (CKind == OMPC_map) {
17259 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17260 } else {
17261 assert(CKind == OMPC_to || CKind == OMPC_from);
17262 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17263 << ERange;
17264 }
17265 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17266 << RE->getSourceRange();
17267 return true;
17268 }
17269 // If we find the same expression in the enclosing data environment,
17270 // that is legal.
17271 IsEnclosedByDataEnvironmentExpr = true;
17272 return false;
17273 }
17274
17275 QualType DerivedType =
17276 std::prev(CI)->getAssociatedDeclaration()->getType();
17277 SourceLocation DerivedLoc =
17278 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17279
17280 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17281 // If the type of a list item is a reference to a type T then the type
17282 // will be considered to be T for all purposes of this clause.
17283 DerivedType = DerivedType.getNonReferenceType();
17284
17285 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17286 // A variable for which the type is pointer and an array section
17287 // derived from that variable must not appear as list items of map
17288 // clauses of the same construct.
17289 //
17290 // Also, cover one of the cases in:
17291 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17292 // If any part of the original storage of a list item has corresponding
17293 // storage in the device data environment, all of the original storage
17294 // must have corresponding storage in the device data environment.
17295 //
17296 if (DerivedType->isAnyPointerType()) {
17297 if (CI == CE || SI == SE) {
17298 SemaRef.Diag(
17299 DerivedLoc,
17300 diag::err_omp_pointer_mapped_along_with_derived_section)
17301 << DerivedLoc;
17302 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17303 << RE->getSourceRange();
17304 return true;
17305 }
17306 if (CI->getAssociatedExpression()->getStmtClass() !=
17307 SI->getAssociatedExpression()->getStmtClass() ||
17308 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17309 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17310 assert(CI != CE && SI != SE);
17311 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17312 << DerivedLoc;
17313 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17314 << RE->getSourceRange();
17315 return true;
17316 }
17317 }
17318
17319 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17320 // List items of map clauses in the same construct must not share
17321 // original storage.
17322 //
17323 // An expression is a subset of the other.
17324 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17325 if (CKind == OMPC_map) {
17326 if (CI != CE || SI != SE) {
17327 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17328 // a pointer.
17329 auto Begin =
17330 CI != CE ? CurComponents.begin() : StackComponents.begin();
17331 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17332 auto It = Begin;
17333 while (It != End && !It->getAssociatedDeclaration())
17334 std::advance(It, 1);
17335 assert(It != End &&
17336 "Expected at least one component with the declaration.");
17337 if (It != Begin && It->getAssociatedDeclaration()
17338 ->getType()
17339 .getCanonicalType()
17340 ->isAnyPointerType()) {
17341 IsEnclosedByDataEnvironmentExpr = false;
17342 EnclosingExpr = nullptr;
17343 return false;
17344 }
17345 }
17346 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17347 } else {
17348 assert(CKind == OMPC_to || CKind == OMPC_from);
17349 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17350 << ERange;
17351 }
17352 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17353 << RE->getSourceRange();
17354 return true;
17355 }
17356
17357 // The current expression uses the same base as other expression in the
17358 // data environment but does not contain it completely.
17359 if (!CurrentRegionOnly && SI != SE)
17360 EnclosingExpr = RE;
17361
17362 // The current expression is a subset of the expression in the data
17363 // environment.
17364 IsEnclosedByDataEnvironmentExpr |=
17365 (!CurrentRegionOnly && CI != CE && SI == SE);
17366
17367 return false;
17368 });
17369
17370 if (CurrentRegionOnly)
17371 return FoundError;
17372
17373 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17374 // If any part of the original storage of a list item has corresponding
17375 // storage in the device data environment, all of the original storage must
17376 // have corresponding storage in the device data environment.
17377 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17378 // If a list item is an element of a structure, and a different element of
17379 // the structure has a corresponding list item in the device data environment
17380 // prior to a task encountering the construct associated with the map clause,
17381 // then the list item must also have a corresponding list item in the device
17382 // data environment prior to the task encountering the construct.
17383 //
17384 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17385 SemaRef.Diag(ELoc,
17386 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17387 << ERange;
17388 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17389 << EnclosingExpr->getSourceRange();
17390 return true;
17391 }
17392
17393 return FoundError;
17394 }
17395
17396 // Look up the user-defined mapper given the mapper name and mapped type, and
17397 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)17398 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17399 CXXScopeSpec &MapperIdScopeSpec,
17400 const DeclarationNameInfo &MapperId,
17401 QualType Type,
17402 Expr *UnresolvedMapper) {
17403 if (MapperIdScopeSpec.isInvalid())
17404 return ExprError();
17405 // Get the actual type for the array type.
17406 if (Type->isArrayType()) {
17407 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
17408 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17409 }
17410 // Find all user-defined mappers with the given MapperId.
17411 SmallVector<UnresolvedSet<8>, 4> Lookups;
17412 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17413 Lookup.suppressDiagnostics();
17414 if (S) {
17415 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17416 NamedDecl *D = Lookup.getRepresentativeDecl();
17417 while (S && !S->isDeclScope(D))
17418 S = S->getParent();
17419 if (S)
17420 S = S->getParent();
17421 Lookups.emplace_back();
17422 Lookups.back().append(Lookup.begin(), Lookup.end());
17423 Lookup.clear();
17424 }
17425 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17426 // Extract the user-defined mappers with the given MapperId.
17427 Lookups.push_back(UnresolvedSet<8>());
17428 for (NamedDecl *D : ULE->decls()) {
17429 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17430 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
17431 Lookups.back().addDecl(DMD);
17432 }
17433 }
17434 // Defer the lookup for dependent types. The results will be passed through
17435 // UnresolvedMapper on instantiation.
17436 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17437 Type->isInstantiationDependentType() ||
17438 Type->containsUnexpandedParameterPack() ||
17439 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17440 return !D->isInvalidDecl() &&
17441 (D->getType()->isDependentType() ||
17442 D->getType()->isInstantiationDependentType() ||
17443 D->getType()->containsUnexpandedParameterPack());
17444 })) {
17445 UnresolvedSet<8> URS;
17446 for (const UnresolvedSet<8> &Set : Lookups) {
17447 if (Set.empty())
17448 continue;
17449 URS.append(Set.begin(), Set.end());
17450 }
17451 return UnresolvedLookupExpr::Create(
17452 SemaRef.Context, /*NamingClass=*/nullptr,
17453 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17454 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17455 }
17456 SourceLocation Loc = MapperId.getLoc();
17457 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17458 // The type must be of struct, union or class type in C and C++
17459 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17460 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17461 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17462 return ExprError();
17463 }
17464 // Perform argument dependent lookup.
17465 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17466 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17467 // Return the first user-defined mapper with the desired type.
17468 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17469 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17470 if (!D->isInvalidDecl() &&
17471 SemaRef.Context.hasSameType(D->getType(), Type))
17472 return D;
17473 return nullptr;
17474 }))
17475 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17476 // Find the first user-defined mapper with a type derived from the desired
17477 // type.
17478 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17479 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17480 if (!D->isInvalidDecl() &&
17481 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17482 !Type.isMoreQualifiedThan(D->getType()))
17483 return D;
17484 return nullptr;
17485 })) {
17486 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17487 /*DetectVirtual=*/false);
17488 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17489 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17490 VD->getType().getUnqualifiedType()))) {
17491 if (SemaRef.CheckBaseClassAccess(
17492 Loc, VD->getType(), Type, Paths.front(),
17493 /*DiagID=*/0) != Sema::AR_inaccessible) {
17494 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17495 }
17496 }
17497 }
17498 }
17499 // Report error if a mapper is specified, but cannot be found.
17500 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17501 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17502 << Type << MapperId.getName();
17503 return ExprError();
17504 }
17505 return ExprEmpty();
17506 }
17507
17508 namespace {
17509 // Utility struct that gathers all the related lists associated with a mappable
17510 // expression.
17511 struct MappableVarListInfo {
17512 // The list of expressions.
17513 ArrayRef<Expr *> VarList;
17514 // The list of processed expressions.
17515 SmallVector<Expr *, 16> ProcessedVarList;
17516 // The mappble components for each expression.
17517 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17518 // The base declaration of the variable.
17519 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17520 // The reference to the user-defined mapper associated with every expression.
17521 SmallVector<Expr *, 16> UDMapperList;
17522
MappableVarListInfo__anon0bb9e2bb4e11::MappableVarListInfo17523 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17524 // We have a list of components and base declarations for each entry in the
17525 // variable list.
17526 VarComponents.reserve(VarList.size());
17527 VarBaseDeclarations.reserve(VarList.size());
17528 }
17529 };
17530 }
17531
17532 // Check the validity of the provided variable list for the provided clause kind
17533 // \a CKind. In the check process the valid expressions, mappable expression
17534 // components, variables, and user-defined mappers are extracted and used to
17535 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17536 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17537 // and \a MapperId are expected to be valid if the clause kind is 'map'.
checkMappableExpressionList(Sema & SemaRef,DSAStackTy * DSAS,OpenMPClauseKind CKind,MappableVarListInfo & MVLI,SourceLocation StartLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo MapperId,ArrayRef<Expr * > UnresolvedMappers,OpenMPMapClauseKind MapType=OMPC_MAP_unknown,bool IsMapTypeImplicit=false)17538 static void checkMappableExpressionList(
17539 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17540 MappableVarListInfo &MVLI, SourceLocation StartLoc,
17541 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17542 ArrayRef<Expr *> UnresolvedMappers,
17543 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17544 bool IsMapTypeImplicit = false) {
17545 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17546 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
17547 "Unexpected clause kind with mappable expressions!");
17548
17549 // If the identifier of user-defined mapper is not specified, it is "default".
17550 // We do not change the actual name in this clause to distinguish whether a
17551 // mapper is specified explicitly, i.e., it is not explicitly specified when
17552 // MapperId.getName() is empty.
17553 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17554 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17555 MapperId.setName(DeclNames.getIdentifier(
17556 &SemaRef.getASTContext().Idents.get("default")));
17557 MapperId.setLoc(StartLoc);
17558 }
17559
17560 // Iterators to find the current unresolved mapper expression.
17561 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17562 bool UpdateUMIt = false;
17563 Expr *UnresolvedMapper = nullptr;
17564
17565 // Keep track of the mappable components and base declarations in this clause.
17566 // Each entry in the list is going to have a list of components associated. We
17567 // record each set of the components so that we can build the clause later on.
17568 // In the end we should have the same amount of declarations and component
17569 // lists.
17570
17571 for (Expr *RE : MVLI.VarList) {
17572 assert(RE && "Null expr in omp to/from/map clause");
17573 SourceLocation ELoc = RE->getExprLoc();
17574
17575 // Find the current unresolved mapper expression.
17576 if (UpdateUMIt && UMIt != UMEnd) {
17577 UMIt++;
17578 assert(
17579 UMIt != UMEnd &&
17580 "Expect the size of UnresolvedMappers to match with that of VarList");
17581 }
17582 UpdateUMIt = true;
17583 if (UMIt != UMEnd)
17584 UnresolvedMapper = *UMIt;
17585
17586 const Expr *VE = RE->IgnoreParenLValueCasts();
17587
17588 if (VE->isValueDependent() || VE->isTypeDependent() ||
17589 VE->isInstantiationDependent() ||
17590 VE->containsUnexpandedParameterPack()) {
17591 // Try to find the associated user-defined mapper.
17592 ExprResult ER = buildUserDefinedMapperRef(
17593 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17594 VE->getType().getCanonicalType(), UnresolvedMapper);
17595 if (ER.isInvalid())
17596 continue;
17597 MVLI.UDMapperList.push_back(ER.get());
17598 // We can only analyze this information once the missing information is
17599 // resolved.
17600 MVLI.ProcessedVarList.push_back(RE);
17601 continue;
17602 }
17603
17604 Expr *SimpleExpr = RE->IgnoreParenCasts();
17605
17606 if (!RE->isLValue()) {
17607 if (SemaRef.getLangOpts().OpenMP < 50) {
17608 SemaRef.Diag(
17609 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17610 << RE->getSourceRange();
17611 } else {
17612 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17613 << getOpenMPClauseName(CKind) << RE->getSourceRange();
17614 }
17615 continue;
17616 }
17617
17618 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17619 ValueDecl *CurDeclaration = nullptr;
17620
17621 // Obtain the array or member expression bases if required. Also, fill the
17622 // components array with all the components identified in the process.
17623 const Expr *BE = checkMapClauseExpressionBase(
17624 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
17625 /*NoDiagnose=*/false);
17626 if (!BE)
17627 continue;
17628
17629 assert(!CurComponents.empty() &&
17630 "Invalid mappable expression information.");
17631
17632 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17633 // Add store "this" pointer to class in DSAStackTy for future checking
17634 DSAS->addMappedClassesQualTypes(TE->getType());
17635 // Try to find the associated user-defined mapper.
17636 ExprResult ER = buildUserDefinedMapperRef(
17637 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17638 VE->getType().getCanonicalType(), UnresolvedMapper);
17639 if (ER.isInvalid())
17640 continue;
17641 MVLI.UDMapperList.push_back(ER.get());
17642 // Skip restriction checking for variable or field declarations
17643 MVLI.ProcessedVarList.push_back(RE);
17644 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17645 MVLI.VarComponents.back().append(CurComponents.begin(),
17646 CurComponents.end());
17647 MVLI.VarBaseDeclarations.push_back(nullptr);
17648 continue;
17649 }
17650
17651 // For the following checks, we rely on the base declaration which is
17652 // expected to be associated with the last component. The declaration is
17653 // expected to be a variable or a field (if 'this' is being mapped).
17654 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17655 assert(CurDeclaration && "Null decl on map clause.");
17656 assert(
17657 CurDeclaration->isCanonicalDecl() &&
17658 "Expecting components to have associated only canonical declarations.");
17659
17660 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17661 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17662
17663 assert((VD || FD) && "Only variables or fields are expected here!");
17664 (void)FD;
17665
17666 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17667 // threadprivate variables cannot appear in a map clause.
17668 // OpenMP 4.5 [2.10.5, target update Construct]
17669 // threadprivate variables cannot appear in a from clause.
17670 if (VD && DSAS->isThreadPrivate(VD)) {
17671 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17672 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17673 << getOpenMPClauseName(CKind);
17674 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17675 continue;
17676 }
17677
17678 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17679 // A list item cannot appear in both a map clause and a data-sharing
17680 // attribute clause on the same construct.
17681
17682 // Check conflicts with other map clause expressions. We check the conflicts
17683 // with the current construct separately from the enclosing data
17684 // environment, because the restrictions are different. We only have to
17685 // check conflicts across regions for the map clauses.
17686 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17687 /*CurrentRegionOnly=*/true, CurComponents, CKind))
17688 break;
17689 if (CKind == OMPC_map &&
17690 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
17691 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17692 /*CurrentRegionOnly=*/false, CurComponents, CKind))
17693 break;
17694
17695 // OpenMP 4.5 [2.10.5, target update Construct]
17696 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17697 // If the type of a list item is a reference to a type T then the type will
17698 // be considered to be T for all purposes of this clause.
17699 auto I = llvm::find_if(
17700 CurComponents,
17701 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17702 return MC.getAssociatedDeclaration();
17703 });
17704 assert(I != CurComponents.end() && "Null decl on map clause.");
17705 QualType Type;
17706 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17707 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17708 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17709 if (ASE) {
17710 Type = ASE->getType().getNonReferenceType();
17711 } else if (OASE) {
17712 QualType BaseType =
17713 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17714 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17715 Type = ATy->getElementType();
17716 else
17717 Type = BaseType->getPointeeType();
17718 Type = Type.getNonReferenceType();
17719 } else if (OAShE) {
17720 Type = OAShE->getBase()->getType()->getPointeeType();
17721 } else {
17722 Type = VE->getType();
17723 }
17724
17725 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17726 // A list item in a to or from clause must have a mappable type.
17727 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17728 // A list item must have a mappable type.
17729 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17730 DSAS, Type))
17731 continue;
17732
17733 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17734
17735 if (CKind == OMPC_map) {
17736 // target enter data
17737 // OpenMP [2.10.2, Restrictions, p. 99]
17738 // A map-type must be specified in all map clauses and must be either
17739 // to or alloc.
17740 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17741 if (DKind == OMPD_target_enter_data &&
17742 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17743 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17744 << (IsMapTypeImplicit ? 1 : 0)
17745 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17746 << getOpenMPDirectiveName(DKind);
17747 continue;
17748 }
17749
17750 // target exit_data
17751 // OpenMP [2.10.3, Restrictions, p. 102]
17752 // A map-type must be specified in all map clauses and must be either
17753 // from, release, or delete.
17754 if (DKind == OMPD_target_exit_data &&
17755 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17756 MapType == OMPC_MAP_delete)) {
17757 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17758 << (IsMapTypeImplicit ? 1 : 0)
17759 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17760 << getOpenMPDirectiveName(DKind);
17761 continue;
17762 }
17763
17764 // target, target data
17765 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17766 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17767 // A map-type in a map clause must be to, from, tofrom or alloc
17768 if ((DKind == OMPD_target_data ||
17769 isOpenMPTargetExecutionDirective(DKind)) &&
17770 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17771 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17772 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17773 << (IsMapTypeImplicit ? 1 : 0)
17774 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17775 << getOpenMPDirectiveName(DKind);
17776 continue;
17777 }
17778
17779 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17780 // A list item cannot appear in both a map clause and a data-sharing
17781 // attribute clause on the same construct
17782 //
17783 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17784 // A list item cannot appear in both a map clause and a data-sharing
17785 // attribute clause on the same construct unless the construct is a
17786 // combined construct.
17787 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17788 isOpenMPTargetExecutionDirective(DKind)) ||
17789 DKind == OMPD_target)) {
17790 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17791 if (isOpenMPPrivate(DVar.CKind)) {
17792 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17793 << getOpenMPClauseName(DVar.CKind)
17794 << getOpenMPClauseName(OMPC_map)
17795 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17796 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17797 continue;
17798 }
17799 }
17800 }
17801
17802 // Try to find the associated user-defined mapper.
17803 ExprResult ER = buildUserDefinedMapperRef(
17804 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17805 Type.getCanonicalType(), UnresolvedMapper);
17806 if (ER.isInvalid())
17807 continue;
17808 MVLI.UDMapperList.push_back(ER.get());
17809
17810 // Save the current expression.
17811 MVLI.ProcessedVarList.push_back(RE);
17812
17813 // Store the components in the stack so that they can be used to check
17814 // against other clauses later on.
17815 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17816 /*WhereFoundClauseKind=*/OMPC_map);
17817
17818 // Save the components and declaration to create the clause. For purposes of
17819 // the clause creation, any component list that has has base 'this' uses
17820 // null as base declaration.
17821 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17822 MVLI.VarComponents.back().append(CurComponents.begin(),
17823 CurComponents.end());
17824 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17825 : CurDeclaration);
17826 }
17827 }
17828
ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation MapLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)17829 OMPClause *Sema::ActOnOpenMPMapClause(
17830 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17831 ArrayRef<SourceLocation> MapTypeModifiersLoc,
17832 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17833 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17834 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17835 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17836 OpenMPMapModifierKind Modifiers[] = {
17837 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
17838 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
17839 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17840
17841 // Process map-type-modifiers, flag errors for duplicate modifiers.
17842 unsigned Count = 0;
17843 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17844 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17845 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17846 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17847 continue;
17848 }
17849 assert(Count < NumberOfOMPMapClauseModifiers &&
17850 "Modifiers exceed the allowed number of map type modifiers");
17851 Modifiers[Count] = MapTypeModifiers[I];
17852 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17853 ++Count;
17854 }
17855
17856 MappableVarListInfo MVLI(VarList);
17857 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
17858 MapperIdScopeSpec, MapperId, UnresolvedMappers,
17859 MapType, IsMapTypeImplicit);
17860
17861 // We need to produce a map clause even if we don't have variables so that
17862 // other diagnostics related with non-existing map clauses are accurate.
17863 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
17864 MVLI.VarBaseDeclarations, MVLI.VarComponents,
17865 MVLI.UDMapperList, Modifiers, ModifiersLoc,
17866 MapperIdScopeSpec.getWithLocInContext(Context),
17867 MapperId, MapType, IsMapTypeImplicit, MapLoc);
17868 }
17869
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)17870 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
17871 TypeResult ParsedType) {
17872 assert(ParsedType.isUsable());
17873
17874 QualType ReductionType = GetTypeFromParser(ParsedType.get());
17875 if (ReductionType.isNull())
17876 return QualType();
17877
17878 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
17879 // A type name in a declare reduction directive cannot be a function type, an
17880 // array type, a reference type, or a type qualified with const, volatile or
17881 // restrict.
17882 if (ReductionType.hasQualifiers()) {
17883 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
17884 return QualType();
17885 }
17886
17887 if (ReductionType->isFunctionType()) {
17888 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
17889 return QualType();
17890 }
17891 if (ReductionType->isReferenceType()) {
17892 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
17893 return QualType();
17894 }
17895 if (ReductionType->isArrayType()) {
17896 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
17897 return QualType();
17898 }
17899 return ReductionType;
17900 }
17901
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)17902 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
17903 Scope *S, DeclContext *DC, DeclarationName Name,
17904 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
17905 AccessSpecifier AS, Decl *PrevDeclInScope) {
17906 SmallVector<Decl *, 8> Decls;
17907 Decls.reserve(ReductionTypes.size());
17908
17909 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
17910 forRedeclarationInCurContext());
17911 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
17912 // A reduction-identifier may not be re-declared in the current scope for the
17913 // same type or for a type that is compatible according to the base language
17914 // rules.
17915 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17916 OMPDeclareReductionDecl *PrevDRD = nullptr;
17917 bool InCompoundScope = true;
17918 if (S != nullptr) {
17919 // Find previous declaration with the same name not referenced in other
17920 // declarations.
17921 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17922 InCompoundScope =
17923 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17924 LookupName(Lookup, S);
17925 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17926 /*AllowInlineNamespace=*/false);
17927 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
17928 LookupResult::Filter Filter = Lookup.makeFilter();
17929 while (Filter.hasNext()) {
17930 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
17931 if (InCompoundScope) {
17932 auto I = UsedAsPrevious.find(PrevDecl);
17933 if (I == UsedAsPrevious.end())
17934 UsedAsPrevious[PrevDecl] = false;
17935 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
17936 UsedAsPrevious[D] = true;
17937 }
17938 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17939 PrevDecl->getLocation();
17940 }
17941 Filter.done();
17942 if (InCompoundScope) {
17943 for (const auto &PrevData : UsedAsPrevious) {
17944 if (!PrevData.second) {
17945 PrevDRD = PrevData.first;
17946 break;
17947 }
17948 }
17949 }
17950 } else if (PrevDeclInScope != nullptr) {
17951 auto *PrevDRDInScope = PrevDRD =
17952 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
17953 do {
17954 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
17955 PrevDRDInScope->getLocation();
17956 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
17957 } while (PrevDRDInScope != nullptr);
17958 }
17959 for (const auto &TyData : ReductionTypes) {
17960 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
17961 bool Invalid = false;
17962 if (I != PreviousRedeclTypes.end()) {
17963 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
17964 << TyData.first;
17965 Diag(I->second, diag::note_previous_definition);
17966 Invalid = true;
17967 }
17968 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
17969 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
17970 Name, TyData.first, PrevDRD);
17971 DC->addDecl(DRD);
17972 DRD->setAccess(AS);
17973 Decls.push_back(DRD);
17974 if (Invalid)
17975 DRD->setInvalidDecl();
17976 else
17977 PrevDRD = DRD;
17978 }
17979
17980 return DeclGroupPtrTy::make(
17981 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
17982 }
17983
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)17984 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
17985 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17986
17987 // Enter new function scope.
17988 PushFunctionScope();
17989 setFunctionHasBranchProtectedScope();
17990 getCurFunction()->setHasOMPDeclareReductionCombiner();
17991
17992 if (S != nullptr)
17993 PushDeclContext(S, DRD);
17994 else
17995 CurContext = DRD;
17996
17997 PushExpressionEvaluationContext(
17998 ExpressionEvaluationContext::PotentiallyEvaluated);
17999
18000 QualType ReductionType = DRD->getType();
18001 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
18002 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
18003 // uses semantics of argument handles by value, but it should be passed by
18004 // reference. C lang does not support references, so pass all parameters as
18005 // pointers.
18006 // Create 'T omp_in;' variable.
18007 VarDecl *OmpInParm =
18008 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
18009 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
18010 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
18011 // uses semantics of argument handles by value, but it should be passed by
18012 // reference. C lang does not support references, so pass all parameters as
18013 // pointers.
18014 // Create 'T omp_out;' variable.
18015 VarDecl *OmpOutParm =
18016 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
18017 if (S != nullptr) {
18018 PushOnScopeChains(OmpInParm, S);
18019 PushOnScopeChains(OmpOutParm, S);
18020 } else {
18021 DRD->addDecl(OmpInParm);
18022 DRD->addDecl(OmpOutParm);
18023 }
18024 Expr *InE =
18025 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
18026 Expr *OutE =
18027 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
18028 DRD->setCombinerData(InE, OutE);
18029 }
18030
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)18031 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
18032 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18033 DiscardCleanupsInEvaluationContext();
18034 PopExpressionEvaluationContext();
18035
18036 PopDeclContext();
18037 PopFunctionScopeInfo();
18038
18039 if (Combiner != nullptr)
18040 DRD->setCombiner(Combiner);
18041 else
18042 DRD->setInvalidDecl();
18043 }
18044
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)18045 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
18046 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18047
18048 // Enter new function scope.
18049 PushFunctionScope();
18050 setFunctionHasBranchProtectedScope();
18051
18052 if (S != nullptr)
18053 PushDeclContext(S, DRD);
18054 else
18055 CurContext = DRD;
18056
18057 PushExpressionEvaluationContext(
18058 ExpressionEvaluationContext::PotentiallyEvaluated);
18059
18060 QualType ReductionType = DRD->getType();
18061 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
18062 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
18063 // uses semantics of argument handles by value, but it should be passed by
18064 // reference. C lang does not support references, so pass all parameters as
18065 // pointers.
18066 // Create 'T omp_priv;' variable.
18067 VarDecl *OmpPrivParm =
18068 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
18069 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
18070 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
18071 // uses semantics of argument handles by value, but it should be passed by
18072 // reference. C lang does not support references, so pass all parameters as
18073 // pointers.
18074 // Create 'T omp_orig;' variable.
18075 VarDecl *OmpOrigParm =
18076 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
18077 if (S != nullptr) {
18078 PushOnScopeChains(OmpPrivParm, S);
18079 PushOnScopeChains(OmpOrigParm, S);
18080 } else {
18081 DRD->addDecl(OmpPrivParm);
18082 DRD->addDecl(OmpOrigParm);
18083 }
18084 Expr *OrigE =
18085 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
18086 Expr *PrivE =
18087 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
18088 DRD->setInitializerData(OrigE, PrivE);
18089 return OmpPrivParm;
18090 }
18091
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)18092 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
18093 VarDecl *OmpPrivParm) {
18094 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18095 DiscardCleanupsInEvaluationContext();
18096 PopExpressionEvaluationContext();
18097
18098 PopDeclContext();
18099 PopFunctionScopeInfo();
18100
18101 if (Initializer != nullptr) {
18102 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
18103 } else if (OmpPrivParm->hasInit()) {
18104 DRD->setInitializer(OmpPrivParm->getInit(),
18105 OmpPrivParm->isDirectInit()
18106 ? OMPDeclareReductionDecl::DirectInit
18107 : OMPDeclareReductionDecl::CopyInit);
18108 } else {
18109 DRD->setInvalidDecl();
18110 }
18111 }
18112
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)18113 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
18114 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
18115 for (Decl *D : DeclReductions.get()) {
18116 if (IsValid) {
18117 if (S)
18118 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
18119 /*AddToContext=*/false);
18120 } else {
18121 D->setInvalidDecl();
18122 }
18123 }
18124 return DeclReductions;
18125 }
18126
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)18127 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
18128 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
18129 QualType T = TInfo->getType();
18130 if (D.isInvalidType())
18131 return true;
18132
18133 if (getLangOpts().CPlusPlus) {
18134 // Check that there are no default arguments (C++ only).
18135 CheckExtraCXXDefaultArguments(D);
18136 }
18137
18138 return CreateParsedType(T, TInfo);
18139 }
18140
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)18141 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
18142 TypeResult ParsedType) {
18143 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
18144
18145 QualType MapperType = GetTypeFromParser(ParsedType.get());
18146 assert(!MapperType.isNull() && "Expect valid mapper type");
18147
18148 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18149 // The type must be of struct, union or class type in C and C++
18150 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
18151 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
18152 return QualType();
18153 }
18154 return MapperType;
18155 }
18156
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)18157 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
18158 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
18159 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
18160 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
18161 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
18162 forRedeclarationInCurContext());
18163 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18164 // A mapper-identifier may not be redeclared in the current scope for the
18165 // same type or for a type that is compatible according to the base language
18166 // rules.
18167 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18168 OMPDeclareMapperDecl *PrevDMD = nullptr;
18169 bool InCompoundScope = true;
18170 if (S != nullptr) {
18171 // Find previous declaration with the same name not referenced in other
18172 // declarations.
18173 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18174 InCompoundScope =
18175 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18176 LookupName(Lookup, S);
18177 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18178 /*AllowInlineNamespace=*/false);
18179 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18180 LookupResult::Filter Filter = Lookup.makeFilter();
18181 while (Filter.hasNext()) {
18182 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18183 if (InCompoundScope) {
18184 auto I = UsedAsPrevious.find(PrevDecl);
18185 if (I == UsedAsPrevious.end())
18186 UsedAsPrevious[PrevDecl] = false;
18187 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18188 UsedAsPrevious[D] = true;
18189 }
18190 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18191 PrevDecl->getLocation();
18192 }
18193 Filter.done();
18194 if (InCompoundScope) {
18195 for (const auto &PrevData : UsedAsPrevious) {
18196 if (!PrevData.second) {
18197 PrevDMD = PrevData.first;
18198 break;
18199 }
18200 }
18201 }
18202 } else if (PrevDeclInScope) {
18203 auto *PrevDMDInScope = PrevDMD =
18204 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18205 do {
18206 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18207 PrevDMDInScope->getLocation();
18208 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18209 } while (PrevDMDInScope != nullptr);
18210 }
18211 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18212 bool Invalid = false;
18213 if (I != PreviousRedeclTypes.end()) {
18214 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18215 << MapperType << Name;
18216 Diag(I->second, diag::note_previous_definition);
18217 Invalid = true;
18218 }
18219 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18220 MapperType, VN, Clauses, PrevDMD);
18221 if (S)
18222 PushOnScopeChains(DMD, S);
18223 else
18224 DC->addDecl(DMD);
18225 DMD->setAccess(AS);
18226 if (Invalid)
18227 DMD->setInvalidDecl();
18228
18229 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
18230 VD->setDeclContext(DMD);
18231 VD->setLexicalDeclContext(DMD);
18232 DMD->addDecl(VD);
18233 DMD->setMapperVarRef(MapperVarRef);
18234
18235 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
18236 }
18237
18238 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)18239 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
18240 SourceLocation StartLoc,
18241 DeclarationName VN) {
18242 TypeSourceInfo *TInfo =
18243 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
18244 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
18245 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
18246 MapperType, TInfo, SC_None);
18247 if (S)
18248 PushOnScopeChains(VD, S, /*AddToContext=*/false);
18249 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18250 DSAStack->addDeclareMapperVarRef(E);
18251 return E;
18252 }
18253
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const18254 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
18255 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18256 const Expr *Ref = DSAStack->getDeclareMapperVarRef();
18257 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
18258 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
18259 return true;
18260 }
18261
getOpenMPDeclareMapperVarName() const18262 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
18263 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18264 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
18265 }
18266
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18267 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18268 SourceLocation StartLoc,
18269 SourceLocation LParenLoc,
18270 SourceLocation EndLoc) {
18271 Expr *ValExpr = NumTeams;
18272 Stmt *HelperValStmt = nullptr;
18273
18274 // OpenMP [teams Constrcut, Restrictions]
18275 // The num_teams expression must evaluate to a positive integer value.
18276 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18277 /*StrictlyPositive=*/true))
18278 return nullptr;
18279
18280 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18281 OpenMPDirectiveKind CaptureRegion =
18282 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18283 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18284 ValExpr = MakeFullExpr(ValExpr).get();
18285 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18286 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18287 HelperValStmt = buildPreInits(Context, Captures);
18288 }
18289
18290 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18291 StartLoc, LParenLoc, EndLoc);
18292 }
18293
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18294 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18295 SourceLocation StartLoc,
18296 SourceLocation LParenLoc,
18297 SourceLocation EndLoc) {
18298 Expr *ValExpr = ThreadLimit;
18299 Stmt *HelperValStmt = nullptr;
18300
18301 // OpenMP [teams Constrcut, Restrictions]
18302 // The thread_limit expression must evaluate to a positive integer value.
18303 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18304 /*StrictlyPositive=*/true))
18305 return nullptr;
18306
18307 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18308 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18309 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18310 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18311 ValExpr = MakeFullExpr(ValExpr).get();
18312 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18313 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18314 HelperValStmt = buildPreInits(Context, Captures);
18315 }
18316
18317 return new (Context) OMPThreadLimitClause(
18318 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18319 }
18320
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18321 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18322 SourceLocation StartLoc,
18323 SourceLocation LParenLoc,
18324 SourceLocation EndLoc) {
18325 Expr *ValExpr = Priority;
18326 Stmt *HelperValStmt = nullptr;
18327 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18328
18329 // OpenMP [2.9.1, task Constrcut]
18330 // The priority-value is a non-negative numerical scalar expression.
18331 if (!isNonNegativeIntegerValue(
18332 ValExpr, *this, OMPC_priority,
18333 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18334 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18335 return nullptr;
18336
18337 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18338 StartLoc, LParenLoc, EndLoc);
18339 }
18340
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18341 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18342 SourceLocation StartLoc,
18343 SourceLocation LParenLoc,
18344 SourceLocation EndLoc) {
18345 Expr *ValExpr = Grainsize;
18346 Stmt *HelperValStmt = nullptr;
18347 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18348
18349 // OpenMP [2.9.2, taskloop Constrcut]
18350 // The parameter of the grainsize clause must be a positive integer
18351 // expression.
18352 if (!isNonNegativeIntegerValue(
18353 ValExpr, *this, OMPC_grainsize,
18354 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18355 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18356 return nullptr;
18357
18358 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18359 StartLoc, LParenLoc, EndLoc);
18360 }
18361
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18362 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18363 SourceLocation StartLoc,
18364 SourceLocation LParenLoc,
18365 SourceLocation EndLoc) {
18366 Expr *ValExpr = NumTasks;
18367 Stmt *HelperValStmt = nullptr;
18368 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18369
18370 // OpenMP [2.9.2, taskloop Constrcut]
18371 // The parameter of the num_tasks clause must be a positive integer
18372 // expression.
18373 if (!isNonNegativeIntegerValue(
18374 ValExpr, *this, OMPC_num_tasks,
18375 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18376 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18377 return nullptr;
18378
18379 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18380 StartLoc, LParenLoc, EndLoc);
18381 }
18382
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18383 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18384 SourceLocation LParenLoc,
18385 SourceLocation EndLoc) {
18386 // OpenMP [2.13.2, critical construct, Description]
18387 // ... where hint-expression is an integer constant expression that evaluates
18388 // to a valid lock hint.
18389 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18390 if (HintExpr.isInvalid())
18391 return nullptr;
18392 return new (Context)
18393 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18394 }
18395
18396 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)18397 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18398 DSAStackTy *Stack) {
18399 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18400 if (!OMPEventHandleT.isNull())
18401 return true;
18402 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18403 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18404 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18405 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18406 return false;
18407 }
18408 Stack->setOMPEventHandleT(PT.get());
18409 return true;
18410 }
18411
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18412 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18413 SourceLocation LParenLoc,
18414 SourceLocation EndLoc) {
18415 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18416 !Evt->isInstantiationDependent() &&
18417 !Evt->containsUnexpandedParameterPack()) {
18418 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
18419 return nullptr;
18420 // OpenMP 5.0, 2.10.1 task Construct.
18421 // event-handle is a variable of the omp_event_handle_t type.
18422 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18423 if (!Ref) {
18424 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18425 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18426 return nullptr;
18427 }
18428 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18429 if (!VD) {
18430 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18431 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18432 return nullptr;
18433 }
18434 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
18435 VD->getType()) ||
18436 VD->getType().isConstant(Context)) {
18437 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18438 << "omp_event_handle_t" << 1 << VD->getType()
18439 << Evt->getSourceRange();
18440 return nullptr;
18441 }
18442 // OpenMP 5.0, 2.10.1 task Construct
18443 // [detach clause]... The event-handle will be considered as if it was
18444 // specified on a firstprivate clause.
18445 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
18446 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18447 DVar.RefExpr) {
18448 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18449 << getOpenMPClauseName(DVar.CKind)
18450 << getOpenMPClauseName(OMPC_firstprivate);
18451 reportOriginalDsa(*this, DSAStack, VD, DVar);
18452 return nullptr;
18453 }
18454 }
18455
18456 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18457 }
18458
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)18459 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18460 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18461 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18462 SourceLocation EndLoc) {
18463 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18464 std::string Values;
18465 Values += "'";
18466 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18467 Values += "'";
18468 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18469 << Values << getOpenMPClauseName(OMPC_dist_schedule);
18470 return nullptr;
18471 }
18472 Expr *ValExpr = ChunkSize;
18473 Stmt *HelperValStmt = nullptr;
18474 if (ChunkSize) {
18475 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18476 !ChunkSize->isInstantiationDependent() &&
18477 !ChunkSize->containsUnexpandedParameterPack()) {
18478 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18479 ExprResult Val =
18480 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18481 if (Val.isInvalid())
18482 return nullptr;
18483
18484 ValExpr = Val.get();
18485
18486 // OpenMP [2.7.1, Restrictions]
18487 // chunk_size must be a loop invariant integer expression with a positive
18488 // value.
18489 if (Optional<llvm::APSInt> Result =
18490 ValExpr->getIntegerConstantExpr(Context)) {
18491 if (Result->isSigned() && !Result->isStrictlyPositive()) {
18492 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18493 << "dist_schedule" << ChunkSize->getSourceRange();
18494 return nullptr;
18495 }
18496 } else if (getOpenMPCaptureRegionForClause(
18497 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
18498 LangOpts.OpenMP) != OMPD_unknown &&
18499 !CurContext->isDependentContext()) {
18500 ValExpr = MakeFullExpr(ValExpr).get();
18501 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18502 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18503 HelperValStmt = buildPreInits(Context, Captures);
18504 }
18505 }
18506 }
18507
18508 return new (Context)
18509 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18510 Kind, ValExpr, HelperValStmt);
18511 }
18512
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)18513 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18514 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18515 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18516 SourceLocation KindLoc, SourceLocation EndLoc) {
18517 if (getLangOpts().OpenMP < 50) {
18518 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18519 Kind != OMPC_DEFAULTMAP_scalar) {
18520 std::string Value;
18521 SourceLocation Loc;
18522 Value += "'";
18523 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18524 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18525 OMPC_DEFAULTMAP_MODIFIER_tofrom);
18526 Loc = MLoc;
18527 } else {
18528 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18529 OMPC_DEFAULTMAP_scalar);
18530 Loc = KindLoc;
18531 }
18532 Value += "'";
18533 Diag(Loc, diag::err_omp_unexpected_clause_value)
18534 << Value << getOpenMPClauseName(OMPC_defaultmap);
18535 return nullptr;
18536 }
18537 } else {
18538 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18539 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18540 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18541 if (!isDefaultmapKind || !isDefaultmapModifier) {
18542 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18543 "'firstprivate', 'none', 'default'";
18544 std::string KindValue = "'scalar', 'aggregate', 'pointer'";
18545 if (!isDefaultmapKind && isDefaultmapModifier) {
18546 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18547 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18548 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18549 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18550 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18551 } else {
18552 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18553 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18554 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18555 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18556 }
18557 return nullptr;
18558 }
18559
18560 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18561 // At most one defaultmap clause for each category can appear on the
18562 // directive.
18563 if (DSAStack->checkDefaultmapCategory(Kind)) {
18564 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18565 return nullptr;
18566 }
18567 }
18568 if (Kind == OMPC_DEFAULTMAP_unknown) {
18569 // Variable category is not specified - mark all categories.
18570 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18571 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18572 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18573 } else {
18574 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
18575 }
18576
18577 return new (Context)
18578 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18579 }
18580
ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)18581 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18582 DeclContext *CurLexicalContext = getCurLexicalContext();
18583 if (!CurLexicalContext->isFileContext() &&
18584 !CurLexicalContext->isExternCContext() &&
18585 !CurLexicalContext->isExternCXXContext() &&
18586 !isa<CXXRecordDecl>(CurLexicalContext) &&
18587 !isa<ClassTemplateDecl>(CurLexicalContext) &&
18588 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18589 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18590 Diag(Loc, diag::err_omp_region_not_file_context);
18591 return false;
18592 }
18593 DeclareTargetNesting.push_back(Loc);
18594 return true;
18595 }
18596
ActOnFinishOpenMPDeclareTargetDirective()18597 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18598 assert(!DeclareTargetNesting.empty() &&
18599 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
18600 DeclareTargetNesting.pop_back();
18601 }
18602
18603 NamedDecl *
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,NamedDeclSetType & SameDirectiveDecls)18604 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18605 const DeclarationNameInfo &Id,
18606 NamedDeclSetType &SameDirectiveDecls) {
18607 LookupResult Lookup(*this, Id, LookupOrdinaryName);
18608 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18609
18610 if (Lookup.isAmbiguous())
18611 return nullptr;
18612 Lookup.suppressDiagnostics();
18613
18614 if (!Lookup.isSingleResult()) {
18615 VarOrFuncDeclFilterCCC CCC(*this);
18616 if (TypoCorrection Corrected =
18617 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18618 CTK_ErrorRecovery)) {
18619 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18620 << Id.getName());
18621 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18622 return nullptr;
18623 }
18624
18625 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18626 return nullptr;
18627 }
18628
18629 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18630 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18631 !isa<FunctionTemplateDecl>(ND)) {
18632 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18633 return nullptr;
18634 }
18635 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18636 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18637 return ND;
18638 }
18639
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,OMPDeclareTargetDeclAttr::DevTypeTy DT)18640 void Sema::ActOnOpenMPDeclareTargetName(
18641 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18642 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18643 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
18644 isa<FunctionTemplateDecl>(ND)) &&
18645 "Expected variable, function or function template.");
18646
18647 // Diagnose marking after use as it may lead to incorrect diagnosis and
18648 // codegen.
18649 if (LangOpts.OpenMP >= 50 &&
18650 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18651 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18652
18653 auto *VD = cast<ValueDecl>(ND);
18654 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18655 OMPDeclareTargetDeclAttr::getDeviceType(VD);
18656 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
18657 if (DevTy.hasValue() && *DevTy != DT &&
18658 (DeclareTargetNesting.empty() ||
18659 *AttrLoc != DeclareTargetNesting.back())) {
18660 Diag(Loc, diag::err_omp_device_type_mismatch)
18661 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18662 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18663 return;
18664 }
18665 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18666 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18667 if (!Res || (!DeclareTargetNesting.empty() &&
18668 *AttrLoc == DeclareTargetNesting.back())) {
18669 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18670 Context, MT, DT, DeclareTargetNesting.size() + 1,
18671 SourceRange(Loc, Loc));
18672 ND->addAttr(A);
18673 if (ASTMutationListener *ML = Context.getASTMutationListener())
18674 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18675 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18676 } else if (*Res != MT) {
18677 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18678 }
18679 }
18680
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)18681 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18682 Sema &SemaRef, Decl *D) {
18683 if (!D || !isa<VarDecl>(D))
18684 return;
18685 auto *VD = cast<VarDecl>(D);
18686 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18687 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18688 if (SemaRef.LangOpts.OpenMP >= 50 &&
18689 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18690 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18691 VD->hasGlobalStorage()) {
18692 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18693 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18694 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18695 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18696 // If a lambda declaration and definition appears between a
18697 // declare target directive and the matching end declare target
18698 // directive, all variables that are captured by the lambda
18699 // expression must also appear in a to clause.
18700 SemaRef.Diag(VD->getLocation(),
18701 diag::err_omp_lambda_capture_in_declare_target_not_to);
18702 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18703 << VD << 0 << SR;
18704 return;
18705 }
18706 }
18707 if (MapTy.hasValue())
18708 return;
18709 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18710 SemaRef.Diag(SL, diag::note_used_here) << SR;
18711 }
18712
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)18713 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18714 Sema &SemaRef, DSAStackTy *Stack,
18715 ValueDecl *VD) {
18716 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18717 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18718 /*FullCheck=*/false);
18719 }
18720
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)18721 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18722 SourceLocation IdLoc) {
18723 if (!D || D->isInvalidDecl())
18724 return;
18725 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18726 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18727 if (auto *VD = dyn_cast<VarDecl>(D)) {
18728 // Only global variables can be marked as declare target.
18729 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18730 !VD->isStaticDataMember())
18731 return;
18732 // 2.10.6: threadprivate variable cannot appear in a declare target
18733 // directive.
18734 if (DSAStack->isThreadPrivate(VD)) {
18735 Diag(SL, diag::err_omp_threadprivate_in_target);
18736 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
18737 return;
18738 }
18739 }
18740 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18741 D = FTD->getTemplatedDecl();
18742 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18743 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18744 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18745 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18746 Diag(IdLoc, diag::err_omp_function_in_link_clause);
18747 Diag(FD->getLocation(), diag::note_defined_here) << FD;
18748 return;
18749 }
18750 }
18751 if (auto *VD = dyn_cast<ValueDecl>(D)) {
18752 // Problem if any with var declared with incomplete type will be reported
18753 // as normal, so no need to check it here.
18754 if ((E || !VD->getType()->isIncompleteType()) &&
18755 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
18756 return;
18757 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18758 // Checking declaration inside declare target region.
18759 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18760 isa<FunctionTemplateDecl>(D)) {
18761 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18762 Context, OMPDeclareTargetDeclAttr::MT_To,
18763 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
18764 SourceRange(DeclareTargetNesting.back(),
18765 DeclareTargetNesting.back()));
18766 D->addAttr(A);
18767 if (ASTMutationListener *ML = Context.getASTMutationListener())
18768 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18769 }
18770 return;
18771 }
18772 }
18773 if (!E)
18774 return;
18775 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18776 }
18777
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)18778 OMPClause *Sema::ActOnOpenMPToClause(
18779 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18780 ArrayRef<SourceLocation> MotionModifiersLoc,
18781 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18782 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18783 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18784 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18785 OMPC_MOTION_MODIFIER_unknown};
18786 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18787
18788 // Process motion-modifiers, flag errors for duplicate modifiers.
18789 unsigned Count = 0;
18790 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18791 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18792 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18793 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18794 continue;
18795 }
18796 assert(Count < NumberOfOMPMotionModifiers &&
18797 "Modifiers exceed the allowed number of motion modifiers");
18798 Modifiers[Count] = MotionModifiers[I];
18799 ModifiersLoc[Count] = MotionModifiersLoc[I];
18800 ++Count;
18801 }
18802
18803 MappableVarListInfo MVLI(VarList);
18804 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
18805 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18806 if (MVLI.ProcessedVarList.empty())
18807 return nullptr;
18808
18809 return OMPToClause::Create(
18810 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18811 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18812 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18813 }
18814
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)18815 OMPClause *Sema::ActOnOpenMPFromClause(
18816 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18817 ArrayRef<SourceLocation> MotionModifiersLoc,
18818 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18819 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18820 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18821 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18822 OMPC_MOTION_MODIFIER_unknown};
18823 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18824
18825 // Process motion-modifiers, flag errors for duplicate modifiers.
18826 unsigned Count = 0;
18827 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18828 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18829 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18830 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18831 continue;
18832 }
18833 assert(Count < NumberOfOMPMotionModifiers &&
18834 "Modifiers exceed the allowed number of motion modifiers");
18835 Modifiers[Count] = MotionModifiers[I];
18836 ModifiersLoc[Count] = MotionModifiersLoc[I];
18837 ++Count;
18838 }
18839
18840 MappableVarListInfo MVLI(VarList);
18841 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
18842 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18843 if (MVLI.ProcessedVarList.empty())
18844 return nullptr;
18845
18846 return OMPFromClause::Create(
18847 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18848 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18849 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18850 }
18851
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)18852 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
18853 const OMPVarListLocTy &Locs) {
18854 MappableVarListInfo MVLI(VarList);
18855 SmallVector<Expr *, 8> PrivateCopies;
18856 SmallVector<Expr *, 8> Inits;
18857
18858 for (Expr *RefExpr : VarList) {
18859 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
18860 SourceLocation ELoc;
18861 SourceRange ERange;
18862 Expr *SimpleRefExpr = RefExpr;
18863 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18864 if (Res.second) {
18865 // It will be analyzed later.
18866 MVLI.ProcessedVarList.push_back(RefExpr);
18867 PrivateCopies.push_back(nullptr);
18868 Inits.push_back(nullptr);
18869 }
18870 ValueDecl *D = Res.first;
18871 if (!D)
18872 continue;
18873
18874 QualType Type = D->getType();
18875 Type = Type.getNonReferenceType().getUnqualifiedType();
18876
18877 auto *VD = dyn_cast<VarDecl>(D);
18878
18879 // Item should be a pointer or reference to pointer.
18880 if (!Type->isPointerType()) {
18881 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
18882 << 0 << RefExpr->getSourceRange();
18883 continue;
18884 }
18885
18886 // Build the private variable and the expression that refers to it.
18887 auto VDPrivate =
18888 buildVarDecl(*this, ELoc, Type, D->getName(),
18889 D->hasAttrs() ? &D->getAttrs() : nullptr,
18890 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18891 if (VDPrivate->isInvalidDecl())
18892 continue;
18893
18894 CurContext->addDecl(VDPrivate);
18895 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18896 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18897
18898 // Add temporary variable to initialize the private copy of the pointer.
18899 VarDecl *VDInit =
18900 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
18901 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
18902 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
18903 AddInitializerToDecl(VDPrivate,
18904 DefaultLvalueConversion(VDInitRefExpr).get(),
18905 /*DirectInit=*/false);
18906
18907 // If required, build a capture to implement the privatization initialized
18908 // with the current list item value.
18909 DeclRefExpr *Ref = nullptr;
18910 if (!VD)
18911 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18912 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18913 PrivateCopies.push_back(VDPrivateRefExpr);
18914 Inits.push_back(VDInitRefExpr);
18915
18916 // We need to add a data sharing attribute for this variable to make sure it
18917 // is correctly captured. A variable that shows up in a use_device_ptr has
18918 // similar properties of a first private variable.
18919 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18920
18921 // Create a mappable component for the list item. List items in this clause
18922 // only need a component.
18923 MVLI.VarBaseDeclarations.push_back(D);
18924 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18925 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
18926 /*IsNonContiguous=*/false);
18927 }
18928
18929 if (MVLI.ProcessedVarList.empty())
18930 return nullptr;
18931
18932 return OMPUseDevicePtrClause::Create(
18933 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
18934 MVLI.VarBaseDeclarations, MVLI.VarComponents);
18935 }
18936
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)18937 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
18938 const OMPVarListLocTy &Locs) {
18939 MappableVarListInfo MVLI(VarList);
18940
18941 for (Expr *RefExpr : VarList) {
18942 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
18943 SourceLocation ELoc;
18944 SourceRange ERange;
18945 Expr *SimpleRefExpr = RefExpr;
18946 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18947 /*AllowArraySection=*/true);
18948 if (Res.second) {
18949 // It will be analyzed later.
18950 MVLI.ProcessedVarList.push_back(RefExpr);
18951 }
18952 ValueDecl *D = Res.first;
18953 if (!D)
18954 continue;
18955 auto *VD = dyn_cast<VarDecl>(D);
18956
18957 // If required, build a capture to implement the privatization initialized
18958 // with the current list item value.
18959 DeclRefExpr *Ref = nullptr;
18960 if (!VD)
18961 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18962 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18963
18964 // We need to add a data sharing attribute for this variable to make sure it
18965 // is correctly captured. A variable that shows up in a use_device_addr has
18966 // similar properties of a first private variable.
18967 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18968
18969 // Create a mappable component for the list item. List items in this clause
18970 // only need a component.
18971 MVLI.VarBaseDeclarations.push_back(D);
18972 MVLI.VarComponents.emplace_back();
18973 Expr *Component = SimpleRefExpr;
18974 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
18975 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
18976 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
18977 MVLI.VarComponents.back().emplace_back(Component, D,
18978 /*IsNonContiguous=*/false);
18979 }
18980
18981 if (MVLI.ProcessedVarList.empty())
18982 return nullptr;
18983
18984 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18985 MVLI.VarBaseDeclarations,
18986 MVLI.VarComponents);
18987 }
18988
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)18989 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
18990 const OMPVarListLocTy &Locs) {
18991 MappableVarListInfo MVLI(VarList);
18992 for (Expr *RefExpr : VarList) {
18993 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
18994 SourceLocation ELoc;
18995 SourceRange ERange;
18996 Expr *SimpleRefExpr = RefExpr;
18997 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18998 if (Res.second) {
18999 // It will be analyzed later.
19000 MVLI.ProcessedVarList.push_back(RefExpr);
19001 }
19002 ValueDecl *D = Res.first;
19003 if (!D)
19004 continue;
19005
19006 QualType Type = D->getType();
19007 // item should be a pointer or array or reference to pointer or array
19008 if (!Type.getNonReferenceType()->isPointerType() &&
19009 !Type.getNonReferenceType()->isArrayType()) {
19010 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
19011 << 0 << RefExpr->getSourceRange();
19012 continue;
19013 }
19014
19015 // Check if the declaration in the clause does not show up in any data
19016 // sharing attribute.
19017 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19018 if (isOpenMPPrivate(DVar.CKind)) {
19019 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19020 << getOpenMPClauseName(DVar.CKind)
19021 << getOpenMPClauseName(OMPC_is_device_ptr)
19022 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
19023 reportOriginalDsa(*this, DSAStack, D, DVar);
19024 continue;
19025 }
19026
19027 const Expr *ConflictExpr;
19028 if (DSAStack->checkMappableExprComponentListsForDecl(
19029 D, /*CurrentRegionOnly=*/true,
19030 [&ConflictExpr](
19031 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
19032 OpenMPClauseKind) -> bool {
19033 ConflictExpr = R.front().getAssociatedExpression();
19034 return true;
19035 })) {
19036 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
19037 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
19038 << ConflictExpr->getSourceRange();
19039 continue;
19040 }
19041
19042 // Store the components in the stack so that they can be used to check
19043 // against other clauses later on.
19044 OMPClauseMappableExprCommon::MappableComponent MC(
19045 SimpleRefExpr, D, /*IsNonContiguous=*/false);
19046 DSAStack->addMappableExpressionComponents(
19047 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
19048
19049 // Record the expression we've just processed.
19050 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
19051
19052 // Create a mappable component for the list item. List items in this clause
19053 // only need a component. We use a null declaration to signal fields in
19054 // 'this'.
19055 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
19056 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
19057 "Unexpected device pointer expression!");
19058 MVLI.VarBaseDeclarations.push_back(
19059 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
19060 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19061 MVLI.VarComponents.back().push_back(MC);
19062 }
19063
19064 if (MVLI.ProcessedVarList.empty())
19065 return nullptr;
19066
19067 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19068 MVLI.VarBaseDeclarations,
19069 MVLI.VarComponents);
19070 }
19071
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19072 OMPClause *Sema::ActOnOpenMPAllocateClause(
19073 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19074 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
19075 if (Allocator) {
19076 // OpenMP [2.11.4 allocate Clause, Description]
19077 // allocator is an expression of omp_allocator_handle_t type.
19078 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
19079 return nullptr;
19080
19081 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
19082 if (AllocatorRes.isInvalid())
19083 return nullptr;
19084 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
19085 DSAStack->getOMPAllocatorHandleT(),
19086 Sema::AA_Initializing,
19087 /*AllowExplicit=*/true);
19088 if (AllocatorRes.isInvalid())
19089 return nullptr;
19090 Allocator = AllocatorRes.get();
19091 } else {
19092 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
19093 // allocate clauses that appear on a target construct or on constructs in a
19094 // target region must specify an allocator expression unless a requires
19095 // directive with the dynamic_allocators clause is present in the same
19096 // compilation unit.
19097 if (LangOpts.OpenMPIsDevice &&
19098 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
19099 targetDiag(StartLoc, diag::err_expected_allocator_expression);
19100 }
19101 // Analyze and build list of variables.
19102 SmallVector<Expr *, 8> Vars;
19103 for (Expr *RefExpr : VarList) {
19104 assert(RefExpr && "NULL expr in OpenMP private clause.");
19105 SourceLocation ELoc;
19106 SourceRange ERange;
19107 Expr *SimpleRefExpr = RefExpr;
19108 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19109 if (Res.second) {
19110 // It will be analyzed later.
19111 Vars.push_back(RefExpr);
19112 }
19113 ValueDecl *D = Res.first;
19114 if (!D)
19115 continue;
19116
19117 auto *VD = dyn_cast<VarDecl>(D);
19118 DeclRefExpr *Ref = nullptr;
19119 if (!VD && !CurContext->isDependentContext())
19120 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19121 Vars.push_back((VD || CurContext->isDependentContext())
19122 ? RefExpr->IgnoreParens()
19123 : Ref);
19124 }
19125
19126 if (Vars.empty())
19127 return nullptr;
19128
19129 if (Allocator)
19130 DSAStack->addInnerAllocatorExpr(Allocator);
19131 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
19132 ColonLoc, EndLoc, Vars);
19133 }
19134
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19135 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
19136 SourceLocation StartLoc,
19137 SourceLocation LParenLoc,
19138 SourceLocation EndLoc) {
19139 SmallVector<Expr *, 8> Vars;
19140 for (Expr *RefExpr : VarList) {
19141 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19142 SourceLocation ELoc;
19143 SourceRange ERange;
19144 Expr *SimpleRefExpr = RefExpr;
19145 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19146 if (Res.second)
19147 // It will be analyzed later.
19148 Vars.push_back(RefExpr);
19149 ValueDecl *D = Res.first;
19150 if (!D)
19151 continue;
19152
19153 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
19154 // A list-item cannot appear in more than one nontemporal clause.
19155 if (const Expr *PrevRef =
19156 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
19157 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19158 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
19159 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19160 << getOpenMPClauseName(OMPC_nontemporal);
19161 continue;
19162 }
19163
19164 Vars.push_back(RefExpr);
19165 }
19166
19167 if (Vars.empty())
19168 return nullptr;
19169
19170 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19171 Vars);
19172 }
19173
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19174 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
19175 SourceLocation StartLoc,
19176 SourceLocation LParenLoc,
19177 SourceLocation EndLoc) {
19178 SmallVector<Expr *, 8> Vars;
19179 for (Expr *RefExpr : VarList) {
19180 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19181 SourceLocation ELoc;
19182 SourceRange ERange;
19183 Expr *SimpleRefExpr = RefExpr;
19184 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19185 /*AllowArraySection=*/true);
19186 if (Res.second)
19187 // It will be analyzed later.
19188 Vars.push_back(RefExpr);
19189 ValueDecl *D = Res.first;
19190 if (!D)
19191 continue;
19192
19193 const DSAStackTy::DSAVarData DVar =
19194 DSAStack->getTopDSA(D, /*FromParent=*/true);
19195 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19196 // A list item that appears in the inclusive or exclusive clause must appear
19197 // in a reduction clause with the inscan modifier on the enclosing
19198 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19199 if (DVar.CKind != OMPC_reduction ||
19200 DVar.Modifier != OMPC_REDUCTION_inscan)
19201 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19202 << RefExpr->getSourceRange();
19203
19204 if (DSAStack->getParentDirective() != OMPD_unknown)
19205 DSAStack->markDeclAsUsedInScanDirective(D);
19206 Vars.push_back(RefExpr);
19207 }
19208
19209 if (Vars.empty())
19210 return nullptr;
19211
19212 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19213 }
19214
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19215 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19216 SourceLocation StartLoc,
19217 SourceLocation LParenLoc,
19218 SourceLocation EndLoc) {
19219 SmallVector<Expr *, 8> Vars;
19220 for (Expr *RefExpr : VarList) {
19221 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19222 SourceLocation ELoc;
19223 SourceRange ERange;
19224 Expr *SimpleRefExpr = RefExpr;
19225 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19226 /*AllowArraySection=*/true);
19227 if (Res.second)
19228 // It will be analyzed later.
19229 Vars.push_back(RefExpr);
19230 ValueDecl *D = Res.first;
19231 if (!D)
19232 continue;
19233
19234 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
19235 DSAStackTy::DSAVarData DVar;
19236 if (ParentDirective != OMPD_unknown)
19237 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
19238 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19239 // A list item that appears in the inclusive or exclusive clause must appear
19240 // in a reduction clause with the inscan modifier on the enclosing
19241 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19242 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19243 DVar.Modifier != OMPC_REDUCTION_inscan) {
19244 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19245 << RefExpr->getSourceRange();
19246 } else {
19247 DSAStack->markDeclAsUsedInScanDirective(D);
19248 }
19249 Vars.push_back(RefExpr);
19250 }
19251
19252 if (Vars.empty())
19253 return nullptr;
19254
19255 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19256 }
19257
19258 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)19259 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19260 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19261 if (!OMPAlloctraitT.isNull())
19262 return true;
19263 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19264 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19265 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19266 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19267 return false;
19268 }
19269 Stack->setOMPAlloctraitT(PT.get());
19270 return true;
19271 }
19272
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)19273 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19274 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19275 ArrayRef<UsesAllocatorsData> Data) {
19276 // OpenMP [2.12.5, target Construct]
19277 // allocator is an identifier of omp_allocator_handle_t type.
19278 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
19279 return nullptr;
19280 // OpenMP [2.12.5, target Construct]
19281 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19282 if (llvm::any_of(
19283 Data,
19284 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19285 !findOMPAlloctraitT(*this, StartLoc, DSAStack))
19286 return nullptr;
19287 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19288 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19289 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19290 StringRef Allocator =
19291 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19292 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19293 PredefinedAllocators.insert(LookupSingleName(
19294 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19295 }
19296
19297 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19298 for (const UsesAllocatorsData &D : Data) {
19299 Expr *AllocatorExpr = nullptr;
19300 // Check allocator expression.
19301 if (D.Allocator->isTypeDependent()) {
19302 AllocatorExpr = D.Allocator;
19303 } else {
19304 // Traits were specified - need to assign new allocator to the specified
19305 // allocator, so it must be an lvalue.
19306 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19307 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19308 bool IsPredefinedAllocator = false;
19309 if (DRE)
19310 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19311 if (!DRE ||
19312 !(Context.hasSameUnqualifiedType(
19313 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
19314 Context.typesAreCompatible(AllocatorExpr->getType(),
19315 DSAStack->getOMPAllocatorHandleT(),
19316 /*CompareUnqualified=*/true)) ||
19317 (!IsPredefinedAllocator &&
19318 (AllocatorExpr->getType().isConstant(Context) ||
19319 !AllocatorExpr->isLValue()))) {
19320 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19321 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19322 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19323 continue;
19324 }
19325 // OpenMP [2.12.5, target Construct]
19326 // Predefined allocators appearing in a uses_allocators clause cannot have
19327 // traits specified.
19328 if (IsPredefinedAllocator && D.AllocatorTraits) {
19329 Diag(D.AllocatorTraits->getExprLoc(),
19330 diag::err_omp_predefined_allocator_with_traits)
19331 << D.AllocatorTraits->getSourceRange();
19332 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19333 << cast<NamedDecl>(DRE->getDecl())->getName()
19334 << D.Allocator->getSourceRange();
19335 continue;
19336 }
19337 // OpenMP [2.12.5, target Construct]
19338 // Non-predefined allocators appearing in a uses_allocators clause must
19339 // have traits specified.
19340 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19341 Diag(D.Allocator->getExprLoc(),
19342 diag::err_omp_nonpredefined_allocator_without_traits);
19343 continue;
19344 }
19345 // No allocator traits - just convert it to rvalue.
19346 if (!D.AllocatorTraits)
19347 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19348 DSAStack->addUsesAllocatorsDecl(
19349 DRE->getDecl(),
19350 IsPredefinedAllocator
19351 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19352 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19353 }
19354 Expr *AllocatorTraitsExpr = nullptr;
19355 if (D.AllocatorTraits) {
19356 if (D.AllocatorTraits->isTypeDependent()) {
19357 AllocatorTraitsExpr = D.AllocatorTraits;
19358 } else {
19359 // OpenMP [2.12.5, target Construct]
19360 // Arrays that contain allocator traits that appear in a uses_allocators
19361 // clause must be constant arrays, have constant values and be defined
19362 // in the same scope as the construct in which the clause appears.
19363 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19364 // Check that traits expr is a constant array.
19365 QualType TraitTy;
19366 if (const ArrayType *Ty =
19367 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19368 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19369 TraitTy = ConstArrayTy->getElementType();
19370 if (TraitTy.isNull() ||
19371 !(Context.hasSameUnqualifiedType(TraitTy,
19372 DSAStack->getOMPAlloctraitT()) ||
19373 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
19374 /*CompareUnqualified=*/true))) {
19375 Diag(D.AllocatorTraits->getExprLoc(),
19376 diag::err_omp_expected_array_alloctraits)
19377 << AllocatorTraitsExpr->getType();
19378 continue;
19379 }
19380 // Do not map by default allocator traits if it is a standalone
19381 // variable.
19382 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19383 DSAStack->addUsesAllocatorsDecl(
19384 DRE->getDecl(),
19385 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19386 }
19387 }
19388 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19389 NewD.Allocator = AllocatorExpr;
19390 NewD.AllocatorTraits = AllocatorTraitsExpr;
19391 NewD.LParenLoc = D.LParenLoc;
19392 NewD.RParenLoc = D.RParenLoc;
19393 }
19394 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19395 NewData);
19396 }
19397
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)19398 OMPClause *Sema::ActOnOpenMPAffinityClause(
19399 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19400 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19401 SmallVector<Expr *, 8> Vars;
19402 for (Expr *RefExpr : Locators) {
19403 assert(RefExpr && "NULL expr in OpenMP shared clause.");
19404 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19405 // It will be analyzed later.
19406 Vars.push_back(RefExpr);
19407 continue;
19408 }
19409
19410 SourceLocation ELoc = RefExpr->getExprLoc();
19411 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19412
19413 if (!SimpleExpr->isLValue()) {
19414 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19415 << 1 << 0 << RefExpr->getSourceRange();
19416 continue;
19417 }
19418
19419 ExprResult Res;
19420 {
19421 Sema::TentativeAnalysisScope Trap(*this);
19422 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19423 }
19424 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19425 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19426 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19427 << 1 << 0 << RefExpr->getSourceRange();
19428 continue;
19429 }
19430 Vars.push_back(SimpleExpr);
19431 }
19432
19433 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19434 EndLoc, Modifier, Vars);
19435 }
19436