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/ADT/StringExtras.h"
39 #include "llvm/Frontend/OpenMP/OMPConstants.h"
40 #include <set>
41
42 using namespace clang;
43 using namespace llvm::omp;
44
45 //===----------------------------------------------------------------------===//
46 // Stack of data-sharing attributes for variables
47 //===----------------------------------------------------------------------===//
48
49 static const Expr *checkMapClauseExpressionBase(
50 Sema &SemaRef, Expr *E,
51 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
52 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
53
54 namespace {
55 /// Default data sharing attributes, which can be applied to directive.
56 enum DefaultDataSharingAttributes {
57 DSA_unspecified = 0, /// Data sharing attribute not specified.
58 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
59 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
60 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
61 };
62
63 /// Stack for tracking declarations used in OpenMP directives and
64 /// clauses and their data-sharing attributes.
65 class DSAStackTy {
66 public:
67 struct DSAVarData {
68 OpenMPDirectiveKind DKind = OMPD_unknown;
69 OpenMPClauseKind CKind = OMPC_unknown;
70 unsigned Modifier = 0;
71 const Expr *RefExpr = nullptr;
72 DeclRefExpr *PrivateCopy = nullptr;
73 SourceLocation ImplicitDSALoc;
74 bool AppliedToPointee = false;
75 DSAVarData() = default;
DSAVarData__anon5b04668f0111::DSAStackTy::DSAVarData76 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
77 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
78 SourceLocation ImplicitDSALoc, unsigned Modifier,
79 bool AppliedToPointee)
80 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
81 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
82 AppliedToPointee(AppliedToPointee) {}
83 };
84 using OperatorOffsetTy =
85 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
86 using DoacrossDependMapTy =
87 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
88 /// Kind of the declaration used in the uses_allocators clauses.
89 enum class UsesAllocatorsDeclKind {
90 /// Predefined allocator
91 PredefinedAllocator,
92 /// User-defined allocator
93 UserDefinedAllocator,
94 /// The declaration that represent allocator trait
95 AllocatorTrait,
96 };
97
98 private:
99 struct DSAInfo {
100 OpenMPClauseKind Attributes = OMPC_unknown;
101 unsigned Modifier = 0;
102 /// Pointer to a reference expression and a flag which shows that the
103 /// variable is marked as lastprivate(true) or not (false).
104 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
105 DeclRefExpr *PrivateCopy = nullptr;
106 /// true if the attribute is applied to the pointee, not the variable
107 /// itself.
108 bool AppliedToPointee = false;
109 };
110 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
111 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
112 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
113 using LoopControlVariablesMapTy =
114 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
115 /// Struct that associates a component with the clause kind where they are
116 /// found.
117 struct MappedExprComponentTy {
118 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
119 OpenMPClauseKind Kind = OMPC_unknown;
120 };
121 using MappedExprComponentsTy =
122 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
123 using CriticalsWithHintsTy =
124 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
125 struct ReductionData {
126 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
127 SourceRange ReductionRange;
128 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
129 ReductionData() = default;
set__anon5b04668f0111::DSAStackTy::ReductionData130 void set(BinaryOperatorKind BO, SourceRange RR) {
131 ReductionRange = RR;
132 ReductionOp = BO;
133 }
set__anon5b04668f0111::DSAStackTy::ReductionData134 void set(const Expr *RefExpr, SourceRange RR) {
135 ReductionRange = RR;
136 ReductionOp = RefExpr;
137 }
138 };
139 using DeclReductionMapTy =
140 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
141 struct DefaultmapInfo {
142 OpenMPDefaultmapClauseModifier ImplicitBehavior =
143 OMPC_DEFAULTMAP_MODIFIER_unknown;
144 SourceLocation SLoc;
145 DefaultmapInfo() = default;
DefaultmapInfo__anon5b04668f0111::DSAStackTy::DefaultmapInfo146 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
147 : ImplicitBehavior(M), SLoc(Loc) {}
148 };
149
150 struct SharingMapTy {
151 DeclSAMapTy SharingMap;
152 DeclReductionMapTy ReductionMap;
153 UsedRefMapTy AlignedMap;
154 UsedRefMapTy NontemporalMap;
155 MappedExprComponentsTy MappedExprComponents;
156 LoopControlVariablesMapTy LCVMap;
157 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
158 SourceLocation DefaultAttrLoc;
159 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
160 OpenMPDirectiveKind Directive = OMPD_unknown;
161 DeclarationNameInfo DirectiveName;
162 Scope *CurScope = nullptr;
163 DeclContext *Context = nullptr;
164 SourceLocation ConstructLoc;
165 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
166 /// get the data (loop counters etc.) about enclosing loop-based construct.
167 /// This data is required during codegen.
168 DoacrossDependMapTy DoacrossDepends;
169 /// First argument (Expr *) contains optional argument of the
170 /// 'ordered' clause, the second one is true if the regions has 'ordered'
171 /// clause, false otherwise.
172 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
173 unsigned AssociatedLoops = 1;
174 bool HasMutipleLoops = false;
175 const Decl *PossiblyLoopCounter = nullptr;
176 bool NowaitRegion = false;
177 bool CancelRegion = false;
178 bool LoopStart = false;
179 bool BodyComplete = false;
180 SourceLocation PrevScanLocation;
181 SourceLocation PrevOrderedLocation;
182 SourceLocation InnerTeamsRegionLoc;
183 /// Reference to the taskgroup task_reduction reference expression.
184 Expr *TaskgroupReductionRef = nullptr;
185 llvm::DenseSet<QualType> MappedClassesQualTypes;
186 SmallVector<Expr *, 4> InnerUsedAllocators;
187 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
188 /// List of globals marked as declare target link in this target region
189 /// (isOpenMPTargetExecutionDirective(Directive) == true).
190 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
191 /// List of decls used in inclusive/exclusive clauses of the scan directive.
192 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
193 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
194 UsesAllocatorsDecls;
195 Expr *DeclareMapperVar = nullptr;
SharingMapTy__anon5b04668f0111::DSAStackTy::SharingMapTy196 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
197 Scope *CurScope, SourceLocation Loc)
198 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
199 ConstructLoc(Loc) {}
200 SharingMapTy() = default;
201 };
202
203 using StackTy = SmallVector<SharingMapTy, 4>;
204
205 /// Stack of used declaration and their data-sharing attributes.
206 DeclSAMapTy Threadprivates;
207 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
208 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
209 /// true, if check for DSA must be from parent directive, false, if
210 /// from current directive.
211 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
212 Sema &SemaRef;
213 bool ForceCapturing = false;
214 /// true if all the variables in the target executable directives must be
215 /// captured by reference.
216 bool ForceCaptureByReferenceInTargetExecutable = false;
217 CriticalsWithHintsTy Criticals;
218 unsigned IgnoredStackElements = 0;
219
220 /// Iterators over the stack iterate in order from innermost to outermost
221 /// directive.
222 using const_iterator = StackTy::const_reverse_iterator;
begin() const223 const_iterator begin() const {
224 return Stack.empty() ? const_iterator()
225 : Stack.back().first.rbegin() + IgnoredStackElements;
226 }
end() const227 const_iterator end() const {
228 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
229 }
230 using iterator = StackTy::reverse_iterator;
begin()231 iterator begin() {
232 return Stack.empty() ? iterator()
233 : Stack.back().first.rbegin() + IgnoredStackElements;
234 }
end()235 iterator end() {
236 return Stack.empty() ? iterator() : Stack.back().first.rend();
237 }
238
239 // Convenience operations to get at the elements of the stack.
240
isStackEmpty() const241 bool isStackEmpty() const {
242 return Stack.empty() ||
243 Stack.back().second != CurrentNonCapturingFunctionScope ||
244 Stack.back().first.size() <= IgnoredStackElements;
245 }
getStackSize() const246 size_t getStackSize() const {
247 return isStackEmpty() ? 0
248 : Stack.back().first.size() - IgnoredStackElements;
249 }
250
getTopOfStackOrNull()251 SharingMapTy *getTopOfStackOrNull() {
252 size_t Size = getStackSize();
253 if (Size == 0)
254 return nullptr;
255 return &Stack.back().first[Size - 1];
256 }
getTopOfStackOrNull() const257 const SharingMapTy *getTopOfStackOrNull() const {
258 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
259 }
getTopOfStack()260 SharingMapTy &getTopOfStack() {
261 assert(!isStackEmpty() && "no current directive");
262 return *getTopOfStackOrNull();
263 }
getTopOfStack() const264 const SharingMapTy &getTopOfStack() const {
265 return const_cast<DSAStackTy&>(*this).getTopOfStack();
266 }
267
getSecondOnStackOrNull()268 SharingMapTy *getSecondOnStackOrNull() {
269 size_t Size = getStackSize();
270 if (Size <= 1)
271 return nullptr;
272 return &Stack.back().first[Size - 2];
273 }
getSecondOnStackOrNull() const274 const SharingMapTy *getSecondOnStackOrNull() const {
275 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
276 }
277
278 /// Get the stack element at a certain level (previously returned by
279 /// \c getNestingLevel).
280 ///
281 /// Note that nesting levels count from outermost to innermost, and this is
282 /// the reverse of our iteration order where new inner levels are pushed at
283 /// the front of the stack.
getStackElemAtLevel(unsigned Level)284 SharingMapTy &getStackElemAtLevel(unsigned Level) {
285 assert(Level < getStackSize() && "no such stack element");
286 return Stack.back().first[Level];
287 }
getStackElemAtLevel(unsigned Level) const288 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
289 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
290 }
291
292 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
293
294 /// Checks if the variable is a local for OpenMP region.
295 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
296
297 /// Vector of previously declared requires directives
298 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
299 /// omp_allocator_handle_t type.
300 QualType OMPAllocatorHandleT;
301 /// omp_depend_t type.
302 QualType OMPDependT;
303 /// omp_event_handle_t type.
304 QualType OMPEventHandleT;
305 /// omp_alloctrait_t type.
306 QualType OMPAlloctraitT;
307 /// Expression for the predefined allocators.
308 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
309 nullptr};
310 /// Vector of previously encountered target directives
311 SmallVector<SourceLocation, 2> TargetLocations;
312 SourceLocation AtomicLocation;
313
314 public:
DSAStackTy(Sema & S)315 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
316
317 /// Sets omp_allocator_handle_t type.
setOMPAllocatorHandleT(QualType Ty)318 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
319 /// Gets omp_allocator_handle_t type.
getOMPAllocatorHandleT() const320 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
321 /// Sets omp_alloctrait_t type.
setOMPAlloctraitT(QualType Ty)322 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
323 /// Gets omp_alloctrait_t type.
getOMPAlloctraitT() const324 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
325 /// Sets the given default allocator.
setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)326 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
327 Expr *Allocator) {
328 OMPPredefinedAllocators[AllocatorKind] = Allocator;
329 }
330 /// Returns the specified default allocator.
getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const331 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
332 return OMPPredefinedAllocators[AllocatorKind];
333 }
334 /// Sets omp_depend_t type.
setOMPDependT(QualType Ty)335 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
336 /// Gets omp_depend_t type.
getOMPDependT() const337 QualType getOMPDependT() const { return OMPDependT; }
338
339 /// Sets omp_event_handle_t type.
setOMPEventHandleT(QualType Ty)340 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
341 /// Gets omp_event_handle_t type.
getOMPEventHandleT() const342 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
343
isClauseParsingMode() const344 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const345 OpenMPClauseKind getClauseParsingMode() const {
346 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
347 return ClauseKindMode;
348 }
setClauseParsingMode(OpenMPClauseKind K)349 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
350
isBodyComplete() const351 bool isBodyComplete() const {
352 const SharingMapTy *Top = getTopOfStackOrNull();
353 return Top && Top->BodyComplete;
354 }
setBodyComplete()355 void setBodyComplete() {
356 getTopOfStack().BodyComplete = true;
357 }
358
isForceVarCapturing() const359 bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)360 void setForceVarCapturing(bool V) { ForceCapturing = V; }
361
setForceCaptureByReferenceInTargetExecutable(bool V)362 void setForceCaptureByReferenceInTargetExecutable(bool V) {
363 ForceCaptureByReferenceInTargetExecutable = V;
364 }
isForceCaptureByReferenceInTargetExecutable() const365 bool isForceCaptureByReferenceInTargetExecutable() const {
366 return ForceCaptureByReferenceInTargetExecutable;
367 }
368
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)369 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
370 Scope *CurScope, SourceLocation Loc) {
371 assert(!IgnoredStackElements &&
372 "cannot change stack while ignoring elements");
373 if (Stack.empty() ||
374 Stack.back().second != CurrentNonCapturingFunctionScope)
375 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
376 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
377 Stack.back().first.back().DefaultAttrLoc = Loc;
378 }
379
pop()380 void pop() {
381 assert(!IgnoredStackElements &&
382 "cannot change stack while ignoring elements");
383 assert(!Stack.back().first.empty() &&
384 "Data-sharing attributes stack is empty!");
385 Stack.back().first.pop_back();
386 }
387
388 /// RAII object to temporarily leave the scope of a directive when we want to
389 /// logically operate in its parent.
390 class ParentDirectiveScope {
391 DSAStackTy &Self;
392 bool Active;
393 public:
ParentDirectiveScope(DSAStackTy & Self,bool Activate)394 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
395 : Self(Self), Active(false) {
396 if (Activate)
397 enable();
398 }
~ParentDirectiveScope()399 ~ParentDirectiveScope() { disable(); }
disable()400 void disable() {
401 if (Active) {
402 --Self.IgnoredStackElements;
403 Active = false;
404 }
405 }
enable()406 void enable() {
407 if (!Active) {
408 ++Self.IgnoredStackElements;
409 Active = true;
410 }
411 }
412 };
413
414 /// Marks that we're started loop parsing.
loopInit()415 void loopInit() {
416 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
417 "Expected loop-based directive.");
418 getTopOfStack().LoopStart = true;
419 }
420 /// Start capturing of the variables in the loop context.
loopStart()421 void loopStart() {
422 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
423 "Expected loop-based directive.");
424 getTopOfStack().LoopStart = false;
425 }
426 /// true, if variables are captured, false otherwise.
isLoopStarted() const427 bool isLoopStarted() const {
428 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
429 "Expected loop-based directive.");
430 return !getTopOfStack().LoopStart;
431 }
432 /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)433 void resetPossibleLoopCounter(const Decl *D = nullptr) {
434 getTopOfStack().PossiblyLoopCounter =
435 D ? D->getCanonicalDecl() : D;
436 }
437 /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const438 const Decl *getPossiblyLoopCunter() const {
439 return getTopOfStack().PossiblyLoopCounter;
440 }
441 /// Start new OpenMP region stack in new non-capturing function.
pushFunction()442 void pushFunction() {
443 assert(!IgnoredStackElements &&
444 "cannot change stack while ignoring elements");
445 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
446 assert(!isa<CapturingScopeInfo>(CurFnScope));
447 CurrentNonCapturingFunctionScope = CurFnScope;
448 }
449 /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)450 void popFunction(const FunctionScopeInfo *OldFSI) {
451 assert(!IgnoredStackElements &&
452 "cannot change stack while ignoring elements");
453 if (!Stack.empty() && Stack.back().second == OldFSI) {
454 assert(Stack.back().first.empty());
455 Stack.pop_back();
456 }
457 CurrentNonCapturingFunctionScope = nullptr;
458 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
459 if (!isa<CapturingScopeInfo>(FSI)) {
460 CurrentNonCapturingFunctionScope = FSI;
461 break;
462 }
463 }
464 }
465
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)466 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
467 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
468 }
469 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const470 getCriticalWithHint(const DeclarationNameInfo &Name) const {
471 auto I = Criticals.find(Name.getAsString());
472 if (I != Criticals.end())
473 return I->second;
474 return std::make_pair(nullptr, llvm::APSInt());
475 }
476 /// If 'aligned' declaration for given variable \a D was not seen yet,
477 /// add it and return NULL; otherwise return previous occurrence's expression
478 /// for diagnostics.
479 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
480 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
481 /// add it and return NULL; otherwise return previous occurrence's expression
482 /// for diagnostics.
483 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
484
485 /// Register specified variable as loop control variable.
486 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
487 /// Check if the specified variable is a loop control variable for
488 /// current region.
489 /// \return The index of the loop control variable in the list of associated
490 /// for-loops (from outer to inner).
491 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
492 /// Check if the specified variable is a loop control variable for
493 /// parent region.
494 /// \return The index of the loop control variable in the list of associated
495 /// for-loops (from outer to inner).
496 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
497 /// Check if the specified variable is a loop control variable for
498 /// current region.
499 /// \return The index of the loop control variable in the list of associated
500 /// for-loops (from outer to inner).
501 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
502 unsigned Level) const;
503 /// Get the loop control variable for the I-th loop (or nullptr) in
504 /// parent directive.
505 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
506
507 /// Marks the specified decl \p D as used in scan directive.
markDeclAsUsedInScanDirective(ValueDecl * D)508 void markDeclAsUsedInScanDirective(ValueDecl *D) {
509 if (SharingMapTy *Stack = getSecondOnStackOrNull())
510 Stack->UsedInScanDirective.insert(D);
511 }
512
513 /// Checks if the specified declaration was used in the inner scan directive.
isUsedInScanDirective(ValueDecl * D) const514 bool isUsedInScanDirective(ValueDecl *D) const {
515 if (const SharingMapTy *Stack = getTopOfStackOrNull())
516 return Stack->UsedInScanDirective.count(D) > 0;
517 return false;
518 }
519
520 /// Adds explicit data sharing attribute to the specified declaration.
521 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
522 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
523 bool AppliedToPointee = false);
524
525 /// Adds additional information for the reduction items with the reduction id
526 /// represented as an operator.
527 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
528 BinaryOperatorKind BOK);
529 /// Adds additional information for the reduction items with the reduction id
530 /// represented as reduction identifier.
531 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
532 const Expr *ReductionRef);
533 /// Returns the location and reduction operation from the innermost parent
534 /// region for the given \p D.
535 const DSAVarData
536 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
537 BinaryOperatorKind &BOK,
538 Expr *&TaskgroupDescriptor) const;
539 /// Returns the location and reduction operation from the innermost parent
540 /// region for the given \p D.
541 const DSAVarData
542 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
543 const Expr *&ReductionRef,
544 Expr *&TaskgroupDescriptor) const;
545 /// Return reduction reference expression for the current taskgroup or
546 /// parallel/worksharing directives with task reductions.
getTaskgroupReductionRef() const547 Expr *getTaskgroupReductionRef() const {
548 assert((getTopOfStack().Directive == OMPD_taskgroup ||
549 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
550 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
551 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
552 "taskgroup reference expression requested for non taskgroup or "
553 "parallel/worksharing directive.");
554 return getTopOfStack().TaskgroupReductionRef;
555 }
556 /// Checks if the given \p VD declaration is actually a taskgroup reduction
557 /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const558 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
559 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
560 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
561 ->getDecl() == VD;
562 }
563
564 /// Returns data sharing attributes from top of the stack for the
565 /// specified declaration.
566 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
567 /// Returns data-sharing attributes for the specified declaration.
568 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
569 /// Returns data-sharing attributes for the specified declaration.
570 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
571 /// Checks if the specified variables has data-sharing attributes which
572 /// match specified \a CPred predicate in any directive which matches \a DPred
573 /// predicate.
574 const DSAVarData
575 hasDSA(ValueDecl *D,
576 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
577 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
578 bool FromParent) const;
579 /// Checks if the specified variables has data-sharing attributes which
580 /// match specified \a CPred predicate in any innermost directive which
581 /// matches \a DPred predicate.
582 const DSAVarData
583 hasInnermostDSA(ValueDecl *D,
584 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
585 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
586 bool FromParent) const;
587 /// Checks if the specified variables has explicit data-sharing
588 /// attributes which match specified \a CPred predicate at the specified
589 /// OpenMP region.
590 bool
591 hasExplicitDSA(const ValueDecl *D,
592 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
593 unsigned Level, bool NotLastprivate = false) const;
594
595 /// Returns true if the directive at level \Level matches in the
596 /// specified \a DPred predicate.
597 bool hasExplicitDirective(
598 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
599 unsigned Level) const;
600
601 /// Finds a directive which matches specified \a DPred predicate.
602 bool hasDirective(
603 const llvm::function_ref<bool(
604 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
605 DPred,
606 bool FromParent) const;
607
608 /// Returns currently analyzed directive.
getCurrentDirective() const609 OpenMPDirectiveKind getCurrentDirective() const {
610 const SharingMapTy *Top = getTopOfStackOrNull();
611 return Top ? Top->Directive : OMPD_unknown;
612 }
613 /// Returns directive kind at specified level.
getDirective(unsigned Level) const614 OpenMPDirectiveKind getDirective(unsigned Level) const {
615 assert(!isStackEmpty() && "No directive at specified level.");
616 return getStackElemAtLevel(Level).Directive;
617 }
618 /// Returns the capture region at the specified level.
getCaptureRegion(unsigned Level,unsigned OpenMPCaptureLevel) const619 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
620 unsigned OpenMPCaptureLevel) const {
621 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
622 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
623 return CaptureRegions[OpenMPCaptureLevel];
624 }
625 /// Returns parent directive.
getParentDirective() const626 OpenMPDirectiveKind getParentDirective() const {
627 const SharingMapTy *Parent = getSecondOnStackOrNull();
628 return Parent ? Parent->Directive : OMPD_unknown;
629 }
630
631 /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)632 void addRequiresDecl(OMPRequiresDecl *RD) {
633 RequiresDecls.push_back(RD);
634 }
635
636 /// Checks if the defined 'requires' directive has specified type of clause.
637 template <typename ClauseType>
hasRequiresDeclWithClause() const638 bool hasRequiresDeclWithClause() const {
639 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
640 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
641 return isa<ClauseType>(C);
642 });
643 });
644 }
645
646 /// Checks for a duplicate clause amongst previously declared requires
647 /// directives
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const648 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
649 bool IsDuplicate = false;
650 for (OMPClause *CNew : ClauseList) {
651 for (const OMPRequiresDecl *D : RequiresDecls) {
652 for (const OMPClause *CPrev : D->clauselists()) {
653 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
654 SemaRef.Diag(CNew->getBeginLoc(),
655 diag::err_omp_requires_clause_redeclaration)
656 << getOpenMPClauseName(CNew->getClauseKind());
657 SemaRef.Diag(CPrev->getBeginLoc(),
658 diag::note_omp_requires_previous_clause)
659 << getOpenMPClauseName(CPrev->getClauseKind());
660 IsDuplicate = true;
661 }
662 }
663 }
664 }
665 return IsDuplicate;
666 }
667
668 /// Add location of previously encountered target to internal vector
addTargetDirLocation(SourceLocation LocStart)669 void addTargetDirLocation(SourceLocation LocStart) {
670 TargetLocations.push_back(LocStart);
671 }
672
673 /// Add location for the first encountered atomicc directive.
addAtomicDirectiveLoc(SourceLocation Loc)674 void addAtomicDirectiveLoc(SourceLocation Loc) {
675 if (AtomicLocation.isInvalid())
676 AtomicLocation = Loc;
677 }
678
679 /// Returns the location of the first encountered atomic directive in the
680 /// module.
getAtomicDirectiveLoc() const681 SourceLocation getAtomicDirectiveLoc() const {
682 return AtomicLocation;
683 }
684
685 // Return previously encountered target region locations.
getEncounteredTargetLocs() const686 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
687 return TargetLocations;
688 }
689
690 /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)691 void setDefaultDSANone(SourceLocation Loc) {
692 getTopOfStack().DefaultAttr = DSA_none;
693 getTopOfStack().DefaultAttrLoc = Loc;
694 }
695 /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)696 void setDefaultDSAShared(SourceLocation Loc) {
697 getTopOfStack().DefaultAttr = DSA_shared;
698 getTopOfStack().DefaultAttrLoc = Loc;
699 }
700 /// Set default data sharing attribute to firstprivate.
setDefaultDSAFirstPrivate(SourceLocation Loc)701 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
702 getTopOfStack().DefaultAttr = DSA_firstprivate;
703 getTopOfStack().DefaultAttrLoc = Loc;
704 }
705 /// Set default data mapping attribute to Modifier:Kind
setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation Loc)706 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
707 OpenMPDefaultmapClauseKind Kind,
708 SourceLocation Loc) {
709 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
710 DMI.ImplicitBehavior = M;
711 DMI.SLoc = Loc;
712 }
713 /// Check whether the implicit-behavior has been set in defaultmap
checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory)714 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
715 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
716 return getTopOfStack()
717 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
718 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
719 getTopOfStack()
720 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
721 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
722 getTopOfStack()
723 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
724 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
725 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
726 OMPC_DEFAULTMAP_MODIFIER_unknown;
727 }
728
getDefaultDSA(unsigned Level) const729 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
730 return getStackSize() <= Level ? DSA_unspecified
731 : getStackElemAtLevel(Level).DefaultAttr;
732 }
getDefaultDSA() const733 DefaultDataSharingAttributes getDefaultDSA() const {
734 return isStackEmpty() ? DSA_unspecified
735 : getTopOfStack().DefaultAttr;
736 }
getDefaultDSALocation() const737 SourceLocation getDefaultDSALocation() const {
738 return isStackEmpty() ? SourceLocation()
739 : getTopOfStack().DefaultAttrLoc;
740 }
741 OpenMPDefaultmapClauseModifier
getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const742 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
743 return isStackEmpty()
744 ? OMPC_DEFAULTMAP_MODIFIER_unknown
745 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
746 }
747 OpenMPDefaultmapClauseModifier
getDefaultmapModifierAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const748 getDefaultmapModifierAtLevel(unsigned Level,
749 OpenMPDefaultmapClauseKind Kind) const {
750 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
751 }
isDefaultmapCapturedByRef(unsigned Level,OpenMPDefaultmapClauseKind Kind) const752 bool isDefaultmapCapturedByRef(unsigned Level,
753 OpenMPDefaultmapClauseKind Kind) const {
754 OpenMPDefaultmapClauseModifier M =
755 getDefaultmapModifierAtLevel(Level, Kind);
756 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
757 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
760 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
761 }
762 return true;
763 }
mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind)764 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
765 OpenMPDefaultmapClauseKind Kind) {
766 switch (Kind) {
767 case OMPC_DEFAULTMAP_scalar:
768 case OMPC_DEFAULTMAP_pointer:
769 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
770 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
771 (M == OMPC_DEFAULTMAP_MODIFIER_default);
772 case OMPC_DEFAULTMAP_aggregate:
773 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
774 default:
775 break;
776 }
777 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
778 }
mustBeFirstprivateAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const779 bool mustBeFirstprivateAtLevel(unsigned Level,
780 OpenMPDefaultmapClauseKind Kind) const {
781 OpenMPDefaultmapClauseModifier M =
782 getDefaultmapModifierAtLevel(Level, Kind);
783 return mustBeFirstprivateBase(M, Kind);
784 }
mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const785 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
786 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
787 return mustBeFirstprivateBase(M, Kind);
788 }
789
790 /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)791 bool isThreadPrivate(VarDecl *D) {
792 const DSAVarData DVar = getTopDSA(D, false);
793 return isOpenMPThreadPrivate(DVar.CKind);
794 }
795
796 /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)797 void setOrderedRegion(bool IsOrdered, const Expr *Param,
798 OMPOrderedClause *Clause) {
799 if (IsOrdered)
800 getTopOfStack().OrderedRegion.emplace(Param, Clause);
801 else
802 getTopOfStack().OrderedRegion.reset();
803 }
804 /// Returns true, if region is ordered (has associated 'ordered' clause),
805 /// false - otherwise.
isOrderedRegion() const806 bool isOrderedRegion() const {
807 if (const SharingMapTy *Top = getTopOfStackOrNull())
808 return Top->OrderedRegion.hasValue();
809 return false;
810 }
811 /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const812 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
813 if (const SharingMapTy *Top = getTopOfStackOrNull())
814 if (Top->OrderedRegion.hasValue())
815 return Top->OrderedRegion.getValue();
816 return std::make_pair(nullptr, nullptr);
817 }
818 /// Returns true, if parent region is ordered (has associated
819 /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const820 bool isParentOrderedRegion() const {
821 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
822 return Parent->OrderedRegion.hasValue();
823 return false;
824 }
825 /// Returns optional parameter for the ordered region.
826 std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const827 getParentOrderedRegionParam() const {
828 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
829 if (Parent->OrderedRegion.hasValue())
830 return Parent->OrderedRegion.getValue();
831 return std::make_pair(nullptr, nullptr);
832 }
833 /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)834 void setNowaitRegion(bool IsNowait = true) {
835 getTopOfStack().NowaitRegion = IsNowait;
836 }
837 /// Returns true, if parent region is nowait (has associated
838 /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const839 bool isParentNowaitRegion() const {
840 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
841 return Parent->NowaitRegion;
842 return false;
843 }
844 /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)845 void setParentCancelRegion(bool Cancel = true) {
846 if (SharingMapTy *Parent = getSecondOnStackOrNull())
847 Parent->CancelRegion |= Cancel;
848 }
849 /// Return true if current region has inner cancel construct.
isCancelRegion() const850 bool isCancelRegion() const {
851 const SharingMapTy *Top = getTopOfStackOrNull();
852 return Top ? Top->CancelRegion : false;
853 }
854
855 /// Mark that parent region already has scan directive.
setParentHasScanDirective(SourceLocation Loc)856 void setParentHasScanDirective(SourceLocation Loc) {
857 if (SharingMapTy *Parent = getSecondOnStackOrNull())
858 Parent->PrevScanLocation = Loc;
859 }
860 /// Return true if current region has inner cancel construct.
doesParentHasScanDirective() const861 bool doesParentHasScanDirective() const {
862 const SharingMapTy *Top = getSecondOnStackOrNull();
863 return Top ? Top->PrevScanLocation.isValid() : false;
864 }
865 /// Return true if current region has inner cancel construct.
getParentScanDirectiveLoc() const866 SourceLocation getParentScanDirectiveLoc() const {
867 const SharingMapTy *Top = getSecondOnStackOrNull();
868 return Top ? Top->PrevScanLocation : SourceLocation();
869 }
870 /// Mark that parent region already has ordered directive.
setParentHasOrderedDirective(SourceLocation Loc)871 void setParentHasOrderedDirective(SourceLocation Loc) {
872 if (SharingMapTy *Parent = getSecondOnStackOrNull())
873 Parent->PrevOrderedLocation = Loc;
874 }
875 /// Return true if current region has inner ordered construct.
doesParentHasOrderedDirective() const876 bool doesParentHasOrderedDirective() const {
877 const SharingMapTy *Top = getSecondOnStackOrNull();
878 return Top ? Top->PrevOrderedLocation.isValid() : false;
879 }
880 /// Returns the location of the previously specified ordered directive.
getParentOrderedDirectiveLoc() const881 SourceLocation getParentOrderedDirectiveLoc() const {
882 const SharingMapTy *Top = getSecondOnStackOrNull();
883 return Top ? Top->PrevOrderedLocation : SourceLocation();
884 }
885
886 /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)887 void setAssociatedLoops(unsigned Val) {
888 getTopOfStack().AssociatedLoops = Val;
889 if (Val > 1)
890 getTopOfStack().HasMutipleLoops = true;
891 }
892 /// Return collapse value for region.
getAssociatedLoops() const893 unsigned getAssociatedLoops() const {
894 const SharingMapTy *Top = getTopOfStackOrNull();
895 return Top ? Top->AssociatedLoops : 0;
896 }
897 /// Returns true if the construct is associated with multiple loops.
hasMutipleLoops() const898 bool hasMutipleLoops() const {
899 const SharingMapTy *Top = getTopOfStackOrNull();
900 return Top ? Top->HasMutipleLoops : false;
901 }
902
903 /// Marks current target region as one with closely nested teams
904 /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)905 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
906 if (SharingMapTy *Parent = getSecondOnStackOrNull())
907 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
908 }
909 /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const910 bool hasInnerTeamsRegion() const {
911 return getInnerTeamsRegionLoc().isValid();
912 }
913 /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const914 SourceLocation getInnerTeamsRegionLoc() const {
915 const SharingMapTy *Top = getTopOfStackOrNull();
916 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
917 }
918
getCurScope() const919 Scope *getCurScope() const {
920 const SharingMapTy *Top = getTopOfStackOrNull();
921 return Top ? Top->CurScope : nullptr;
922 }
setContext(DeclContext * DC)923 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
getConstructLoc() const924 SourceLocation getConstructLoc() const {
925 const SharingMapTy *Top = getTopOfStackOrNull();
926 return Top ? Top->ConstructLoc : SourceLocation();
927 }
928
929 /// Do the check specified in \a Check to all component lists and return true
930 /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const931 bool checkMappableExprComponentListsForDecl(
932 const ValueDecl *VD, bool CurrentRegionOnly,
933 const llvm::function_ref<
934 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
935 OpenMPClauseKind)>
936 Check) const {
937 if (isStackEmpty())
938 return false;
939 auto SI = begin();
940 auto SE = end();
941
942 if (SI == SE)
943 return false;
944
945 if (CurrentRegionOnly)
946 SE = std::next(SI);
947 else
948 std::advance(SI, 1);
949
950 for (; SI != SE; ++SI) {
951 auto MI = SI->MappedExprComponents.find(VD);
952 if (MI != SI->MappedExprComponents.end())
953 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
954 MI->second.Components)
955 if (Check(L, MI->second.Kind))
956 return true;
957 }
958 return false;
959 }
960
961 /// Do the check specified in \a Check to all component lists at a given level
962 /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const963 bool checkMappableExprComponentListsForDeclAtLevel(
964 const ValueDecl *VD, unsigned Level,
965 const llvm::function_ref<
966 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
967 OpenMPClauseKind)>
968 Check) const {
969 if (getStackSize() <= Level)
970 return false;
971
972 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
973 auto MI = StackElem.MappedExprComponents.find(VD);
974 if (MI != StackElem.MappedExprComponents.end())
975 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
976 MI->second.Components)
977 if (Check(L, MI->second.Kind))
978 return true;
979 return false;
980 }
981
982 /// Create a new mappable expression component list associated with a given
983 /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)984 void addMappableExpressionComponents(
985 const ValueDecl *VD,
986 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
987 OpenMPClauseKind WhereFoundClauseKind) {
988 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
989 // Create new entry and append the new components there.
990 MEC.Components.resize(MEC.Components.size() + 1);
991 MEC.Components.back().append(Components.begin(), Components.end());
992 MEC.Kind = WhereFoundClauseKind;
993 }
994
getNestingLevel() const995 unsigned getNestingLevel() const {
996 assert(!isStackEmpty());
997 return getStackSize() - 1;
998 }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)999 void addDoacrossDependClause(OMPDependClause *C,
1000 const OperatorOffsetTy &OpsOffs) {
1001 SharingMapTy *Parent = getSecondOnStackOrNull();
1002 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1003 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1004 }
1005 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const1006 getDoacrossDependClauses() const {
1007 const SharingMapTy &StackElem = getTopOfStack();
1008 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1009 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1010 return llvm::make_range(Ref.begin(), Ref.end());
1011 }
1012 return llvm::make_range(StackElem.DoacrossDepends.end(),
1013 StackElem.DoacrossDepends.end());
1014 }
1015
1016 // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)1017 void addMappedClassesQualTypes(QualType QT) {
1018 SharingMapTy &StackElem = getTopOfStack();
1019 StackElem.MappedClassesQualTypes.insert(QT);
1020 }
1021
1022 // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const1023 bool isClassPreviouslyMapped(QualType QT) const {
1024 const SharingMapTy &StackElem = getTopOfStack();
1025 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1026 }
1027
1028 /// Adds global declare target to the parent target region.
addToParentTargetRegionLinkGlobals(DeclRefExpr * E)1029 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1030 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1031 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1032 "Expected declare target link global.");
1033 for (auto &Elem : *this) {
1034 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1035 Elem.DeclareTargetLinkVarDecls.push_back(E);
1036 return;
1037 }
1038 }
1039 }
1040
1041 /// Returns the list of globals with declare target link if current directive
1042 /// is target.
getLinkGlobals() const1043 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1044 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1045 "Expected target executable directive.");
1046 return getTopOfStack().DeclareTargetLinkVarDecls;
1047 }
1048
1049 /// Adds list of allocators expressions.
addInnerAllocatorExpr(Expr * E)1050 void addInnerAllocatorExpr(Expr *E) {
1051 getTopOfStack().InnerUsedAllocators.push_back(E);
1052 }
1053 /// Return list of used allocators.
getInnerAllocators() const1054 ArrayRef<Expr *> getInnerAllocators() const {
1055 return getTopOfStack().InnerUsedAllocators;
1056 }
1057 /// Marks the declaration as implicitly firstprivate nin the task-based
1058 /// regions.
addImplicitTaskFirstprivate(unsigned Level,Decl * D)1059 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1060 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1061 }
1062 /// Checks if the decl is implicitly firstprivate in the task-based region.
isImplicitTaskFirstprivate(Decl * D) const1063 bool isImplicitTaskFirstprivate(Decl *D) const {
1064 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1065 }
1066
1067 /// Marks decl as used in uses_allocators clause as the allocator.
addUsesAllocatorsDecl(const Decl * D,UsesAllocatorsDeclKind Kind)1068 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1069 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1070 }
1071 /// Checks if specified decl is used in uses allocator clause as the
1072 /// allocator.
isUsesAllocatorsDecl(unsigned Level,const Decl * D) const1073 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1074 const Decl *D) const {
1075 const SharingMapTy &StackElem = getTopOfStack();
1076 auto I = StackElem.UsesAllocatorsDecls.find(D);
1077 if (I == StackElem.UsesAllocatorsDecls.end())
1078 return None;
1079 return I->getSecond();
1080 }
isUsesAllocatorsDecl(const Decl * D) const1081 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1082 const SharingMapTy &StackElem = getTopOfStack();
1083 auto I = StackElem.UsesAllocatorsDecls.find(D);
1084 if (I == StackElem.UsesAllocatorsDecls.end())
1085 return None;
1086 return I->getSecond();
1087 }
1088
addDeclareMapperVarRef(Expr * Ref)1089 void addDeclareMapperVarRef(Expr *Ref) {
1090 SharingMapTy &StackElem = getTopOfStack();
1091 StackElem.DeclareMapperVar = Ref;
1092 }
getDeclareMapperVarRef() const1093 const Expr *getDeclareMapperVarRef() const {
1094 const SharingMapTy *Top = getTopOfStackOrNull();
1095 return Top ? Top->DeclareMapperVar : nullptr;
1096 }
1097 };
1098
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)1099 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1100 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1101 }
1102
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)1103 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1104 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1105 DKind == OMPD_unknown;
1106 }
1107
1108 } // namespace
1109
getExprAsWritten(const Expr * E)1110 static const Expr *getExprAsWritten(const Expr *E) {
1111 if (const auto *FE = dyn_cast<FullExpr>(E))
1112 E = FE->getSubExpr();
1113
1114 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1115 E = MTE->getSubExpr();
1116
1117 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1118 E = Binder->getSubExpr();
1119
1120 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1121 E = ICE->getSubExprAsWritten();
1122 return E->IgnoreParens();
1123 }
1124
getExprAsWritten(Expr * E)1125 static Expr *getExprAsWritten(Expr *E) {
1126 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1127 }
1128
getCanonicalDecl(const ValueDecl * D)1129 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1130 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1131 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1132 D = ME->getMemberDecl();
1133 const auto *VD = dyn_cast<VarDecl>(D);
1134 const auto *FD = dyn_cast<FieldDecl>(D);
1135 if (VD != nullptr) {
1136 VD = VD->getCanonicalDecl();
1137 D = VD;
1138 } else {
1139 assert(FD);
1140 FD = FD->getCanonicalDecl();
1141 D = FD;
1142 }
1143 return D;
1144 }
1145
getCanonicalDecl(ValueDecl * D)1146 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1147 return const_cast<ValueDecl *>(
1148 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1149 }
1150
getDSA(const_iterator & Iter,ValueDecl * D) const1151 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1152 ValueDecl *D) const {
1153 D = getCanonicalDecl(D);
1154 auto *VD = dyn_cast<VarDecl>(D);
1155 const auto *FD = dyn_cast<FieldDecl>(D);
1156 DSAVarData DVar;
1157 if (Iter == end()) {
1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1159 // in a region but not in construct]
1160 // File-scope or namespace-scope variables referenced in called routines
1161 // in the region are shared unless they appear in a threadprivate
1162 // directive.
1163 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1164 DVar.CKind = OMPC_shared;
1165
1166 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1167 // in a region but not in construct]
1168 // Variables with static storage duration that are declared in called
1169 // routines in the region are shared.
1170 if (VD && VD->hasGlobalStorage())
1171 DVar.CKind = OMPC_shared;
1172
1173 // Non-static data members are shared by default.
1174 if (FD)
1175 DVar.CKind = OMPC_shared;
1176
1177 return DVar;
1178 }
1179
1180 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1181 // in a Construct, C/C++, predetermined, p.1]
1182 // Variables with automatic storage duration that are declared in a scope
1183 // inside the construct are private.
1184 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1185 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1186 DVar.CKind = OMPC_private;
1187 return DVar;
1188 }
1189
1190 DVar.DKind = Iter->Directive;
1191 // Explicitly specified attributes and local variables with predetermined
1192 // attributes.
1193 if (Iter->SharingMap.count(D)) {
1194 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1195 DVar.RefExpr = Data.RefExpr.getPointer();
1196 DVar.PrivateCopy = Data.PrivateCopy;
1197 DVar.CKind = Data.Attributes;
1198 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1199 DVar.Modifier = Data.Modifier;
1200 DVar.AppliedToPointee = Data.AppliedToPointee;
1201 return DVar;
1202 }
1203
1204 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1205 // in a Construct, C/C++, implicitly determined, p.1]
1206 // In a parallel or task construct, the data-sharing attributes of these
1207 // variables are determined by the default clause, if present.
1208 switch (Iter->DefaultAttr) {
1209 case DSA_shared:
1210 DVar.CKind = OMPC_shared;
1211 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1212 return DVar;
1213 case DSA_none:
1214 return DVar;
1215 case DSA_firstprivate:
1216 if (VD->getStorageDuration() == SD_Static &&
1217 VD->getDeclContext()->isFileContext()) {
1218 DVar.CKind = OMPC_unknown;
1219 } else {
1220 DVar.CKind = OMPC_firstprivate;
1221 }
1222 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1223 return DVar;
1224 case DSA_unspecified:
1225 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1226 // in a Construct, implicitly determined, p.2]
1227 // In a parallel construct, if no default clause is present, these
1228 // variables are shared.
1229 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1230 if ((isOpenMPParallelDirective(DVar.DKind) &&
1231 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1232 isOpenMPTeamsDirective(DVar.DKind)) {
1233 DVar.CKind = OMPC_shared;
1234 return DVar;
1235 }
1236
1237 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1238 // in a Construct, implicitly determined, p.4]
1239 // In a task construct, if no default clause is present, a variable that in
1240 // the enclosing context is determined to be shared by all implicit tasks
1241 // bound to the current team is shared.
1242 if (isOpenMPTaskingDirective(DVar.DKind)) {
1243 DSAVarData DVarTemp;
1244 const_iterator I = Iter, E = end();
1245 do {
1246 ++I;
1247 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1248 // Referenced in a Construct, implicitly determined, p.6]
1249 // In a task construct, if no default clause is present, a variable
1250 // whose data-sharing attribute is not determined by the rules above is
1251 // firstprivate.
1252 DVarTemp = getDSA(I, D);
1253 if (DVarTemp.CKind != OMPC_shared) {
1254 DVar.RefExpr = nullptr;
1255 DVar.CKind = OMPC_firstprivate;
1256 return DVar;
1257 }
1258 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1259 DVar.CKind =
1260 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1261 return DVar;
1262 }
1263 }
1264 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1265 // in a Construct, implicitly determined, p.3]
1266 // For constructs other than task, if no default clause is present, these
1267 // variables inherit their data-sharing attributes from the enclosing
1268 // context.
1269 return getDSA(++Iter, D);
1270 }
1271
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)1272 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1273 const Expr *NewDE) {
1274 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1275 D = getCanonicalDecl(D);
1276 SharingMapTy &StackElem = getTopOfStack();
1277 auto It = StackElem.AlignedMap.find(D);
1278 if (It == StackElem.AlignedMap.end()) {
1279 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1280 StackElem.AlignedMap[D] = NewDE;
1281 return nullptr;
1282 }
1283 assert(It->second && "Unexpected nullptr expr in the aligned map");
1284 return It->second;
1285 }
1286
addUniqueNontemporal(const ValueDecl * D,const Expr * NewDE)1287 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1288 const Expr *NewDE) {
1289 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1290 D = getCanonicalDecl(D);
1291 SharingMapTy &StackElem = getTopOfStack();
1292 auto It = StackElem.NontemporalMap.find(D);
1293 if (It == StackElem.NontemporalMap.end()) {
1294 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1295 StackElem.NontemporalMap[D] = NewDE;
1296 return nullptr;
1297 }
1298 assert(It->second && "Unexpected nullptr expr in the aligned map");
1299 return It->second;
1300 }
1301
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)1302 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1303 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1304 D = getCanonicalDecl(D);
1305 SharingMapTy &StackElem = getTopOfStack();
1306 StackElem.LCVMap.try_emplace(
1307 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1308 }
1309
1310 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const1311 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1312 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1313 D = getCanonicalDecl(D);
1314 const SharingMapTy &StackElem = getTopOfStack();
1315 auto It = StackElem.LCVMap.find(D);
1316 if (It != StackElem.LCVMap.end())
1317 return It->second;
1318 return {0, nullptr};
1319 }
1320
1321 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D,unsigned Level) const1322 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1323 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1324 D = getCanonicalDecl(D);
1325 for (unsigned I = Level + 1; I > 0; --I) {
1326 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1327 auto It = StackElem.LCVMap.find(D);
1328 if (It != StackElem.LCVMap.end())
1329 return It->second;
1330 }
1331 return {0, nullptr};
1332 }
1333
1334 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const1335 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1336 const SharingMapTy *Parent = getSecondOnStackOrNull();
1337 assert(Parent && "Data-sharing attributes stack is empty");
1338 D = getCanonicalDecl(D);
1339 auto It = Parent->LCVMap.find(D);
1340 if (It != Parent->LCVMap.end())
1341 return It->second;
1342 return {0, nullptr};
1343 }
1344
getParentLoopControlVariable(unsigned I) const1345 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1346 const SharingMapTy *Parent = getSecondOnStackOrNull();
1347 assert(Parent && "Data-sharing attributes stack is empty");
1348 if (Parent->LCVMap.size() < I)
1349 return nullptr;
1350 for (const auto &Pair : Parent->LCVMap)
1351 if (Pair.second.first == I)
1352 return Pair.first;
1353 return nullptr;
1354 }
1355
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy,unsigned Modifier,bool AppliedToPointee)1356 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1357 DeclRefExpr *PrivateCopy, unsigned Modifier,
1358 bool AppliedToPointee) {
1359 D = getCanonicalDecl(D);
1360 if (A == OMPC_threadprivate) {
1361 DSAInfo &Data = Threadprivates[D];
1362 Data.Attributes = A;
1363 Data.RefExpr.setPointer(E);
1364 Data.PrivateCopy = nullptr;
1365 Data.Modifier = Modifier;
1366 } else {
1367 DSAInfo &Data = getTopOfStack().SharingMap[D];
1368 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1369 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1370 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1371 (isLoopControlVariable(D).first && A == OMPC_private));
1372 Data.Modifier = Modifier;
1373 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1374 Data.RefExpr.setInt(/*IntVal=*/true);
1375 return;
1376 }
1377 const bool IsLastprivate =
1378 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1379 Data.Attributes = A;
1380 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1381 Data.PrivateCopy = PrivateCopy;
1382 Data.AppliedToPointee = AppliedToPointee;
1383 if (PrivateCopy) {
1384 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1385 Data.Modifier = Modifier;
1386 Data.Attributes = A;
1387 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1388 Data.PrivateCopy = nullptr;
1389 Data.AppliedToPointee = AppliedToPointee;
1390 }
1391 }
1392 }
1393
1394 /// 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)1395 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1396 StringRef Name, const AttrVec *Attrs = nullptr,
1397 DeclRefExpr *OrigRef = nullptr) {
1398 DeclContext *DC = SemaRef.CurContext;
1399 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1400 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1401 auto *Decl =
1402 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1403 if (Attrs) {
1404 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1405 I != E; ++I)
1406 Decl->addAttr(*I);
1407 }
1408 Decl->setImplicit();
1409 if (OrigRef) {
1410 Decl->addAttr(
1411 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1412 }
1413 return Decl;
1414 }
1415
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)1416 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1417 SourceLocation Loc,
1418 bool RefersToCapture = false) {
1419 D->setReferenced();
1420 D->markUsed(S.Context);
1421 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1422 SourceLocation(), D, RefersToCapture, Loc, Ty,
1423 VK_LValue);
1424 }
1425
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)1426 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1427 BinaryOperatorKind BOK) {
1428 D = getCanonicalDecl(D);
1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1430 assert(
1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1432 "Additional reduction info may be specified only for reduction items.");
1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434 assert(ReductionData.ReductionRange.isInvalid() &&
1435 (getTopOfStack().Directive == OMPD_taskgroup ||
1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1439 "Additional reduction info may be specified only once for reduction "
1440 "items.");
1441 ReductionData.set(BOK, SR);
1442 Expr *&TaskgroupReductionRef =
1443 getTopOfStack().TaskgroupReductionRef;
1444 if (!TaskgroupReductionRef) {
1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1446 SemaRef.Context.VoidPtrTy, ".task_red.");
1447 TaskgroupReductionRef =
1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1449 }
1450 }
1451
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)1452 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1453 const Expr *ReductionRef) {
1454 D = getCanonicalDecl(D);
1455 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1456 assert(
1457 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1458 "Additional reduction info may be specified only for reduction items.");
1459 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1460 assert(ReductionData.ReductionRange.isInvalid() &&
1461 (getTopOfStack().Directive == OMPD_taskgroup ||
1462 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1463 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1464 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1465 "Additional reduction info may be specified only once for reduction "
1466 "items.");
1467 ReductionData.set(ReductionRef, SR);
1468 Expr *&TaskgroupReductionRef =
1469 getTopOfStack().TaskgroupReductionRef;
1470 if (!TaskgroupReductionRef) {
1471 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1472 SemaRef.Context.VoidPtrTy, ".task_red.");
1473 TaskgroupReductionRef =
1474 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1475 }
1476 }
1477
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1478 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1479 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1480 Expr *&TaskgroupDescriptor) const {
1481 D = getCanonicalDecl(D);
1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1484 const DSAInfo &Data = I->SharingMap.lookup(D);
1485 if (Data.Attributes != OMPC_reduction ||
1486 Data.Modifier != OMPC_REDUCTION_task)
1487 continue;
1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1489 if (!ReductionData.ReductionOp ||
1490 ReductionData.ReductionOp.is<const Expr *>())
1491 return DSAVarData();
1492 SR = ReductionData.ReductionRange;
1493 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1495 "expression for the descriptor is not "
1496 "set.");
1497 TaskgroupDescriptor = I->TaskgroupReductionRef;
1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1500 /*AppliedToPointee=*/false);
1501 }
1502 return DSAVarData();
1503 }
1504
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1505 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1506 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1507 Expr *&TaskgroupDescriptor) const {
1508 D = getCanonicalDecl(D);
1509 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1510 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1511 const DSAInfo &Data = I->SharingMap.lookup(D);
1512 if (Data.Attributes != OMPC_reduction ||
1513 Data.Modifier != OMPC_REDUCTION_task)
1514 continue;
1515 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1516 if (!ReductionData.ReductionOp ||
1517 !ReductionData.ReductionOp.is<const Expr *>())
1518 return DSAVarData();
1519 SR = ReductionData.ReductionRange;
1520 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1521 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1522 "expression for the descriptor is not "
1523 "set.");
1524 TaskgroupDescriptor = I->TaskgroupReductionRef;
1525 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1526 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1527 /*AppliedToPointee=*/false);
1528 }
1529 return DSAVarData();
1530 }
1531
isOpenMPLocal(VarDecl * D,const_iterator I) const1532 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1533 D = D->getCanonicalDecl();
1534 for (const_iterator E = end(); I != E; ++I) {
1535 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1536 isOpenMPTargetExecutionDirective(I->Directive)) {
1537 if (I->CurScope) {
1538 Scope *TopScope = I->CurScope->getParent();
1539 Scope *CurScope = getCurScope();
1540 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1541 CurScope = CurScope->getParent();
1542 return CurScope != TopScope;
1543 }
1544 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1545 if (I->Context == DC)
1546 return true;
1547 return false;
1548 }
1549 }
1550 return false;
1551 }
1552
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1553 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1554 bool AcceptIfMutable = true,
1555 bool *IsClassType = nullptr) {
1556 ASTContext &Context = SemaRef.getASTContext();
1557 Type = Type.getNonReferenceType().getCanonicalType();
1558 bool IsConstant = Type.isConstant(Context);
1559 Type = Context.getBaseElementType(Type);
1560 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1561 ? Type->getAsCXXRecordDecl()
1562 : nullptr;
1563 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1564 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1565 RD = CTD->getTemplatedDecl();
1566 if (IsClassType)
1567 *IsClassType = RD;
1568 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1569 RD->hasDefinition() && RD->hasMutableFields());
1570 }
1571
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1572 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1573 QualType Type, OpenMPClauseKind CKind,
1574 SourceLocation ELoc,
1575 bool AcceptIfMutable = true,
1576 bool ListItemNotVar = false) {
1577 ASTContext &Context = SemaRef.getASTContext();
1578 bool IsClassType;
1579 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1580 unsigned Diag = ListItemNotVar
1581 ? diag::err_omp_const_list_item
1582 : IsClassType ? diag::err_omp_const_not_mutable_variable
1583 : diag::err_omp_const_variable;
1584 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1585 if (!ListItemNotVar && D) {
1586 const VarDecl *VD = dyn_cast<VarDecl>(D);
1587 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1588 VarDecl::DeclarationOnly;
1589 SemaRef.Diag(D->getLocation(),
1590 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1591 << D;
1592 }
1593 return true;
1594 }
1595 return false;
1596 }
1597
getTopDSA(ValueDecl * D,bool FromParent)1598 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1599 bool FromParent) {
1600 D = getCanonicalDecl(D);
1601 DSAVarData DVar;
1602
1603 auto *VD = dyn_cast<VarDecl>(D);
1604 auto TI = Threadprivates.find(D);
1605 if (TI != Threadprivates.end()) {
1606 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1607 DVar.CKind = OMPC_threadprivate;
1608 DVar.Modifier = TI->getSecond().Modifier;
1609 return DVar;
1610 }
1611 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1612 DVar.RefExpr = buildDeclRefExpr(
1613 SemaRef, VD, D->getType().getNonReferenceType(),
1614 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1615 DVar.CKind = OMPC_threadprivate;
1616 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1617 return DVar;
1618 }
1619 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1620 // in a Construct, C/C++, predetermined, p.1]
1621 // Variables appearing in threadprivate directives are threadprivate.
1622 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1623 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1624 SemaRef.getLangOpts().OpenMPUseTLS &&
1625 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1626 (VD && VD->getStorageClass() == SC_Register &&
1627 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1628 DVar.RefExpr = buildDeclRefExpr(
1629 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1630 DVar.CKind = OMPC_threadprivate;
1631 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1632 return DVar;
1633 }
1634 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1635 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1636 !isLoopControlVariable(D).first) {
1637 const_iterator IterTarget =
1638 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1639 return isOpenMPTargetExecutionDirective(Data.Directive);
1640 });
1641 if (IterTarget != end()) {
1642 const_iterator ParentIterTarget = IterTarget + 1;
1643 for (const_iterator Iter = begin();
1644 Iter != ParentIterTarget; ++Iter) {
1645 if (isOpenMPLocal(VD, Iter)) {
1646 DVar.RefExpr =
1647 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1648 D->getLocation());
1649 DVar.CKind = OMPC_threadprivate;
1650 return DVar;
1651 }
1652 }
1653 if (!isClauseParsingMode() || IterTarget != begin()) {
1654 auto DSAIter = IterTarget->SharingMap.find(D);
1655 if (DSAIter != IterTarget->SharingMap.end() &&
1656 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1657 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1658 DVar.CKind = OMPC_threadprivate;
1659 return DVar;
1660 }
1661 const_iterator End = end();
1662 if (!SemaRef.isOpenMPCapturedByRef(
1663 D, std::distance(ParentIterTarget, End),
1664 /*OpenMPCaptureLevel=*/0)) {
1665 DVar.RefExpr =
1666 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1667 IterTarget->ConstructLoc);
1668 DVar.CKind = OMPC_threadprivate;
1669 return DVar;
1670 }
1671 }
1672 }
1673 }
1674
1675 if (isStackEmpty())
1676 // Not in OpenMP execution region and top scope was already checked.
1677 return DVar;
1678
1679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1680 // in a Construct, C/C++, predetermined, p.4]
1681 // Static data members are shared.
1682 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1683 // in a Construct, C/C++, predetermined, p.7]
1684 // Variables with static storage duration that are declared in a scope
1685 // inside the construct are shared.
1686 if (VD && VD->isStaticDataMember()) {
1687 // Check for explicitly specified attributes.
1688 const_iterator I = begin();
1689 const_iterator EndI = end();
1690 if (FromParent && I != EndI)
1691 ++I;
1692 if (I != EndI) {
1693 auto It = I->SharingMap.find(D);
1694 if (It != I->SharingMap.end()) {
1695 const DSAInfo &Data = It->getSecond();
1696 DVar.RefExpr = Data.RefExpr.getPointer();
1697 DVar.PrivateCopy = Data.PrivateCopy;
1698 DVar.CKind = Data.Attributes;
1699 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1700 DVar.DKind = I->Directive;
1701 DVar.Modifier = Data.Modifier;
1702 DVar.AppliedToPointee = Data.AppliedToPointee;
1703 return DVar;
1704 }
1705 }
1706
1707 DVar.CKind = OMPC_shared;
1708 return DVar;
1709 }
1710
1711 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1712 // The predetermined shared attribute for const-qualified types having no
1713 // mutable members was removed after OpenMP 3.1.
1714 if (SemaRef.LangOpts.OpenMP <= 31) {
1715 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1716 // in a Construct, C/C++, predetermined, p.6]
1717 // Variables with const qualified type having no mutable member are
1718 // shared.
1719 if (isConstNotMutableType(SemaRef, D->getType())) {
1720 // Variables with const-qualified type having no mutable member may be
1721 // listed in a firstprivate clause, even if they are static data members.
1722 DSAVarData DVarTemp = hasInnermostDSA(
1723 D,
1724 [](OpenMPClauseKind C, bool) {
1725 return C == OMPC_firstprivate || C == OMPC_shared;
1726 },
1727 MatchesAlways, FromParent);
1728 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1729 return DVarTemp;
1730
1731 DVar.CKind = OMPC_shared;
1732 return DVar;
1733 }
1734 }
1735
1736 // Explicitly specified attributes and local variables with predetermined
1737 // attributes.
1738 const_iterator I = begin();
1739 const_iterator EndI = end();
1740 if (FromParent && I != EndI)
1741 ++I;
1742 if (I == EndI)
1743 return DVar;
1744 auto It = I->SharingMap.find(D);
1745 if (It != I->SharingMap.end()) {
1746 const DSAInfo &Data = It->getSecond();
1747 DVar.RefExpr = Data.RefExpr.getPointer();
1748 DVar.PrivateCopy = Data.PrivateCopy;
1749 DVar.CKind = Data.Attributes;
1750 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1751 DVar.DKind = I->Directive;
1752 DVar.Modifier = Data.Modifier;
1753 DVar.AppliedToPointee = Data.AppliedToPointee;
1754 }
1755
1756 return DVar;
1757 }
1758
getImplicitDSA(ValueDecl * D,bool FromParent) const1759 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1760 bool FromParent) const {
1761 if (isStackEmpty()) {
1762 const_iterator I;
1763 return getDSA(I, D);
1764 }
1765 D = getCanonicalDecl(D);
1766 const_iterator StartI = begin();
1767 const_iterator EndI = end();
1768 if (FromParent && StartI != EndI)
1769 ++StartI;
1770 return getDSA(StartI, D);
1771 }
1772
getImplicitDSA(ValueDecl * D,unsigned Level) const1773 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1774 unsigned Level) const {
1775 if (getStackSize() <= Level)
1776 return DSAVarData();
1777 D = getCanonicalDecl(D);
1778 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1779 return getDSA(StartI, D);
1780 }
1781
1782 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1783 DSAStackTy::hasDSA(ValueDecl *D,
1784 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1785 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1786 bool FromParent) const {
1787 if (isStackEmpty())
1788 return {};
1789 D = getCanonicalDecl(D);
1790 const_iterator I = begin();
1791 const_iterator EndI = end();
1792 if (FromParent && I != EndI)
1793 ++I;
1794 for (; I != EndI; ++I) {
1795 if (!DPred(I->Directive) &&
1796 !isImplicitOrExplicitTaskingRegion(I->Directive))
1797 continue;
1798 const_iterator NewI = I;
1799 DSAVarData DVar = getDSA(NewI, D);
1800 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1801 return DVar;
1802 }
1803 return {};
1804 }
1805
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1806 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1807 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1808 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1809 bool FromParent) const {
1810 if (isStackEmpty())
1811 return {};
1812 D = getCanonicalDecl(D);
1813 const_iterator StartI = begin();
1814 const_iterator EndI = end();
1815 if (FromParent && StartI != EndI)
1816 ++StartI;
1817 if (StartI == EndI || !DPred(StartI->Directive))
1818 return {};
1819 const_iterator NewI = StartI;
1820 DSAVarData DVar = getDSA(NewI, D);
1821 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1822 ? DVar
1823 : DSAVarData();
1824 }
1825
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,unsigned Level,bool NotLastprivate) const1826 bool DSAStackTy::hasExplicitDSA(
1827 const ValueDecl *D,
1828 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1829 unsigned Level, bool NotLastprivate) const {
1830 if (getStackSize() <= Level)
1831 return false;
1832 D = getCanonicalDecl(D);
1833 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1834 auto I = StackElem.SharingMap.find(D);
1835 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1836 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1837 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1838 return true;
1839 // Check predetermined rules for the loop control variables.
1840 auto LI = StackElem.LCVMap.find(D);
1841 if (LI != StackElem.LCVMap.end())
1842 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1843 return false;
1844 }
1845
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1846 bool DSAStackTy::hasExplicitDirective(
1847 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1848 unsigned Level) const {
1849 if (getStackSize() <= Level)
1850 return false;
1851 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1852 return DPred(StackElem.Directive);
1853 }
1854
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1855 bool DSAStackTy::hasDirective(
1856 const llvm::function_ref<bool(OpenMPDirectiveKind,
1857 const DeclarationNameInfo &, SourceLocation)>
1858 DPred,
1859 bool FromParent) const {
1860 // We look only in the enclosing region.
1861 size_t Skip = FromParent ? 2 : 1;
1862 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1863 I != E; ++I) {
1864 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1865 return true;
1866 }
1867 return false;
1868 }
1869
InitDataSharingAttributesStack()1870 void Sema::InitDataSharingAttributesStack() {
1871 VarDataSharingAttributesStack = new DSAStackTy(*this);
1872 }
1873
1874 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1875
pushOpenMPFunctionRegion()1876 void Sema::pushOpenMPFunctionRegion() {
1877 DSAStack->pushFunction();
1878 }
1879
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1880 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1881 DSAStack->popFunction(OldFSI);
1882 }
1883
isOpenMPDeviceDelayedContext(Sema & S)1884 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1885 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1886 "Expected OpenMP device compilation.");
1887 return !S.isInOpenMPTargetExecutionDirective();
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,FunctionDecl * FD)1899 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1900 unsigned DiagID,
1901 FunctionDecl *FD) {
1902 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1903 "Expected OpenMP device compilation.");
1904
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 // TODO: We should always delay diagnostics here in case a target
1914 // region is in a function we do not emit. However, as the
1915 // current diagnostics are associated with the function containing
1916 // the target region and we do not emit that one, we would miss out
1917 // on diagnostics for the target region itself. We need to anchor
1918 // the diagnostics with the new generated function *or* ensure we
1919 // emit diagnostics associated with the surrounding function.
1920 Kind = isOpenMPDeviceDelayedContext(*this)
1921 ? SemaDiagnosticBuilder::K_Deferred
1922 : SemaDiagnosticBuilder::K_Immediate;
1923 break;
1924 case FunctionEmissionStatus::TemplateDiscarded:
1925 case FunctionEmissionStatus::OMPDiscarded:
1926 Kind = SemaDiagnosticBuilder::K_Nop;
1927 break;
1928 case FunctionEmissionStatus::CUDADiscarded:
1929 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1930 break;
1931 }
1932 }
1933
1934 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1935 }
1936
diagIfOpenMPHostCode(SourceLocation Loc,unsigned DiagID,FunctionDecl * FD)1937 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1938 unsigned DiagID,
1939 FunctionDecl *FD) {
1940 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1941 "Expected OpenMP host compilation.");
1942
1943 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944 if (FD) {
1945 FunctionEmissionStatus FES = getEmissionStatus(FD);
1946 switch (FES) {
1947 case FunctionEmissionStatus::Emitted:
1948 Kind = SemaDiagnosticBuilder::K_Immediate;
1949 break;
1950 case FunctionEmissionStatus::Unknown:
1951 Kind = SemaDiagnosticBuilder::K_Deferred;
1952 break;
1953 case FunctionEmissionStatus::TemplateDiscarded:
1954 case FunctionEmissionStatus::OMPDiscarded:
1955 case FunctionEmissionStatus::CUDADiscarded:
1956 Kind = SemaDiagnosticBuilder::K_Nop;
1957 break;
1958 }
1959 }
1960
1961 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1962 }
1963
1964 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)1965 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1966 if (LO.OpenMP <= 45) {
1967 if (VD->getType().getNonReferenceType()->isScalarType())
1968 return OMPC_DEFAULTMAP_scalar;
1969 return OMPC_DEFAULTMAP_aggregate;
1970 }
1971 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1972 return OMPC_DEFAULTMAP_pointer;
1973 if (VD->getType().getNonReferenceType()->isScalarType())
1974 return OMPC_DEFAULTMAP_scalar;
1975 return OMPC_DEFAULTMAP_aggregate;
1976 }
1977
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const1978 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1979 unsigned OpenMPCaptureLevel) const {
1980 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1981
1982 ASTContext &Ctx = getASTContext();
1983 bool IsByRef = true;
1984
1985 // Find the directive that is associated with the provided scope.
1986 D = cast<ValueDecl>(D->getCanonicalDecl());
1987 QualType Ty = D->getType();
1988
1989 bool IsVariableUsedInMapClause = false;
1990 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1991 // This table summarizes how a given variable should be passed to the device
1992 // given its type and the clauses where it appears. This table is based on
1993 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1994 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1995 //
1996 // =========================================================================
1997 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1998 // | |(tofrom:scalar)| | pvt | | | |
1999 // =========================================================================
2000 // | scl | | | | - | | bycopy|
2001 // | scl | | - | x | - | - | bycopy|
2002 // | scl | | x | - | - | - | null |
2003 // | scl | x | | | - | | byref |
2004 // | scl | x | - | x | - | - | bycopy|
2005 // | scl | x | x | - | - | - | null |
2006 // | scl | | - | - | - | x | byref |
2007 // | scl | x | - | - | - | x | byref |
2008 //
2009 // | agg | n.a. | | | - | | byref |
2010 // | agg | n.a. | - | x | - | - | byref |
2011 // | agg | n.a. | x | - | - | - | null |
2012 // | agg | n.a. | - | - | - | x | byref |
2013 // | agg | n.a. | - | - | - | x[] | byref |
2014 //
2015 // | ptr | n.a. | | | - | | bycopy|
2016 // | ptr | n.a. | - | x | - | - | bycopy|
2017 // | ptr | n.a. | x | - | - | - | null |
2018 // | ptr | n.a. | - | - | - | x | byref |
2019 // | ptr | n.a. | - | - | - | x[] | bycopy|
2020 // | ptr | n.a. | - | - | x | | bycopy|
2021 // | ptr | n.a. | - | - | x | x | bycopy|
2022 // | ptr | n.a. | - | - | x | x[] | bycopy|
2023 // =========================================================================
2024 // Legend:
2025 // scl - scalar
2026 // ptr - pointer
2027 // agg - aggregate
2028 // x - applies
2029 // - - invalid in this combination
2030 // [] - mapped with an array section
2031 // byref - should be mapped by reference
2032 // byval - should be mapped by value
2033 // null - initialize a local variable to null on the device
2034 //
2035 // Observations:
2036 // - All scalar declarations that show up in a map clause have to be passed
2037 // by reference, because they may have been mapped in the enclosing data
2038 // environment.
2039 // - If the scalar value does not fit the size of uintptr, it has to be
2040 // passed by reference, regardless the result in the table above.
2041 // - For pointers mapped by value that have either an implicit map or an
2042 // array section, the runtime library may pass the NULL value to the
2043 // device instead of the value passed to it by the compiler.
2044
2045 if (Ty->isReferenceType())
2046 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2047
2048 // Locate map clauses and see if the variable being captured is referred to
2049 // in any of those clauses. Here we only care about variables, not fields,
2050 // because fields are part of aggregates.
2051 bool IsVariableAssociatedWithSection = false;
2052
2053 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2054 D, Level,
2055 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2056 OMPClauseMappableExprCommon::MappableExprComponentListRef
2057 MapExprComponents,
2058 OpenMPClauseKind WhereFoundClauseKind) {
2059 // Only the map clause information influences how a variable is
2060 // captured. E.g. is_device_ptr does not require changing the default
2061 // behavior.
2062 if (WhereFoundClauseKind != OMPC_map)
2063 return false;
2064
2065 auto EI = MapExprComponents.rbegin();
2066 auto EE = MapExprComponents.rend();
2067
2068 assert(EI != EE && "Invalid map expression!");
2069
2070 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2071 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2072
2073 ++EI;
2074 if (EI == EE)
2075 return false;
2076
2077 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2078 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2079 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2080 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2081 IsVariableAssociatedWithSection = true;
2082 // There is nothing more we need to know about this variable.
2083 return true;
2084 }
2085
2086 // Keep looking for more map info.
2087 return false;
2088 });
2089
2090 if (IsVariableUsedInMapClause) {
2091 // If variable is identified in a map clause it is always captured by
2092 // reference except if it is a pointer that is dereferenced somehow.
2093 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2094 } else {
2095 // By default, all the data that has a scalar type is mapped by copy
2096 // (except for reduction variables).
2097 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2098 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2099 !Ty->isAnyPointerType()) ||
2100 !Ty->isScalarType() ||
2101 DSAStack->isDefaultmapCapturedByRef(
2102 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2103 DSAStack->hasExplicitDSA(
2104 D,
2105 [](OpenMPClauseKind K, bool AppliedToPointee) {
2106 return K == OMPC_reduction && !AppliedToPointee;
2107 },
2108 Level);
2109 }
2110 }
2111
2112 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2113 IsByRef =
2114 ((IsVariableUsedInMapClause &&
2115 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2116 OMPD_target) ||
2117 !(DSAStack->hasExplicitDSA(
2118 D,
2119 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2120 return K == OMPC_firstprivate ||
2121 (K == OMPC_reduction && AppliedToPointee);
2122 },
2123 Level, /*NotLastprivate=*/true) ||
2124 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2125 // If the variable is artificial and must be captured by value - try to
2126 // capture by value.
2127 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2128 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2129 // If the variable is implicitly firstprivate and scalar - capture by
2130 // copy
2131 !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2132 !DSAStack->hasExplicitDSA(
2133 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2134 Level) &&
2135 !DSAStack->isLoopControlVariable(D, Level).first);
2136 }
2137
2138 // When passing data by copy, we need to make sure it fits the uintptr size
2139 // and alignment, because the runtime library only deals with uintptr types.
2140 // If it does not fit the uintptr size, we need to pass the data by reference
2141 // instead.
2142 if (!IsByRef &&
2143 (Ctx.getTypeSizeInChars(Ty) >
2144 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2145 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2146 IsByRef = true;
2147 }
2148
2149 return IsByRef;
2150 }
2151
getOpenMPNestingLevel() const2152 unsigned Sema::getOpenMPNestingLevel() const {
2153 assert(getLangOpts().OpenMP);
2154 return DSAStack->getNestingLevel();
2155 }
2156
isInOpenMPTargetExecutionDirective() const2157 bool Sema::isInOpenMPTargetExecutionDirective() const {
2158 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2159 !DSAStack->isClauseParsingMode()) ||
2160 DSAStack->hasDirective(
2161 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2162 SourceLocation) -> bool {
2163 return isOpenMPTargetExecutionDirective(K);
2164 },
2165 false);
2166 }
2167
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2168 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2169 unsigned StopAt) {
2170 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2171 D = getCanonicalDecl(D);
2172
2173 auto *VD = dyn_cast<VarDecl>(D);
2174 // Do not capture constexpr variables.
2175 if (VD && VD->isConstexpr())
2176 return nullptr;
2177
2178 // If we want to determine whether the variable should be captured from the
2179 // perspective of the current capturing scope, and we've already left all the
2180 // capturing scopes of the top directive on the stack, check from the
2181 // perspective of its parent directive (if any) instead.
2182 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2183 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2184
2185 // If we are attempting to capture a global variable in a directive with
2186 // 'target' we return true so that this global is also mapped to the device.
2187 //
2188 if (VD && !VD->hasLocalStorage() &&
2189 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2190 if (isInOpenMPTargetExecutionDirective()) {
2191 DSAStackTy::DSAVarData DVarTop =
2192 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2193 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2194 return VD;
2195 // If the declaration is enclosed in a 'declare target' directive,
2196 // then it should not be captured.
2197 //
2198 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2199 return nullptr;
2200 CapturedRegionScopeInfo *CSI = nullptr;
2201 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2202 llvm::reverse(FunctionScopes),
2203 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2204 if (!isa<CapturingScopeInfo>(FSI))
2205 return nullptr;
2206 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2207 if (RSI->CapRegionKind == CR_OpenMP) {
2208 CSI = RSI;
2209 break;
2210 }
2211 }
2212 assert(CSI && "Failed to find CapturedRegionScopeInfo");
2213 SmallVector<OpenMPDirectiveKind, 4> Regions;
2214 getOpenMPCaptureRegions(Regions,
2215 DSAStack->getDirective(CSI->OpenMPLevel));
2216 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2217 return VD;
2218 }
2219 if (isInOpenMPDeclareTargetContext()) {
2220 // Try to mark variable as declare target if it is used in capturing
2221 // regions.
2222 if (LangOpts.OpenMP <= 45 &&
2223 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2224 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2225 return nullptr;
2226 }
2227 }
2228
2229 if (CheckScopeInfo) {
2230 bool OpenMPFound = false;
2231 for (unsigned I = StopAt + 1; I > 0; --I) {
2232 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2233 if(!isa<CapturingScopeInfo>(FSI))
2234 return nullptr;
2235 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2236 if (RSI->CapRegionKind == CR_OpenMP) {
2237 OpenMPFound = true;
2238 break;
2239 }
2240 }
2241 if (!OpenMPFound)
2242 return nullptr;
2243 }
2244
2245 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2246 (!DSAStack->isClauseParsingMode() ||
2247 DSAStack->getParentDirective() != OMPD_unknown)) {
2248 auto &&Info = DSAStack->isLoopControlVariable(D);
2249 if (Info.first ||
2250 (VD && VD->hasLocalStorage() &&
2251 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2252 (VD && DSAStack->isForceVarCapturing()))
2253 return VD ? VD : Info.second;
2254 DSAStackTy::DSAVarData DVarTop =
2255 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2256 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2257 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2258 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2259 // Threadprivate variables must not be captured.
2260 if (isOpenMPThreadPrivate(DVarTop.CKind))
2261 return nullptr;
2262 // The variable is not private or it is the variable in the directive with
2263 // default(none) clause and not used in any clause.
2264 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2265 D,
2266 [](OpenMPClauseKind C, bool AppliedToPointee) {
2267 return isOpenMPPrivate(C) && !AppliedToPointee;
2268 },
2269 [](OpenMPDirectiveKind) { return true; },
2270 DSAStack->isClauseParsingMode());
2271 // Global shared must not be captured.
2272 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2273 ((DSAStack->getDefaultDSA() != DSA_none &&
2274 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2275 DVarTop.CKind == OMPC_shared))
2276 return nullptr;
2277 if (DVarPrivate.CKind != OMPC_unknown ||
2278 (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2279 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2280 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2281 }
2282 return nullptr;
2283 }
2284
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2285 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2286 unsigned Level) const {
2287 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2288 }
2289
startOpenMPLoop()2290 void Sema::startOpenMPLoop() {
2291 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2292 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2293 DSAStack->loopInit();
2294 }
2295
startOpenMPCXXRangeFor()2296 void Sema::startOpenMPCXXRangeFor() {
2297 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2298 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2299 DSAStack->resetPossibleLoopCounter();
2300 DSAStack->loopStart();
2301 }
2302 }
2303
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2304 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2305 unsigned CapLevel) const {
2306 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2307 if (DSAStack->hasExplicitDirective(
2308 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2309 Level)) {
2310 bool IsTriviallyCopyable =
2311 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2312 !D->getType()
2313 .getNonReferenceType()
2314 .getCanonicalType()
2315 ->getAsCXXRecordDecl();
2316 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2317 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2318 getOpenMPCaptureRegions(CaptureRegions, DKind);
2319 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2320 (IsTriviallyCopyable ||
2321 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2322 if (DSAStack->hasExplicitDSA(
2323 D,
2324 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2325 Level, /*NotLastprivate=*/true))
2326 return OMPC_firstprivate;
2327 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2328 if (DVar.CKind != OMPC_shared &&
2329 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2330 DSAStack->addImplicitTaskFirstprivate(Level, D);
2331 return OMPC_firstprivate;
2332 }
2333 }
2334 }
2335 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2336 if (DSAStack->getAssociatedLoops() > 0 &&
2337 !DSAStack->isLoopStarted()) {
2338 DSAStack->resetPossibleLoopCounter(D);
2339 DSAStack->loopStart();
2340 return OMPC_private;
2341 }
2342 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2343 DSAStack->isLoopControlVariable(D).first) &&
2344 !DSAStack->hasExplicitDSA(
2345 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2346 Level) &&
2347 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2348 return OMPC_private;
2349 }
2350 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2351 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2352 DSAStack->isForceVarCapturing() &&
2353 !DSAStack->hasExplicitDSA(
2354 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2355 Level))
2356 return OMPC_private;
2357 }
2358 // User-defined allocators are private since they must be defined in the
2359 // context of target region.
2360 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2361 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2362 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2363 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2364 return OMPC_private;
2365 return (DSAStack->hasExplicitDSA(
2366 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2367 Level) ||
2368 (DSAStack->isClauseParsingMode() &&
2369 DSAStack->getClauseParsingMode() == OMPC_private) ||
2370 // Consider taskgroup reduction descriptor variable a private
2371 // to avoid possible capture in the region.
2372 (DSAStack->hasExplicitDirective(
2373 [](OpenMPDirectiveKind K) {
2374 return K == OMPD_taskgroup ||
2375 ((isOpenMPParallelDirective(K) ||
2376 isOpenMPWorksharingDirective(K)) &&
2377 !isOpenMPSimdDirective(K));
2378 },
2379 Level) &&
2380 DSAStack->isTaskgroupReductionRef(D, Level)))
2381 ? OMPC_private
2382 : OMPC_unknown;
2383 }
2384
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2385 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2386 unsigned Level) {
2387 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2388 D = getCanonicalDecl(D);
2389 OpenMPClauseKind OMPC = OMPC_unknown;
2390 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2391 const unsigned NewLevel = I - 1;
2392 if (DSAStack->hasExplicitDSA(
2393 D,
2394 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2395 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2396 OMPC = K;
2397 return true;
2398 }
2399 return false;
2400 },
2401 NewLevel))
2402 break;
2403 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2404 D, NewLevel,
2405 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2406 OpenMPClauseKind) { return true; })) {
2407 OMPC = OMPC_map;
2408 break;
2409 }
2410 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2411 NewLevel)) {
2412 OMPC = OMPC_map;
2413 if (DSAStack->mustBeFirstprivateAtLevel(
2414 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2415 OMPC = OMPC_firstprivate;
2416 break;
2417 }
2418 }
2419 if (OMPC != OMPC_unknown)
2420 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2421 }
2422
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2423 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2424 unsigned CaptureLevel) const {
2425 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2426 // Return true if the current level is no longer enclosed in a target region.
2427
2428 SmallVector<OpenMPDirectiveKind, 4> Regions;
2429 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2430 const auto *VD = dyn_cast<VarDecl>(D);
2431 return VD && !VD->hasLocalStorage() &&
2432 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2433 Level) &&
2434 Regions[CaptureLevel] != OMPD_task;
2435 }
2436
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2437 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2438 unsigned CaptureLevel) const {
2439 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2440 // Return true if the current level is no longer enclosed in a target region.
2441
2442 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2443 if (!VD->hasLocalStorage()) {
2444 if (isInOpenMPTargetExecutionDirective())
2445 return true;
2446 DSAStackTy::DSAVarData TopDVar =
2447 DSAStack->getTopDSA(D, /*FromParent=*/false);
2448 unsigned NumLevels =
2449 getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2450 if (Level == 0)
2451 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2452 do {
2453 --Level;
2454 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2455 if (DVar.CKind != OMPC_shared)
2456 return true;
2457 } while (Level > 0);
2458 }
2459 }
2460 return true;
2461 }
2462
DestroyDataSharingAttributesStack()2463 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2464
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2465 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2466 OMPTraitInfo &TI) {
2467 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2468 }
2469
ActOnOpenMPEndDeclareVariant()2470 void Sema::ActOnOpenMPEndDeclareVariant() {
2471 assert(isInOpenMPDeclareVariantScope() &&
2472 "Not in OpenMP declare variant scope!");
2473
2474 OMPDeclareVariantScopes.pop_back();
2475 }
2476
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2477 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2478 const FunctionDecl *Callee,
2479 SourceLocation Loc) {
2480 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2481 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2482 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2483 // Ignore host functions during device analyzis.
2484 if (LangOpts.OpenMPIsDevice &&
2485 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2486 return;
2487 // Ignore nohost functions during host analyzis.
2488 if (!LangOpts.OpenMPIsDevice && DevTy &&
2489 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2490 return;
2491 const FunctionDecl *FD = Callee->getMostRecentDecl();
2492 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2493 if (LangOpts.OpenMPIsDevice && DevTy &&
2494 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2495 // Diagnose host function called during device codegen.
2496 StringRef HostDevTy =
2497 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2498 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2499 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2500 diag::note_omp_marked_device_type_here)
2501 << HostDevTy;
2502 return;
2503 }
2504 if (!LangOpts.OpenMPIsDevice && DevTy &&
2505 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2506 // Diagnose nohost function called during host codegen.
2507 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2508 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2509 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2510 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2511 diag::note_omp_marked_device_type_here)
2512 << NoHostDevTy;
2513 }
2514 }
2515
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2516 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2517 const DeclarationNameInfo &DirName,
2518 Scope *CurScope, SourceLocation Loc) {
2519 DSAStack->push(DKind, DirName, CurScope, Loc);
2520 PushExpressionEvaluationContext(
2521 ExpressionEvaluationContext::PotentiallyEvaluated);
2522 }
2523
StartOpenMPClause(OpenMPClauseKind K)2524 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2525 DSAStack->setClauseParsingMode(K);
2526 }
2527
EndOpenMPClause()2528 void Sema::EndOpenMPClause() {
2529 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2530 CleanupVarDeclMarking();
2531 }
2532
2533 static std::pair<ValueDecl *, bool>
2534 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2535 SourceRange &ERange, bool AllowArraySection = false);
2536
2537 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2538 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2539 ArrayRef<OMPClause *> Clauses) {
2540 bool InscanFound = false;
2541 SourceLocation InscanLoc;
2542 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2543 // A reduction clause without the inscan reduction-modifier may not appear on
2544 // a construct on which a reduction clause with the inscan reduction-modifier
2545 // appears.
2546 for (OMPClause *C : Clauses) {
2547 if (C->getClauseKind() != OMPC_reduction)
2548 continue;
2549 auto *RC = cast<OMPReductionClause>(C);
2550 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2551 InscanFound = true;
2552 InscanLoc = RC->getModifierLoc();
2553 continue;
2554 }
2555 if (RC->getModifier() == OMPC_REDUCTION_task) {
2556 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2557 // A reduction clause with the task reduction-modifier may only appear on
2558 // a parallel construct, a worksharing construct or a combined or
2559 // composite construct for which any of the aforementioned constructs is a
2560 // constituent construct and simd or loop are not constituent constructs.
2561 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2562 if (!(isOpenMPParallelDirective(CurDir) ||
2563 isOpenMPWorksharingDirective(CurDir)) ||
2564 isOpenMPSimdDirective(CurDir))
2565 S.Diag(RC->getModifierLoc(),
2566 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2567 continue;
2568 }
2569 }
2570 if (InscanFound) {
2571 for (OMPClause *C : Clauses) {
2572 if (C->getClauseKind() != OMPC_reduction)
2573 continue;
2574 auto *RC = cast<OMPReductionClause>(C);
2575 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2576 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2577 ? RC->getBeginLoc()
2578 : RC->getModifierLoc(),
2579 diag::err_omp_inscan_reduction_expected);
2580 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2581 continue;
2582 }
2583 for (Expr *Ref : RC->varlists()) {
2584 assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2585 SourceLocation ELoc;
2586 SourceRange ERange;
2587 Expr *SimpleRefExpr = Ref;
2588 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2589 /*AllowArraySection=*/true);
2590 ValueDecl *D = Res.first;
2591 if (!D)
2592 continue;
2593 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2594 S.Diag(Ref->getExprLoc(),
2595 diag::err_omp_reduction_not_inclusive_exclusive)
2596 << Ref->getSourceRange();
2597 }
2598 }
2599 }
2600 }
2601 }
2602
2603 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2604 ArrayRef<OMPClause *> Clauses);
2605 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2606 bool WithInit);
2607
2608 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2609 const ValueDecl *D,
2610 const DSAStackTy::DSAVarData &DVar,
2611 bool IsLoopIterVar = false);
2612
EndOpenMPDSABlock(Stmt * CurDirective)2613 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2614 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2615 // A variable of class type (or array thereof) that appears in a lastprivate
2616 // clause requires an accessible, unambiguous default constructor for the
2617 // class type, unless the list item is also specified in a firstprivate
2618 // clause.
2619 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2620 for (OMPClause *C : D->clauses()) {
2621 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2622 SmallVector<Expr *, 8> PrivateCopies;
2623 for (Expr *DE : Clause->varlists()) {
2624 if (DE->isValueDependent() || DE->isTypeDependent()) {
2625 PrivateCopies.push_back(nullptr);
2626 continue;
2627 }
2628 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2629 auto *VD = cast<VarDecl>(DRE->getDecl());
2630 QualType Type = VD->getType().getNonReferenceType();
2631 const DSAStackTy::DSAVarData DVar =
2632 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2633 if (DVar.CKind == OMPC_lastprivate) {
2634 // Generate helper private variable and initialize it with the
2635 // default value. The address of the original variable is replaced
2636 // by the address of the new private variable in CodeGen. This new
2637 // variable is not added to IdResolver, so the code in the OpenMP
2638 // region uses original variable for proper diagnostics.
2639 VarDecl *VDPrivate = buildVarDecl(
2640 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2641 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2642 ActOnUninitializedDecl(VDPrivate);
2643 if (VDPrivate->isInvalidDecl()) {
2644 PrivateCopies.push_back(nullptr);
2645 continue;
2646 }
2647 PrivateCopies.push_back(buildDeclRefExpr(
2648 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2649 } else {
2650 // The variable is also a firstprivate, so initialization sequence
2651 // for private copy is generated already.
2652 PrivateCopies.push_back(nullptr);
2653 }
2654 }
2655 Clause->setPrivateCopies(PrivateCopies);
2656 continue;
2657 }
2658 // Finalize nontemporal clause by handling private copies, if any.
2659 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2660 SmallVector<Expr *, 8> PrivateRefs;
2661 for (Expr *RefExpr : Clause->varlists()) {
2662 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2663 SourceLocation ELoc;
2664 SourceRange ERange;
2665 Expr *SimpleRefExpr = RefExpr;
2666 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2667 if (Res.second)
2668 // It will be analyzed later.
2669 PrivateRefs.push_back(RefExpr);
2670 ValueDecl *D = Res.first;
2671 if (!D)
2672 continue;
2673
2674 const DSAStackTy::DSAVarData DVar =
2675 DSAStack->getTopDSA(D, /*FromParent=*/false);
2676 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2677 : SimpleRefExpr);
2678 }
2679 Clause->setPrivateRefs(PrivateRefs);
2680 continue;
2681 }
2682 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2683 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2684 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2685 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2686 if (!DRE)
2687 continue;
2688 ValueDecl *VD = DRE->getDecl();
2689 if (!VD || !isa<VarDecl>(VD))
2690 continue;
2691 DSAStackTy::DSAVarData DVar =
2692 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2693 // OpenMP [2.12.5, target Construct]
2694 // Memory allocators that appear in a uses_allocators clause cannot
2695 // appear in other data-sharing attribute clauses or data-mapping
2696 // attribute clauses in the same construct.
2697 Expr *MapExpr = nullptr;
2698 if (DVar.RefExpr ||
2699 DSAStack->checkMappableExprComponentListsForDecl(
2700 VD, /*CurrentRegionOnly=*/true,
2701 [VD, &MapExpr](
2702 OMPClauseMappableExprCommon::MappableExprComponentListRef
2703 MapExprComponents,
2704 OpenMPClauseKind C) {
2705 auto MI = MapExprComponents.rbegin();
2706 auto ME = MapExprComponents.rend();
2707 if (MI != ME &&
2708 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2709 VD->getCanonicalDecl()) {
2710 MapExpr = MI->getAssociatedExpression();
2711 return true;
2712 }
2713 return false;
2714 })) {
2715 Diag(D.Allocator->getExprLoc(),
2716 diag::err_omp_allocator_used_in_clauses)
2717 << D.Allocator->getSourceRange();
2718 if (DVar.RefExpr)
2719 reportOriginalDsa(*this, DSAStack, VD, DVar);
2720 else
2721 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2722 << MapExpr->getSourceRange();
2723 }
2724 }
2725 continue;
2726 }
2727 }
2728 // Check allocate clauses.
2729 if (!CurContext->isDependentContext())
2730 checkAllocateClauses(*this, DSAStack, D->clauses());
2731 checkReductionClauses(*this, DSAStack, D->clauses());
2732 }
2733
2734 DSAStack->pop();
2735 DiscardCleanupsInEvaluationContext();
2736 PopExpressionEvaluationContext();
2737 }
2738
2739 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2740 Expr *NumIterations, Sema &SemaRef,
2741 Scope *S, DSAStackTy *Stack);
2742
2743 namespace {
2744
2745 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2746 private:
2747 Sema &SemaRef;
2748
2749 public:
VarDeclFilterCCC(Sema & S)2750 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2751 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2752 NamedDecl *ND = Candidate.getCorrectionDecl();
2753 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2754 return VD->hasGlobalStorage() &&
2755 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2756 SemaRef.getCurScope());
2757 }
2758 return false;
2759 }
2760
clone()2761 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2762 return std::make_unique<VarDeclFilterCCC>(*this);
2763 }
2764
2765 };
2766
2767 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2768 private:
2769 Sema &SemaRef;
2770
2771 public:
VarOrFuncDeclFilterCCC(Sema & S)2772 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2773 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2774 NamedDecl *ND = Candidate.getCorrectionDecl();
2775 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2776 isa<FunctionDecl>(ND))) {
2777 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2778 SemaRef.getCurScope());
2779 }
2780 return false;
2781 }
2782
clone()2783 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2784 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2785 }
2786 };
2787
2788 } // namespace
2789
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)2790 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2791 CXXScopeSpec &ScopeSpec,
2792 const DeclarationNameInfo &Id,
2793 OpenMPDirectiveKind Kind) {
2794 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2795 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2796
2797 if (Lookup.isAmbiguous())
2798 return ExprError();
2799
2800 VarDecl *VD;
2801 if (!Lookup.isSingleResult()) {
2802 VarDeclFilterCCC CCC(*this);
2803 if (TypoCorrection Corrected =
2804 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2805 CTK_ErrorRecovery)) {
2806 diagnoseTypo(Corrected,
2807 PDiag(Lookup.empty()
2808 ? diag::err_undeclared_var_use_suggest
2809 : diag::err_omp_expected_var_arg_suggest)
2810 << Id.getName());
2811 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2812 } else {
2813 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2814 : diag::err_omp_expected_var_arg)
2815 << Id.getName();
2816 return ExprError();
2817 }
2818 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2819 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2820 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2821 return ExprError();
2822 }
2823 Lookup.suppressDiagnostics();
2824
2825 // OpenMP [2.9.2, Syntax, C/C++]
2826 // Variables must be file-scope, namespace-scope, or static block-scope.
2827 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2828 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2829 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2830 bool IsDecl =
2831 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2832 Diag(VD->getLocation(),
2833 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2834 << VD;
2835 return ExprError();
2836 }
2837
2838 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2839 NamedDecl *ND = CanonicalVD;
2840 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2841 // A threadprivate directive for file-scope variables must appear outside
2842 // any definition or declaration.
2843 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2844 !getCurLexicalContext()->isTranslationUnit()) {
2845 Diag(Id.getLoc(), diag::err_omp_var_scope)
2846 << getOpenMPDirectiveName(Kind) << VD;
2847 bool IsDecl =
2848 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2849 Diag(VD->getLocation(),
2850 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2851 << VD;
2852 return ExprError();
2853 }
2854 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2855 // A threadprivate directive for static class member variables must appear
2856 // in the class definition, in the same scope in which the member
2857 // variables are declared.
2858 if (CanonicalVD->isStaticDataMember() &&
2859 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
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.4]
2870 // A threadprivate directive for namespace-scope variables must appear
2871 // outside any definition or declaration other than the namespace
2872 // definition itself.
2873 if (CanonicalVD->getDeclContext()->isNamespace() &&
2874 (!getCurLexicalContext()->isFileContext() ||
2875 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2876 Diag(Id.getLoc(), diag::err_omp_var_scope)
2877 << getOpenMPDirectiveName(Kind) << VD;
2878 bool IsDecl =
2879 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2880 Diag(VD->getLocation(),
2881 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2882 << VD;
2883 return ExprError();
2884 }
2885 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2886 // A threadprivate directive for static block-scope variables must appear
2887 // in the scope of the variable and not in a nested scope.
2888 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2889 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2890 Diag(Id.getLoc(), diag::err_omp_var_scope)
2891 << getOpenMPDirectiveName(Kind) << VD;
2892 bool IsDecl =
2893 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2894 Diag(VD->getLocation(),
2895 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2896 << VD;
2897 return ExprError();
2898 }
2899
2900 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2901 // A threadprivate directive must lexically precede all references to any
2902 // of the variables in its list.
2903 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2904 !DSAStack->isThreadPrivate(VD)) {
2905 Diag(Id.getLoc(), diag::err_omp_var_used)
2906 << getOpenMPDirectiveName(Kind) << VD;
2907 return ExprError();
2908 }
2909
2910 QualType ExprType = VD->getType().getNonReferenceType();
2911 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2912 SourceLocation(), VD,
2913 /*RefersToEnclosingVariableOrCapture=*/false,
2914 Id.getLoc(), ExprType, VK_LValue);
2915 }
2916
2917 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)2918 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2919 ArrayRef<Expr *> VarList) {
2920 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2921 CurContext->addDecl(D);
2922 return DeclGroupPtrTy::make(DeclGroupRef(D));
2923 }
2924 return nullptr;
2925 }
2926
2927 namespace {
2928 class LocalVarRefChecker final
2929 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2930 Sema &SemaRef;
2931
2932 public:
VisitDeclRefExpr(const DeclRefExpr * E)2933 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2934 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2935 if (VD->hasLocalStorage()) {
2936 SemaRef.Diag(E->getBeginLoc(),
2937 diag::err_omp_local_var_in_threadprivate_init)
2938 << E->getSourceRange();
2939 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2940 << VD << VD->getSourceRange();
2941 return true;
2942 }
2943 }
2944 return false;
2945 }
VisitStmt(const Stmt * S)2946 bool VisitStmt(const Stmt *S) {
2947 for (const Stmt *Child : S->children()) {
2948 if (Child && Visit(Child))
2949 return true;
2950 }
2951 return false;
2952 }
LocalVarRefChecker(Sema & SemaRef)2953 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2954 };
2955 } // namespace
2956
2957 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)2958 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2959 SmallVector<Expr *, 8> Vars;
2960 for (Expr *RefExpr : VarList) {
2961 auto *DE = cast<DeclRefExpr>(RefExpr);
2962 auto *VD = cast<VarDecl>(DE->getDecl());
2963 SourceLocation ILoc = DE->getExprLoc();
2964
2965 // Mark variable as used.
2966 VD->setReferenced();
2967 VD->markUsed(Context);
2968
2969 QualType QType = VD->getType();
2970 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2971 // It will be analyzed later.
2972 Vars.push_back(DE);
2973 continue;
2974 }
2975
2976 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2977 // A threadprivate variable must not have an incomplete type.
2978 if (RequireCompleteType(ILoc, VD->getType(),
2979 diag::err_omp_threadprivate_incomplete_type)) {
2980 continue;
2981 }
2982
2983 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2984 // A threadprivate variable must not have a reference type.
2985 if (VD->getType()->isReferenceType()) {
2986 Diag(ILoc, diag::err_omp_ref_type_arg)
2987 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2988 bool IsDecl =
2989 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2990 Diag(VD->getLocation(),
2991 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2992 << VD;
2993 continue;
2994 }
2995
2996 // Check if this is a TLS variable. If TLS is not being supported, produce
2997 // the corresponding diagnostic.
2998 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2999 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3000 getLangOpts().OpenMPUseTLS &&
3001 getASTContext().getTargetInfo().isTLSSupported())) ||
3002 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3003 !VD->isLocalVarDecl())) {
3004 Diag(ILoc, diag::err_omp_var_thread_local)
3005 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3006 bool IsDecl =
3007 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3008 Diag(VD->getLocation(),
3009 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3010 << VD;
3011 continue;
3012 }
3013
3014 // Check if initial value of threadprivate variable reference variable with
3015 // local storage (it is not supported by runtime).
3016 if (const Expr *Init = VD->getAnyInitializer()) {
3017 LocalVarRefChecker Checker(*this);
3018 if (Checker.Visit(Init))
3019 continue;
3020 }
3021
3022 Vars.push_back(RefExpr);
3023 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3024 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3025 Context, SourceRange(Loc, Loc)));
3026 if (ASTMutationListener *ML = Context.getASTMutationListener())
3027 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3028 }
3029 OMPThreadPrivateDecl *D = nullptr;
3030 if (!Vars.empty()) {
3031 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3032 Vars);
3033 D->setAccess(AS_public);
3034 }
3035 return D;
3036 }
3037
3038 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3039 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3040 if (!Allocator)
3041 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3042 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3043 Allocator->isInstantiationDependent() ||
3044 Allocator->containsUnexpandedParameterPack())
3045 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3046 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3047 const Expr *AE = Allocator->IgnoreParenImpCasts();
3048 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3049 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3050 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3051 llvm::FoldingSetNodeID AEId, DAEId;
3052 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3053 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3054 if (AEId == DAEId) {
3055 AllocatorKindRes = AllocatorKind;
3056 break;
3057 }
3058 }
3059 return AllocatorKindRes;
3060 }
3061
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3062 static bool checkPreviousOMPAllocateAttribute(
3063 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3064 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3065 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3066 return false;
3067 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3068 Expr *PrevAllocator = A->getAllocator();
3069 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3070 getAllocatorKind(S, Stack, PrevAllocator);
3071 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3072 if (AllocatorsMatch &&
3073 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3074 Allocator && PrevAllocator) {
3075 const Expr *AE = Allocator->IgnoreParenImpCasts();
3076 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3077 llvm::FoldingSetNodeID AEId, PAEId;
3078 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3079 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3080 AllocatorsMatch = AEId == PAEId;
3081 }
3082 if (!AllocatorsMatch) {
3083 SmallString<256> AllocatorBuffer;
3084 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3085 if (Allocator)
3086 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3087 SmallString<256> PrevAllocatorBuffer;
3088 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3089 if (PrevAllocator)
3090 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3091 S.getPrintingPolicy());
3092
3093 SourceLocation AllocatorLoc =
3094 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3095 SourceRange AllocatorRange =
3096 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3097 SourceLocation PrevAllocatorLoc =
3098 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3099 SourceRange PrevAllocatorRange =
3100 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3101 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3102 << (Allocator ? 1 : 0) << AllocatorStream.str()
3103 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3104 << AllocatorRange;
3105 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3106 << PrevAllocatorRange;
3107 return true;
3108 }
3109 return false;
3110 }
3111
3112 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,SourceRange SR)3113 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3114 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3115 Expr *Allocator, SourceRange SR) {
3116 if (VD->hasAttr<OMPAllocateDeclAttr>())
3117 return;
3118 if (Allocator &&
3119 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3120 Allocator->isInstantiationDependent() ||
3121 Allocator->containsUnexpandedParameterPack()))
3122 return;
3123 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3124 Allocator, SR);
3125 VD->addAttr(A);
3126 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3127 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3128 }
3129
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3130 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3131 SourceLocation Loc, ArrayRef<Expr *> VarList,
3132 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3133 assert(Clauses.size() <= 1 && "Expected at most one clause.");
3134 Expr *Allocator = nullptr;
3135 if (Clauses.empty()) {
3136 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3137 // allocate directives that appear in a target region must specify an
3138 // allocator clause unless a requires directive with the dynamic_allocators
3139 // clause is present in the same compilation unit.
3140 if (LangOpts.OpenMPIsDevice &&
3141 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3142 targetDiag(Loc, diag::err_expected_allocator_clause);
3143 } else {
3144 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3145 }
3146 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3147 getAllocatorKind(*this, DSAStack, Allocator);
3148 SmallVector<Expr *, 8> Vars;
3149 for (Expr *RefExpr : VarList) {
3150 auto *DE = cast<DeclRefExpr>(RefExpr);
3151 auto *VD = cast<VarDecl>(DE->getDecl());
3152
3153 // Check if this is a TLS variable or global register.
3154 if (VD->getTLSKind() != VarDecl::TLS_None ||
3155 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3156 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3157 !VD->isLocalVarDecl()))
3158 continue;
3159
3160 // If the used several times in the allocate directive, the same allocator
3161 // must be used.
3162 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3163 AllocatorKind, Allocator))
3164 continue;
3165
3166 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3167 // If a list item has a static storage type, the allocator expression in the
3168 // allocator clause must be a constant expression that evaluates to one of
3169 // the predefined memory allocator values.
3170 if (Allocator && VD->hasGlobalStorage()) {
3171 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3172 Diag(Allocator->getExprLoc(),
3173 diag::err_omp_expected_predefined_allocator)
3174 << Allocator->getSourceRange();
3175 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3176 VarDecl::DeclarationOnly;
3177 Diag(VD->getLocation(),
3178 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3179 << VD;
3180 continue;
3181 }
3182 }
3183
3184 Vars.push_back(RefExpr);
3185 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3186 DE->getSourceRange());
3187 }
3188 if (Vars.empty())
3189 return nullptr;
3190 if (!Owner)
3191 Owner = getCurLexicalContext();
3192 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3193 D->setAccess(AS_public);
3194 Owner->addDecl(D);
3195 return DeclGroupPtrTy::make(DeclGroupRef(D));
3196 }
3197
3198 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3199 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3200 ArrayRef<OMPClause *> ClauseList) {
3201 OMPRequiresDecl *D = nullptr;
3202 if (!CurContext->isFileContext()) {
3203 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3204 } else {
3205 D = CheckOMPRequiresDecl(Loc, ClauseList);
3206 if (D) {
3207 CurContext->addDecl(D);
3208 DSAStack->addRequiresDecl(D);
3209 }
3210 }
3211 return DeclGroupPtrTy::make(DeclGroupRef(D));
3212 }
3213
ActOnOpenMPAssumesDirective(SourceLocation Loc,OpenMPDirectiveKind DKind,ArrayRef<StringRef> Assumptions,bool SkippedClauses)3214 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3215 OpenMPDirectiveKind DKind,
3216 ArrayRef<StringRef> Assumptions,
3217 bool SkippedClauses) {
3218 if (!SkippedClauses && Assumptions.empty())
3219 Diag(Loc, diag::err_omp_no_clause_for_directive)
3220 << llvm::omp::getAllAssumeClauseOptions()
3221 << llvm::omp::getOpenMPDirectiveName(DKind);
3222
3223 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3224 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3225 OMPAssumeScoped.push_back(AA);
3226 return;
3227 }
3228
3229 // Global assumes without assumption clauses are ignored.
3230 if (Assumptions.empty())
3231 return;
3232
3233 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3234 "Unexpected omp assumption directive!");
3235 OMPAssumeGlobal.push_back(AA);
3236
3237 // The OMPAssumeGlobal scope above will take care of new declarations but
3238 // we also want to apply the assumption to existing ones, e.g., to
3239 // declarations in included headers. To this end, we traverse all existing
3240 // declaration contexts and annotate function declarations here.
3241 SmallVector<DeclContext *, 8> DeclContexts;
3242 auto *Ctx = CurContext;
3243 while (Ctx->getLexicalParent())
3244 Ctx = Ctx->getLexicalParent();
3245 DeclContexts.push_back(Ctx);
3246 while (!DeclContexts.empty()) {
3247 DeclContext *DC = DeclContexts.pop_back_val();
3248 for (auto *SubDC : DC->decls()) {
3249 if (SubDC->isInvalidDecl())
3250 continue;
3251 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3252 DeclContexts.push_back(CTD->getTemplatedDecl());
3253 for (auto *S : CTD->specializations())
3254 DeclContexts.push_back(S);
3255 continue;
3256 }
3257 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3258 DeclContexts.push_back(DC);
3259 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3260 F->addAttr(AA);
3261 continue;
3262 }
3263 }
3264 }
3265 }
3266
ActOnOpenMPEndAssumesDirective()3267 void Sema::ActOnOpenMPEndAssumesDirective() {
3268 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3269 OMPAssumeScoped.pop_back();
3270 }
3271
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3272 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3273 ArrayRef<OMPClause *> ClauseList) {
3274 /// For target specific clauses, the requires directive cannot be
3275 /// specified after the handling of any of the target regions in the
3276 /// current compilation unit.
3277 ArrayRef<SourceLocation> TargetLocations =
3278 DSAStack->getEncounteredTargetLocs();
3279 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3280 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3281 for (const OMPClause *CNew : ClauseList) {
3282 // Check if any of the requires clauses affect target regions.
3283 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3284 isa<OMPUnifiedAddressClause>(CNew) ||
3285 isa<OMPReverseOffloadClause>(CNew) ||
3286 isa<OMPDynamicAllocatorsClause>(CNew)) {
3287 Diag(Loc, diag::err_omp_directive_before_requires)
3288 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3289 for (SourceLocation TargetLoc : TargetLocations) {
3290 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3291 << "target";
3292 }
3293 } else if (!AtomicLoc.isInvalid() &&
3294 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3295 Diag(Loc, diag::err_omp_directive_before_requires)
3296 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3297 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3298 << "atomic";
3299 }
3300 }
3301 }
3302
3303 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3304 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3305 ClauseList);
3306 return nullptr;
3307 }
3308
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3309 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3310 const ValueDecl *D,
3311 const DSAStackTy::DSAVarData &DVar,
3312 bool IsLoopIterVar) {
3313 if (DVar.RefExpr) {
3314 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3315 << getOpenMPClauseName(DVar.CKind);
3316 return;
3317 }
3318 enum {
3319 PDSA_StaticMemberShared,
3320 PDSA_StaticLocalVarShared,
3321 PDSA_LoopIterVarPrivate,
3322 PDSA_LoopIterVarLinear,
3323 PDSA_LoopIterVarLastprivate,
3324 PDSA_ConstVarShared,
3325 PDSA_GlobalVarShared,
3326 PDSA_TaskVarFirstprivate,
3327 PDSA_LocalVarPrivate,
3328 PDSA_Implicit
3329 } Reason = PDSA_Implicit;
3330 bool ReportHint = false;
3331 auto ReportLoc = D->getLocation();
3332 auto *VD = dyn_cast<VarDecl>(D);
3333 if (IsLoopIterVar) {
3334 if (DVar.CKind == OMPC_private)
3335 Reason = PDSA_LoopIterVarPrivate;
3336 else if (DVar.CKind == OMPC_lastprivate)
3337 Reason = PDSA_LoopIterVarLastprivate;
3338 else
3339 Reason = PDSA_LoopIterVarLinear;
3340 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3341 DVar.CKind == OMPC_firstprivate) {
3342 Reason = PDSA_TaskVarFirstprivate;
3343 ReportLoc = DVar.ImplicitDSALoc;
3344 } else if (VD && VD->isStaticLocal())
3345 Reason = PDSA_StaticLocalVarShared;
3346 else if (VD && VD->isStaticDataMember())
3347 Reason = PDSA_StaticMemberShared;
3348 else if (VD && VD->isFileVarDecl())
3349 Reason = PDSA_GlobalVarShared;
3350 else if (D->getType().isConstant(SemaRef.getASTContext()))
3351 Reason = PDSA_ConstVarShared;
3352 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3353 ReportHint = true;
3354 Reason = PDSA_LocalVarPrivate;
3355 }
3356 if (Reason != PDSA_Implicit) {
3357 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3358 << Reason << ReportHint
3359 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3360 } else if (DVar.ImplicitDSALoc.isValid()) {
3361 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3362 << getOpenMPClauseName(DVar.CKind);
3363 }
3364 }
3365
3366 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3367 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3368 bool IsAggregateOrDeclareTarget) {
3369 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3370 switch (M) {
3371 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3372 Kind = OMPC_MAP_alloc;
3373 break;
3374 case OMPC_DEFAULTMAP_MODIFIER_to:
3375 Kind = OMPC_MAP_to;
3376 break;
3377 case OMPC_DEFAULTMAP_MODIFIER_from:
3378 Kind = OMPC_MAP_from;
3379 break;
3380 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3381 Kind = OMPC_MAP_tofrom;
3382 break;
3383 case OMPC_DEFAULTMAP_MODIFIER_present:
3384 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3385 // If implicit-behavior is present, each variable referenced in the
3386 // construct in the category specified by variable-category is treated as if
3387 // it had been listed in a map clause with the map-type of alloc and
3388 // map-type-modifier of present.
3389 Kind = OMPC_MAP_alloc;
3390 break;
3391 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3392 case OMPC_DEFAULTMAP_MODIFIER_last:
3393 llvm_unreachable("Unexpected defaultmap implicit behavior");
3394 case OMPC_DEFAULTMAP_MODIFIER_none:
3395 case OMPC_DEFAULTMAP_MODIFIER_default:
3396 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3397 // IsAggregateOrDeclareTarget could be true if:
3398 // 1. the implicit behavior for aggregate is tofrom
3399 // 2. it's a declare target link
3400 if (IsAggregateOrDeclareTarget) {
3401 Kind = OMPC_MAP_tofrom;
3402 break;
3403 }
3404 llvm_unreachable("Unexpected defaultmap implicit behavior");
3405 }
3406 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3407 return Kind;
3408 }
3409
3410 namespace {
3411 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3412 DSAStackTy *Stack;
3413 Sema &SemaRef;
3414 bool ErrorFound = false;
3415 bool TryCaptureCXXThisMembers = false;
3416 CapturedStmt *CS = nullptr;
3417 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3418 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3419 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3420 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3421 ImplicitMapModifier[DefaultmapKindNum];
3422 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3423 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3424
VisitSubCaptures(OMPExecutableDirective * S)3425 void VisitSubCaptures(OMPExecutableDirective *S) {
3426 // Check implicitly captured variables.
3427 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3428 return;
3429 if (S->getDirectiveKind() == OMPD_atomic ||
3430 S->getDirectiveKind() == OMPD_critical ||
3431 S->getDirectiveKind() == OMPD_section ||
3432 S->getDirectiveKind() == OMPD_master ||
3433 S->getDirectiveKind() == OMPD_masked ||
3434 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3435 Visit(S->getAssociatedStmt());
3436 return;
3437 }
3438 visitSubCaptures(S->getInnermostCapturedStmt());
3439 // Try to capture inner this->member references to generate correct mappings
3440 // and diagnostics.
3441 if (TryCaptureCXXThisMembers ||
3442 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3443 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3444 [](const CapturedStmt::Capture &C) {
3445 return C.capturesThis();
3446 }))) {
3447 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3448 TryCaptureCXXThisMembers = true;
3449 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3450 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3451 }
3452 // In tasks firstprivates are not captured anymore, need to analyze them
3453 // explicitly.
3454 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3455 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3456 for (OMPClause *C : S->clauses())
3457 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3458 for (Expr *Ref : FC->varlists())
3459 Visit(Ref);
3460 }
3461 }
3462 }
3463
3464 public:
VisitDeclRefExpr(DeclRefExpr * E)3465 void VisitDeclRefExpr(DeclRefExpr *E) {
3466 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3467 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3468 E->isInstantiationDependent())
3469 return;
3470 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3471 // Check the datasharing rules for the expressions in the clauses.
3472 if (!CS) {
3473 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3474 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3475 Visit(CED->getInit());
3476 return;
3477 }
3478 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3479 // Do not analyze internal variables and do not enclose them into
3480 // implicit clauses.
3481 return;
3482 VD = VD->getCanonicalDecl();
3483 // Skip internally declared variables.
3484 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3485 !Stack->isImplicitTaskFirstprivate(VD))
3486 return;
3487 // Skip allocators in uses_allocators clauses.
3488 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3489 return;
3490
3491 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3492 // Check if the variable has explicit DSA set and stop analysis if it so.
3493 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3494 return;
3495
3496 // Skip internally declared static variables.
3497 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3498 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3499 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3500 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3501 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3502 !Stack->isImplicitTaskFirstprivate(VD))
3503 return;
3504
3505 SourceLocation ELoc = E->getExprLoc();
3506 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3507 // The default(none) clause requires that each variable that is referenced
3508 // in the construct, and does not have a predetermined data-sharing
3509 // attribute, must have its data-sharing attribute explicitly determined
3510 // by being listed in a data-sharing attribute clause.
3511 if (DVar.CKind == OMPC_unknown &&
3512 (Stack->getDefaultDSA() == DSA_none ||
3513 Stack->getDefaultDSA() == DSA_firstprivate) &&
3514 isImplicitOrExplicitTaskingRegion(DKind) &&
3515 VarsWithInheritedDSA.count(VD) == 0) {
3516 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3517 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3518 DSAStackTy::DSAVarData DVar =
3519 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3520 InheritedDSA = DVar.CKind == OMPC_unknown;
3521 }
3522 if (InheritedDSA)
3523 VarsWithInheritedDSA[VD] = E;
3524 return;
3525 }
3526
3527 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3528 // If implicit-behavior is none, each variable referenced in the
3529 // construct that does not have a predetermined data-sharing attribute
3530 // and does not appear in a to or link clause on a declare target
3531 // directive must be listed in a data-mapping attribute clause, a
3532 // data-haring attribute clause (including a data-sharing attribute
3533 // clause on a combined construct where target. is one of the
3534 // constituent constructs), or an is_device_ptr clause.
3535 OpenMPDefaultmapClauseKind ClauseKind =
3536 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3537 if (SemaRef.getLangOpts().OpenMP >= 50) {
3538 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3539 OMPC_DEFAULTMAP_MODIFIER_none;
3540 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3541 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3542 // Only check for data-mapping attribute and is_device_ptr here
3543 // since we have already make sure that the declaration does not
3544 // have a data-sharing attribute above
3545 if (!Stack->checkMappableExprComponentListsForDecl(
3546 VD, /*CurrentRegionOnly=*/true,
3547 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3548 MapExprComponents,
3549 OpenMPClauseKind) {
3550 auto MI = MapExprComponents.rbegin();
3551 auto ME = MapExprComponents.rend();
3552 return MI != ME && MI->getAssociatedDeclaration() == VD;
3553 })) {
3554 VarsWithInheritedDSA[VD] = E;
3555 return;
3556 }
3557 }
3558 }
3559 if (SemaRef.getLangOpts().OpenMP > 50) {
3560 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3561 OMPC_DEFAULTMAP_MODIFIER_present;
3562 if (IsModifierPresent) {
3563 if (llvm::find(ImplicitMapModifier[ClauseKind],
3564 OMPC_MAP_MODIFIER_present) ==
3565 std::end(ImplicitMapModifier[ClauseKind])) {
3566 ImplicitMapModifier[ClauseKind].push_back(
3567 OMPC_MAP_MODIFIER_present);
3568 }
3569 }
3570 }
3571
3572 if (isOpenMPTargetExecutionDirective(DKind) &&
3573 !Stack->isLoopControlVariable(VD).first) {
3574 if (!Stack->checkMappableExprComponentListsForDecl(
3575 VD, /*CurrentRegionOnly=*/true,
3576 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3577 StackComponents,
3578 OpenMPClauseKind) {
3579 if (SemaRef.LangOpts.OpenMP >= 50)
3580 return !StackComponents.empty();
3581 // Variable is used if it has been marked as an array, array
3582 // section, array shaping or the variable iself.
3583 return StackComponents.size() == 1 ||
3584 std::all_of(
3585 std::next(StackComponents.rbegin()),
3586 StackComponents.rend(),
3587 [](const OMPClauseMappableExprCommon::
3588 MappableComponent &MC) {
3589 return MC.getAssociatedDeclaration() ==
3590 nullptr &&
3591 (isa<OMPArraySectionExpr>(
3592 MC.getAssociatedExpression()) ||
3593 isa<OMPArrayShapingExpr>(
3594 MC.getAssociatedExpression()) ||
3595 isa<ArraySubscriptExpr>(
3596 MC.getAssociatedExpression()));
3597 });
3598 })) {
3599 bool IsFirstprivate = false;
3600 // By default lambdas are captured as firstprivates.
3601 if (const auto *RD =
3602 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3603 IsFirstprivate = RD->isLambda();
3604 IsFirstprivate =
3605 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3606 if (IsFirstprivate) {
3607 ImplicitFirstprivate.emplace_back(E);
3608 } else {
3609 OpenMPDefaultmapClauseModifier M =
3610 Stack->getDefaultmapModifier(ClauseKind);
3611 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3612 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3613 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3614 }
3615 return;
3616 }
3617 }
3618
3619 // OpenMP [2.9.3.6, Restrictions, p.2]
3620 // A list item that appears in a reduction clause of the innermost
3621 // enclosing worksharing or parallel construct may not be accessed in an
3622 // explicit task.
3623 DVar = Stack->hasInnermostDSA(
3624 VD,
3625 [](OpenMPClauseKind C, bool AppliedToPointee) {
3626 return C == OMPC_reduction && !AppliedToPointee;
3627 },
3628 [](OpenMPDirectiveKind K) {
3629 return isOpenMPParallelDirective(K) ||
3630 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3631 },
3632 /*FromParent=*/true);
3633 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3634 ErrorFound = true;
3635 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3636 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3637 return;
3638 }
3639
3640 // Define implicit data-sharing attributes for task.
3641 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3642 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3643 (Stack->getDefaultDSA() == DSA_firstprivate &&
3644 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3645 !Stack->isLoopControlVariable(VD).first) {
3646 ImplicitFirstprivate.push_back(E);
3647 return;
3648 }
3649
3650 // Store implicitly used globals with declare target link for parent
3651 // target.
3652 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3653 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3654 Stack->addToParentTargetRegionLinkGlobals(E);
3655 return;
3656 }
3657 }
3658 }
VisitMemberExpr(MemberExpr * E)3659 void VisitMemberExpr(MemberExpr *E) {
3660 if (E->isTypeDependent() || E->isValueDependent() ||
3661 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3662 return;
3663 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3664 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3665 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3666 if (!FD)
3667 return;
3668 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3669 // Check if the variable has explicit DSA set and stop analysis if it
3670 // so.
3671 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3672 return;
3673
3674 if (isOpenMPTargetExecutionDirective(DKind) &&
3675 !Stack->isLoopControlVariable(FD).first &&
3676 !Stack->checkMappableExprComponentListsForDecl(
3677 FD, /*CurrentRegionOnly=*/true,
3678 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3679 StackComponents,
3680 OpenMPClauseKind) {
3681 return isa<CXXThisExpr>(
3682 cast<MemberExpr>(
3683 StackComponents.back().getAssociatedExpression())
3684 ->getBase()
3685 ->IgnoreParens());
3686 })) {
3687 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3688 // A bit-field cannot appear in a map clause.
3689 //
3690 if (FD->isBitField())
3691 return;
3692
3693 // Check to see if the member expression is referencing a class that
3694 // has already been explicitly mapped
3695 if (Stack->isClassPreviouslyMapped(TE->getType()))
3696 return;
3697
3698 OpenMPDefaultmapClauseModifier Modifier =
3699 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3700 OpenMPDefaultmapClauseKind ClauseKind =
3701 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3702 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3703 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3704 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3705 return;
3706 }
3707
3708 SourceLocation ELoc = E->getExprLoc();
3709 // OpenMP [2.9.3.6, Restrictions, p.2]
3710 // A list item that appears in a reduction clause of the innermost
3711 // enclosing worksharing or parallel construct may not be accessed in
3712 // an explicit task.
3713 DVar = Stack->hasInnermostDSA(
3714 FD,
3715 [](OpenMPClauseKind C, bool AppliedToPointee) {
3716 return C == OMPC_reduction && !AppliedToPointee;
3717 },
3718 [](OpenMPDirectiveKind K) {
3719 return isOpenMPParallelDirective(K) ||
3720 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3721 },
3722 /*FromParent=*/true);
3723 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3724 ErrorFound = true;
3725 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3726 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3727 return;
3728 }
3729
3730 // Define implicit data-sharing attributes for task.
3731 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3732 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3733 !Stack->isLoopControlVariable(FD).first) {
3734 // Check if there is a captured expression for the current field in the
3735 // region. Do not mark it as firstprivate unless there is no captured
3736 // expression.
3737 // TODO: try to make it firstprivate.
3738 if (DVar.CKind != OMPC_unknown)
3739 ImplicitFirstprivate.push_back(E);
3740 }
3741 return;
3742 }
3743 if (isOpenMPTargetExecutionDirective(DKind)) {
3744 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3745 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3746 Stack->getCurrentDirective(),
3747 /*NoDiagnose=*/true))
3748 return;
3749 const auto *VD = cast<ValueDecl>(
3750 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3751 if (!Stack->checkMappableExprComponentListsForDecl(
3752 VD, /*CurrentRegionOnly=*/true,
3753 [&CurComponents](
3754 OMPClauseMappableExprCommon::MappableExprComponentListRef
3755 StackComponents,
3756 OpenMPClauseKind) {
3757 auto CCI = CurComponents.rbegin();
3758 auto CCE = CurComponents.rend();
3759 for (const auto &SC : llvm::reverse(StackComponents)) {
3760 // Do both expressions have the same kind?
3761 if (CCI->getAssociatedExpression()->getStmtClass() !=
3762 SC.getAssociatedExpression()->getStmtClass())
3763 if (!((isa<OMPArraySectionExpr>(
3764 SC.getAssociatedExpression()) ||
3765 isa<OMPArrayShapingExpr>(
3766 SC.getAssociatedExpression())) &&
3767 isa<ArraySubscriptExpr>(
3768 CCI->getAssociatedExpression())))
3769 return false;
3770
3771 const Decl *CCD = CCI->getAssociatedDeclaration();
3772 const Decl *SCD = SC.getAssociatedDeclaration();
3773 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3774 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3775 if (SCD != CCD)
3776 return false;
3777 std::advance(CCI, 1);
3778 if (CCI == CCE)
3779 break;
3780 }
3781 return true;
3782 })) {
3783 Visit(E->getBase());
3784 }
3785 } else if (!TryCaptureCXXThisMembers) {
3786 Visit(E->getBase());
3787 }
3788 }
VisitOMPExecutableDirective(OMPExecutableDirective * S)3789 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3790 for (OMPClause *C : S->clauses()) {
3791 // Skip analysis of arguments of implicitly defined firstprivate clause
3792 // for task|target directives.
3793 // Skip analysis of arguments of implicitly defined map clause for target
3794 // directives.
3795 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3796 C->isImplicit() &&
3797 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3798 for (Stmt *CC : C->children()) {
3799 if (CC)
3800 Visit(CC);
3801 }
3802 }
3803 }
3804 // Check implicitly captured variables.
3805 VisitSubCaptures(S);
3806 }
3807
VisitOMPTileDirective(OMPTileDirective * S)3808 void VisitOMPTileDirective(OMPTileDirective *S) {
3809 // #pragma omp tile does not introduce data sharing.
3810 VisitStmt(S);
3811 }
3812
VisitStmt(Stmt * S)3813 void VisitStmt(Stmt *S) {
3814 for (Stmt *C : S->children()) {
3815 if (C) {
3816 // Check implicitly captured variables in the task-based directives to
3817 // check if they must be firstprivatized.
3818 Visit(C);
3819 }
3820 }
3821 }
3822
visitSubCaptures(CapturedStmt * S)3823 void visitSubCaptures(CapturedStmt *S) {
3824 for (const CapturedStmt::Capture &Cap : S->captures()) {
3825 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3826 continue;
3827 VarDecl *VD = Cap.getCapturedVar();
3828 // Do not try to map the variable if it or its sub-component was mapped
3829 // already.
3830 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3831 Stack->checkMappableExprComponentListsForDecl(
3832 VD, /*CurrentRegionOnly=*/true,
3833 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3834 OpenMPClauseKind) { return true; }))
3835 continue;
3836 DeclRefExpr *DRE = buildDeclRefExpr(
3837 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3838 Cap.getLocation(), /*RefersToCapture=*/true);
3839 Visit(DRE);
3840 }
3841 }
isErrorFound() const3842 bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const3843 ArrayRef<Expr *> getImplicitFirstprivate() const {
3844 return ImplicitFirstprivate;
3845 }
getImplicitMap(OpenMPDefaultmapClauseKind DK,OpenMPMapClauseKind MK) const3846 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3847 OpenMPMapClauseKind MK) const {
3848 return ImplicitMap[DK][MK];
3849 }
3850 ArrayRef<OpenMPMapModifierKind>
getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const3851 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3852 return ImplicitMapModifier[Kind];
3853 }
getVarsWithInheritedDSA() const3854 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3855 return VarsWithInheritedDSA;
3856 }
3857
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)3858 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3859 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3860 // Process declare target link variables for the target directives.
3861 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3862 for (DeclRefExpr *E : Stack->getLinkGlobals())
3863 Visit(E);
3864 }
3865 }
3866 };
3867 } // namespace
3868
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)3869 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3870 switch (DKind) {
3871 case OMPD_parallel:
3872 case OMPD_parallel_for:
3873 case OMPD_parallel_for_simd:
3874 case OMPD_parallel_sections:
3875 case OMPD_parallel_master:
3876 case OMPD_teams:
3877 case OMPD_teams_distribute:
3878 case OMPD_teams_distribute_simd: {
3879 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3880 QualType KmpInt32PtrTy =
3881 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3882 Sema::CapturedParamNameType Params[] = {
3883 std::make_pair(".global_tid.", KmpInt32PtrTy),
3884 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3885 std::make_pair(StringRef(), QualType()) // __context with shared vars
3886 };
3887 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3888 Params);
3889 break;
3890 }
3891 case OMPD_target_teams:
3892 case OMPD_target_parallel:
3893 case OMPD_target_parallel_for:
3894 case OMPD_target_parallel_for_simd:
3895 case OMPD_target_teams_distribute:
3896 case OMPD_target_teams_distribute_simd: {
3897 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3898 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3899 QualType KmpInt32PtrTy =
3900 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3901 QualType Args[] = {VoidPtrTy};
3902 FunctionProtoType::ExtProtoInfo EPI;
3903 EPI.Variadic = true;
3904 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3905 Sema::CapturedParamNameType Params[] = {
3906 std::make_pair(".global_tid.", KmpInt32Ty),
3907 std::make_pair(".part_id.", KmpInt32PtrTy),
3908 std::make_pair(".privates.", VoidPtrTy),
3909 std::make_pair(
3910 ".copy_fn.",
3911 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3912 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3913 std::make_pair(StringRef(), QualType()) // __context with shared vars
3914 };
3915 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3916 Params, /*OpenMPCaptureLevel=*/0);
3917 // Mark this captured region as inlined, because we don't use outlined
3918 // function directly.
3919 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3920 AlwaysInlineAttr::CreateImplicit(
3921 Context, {}, AttributeCommonInfo::AS_Keyword,
3922 AlwaysInlineAttr::Keyword_forceinline));
3923 Sema::CapturedParamNameType ParamsTarget[] = {
3924 std::make_pair(StringRef(), QualType()) // __context with shared vars
3925 };
3926 // Start a captured region for 'target' with no implicit parameters.
3927 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3928 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3929 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3930 std::make_pair(".global_tid.", KmpInt32PtrTy),
3931 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3932 std::make_pair(StringRef(), QualType()) // __context with shared vars
3933 };
3934 // Start a captured region for 'teams' or 'parallel'. Both regions have
3935 // the same implicit parameters.
3936 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3937 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3938 break;
3939 }
3940 case OMPD_target:
3941 case OMPD_target_simd: {
3942 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3943 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3944 QualType KmpInt32PtrTy =
3945 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3946 QualType Args[] = {VoidPtrTy};
3947 FunctionProtoType::ExtProtoInfo EPI;
3948 EPI.Variadic = true;
3949 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3950 Sema::CapturedParamNameType Params[] = {
3951 std::make_pair(".global_tid.", KmpInt32Ty),
3952 std::make_pair(".part_id.", KmpInt32PtrTy),
3953 std::make_pair(".privates.", VoidPtrTy),
3954 std::make_pair(
3955 ".copy_fn.",
3956 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3957 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3958 std::make_pair(StringRef(), QualType()) // __context with shared vars
3959 };
3960 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3961 Params, /*OpenMPCaptureLevel=*/0);
3962 // Mark this captured region as inlined, because we don't use outlined
3963 // function directly.
3964 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3965 AlwaysInlineAttr::CreateImplicit(
3966 Context, {}, AttributeCommonInfo::AS_Keyword,
3967 AlwaysInlineAttr::Keyword_forceinline));
3968 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3969 std::make_pair(StringRef(), QualType()),
3970 /*OpenMPCaptureLevel=*/1);
3971 break;
3972 }
3973 case OMPD_atomic:
3974 case OMPD_critical:
3975 case OMPD_section:
3976 case OMPD_master:
3977 case OMPD_masked:
3978 case OMPD_tile:
3979 break;
3980 case OMPD_simd:
3981 case OMPD_for:
3982 case OMPD_for_simd:
3983 case OMPD_sections:
3984 case OMPD_single:
3985 case OMPD_taskgroup:
3986 case OMPD_distribute:
3987 case OMPD_distribute_simd:
3988 case OMPD_ordered:
3989 case OMPD_target_data:
3990 case OMPD_dispatch: {
3991 Sema::CapturedParamNameType Params[] = {
3992 std::make_pair(StringRef(), QualType()) // __context with shared vars
3993 };
3994 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3995 Params);
3996 break;
3997 }
3998 case OMPD_task: {
3999 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4000 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4001 QualType KmpInt32PtrTy =
4002 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4003 QualType Args[] = {VoidPtrTy};
4004 FunctionProtoType::ExtProtoInfo EPI;
4005 EPI.Variadic = true;
4006 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4007 Sema::CapturedParamNameType Params[] = {
4008 std::make_pair(".global_tid.", KmpInt32Ty),
4009 std::make_pair(".part_id.", KmpInt32PtrTy),
4010 std::make_pair(".privates.", VoidPtrTy),
4011 std::make_pair(
4012 ".copy_fn.",
4013 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4014 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4015 std::make_pair(StringRef(), QualType()) // __context with shared vars
4016 };
4017 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4018 Params);
4019 // Mark this captured region as inlined, because we don't use outlined
4020 // function directly.
4021 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4022 AlwaysInlineAttr::CreateImplicit(
4023 Context, {}, AttributeCommonInfo::AS_Keyword,
4024 AlwaysInlineAttr::Keyword_forceinline));
4025 break;
4026 }
4027 case OMPD_taskloop:
4028 case OMPD_taskloop_simd:
4029 case OMPD_master_taskloop:
4030 case OMPD_master_taskloop_simd: {
4031 QualType KmpInt32Ty =
4032 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4033 .withConst();
4034 QualType KmpUInt64Ty =
4035 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4036 .withConst();
4037 QualType KmpInt64Ty =
4038 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4039 .withConst();
4040 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4041 QualType KmpInt32PtrTy =
4042 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4043 QualType Args[] = {VoidPtrTy};
4044 FunctionProtoType::ExtProtoInfo EPI;
4045 EPI.Variadic = true;
4046 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4047 Sema::CapturedParamNameType Params[] = {
4048 std::make_pair(".global_tid.", KmpInt32Ty),
4049 std::make_pair(".part_id.", KmpInt32PtrTy),
4050 std::make_pair(".privates.", VoidPtrTy),
4051 std::make_pair(
4052 ".copy_fn.",
4053 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4054 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4055 std::make_pair(".lb.", KmpUInt64Ty),
4056 std::make_pair(".ub.", KmpUInt64Ty),
4057 std::make_pair(".st.", KmpInt64Ty),
4058 std::make_pair(".liter.", KmpInt32Ty),
4059 std::make_pair(".reductions.", VoidPtrTy),
4060 std::make_pair(StringRef(), QualType()) // __context with shared vars
4061 };
4062 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4063 Params);
4064 // Mark this captured region as inlined, because we don't use outlined
4065 // function directly.
4066 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4067 AlwaysInlineAttr::CreateImplicit(
4068 Context, {}, AttributeCommonInfo::AS_Keyword,
4069 AlwaysInlineAttr::Keyword_forceinline));
4070 break;
4071 }
4072 case OMPD_parallel_master_taskloop:
4073 case OMPD_parallel_master_taskloop_simd: {
4074 QualType KmpInt32Ty =
4075 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4076 .withConst();
4077 QualType KmpUInt64Ty =
4078 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4079 .withConst();
4080 QualType KmpInt64Ty =
4081 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4082 .withConst();
4083 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4084 QualType KmpInt32PtrTy =
4085 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4086 Sema::CapturedParamNameType ParamsParallel[] = {
4087 std::make_pair(".global_tid.", KmpInt32PtrTy),
4088 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4089 std::make_pair(StringRef(), QualType()) // __context with shared vars
4090 };
4091 // Start a captured region for 'parallel'.
4092 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4093 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4094 QualType Args[] = {VoidPtrTy};
4095 FunctionProtoType::ExtProtoInfo EPI;
4096 EPI.Variadic = true;
4097 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4098 Sema::CapturedParamNameType Params[] = {
4099 std::make_pair(".global_tid.", KmpInt32Ty),
4100 std::make_pair(".part_id.", KmpInt32PtrTy),
4101 std::make_pair(".privates.", VoidPtrTy),
4102 std::make_pair(
4103 ".copy_fn.",
4104 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4105 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4106 std::make_pair(".lb.", KmpUInt64Ty),
4107 std::make_pair(".ub.", KmpUInt64Ty),
4108 std::make_pair(".st.", KmpInt64Ty),
4109 std::make_pair(".liter.", KmpInt32Ty),
4110 std::make_pair(".reductions.", VoidPtrTy),
4111 std::make_pair(StringRef(), QualType()) // __context with shared vars
4112 };
4113 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4114 Params, /*OpenMPCaptureLevel=*/1);
4115 // Mark this captured region as inlined, because we don't use outlined
4116 // function directly.
4117 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4118 AlwaysInlineAttr::CreateImplicit(
4119 Context, {}, AttributeCommonInfo::AS_Keyword,
4120 AlwaysInlineAttr::Keyword_forceinline));
4121 break;
4122 }
4123 case OMPD_distribute_parallel_for_simd:
4124 case OMPD_distribute_parallel_for: {
4125 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4126 QualType KmpInt32PtrTy =
4127 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4128 Sema::CapturedParamNameType Params[] = {
4129 std::make_pair(".global_tid.", KmpInt32PtrTy),
4130 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4131 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4132 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4133 std::make_pair(StringRef(), QualType()) // __context with shared vars
4134 };
4135 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4136 Params);
4137 break;
4138 }
4139 case OMPD_target_teams_distribute_parallel_for:
4140 case OMPD_target_teams_distribute_parallel_for_simd: {
4141 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4142 QualType KmpInt32PtrTy =
4143 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4144 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4145
4146 QualType Args[] = {VoidPtrTy};
4147 FunctionProtoType::ExtProtoInfo EPI;
4148 EPI.Variadic = true;
4149 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4150 Sema::CapturedParamNameType Params[] = {
4151 std::make_pair(".global_tid.", KmpInt32Ty),
4152 std::make_pair(".part_id.", KmpInt32PtrTy),
4153 std::make_pair(".privates.", VoidPtrTy),
4154 std::make_pair(
4155 ".copy_fn.",
4156 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4157 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4158 std::make_pair(StringRef(), QualType()) // __context with shared vars
4159 };
4160 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4161 Params, /*OpenMPCaptureLevel=*/0);
4162 // Mark this captured region as inlined, because we don't use outlined
4163 // function directly.
4164 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4165 AlwaysInlineAttr::CreateImplicit(
4166 Context, {}, AttributeCommonInfo::AS_Keyword,
4167 AlwaysInlineAttr::Keyword_forceinline));
4168 Sema::CapturedParamNameType ParamsTarget[] = {
4169 std::make_pair(StringRef(), QualType()) // __context with shared vars
4170 };
4171 // Start a captured region for 'target' with no implicit parameters.
4172 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4173 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4174
4175 Sema::CapturedParamNameType ParamsTeams[] = {
4176 std::make_pair(".global_tid.", KmpInt32PtrTy),
4177 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4178 std::make_pair(StringRef(), QualType()) // __context with shared vars
4179 };
4180 // Start a captured region for 'target' with no implicit parameters.
4181 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4182 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4183
4184 Sema::CapturedParamNameType ParamsParallel[] = {
4185 std::make_pair(".global_tid.", KmpInt32PtrTy),
4186 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4187 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4188 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4189 std::make_pair(StringRef(), QualType()) // __context with shared vars
4190 };
4191 // Start a captured region for 'teams' or 'parallel'. Both regions have
4192 // the same implicit parameters.
4193 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4194 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4195 break;
4196 }
4197
4198 case OMPD_teams_distribute_parallel_for:
4199 case OMPD_teams_distribute_parallel_for_simd: {
4200 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4201 QualType KmpInt32PtrTy =
4202 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4203
4204 Sema::CapturedParamNameType ParamsTeams[] = {
4205 std::make_pair(".global_tid.", KmpInt32PtrTy),
4206 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4207 std::make_pair(StringRef(), QualType()) // __context with shared vars
4208 };
4209 // Start a captured region for 'target' with no implicit parameters.
4210 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4211 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4212
4213 Sema::CapturedParamNameType ParamsParallel[] = {
4214 std::make_pair(".global_tid.", KmpInt32PtrTy),
4215 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4216 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4217 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4218 std::make_pair(StringRef(), QualType()) // __context with shared vars
4219 };
4220 // Start a captured region for 'teams' or 'parallel'. Both regions have
4221 // the same implicit parameters.
4222 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4223 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4224 break;
4225 }
4226 case OMPD_target_update:
4227 case OMPD_target_enter_data:
4228 case OMPD_target_exit_data: {
4229 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4230 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4231 QualType KmpInt32PtrTy =
4232 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4233 QualType Args[] = {VoidPtrTy};
4234 FunctionProtoType::ExtProtoInfo EPI;
4235 EPI.Variadic = true;
4236 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4237 Sema::CapturedParamNameType Params[] = {
4238 std::make_pair(".global_tid.", KmpInt32Ty),
4239 std::make_pair(".part_id.", KmpInt32PtrTy),
4240 std::make_pair(".privates.", VoidPtrTy),
4241 std::make_pair(
4242 ".copy_fn.",
4243 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4244 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4245 std::make_pair(StringRef(), QualType()) // __context with shared vars
4246 };
4247 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4248 Params);
4249 // Mark this captured region as inlined, because we don't use outlined
4250 // function directly.
4251 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4252 AlwaysInlineAttr::CreateImplicit(
4253 Context, {}, AttributeCommonInfo::AS_Keyword,
4254 AlwaysInlineAttr::Keyword_forceinline));
4255 break;
4256 }
4257 case OMPD_threadprivate:
4258 case OMPD_allocate:
4259 case OMPD_taskyield:
4260 case OMPD_barrier:
4261 case OMPD_taskwait:
4262 case OMPD_cancellation_point:
4263 case OMPD_cancel:
4264 case OMPD_flush:
4265 case OMPD_depobj:
4266 case OMPD_scan:
4267 case OMPD_declare_reduction:
4268 case OMPD_declare_mapper:
4269 case OMPD_declare_simd:
4270 case OMPD_declare_target:
4271 case OMPD_end_declare_target:
4272 case OMPD_requires:
4273 case OMPD_declare_variant:
4274 case OMPD_begin_declare_variant:
4275 case OMPD_end_declare_variant:
4276 llvm_unreachable("OpenMP Directive is not allowed");
4277 case OMPD_unknown:
4278 default:
4279 llvm_unreachable("Unknown OpenMP directive");
4280 }
4281 DSAStack->setContext(CurContext);
4282 }
4283
getNumberOfConstructScopes(unsigned Level) const4284 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4285 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4286 }
4287
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4288 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4289 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4290 getOpenMPCaptureRegions(CaptureRegions, DKind);
4291 return CaptureRegions.size();
4292 }
4293
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)4294 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4295 Expr *CaptureExpr, bool WithInit,
4296 bool AsExpression) {
4297 assert(CaptureExpr);
4298 ASTContext &C = S.getASTContext();
4299 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4300 QualType Ty = Init->getType();
4301 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4302 if (S.getLangOpts().CPlusPlus) {
4303 Ty = C.getLValueReferenceType(Ty);
4304 } else {
4305 Ty = C.getPointerType(Ty);
4306 ExprResult Res =
4307 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4308 if (!Res.isUsable())
4309 return nullptr;
4310 Init = Res.get();
4311 }
4312 WithInit = true;
4313 }
4314 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4315 CaptureExpr->getBeginLoc());
4316 if (!WithInit)
4317 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4318 S.CurContext->addHiddenDecl(CED);
4319 Sema::TentativeAnalysisScope Trap(S);
4320 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4321 return CED;
4322 }
4323
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4324 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4325 bool WithInit) {
4326 OMPCapturedExprDecl *CD;
4327 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4328 CD = cast<OMPCapturedExprDecl>(VD);
4329 else
4330 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4331 /*AsExpression=*/false);
4332 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4333 CaptureExpr->getExprLoc());
4334 }
4335
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4336 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4337 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4338 if (!Ref) {
4339 OMPCapturedExprDecl *CD = buildCaptureDecl(
4340 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4341 /*WithInit=*/true, /*AsExpression=*/true);
4342 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4343 CaptureExpr->getExprLoc());
4344 }
4345 ExprResult Res = Ref;
4346 if (!S.getLangOpts().CPlusPlus &&
4347 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4348 Ref->getType()->isPointerType()) {
4349 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4350 if (!Res.isUsable())
4351 return ExprError();
4352 }
4353 return S.DefaultLvalueConversion(Res.get());
4354 }
4355
4356 namespace {
4357 // OpenMP directives parsed in this section are represented as a
4358 // CapturedStatement with an associated statement. If a syntax error
4359 // is detected during the parsing of the associated statement, the
4360 // compiler must abort processing and close the CapturedStatement.
4361 //
4362 // Combined directives such as 'target parallel' have more than one
4363 // nested CapturedStatements. This RAII ensures that we unwind out
4364 // of all the nested CapturedStatements when an error is found.
4365 class CaptureRegionUnwinderRAII {
4366 private:
4367 Sema &S;
4368 bool &ErrorFound;
4369 OpenMPDirectiveKind DKind = OMPD_unknown;
4370
4371 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4372 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4373 OpenMPDirectiveKind DKind)
4374 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4375 ~CaptureRegionUnwinderRAII() {
4376 if (ErrorFound) {
4377 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4378 while (--ThisCaptureLevel >= 0)
4379 S.ActOnCapturedRegionError();
4380 }
4381 }
4382 };
4383 } // namespace
4384
tryCaptureOpenMPLambdas(ValueDecl * V)4385 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4386 // Capture variables captured by reference in lambdas for target-based
4387 // directives.
4388 if (!CurContext->isDependentContext() &&
4389 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4390 isOpenMPTargetDataManagementDirective(
4391 DSAStack->getCurrentDirective()))) {
4392 QualType Type = V->getType();
4393 if (const auto *RD = Type.getCanonicalType()
4394 .getNonReferenceType()
4395 ->getAsCXXRecordDecl()) {
4396 bool SavedForceCaptureByReferenceInTargetExecutable =
4397 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4398 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4399 /*V=*/true);
4400 if (RD->isLambda()) {
4401 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4402 FieldDecl *ThisCapture;
4403 RD->getCaptureFields(Captures, ThisCapture);
4404 for (const LambdaCapture &LC : RD->captures()) {
4405 if (LC.getCaptureKind() == LCK_ByRef) {
4406 VarDecl *VD = LC.getCapturedVar();
4407 DeclContext *VDC = VD->getDeclContext();
4408 if (!VDC->Encloses(CurContext))
4409 continue;
4410 MarkVariableReferenced(LC.getLocation(), VD);
4411 } else if (LC.getCaptureKind() == LCK_This) {
4412 QualType ThisTy = getCurrentThisType();
4413 if (!ThisTy.isNull() &&
4414 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4415 CheckCXXThisCapture(LC.getLocation());
4416 }
4417 }
4418 }
4419 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4420 SavedForceCaptureByReferenceInTargetExecutable);
4421 }
4422 }
4423 }
4424
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4425 static bool checkOrderedOrderSpecified(Sema &S,
4426 const ArrayRef<OMPClause *> Clauses) {
4427 const OMPOrderedClause *Ordered = nullptr;
4428 const OMPOrderClause *Order = nullptr;
4429
4430 for (const OMPClause *Clause : Clauses) {
4431 if (Clause->getClauseKind() == OMPC_ordered)
4432 Ordered = cast<OMPOrderedClause>(Clause);
4433 else if (Clause->getClauseKind() == OMPC_order) {
4434 Order = cast<OMPOrderClause>(Clause);
4435 if (Order->getKind() != OMPC_ORDER_concurrent)
4436 Order = nullptr;
4437 }
4438 if (Ordered && Order)
4439 break;
4440 }
4441
4442 if (Ordered && Order) {
4443 S.Diag(Order->getKindKwLoc(),
4444 diag::err_omp_simple_clause_incompatible_with_ordered)
4445 << getOpenMPClauseName(OMPC_order)
4446 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4447 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4448 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4449 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4450 return true;
4451 }
4452 return false;
4453 }
4454
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4455 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4456 ArrayRef<OMPClause *> Clauses) {
4457 if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4458 DSAStack->getCurrentDirective() == OMPD_critical ||
4459 DSAStack->getCurrentDirective() == OMPD_section ||
4460 DSAStack->getCurrentDirective() == OMPD_master ||
4461 DSAStack->getCurrentDirective() == OMPD_masked)
4462 return S;
4463
4464 bool ErrorFound = false;
4465 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4466 *this, ErrorFound, DSAStack->getCurrentDirective());
4467 if (!S.isUsable()) {
4468 ErrorFound = true;
4469 return StmtError();
4470 }
4471
4472 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4473 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4474 OMPOrderedClause *OC = nullptr;
4475 OMPScheduleClause *SC = nullptr;
4476 SmallVector<const OMPLinearClause *, 4> LCs;
4477 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4478 // This is required for proper codegen.
4479 for (OMPClause *Clause : Clauses) {
4480 if (!LangOpts.OpenMPSimd &&
4481 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4482 Clause->getClauseKind() == OMPC_in_reduction) {
4483 // Capture taskgroup task_reduction descriptors inside the tasking regions
4484 // with the corresponding in_reduction items.
4485 auto *IRC = cast<OMPInReductionClause>(Clause);
4486 for (Expr *E : IRC->taskgroup_descriptors())
4487 if (E)
4488 MarkDeclarationsReferencedInExpr(E);
4489 }
4490 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4491 Clause->getClauseKind() == OMPC_copyprivate ||
4492 (getLangOpts().OpenMPUseTLS &&
4493 getASTContext().getTargetInfo().isTLSSupported() &&
4494 Clause->getClauseKind() == OMPC_copyin)) {
4495 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4496 // Mark all variables in private list clauses as used in inner region.
4497 for (Stmt *VarRef : Clause->children()) {
4498 if (auto *E = cast_or_null<Expr>(VarRef)) {
4499 MarkDeclarationsReferencedInExpr(E);
4500 }
4501 }
4502 DSAStack->setForceVarCapturing(/*V=*/false);
4503 } else if (isOpenMPLoopTransformationDirective(
4504 DSAStack->getCurrentDirective())) {
4505 assert(CaptureRegions.empty() &&
4506 "No captured regions in loop transformation directives.");
4507 } else if (CaptureRegions.size() > 1 ||
4508 CaptureRegions.back() != OMPD_unknown) {
4509 if (auto *C = OMPClauseWithPreInit::get(Clause))
4510 PICs.push_back(C);
4511 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4512 if (Expr *E = C->getPostUpdateExpr())
4513 MarkDeclarationsReferencedInExpr(E);
4514 }
4515 }
4516 if (Clause->getClauseKind() == OMPC_schedule)
4517 SC = cast<OMPScheduleClause>(Clause);
4518 else if (Clause->getClauseKind() == OMPC_ordered)
4519 OC = cast<OMPOrderedClause>(Clause);
4520 else if (Clause->getClauseKind() == OMPC_linear)
4521 LCs.push_back(cast<OMPLinearClause>(Clause));
4522 }
4523 // Capture allocator expressions if used.
4524 for (Expr *E : DSAStack->getInnerAllocators())
4525 MarkDeclarationsReferencedInExpr(E);
4526 // OpenMP, 2.7.1 Loop Construct, Restrictions
4527 // The nonmonotonic modifier cannot be specified if an ordered clause is
4528 // specified.
4529 if (SC &&
4530 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4531 SC->getSecondScheduleModifier() ==
4532 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4533 OC) {
4534 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4535 ? SC->getFirstScheduleModifierLoc()
4536 : SC->getSecondScheduleModifierLoc(),
4537 diag::err_omp_simple_clause_incompatible_with_ordered)
4538 << getOpenMPClauseName(OMPC_schedule)
4539 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4540 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4541 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4542 ErrorFound = true;
4543 }
4544 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4545 // If an order(concurrent) clause is present, an ordered clause may not appear
4546 // on the same directive.
4547 if (checkOrderedOrderSpecified(*this, Clauses))
4548 ErrorFound = true;
4549 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4550 for (const OMPLinearClause *C : LCs) {
4551 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4552 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4553 }
4554 ErrorFound = true;
4555 }
4556 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4557 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4558 OC->getNumForLoops()) {
4559 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4560 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4561 ErrorFound = true;
4562 }
4563 if (ErrorFound) {
4564 return StmtError();
4565 }
4566 StmtResult SR = S;
4567 unsigned CompletedRegions = 0;
4568 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4569 // Mark all variables in private list clauses as used in inner region.
4570 // Required for proper codegen of combined directives.
4571 // TODO: add processing for other clauses.
4572 if (ThisCaptureRegion != OMPD_unknown) {
4573 for (const clang::OMPClauseWithPreInit *C : PICs) {
4574 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4575 // Find the particular capture region for the clause if the
4576 // directive is a combined one with multiple capture regions.
4577 // If the directive is not a combined one, the capture region
4578 // associated with the clause is OMPD_unknown and is generated
4579 // only once.
4580 if (CaptureRegion == ThisCaptureRegion ||
4581 CaptureRegion == OMPD_unknown) {
4582 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4583 for (Decl *D : DS->decls())
4584 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4585 }
4586 }
4587 }
4588 }
4589 if (ThisCaptureRegion == OMPD_target) {
4590 // Capture allocator traits in the target region. They are used implicitly
4591 // and, thus, are not captured by default.
4592 for (OMPClause *C : Clauses) {
4593 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4594 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4595 ++I) {
4596 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4597 if (Expr *E = D.AllocatorTraits)
4598 MarkDeclarationsReferencedInExpr(E);
4599 }
4600 continue;
4601 }
4602 }
4603 }
4604 if (ThisCaptureRegion == OMPD_parallel) {
4605 // Capture temp arrays for inscan reductions.
4606 for (OMPClause *C : Clauses) {
4607 if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4608 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4609 continue;
4610 for (Expr *E : RC->copy_array_temps())
4611 MarkDeclarationsReferencedInExpr(E);
4612 }
4613 }
4614 }
4615 if (++CompletedRegions == CaptureRegions.size())
4616 DSAStack->setBodyComplete();
4617 SR = ActOnCapturedRegionEnd(SR.get());
4618 }
4619 return SR;
4620 }
4621
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4622 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4623 OpenMPDirectiveKind CancelRegion,
4624 SourceLocation StartLoc) {
4625 // CancelRegion is only needed for cancel and cancellation_point.
4626 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4627 return false;
4628
4629 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4630 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4631 return false;
4632
4633 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4634 << getOpenMPDirectiveName(CancelRegion);
4635 return true;
4636 }
4637
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4638 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4639 OpenMPDirectiveKind CurrentRegion,
4640 const DeclarationNameInfo &CurrentName,
4641 OpenMPDirectiveKind CancelRegion,
4642 SourceLocation StartLoc) {
4643 if (Stack->getCurScope()) {
4644 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4645 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4646 bool NestingProhibited = false;
4647 bool CloseNesting = true;
4648 bool OrphanSeen = false;
4649 enum {
4650 NoRecommend,
4651 ShouldBeInParallelRegion,
4652 ShouldBeInOrderedRegion,
4653 ShouldBeInTargetRegion,
4654 ShouldBeInTeamsRegion,
4655 ShouldBeInLoopSimdRegion,
4656 } Recommend = NoRecommend;
4657 if (isOpenMPSimdDirective(ParentRegion) &&
4658 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4659 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4660 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4661 CurrentRegion != OMPD_scan))) {
4662 // OpenMP [2.16, Nesting of Regions]
4663 // OpenMP constructs may not be nested inside a simd region.
4664 // OpenMP [2.8.1,simd Construct, Restrictions]
4665 // An ordered construct with the simd clause is the only OpenMP
4666 // construct that can appear in the simd region.
4667 // Allowing a SIMD construct nested in another SIMD construct is an
4668 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4669 // message.
4670 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4671 // The only OpenMP constructs that can be encountered during execution of
4672 // a simd region are the atomic construct, the loop construct, the simd
4673 // construct and the ordered construct with the simd clause.
4674 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4675 ? diag::err_omp_prohibited_region_simd
4676 : diag::warn_omp_nesting_simd)
4677 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4678 return CurrentRegion != OMPD_simd;
4679 }
4680 if (ParentRegion == OMPD_atomic) {
4681 // OpenMP [2.16, Nesting of Regions]
4682 // OpenMP constructs may not be nested inside an atomic region.
4683 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4684 return true;
4685 }
4686 if (CurrentRegion == OMPD_section) {
4687 // OpenMP [2.7.2, sections Construct, Restrictions]
4688 // Orphaned section directives are prohibited. That is, the section
4689 // directives must appear within the sections construct and must not be
4690 // encountered elsewhere in the sections region.
4691 if (ParentRegion != OMPD_sections &&
4692 ParentRegion != OMPD_parallel_sections) {
4693 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4694 << (ParentRegion != OMPD_unknown)
4695 << getOpenMPDirectiveName(ParentRegion);
4696 return true;
4697 }
4698 return false;
4699 }
4700 // Allow some constructs (except teams and cancellation constructs) to be
4701 // orphaned (they could be used in functions, called from OpenMP regions
4702 // with the required preconditions).
4703 if (ParentRegion == OMPD_unknown &&
4704 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4705 CurrentRegion != OMPD_cancellation_point &&
4706 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4707 return false;
4708 if (CurrentRegion == OMPD_cancellation_point ||
4709 CurrentRegion == OMPD_cancel) {
4710 // OpenMP [2.16, Nesting of Regions]
4711 // A cancellation point construct for which construct-type-clause is
4712 // taskgroup must be nested inside a task construct. A cancellation
4713 // point construct for which construct-type-clause is not taskgroup must
4714 // be closely nested inside an OpenMP construct that matches the type
4715 // specified in construct-type-clause.
4716 // A cancel construct for which construct-type-clause is taskgroup must be
4717 // nested inside a task construct. A cancel construct for which
4718 // construct-type-clause is not taskgroup must be closely nested inside an
4719 // OpenMP construct that matches the type specified in
4720 // construct-type-clause.
4721 NestingProhibited =
4722 !((CancelRegion == OMPD_parallel &&
4723 (ParentRegion == OMPD_parallel ||
4724 ParentRegion == OMPD_target_parallel)) ||
4725 (CancelRegion == OMPD_for &&
4726 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4727 ParentRegion == OMPD_target_parallel_for ||
4728 ParentRegion == OMPD_distribute_parallel_for ||
4729 ParentRegion == OMPD_teams_distribute_parallel_for ||
4730 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4731 (CancelRegion == OMPD_taskgroup &&
4732 (ParentRegion == OMPD_task ||
4733 (SemaRef.getLangOpts().OpenMP >= 50 &&
4734 (ParentRegion == OMPD_taskloop ||
4735 ParentRegion == OMPD_master_taskloop ||
4736 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4737 (CancelRegion == OMPD_sections &&
4738 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4739 ParentRegion == OMPD_parallel_sections)));
4740 OrphanSeen = ParentRegion == OMPD_unknown;
4741 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4742 // OpenMP 5.1 [2.22, Nesting of Regions]
4743 // A masked region may not be closely nested inside a worksharing, loop,
4744 // atomic, task, or taskloop region.
4745 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4746 isOpenMPTaskingDirective(ParentRegion);
4747 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4748 // OpenMP [2.16, Nesting of Regions]
4749 // A critical region may not be nested (closely or otherwise) inside a
4750 // critical region with the same name. Note that this restriction is not
4751 // sufficient to prevent deadlock.
4752 SourceLocation PreviousCriticalLoc;
4753 bool DeadLock = Stack->hasDirective(
4754 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4755 const DeclarationNameInfo &DNI,
4756 SourceLocation Loc) {
4757 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4758 PreviousCriticalLoc = Loc;
4759 return true;
4760 }
4761 return false;
4762 },
4763 false /* skip top directive */);
4764 if (DeadLock) {
4765 SemaRef.Diag(StartLoc,
4766 diag::err_omp_prohibited_region_critical_same_name)
4767 << CurrentName.getName();
4768 if (PreviousCriticalLoc.isValid())
4769 SemaRef.Diag(PreviousCriticalLoc,
4770 diag::note_omp_previous_critical_region);
4771 return true;
4772 }
4773 } else if (CurrentRegion == OMPD_barrier) {
4774 // OpenMP 5.1 [2.22, Nesting of Regions]
4775 // A barrier region may not be closely nested inside a worksharing, loop,
4776 // task, taskloop, critical, ordered, atomic, or masked region.
4777 NestingProhibited =
4778 isOpenMPWorksharingDirective(ParentRegion) ||
4779 isOpenMPTaskingDirective(ParentRegion) ||
4780 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4781 ParentRegion == OMPD_parallel_master ||
4782 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4783 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4784 !isOpenMPParallelDirective(CurrentRegion) &&
4785 !isOpenMPTeamsDirective(CurrentRegion)) {
4786 // OpenMP 5.1 [2.22, Nesting of Regions]
4787 // A loop region that binds to a parallel region or a worksharing region
4788 // may not be closely nested inside a worksharing, loop, task, taskloop,
4789 // critical, ordered, atomic, or masked region.
4790 NestingProhibited =
4791 isOpenMPWorksharingDirective(ParentRegion) ||
4792 isOpenMPTaskingDirective(ParentRegion) ||
4793 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4794 ParentRegion == OMPD_parallel_master ||
4795 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4796 Recommend = ShouldBeInParallelRegion;
4797 } else if (CurrentRegion == OMPD_ordered) {
4798 // OpenMP [2.16, Nesting of Regions]
4799 // An ordered region may not be closely nested inside a critical,
4800 // atomic, or explicit task region.
4801 // An ordered region must be closely nested inside a loop region (or
4802 // parallel loop region) with an ordered clause.
4803 // OpenMP [2.8.1,simd Construct, Restrictions]
4804 // An ordered construct with the simd clause is the only OpenMP construct
4805 // that can appear in the simd region.
4806 NestingProhibited = ParentRegion == OMPD_critical ||
4807 isOpenMPTaskingDirective(ParentRegion) ||
4808 !(isOpenMPSimdDirective(ParentRegion) ||
4809 Stack->isParentOrderedRegion());
4810 Recommend = ShouldBeInOrderedRegion;
4811 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4812 // OpenMP [2.16, Nesting of Regions]
4813 // If specified, a teams construct must be contained within a target
4814 // construct.
4815 NestingProhibited =
4816 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4817 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4818 ParentRegion != OMPD_target);
4819 OrphanSeen = ParentRegion == OMPD_unknown;
4820 Recommend = ShouldBeInTargetRegion;
4821 } else if (CurrentRegion == OMPD_scan) {
4822 // OpenMP [2.16, Nesting of Regions]
4823 // If specified, a teams construct must be contained within a target
4824 // construct.
4825 NestingProhibited =
4826 SemaRef.LangOpts.OpenMP < 50 ||
4827 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4828 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4829 ParentRegion != OMPD_parallel_for_simd);
4830 OrphanSeen = ParentRegion == OMPD_unknown;
4831 Recommend = ShouldBeInLoopSimdRegion;
4832 }
4833 if (!NestingProhibited &&
4834 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4835 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4836 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4837 // OpenMP [2.16, Nesting of Regions]
4838 // distribute, parallel, parallel sections, parallel workshare, and the
4839 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4840 // constructs that can be closely nested in the teams region.
4841 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4842 !isOpenMPDistributeDirective(CurrentRegion);
4843 Recommend = ShouldBeInParallelRegion;
4844 }
4845 if (!NestingProhibited &&
4846 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4847 // OpenMP 4.5 [2.17 Nesting of Regions]
4848 // The region associated with the distribute construct must be strictly
4849 // nested inside a teams region
4850 NestingProhibited =
4851 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4852 Recommend = ShouldBeInTeamsRegion;
4853 }
4854 if (!NestingProhibited &&
4855 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4856 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4857 // OpenMP 4.5 [2.17 Nesting of Regions]
4858 // If a target, target update, target data, target enter data, or
4859 // target exit data construct is encountered during execution of a
4860 // target region, the behavior is unspecified.
4861 NestingProhibited = Stack->hasDirective(
4862 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4863 SourceLocation) {
4864 if (isOpenMPTargetExecutionDirective(K)) {
4865 OffendingRegion = K;
4866 return true;
4867 }
4868 return false;
4869 },
4870 false /* don't skip top directive */);
4871 CloseNesting = false;
4872 }
4873 if (NestingProhibited) {
4874 if (OrphanSeen) {
4875 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4876 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4877 } else {
4878 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4879 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4880 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4881 }
4882 return true;
4883 }
4884 }
4885 return false;
4886 }
4887
4888 struct Kind2Unsigned {
4889 using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned4890 unsigned operator()(argument_type DK) { return unsigned(DK); }
4891 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)4892 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4893 ArrayRef<OMPClause *> Clauses,
4894 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4895 bool ErrorFound = false;
4896 unsigned NamedModifiersNumber = 0;
4897 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4898 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4899 SmallVector<SourceLocation, 4> NameModifierLoc;
4900 for (const OMPClause *C : Clauses) {
4901 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4902 // At most one if clause without a directive-name-modifier can appear on
4903 // the directive.
4904 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4905 if (FoundNameModifiers[CurNM]) {
4906 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4907 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4908 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4909 ErrorFound = true;
4910 } else if (CurNM != OMPD_unknown) {
4911 NameModifierLoc.push_back(IC->getNameModifierLoc());
4912 ++NamedModifiersNumber;
4913 }
4914 FoundNameModifiers[CurNM] = IC;
4915 if (CurNM == OMPD_unknown)
4916 continue;
4917 // Check if the specified name modifier is allowed for the current
4918 // directive.
4919 // At most one if clause with the particular directive-name-modifier can
4920 // appear on the directive.
4921 bool MatchFound = false;
4922 for (auto NM : AllowedNameModifiers) {
4923 if (CurNM == NM) {
4924 MatchFound = true;
4925 break;
4926 }
4927 }
4928 if (!MatchFound) {
4929 S.Diag(IC->getNameModifierLoc(),
4930 diag::err_omp_wrong_if_directive_name_modifier)
4931 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4932 ErrorFound = true;
4933 }
4934 }
4935 }
4936 // If any if clause on the directive includes a directive-name-modifier then
4937 // all if clauses on the directive must include a directive-name-modifier.
4938 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4939 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4940 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4941 diag::err_omp_no_more_if_clause);
4942 } else {
4943 std::string Values;
4944 std::string Sep(", ");
4945 unsigned AllowedCnt = 0;
4946 unsigned TotalAllowedNum =
4947 AllowedNameModifiers.size() - NamedModifiersNumber;
4948 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4949 ++Cnt) {
4950 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4951 if (!FoundNameModifiers[NM]) {
4952 Values += "'";
4953 Values += getOpenMPDirectiveName(NM);
4954 Values += "'";
4955 if (AllowedCnt + 2 == TotalAllowedNum)
4956 Values += " or ";
4957 else if (AllowedCnt + 1 != TotalAllowedNum)
4958 Values += Sep;
4959 ++AllowedCnt;
4960 }
4961 }
4962 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4963 diag::err_omp_unnamed_if_clause)
4964 << (TotalAllowedNum > 1) << Values;
4965 }
4966 for (SourceLocation Loc : NameModifierLoc) {
4967 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4968 }
4969 ErrorFound = true;
4970 }
4971 return ErrorFound;
4972 }
4973
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)4974 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4975 SourceLocation &ELoc,
4976 SourceRange &ERange,
4977 bool AllowArraySection) {
4978 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4979 RefExpr->containsUnexpandedParameterPack())
4980 return std::make_pair(nullptr, true);
4981
4982 // OpenMP [3.1, C/C++]
4983 // A list item is a variable name.
4984 // OpenMP [2.9.3.3, Restrictions, p.1]
4985 // A variable that is part of another variable (as an array or
4986 // structure element) cannot appear in a private clause.
4987 RefExpr = RefExpr->IgnoreParens();
4988 enum {
4989 NoArrayExpr = -1,
4990 ArraySubscript = 0,
4991 OMPArraySection = 1
4992 } IsArrayExpr = NoArrayExpr;
4993 if (AllowArraySection) {
4994 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4995 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4996 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4997 Base = TempASE->getBase()->IgnoreParenImpCasts();
4998 RefExpr = Base;
4999 IsArrayExpr = ArraySubscript;
5000 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5001 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5002 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5003 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5004 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5005 Base = TempASE->getBase()->IgnoreParenImpCasts();
5006 RefExpr = Base;
5007 IsArrayExpr = OMPArraySection;
5008 }
5009 }
5010 ELoc = RefExpr->getExprLoc();
5011 ERange = RefExpr->getSourceRange();
5012 RefExpr = RefExpr->IgnoreParenImpCasts();
5013 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5014 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5015 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5016 (S.getCurrentThisType().isNull() || !ME ||
5017 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5018 !isa<FieldDecl>(ME->getMemberDecl()))) {
5019 if (IsArrayExpr != NoArrayExpr) {
5020 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
5021 << ERange;
5022 } else {
5023 S.Diag(ELoc,
5024 AllowArraySection
5025 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5026 : diag::err_omp_expected_var_name_member_expr)
5027 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5028 }
5029 return std::make_pair(nullptr, false);
5030 }
5031 return std::make_pair(
5032 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5033 }
5034
5035 namespace {
5036 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5037 /// target regions.
5038 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5039 DSAStackTy *S = nullptr;
5040
5041 public:
VisitDeclRefExpr(const DeclRefExpr * E)5042 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5043 return S->isUsesAllocatorsDecl(E->getDecl())
5044 .getValueOr(
5045 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5046 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5047 }
VisitStmt(const Stmt * S)5048 bool VisitStmt(const Stmt *S) {
5049 for (const Stmt *Child : S->children()) {
5050 if (Child && Visit(Child))
5051 return true;
5052 }
5053 return false;
5054 }
AllocatorChecker(DSAStackTy * S)5055 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5056 };
5057 } // namespace
5058
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)5059 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5060 ArrayRef<OMPClause *> Clauses) {
5061 assert(!S.CurContext->isDependentContext() &&
5062 "Expected non-dependent context.");
5063 auto AllocateRange =
5064 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5065 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5066 DeclToCopy;
5067 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5068 return isOpenMPPrivate(C->getClauseKind());
5069 });
5070 for (OMPClause *Cl : PrivateRange) {
5071 MutableArrayRef<Expr *>::iterator I, It, Et;
5072 if (Cl->getClauseKind() == OMPC_private) {
5073 auto *PC = cast<OMPPrivateClause>(Cl);
5074 I = PC->private_copies().begin();
5075 It = PC->varlist_begin();
5076 Et = PC->varlist_end();
5077 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5078 auto *PC = cast<OMPFirstprivateClause>(Cl);
5079 I = PC->private_copies().begin();
5080 It = PC->varlist_begin();
5081 Et = PC->varlist_end();
5082 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5083 auto *PC = cast<OMPLastprivateClause>(Cl);
5084 I = PC->private_copies().begin();
5085 It = PC->varlist_begin();
5086 Et = PC->varlist_end();
5087 } else if (Cl->getClauseKind() == OMPC_linear) {
5088 auto *PC = cast<OMPLinearClause>(Cl);
5089 I = PC->privates().begin();
5090 It = PC->varlist_begin();
5091 Et = PC->varlist_end();
5092 } else if (Cl->getClauseKind() == OMPC_reduction) {
5093 auto *PC = cast<OMPReductionClause>(Cl);
5094 I = PC->privates().begin();
5095 It = PC->varlist_begin();
5096 Et = PC->varlist_end();
5097 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5098 auto *PC = cast<OMPTaskReductionClause>(Cl);
5099 I = PC->privates().begin();
5100 It = PC->varlist_begin();
5101 Et = PC->varlist_end();
5102 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5103 auto *PC = cast<OMPInReductionClause>(Cl);
5104 I = PC->privates().begin();
5105 It = PC->varlist_begin();
5106 Et = PC->varlist_end();
5107 } else {
5108 llvm_unreachable("Expected private clause.");
5109 }
5110 for (Expr *E : llvm::make_range(It, Et)) {
5111 if (!*I) {
5112 ++I;
5113 continue;
5114 }
5115 SourceLocation ELoc;
5116 SourceRange ERange;
5117 Expr *SimpleRefExpr = E;
5118 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5119 /*AllowArraySection=*/true);
5120 DeclToCopy.try_emplace(Res.first,
5121 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5122 ++I;
5123 }
5124 }
5125 for (OMPClause *C : AllocateRange) {
5126 auto *AC = cast<OMPAllocateClause>(C);
5127 if (S.getLangOpts().OpenMP >= 50 &&
5128 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5129 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5130 AC->getAllocator()) {
5131 Expr *Allocator = AC->getAllocator();
5132 // OpenMP, 2.12.5 target Construct
5133 // Memory allocators that do not appear in a uses_allocators clause cannot
5134 // appear as an allocator in an allocate clause or be used in the target
5135 // region unless a requires directive with the dynamic_allocators clause
5136 // is present in the same compilation unit.
5137 AllocatorChecker Checker(Stack);
5138 if (Checker.Visit(Allocator))
5139 S.Diag(Allocator->getExprLoc(),
5140 diag::err_omp_allocator_not_in_uses_allocators)
5141 << Allocator->getSourceRange();
5142 }
5143 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5144 getAllocatorKind(S, Stack, AC->getAllocator());
5145 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5146 // For task, taskloop or target directives, allocation requests to memory
5147 // allocators with the trait access set to thread result in unspecified
5148 // behavior.
5149 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5150 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5151 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5152 S.Diag(AC->getAllocator()->getExprLoc(),
5153 diag::warn_omp_allocate_thread_on_task_target_directive)
5154 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5155 }
5156 for (Expr *E : AC->varlists()) {
5157 SourceLocation ELoc;
5158 SourceRange ERange;
5159 Expr *SimpleRefExpr = E;
5160 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5161 ValueDecl *VD = Res.first;
5162 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5163 if (!isOpenMPPrivate(Data.CKind)) {
5164 S.Diag(E->getExprLoc(),
5165 diag::err_omp_expected_private_copy_for_allocate);
5166 continue;
5167 }
5168 VarDecl *PrivateVD = DeclToCopy[VD];
5169 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5170 AllocatorKind, AC->getAllocator()))
5171 continue;
5172 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5173 E->getSourceRange());
5174 }
5175 }
5176 }
5177
5178 namespace {
5179 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5180 ///
5181 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5182 /// context. DeclRefExpr used inside the new context are changed to refer to the
5183 /// captured variable instead.
5184 class CaptureVars : public TreeTransform<CaptureVars> {
5185 using BaseTransform = TreeTransform<CaptureVars>;
5186
5187 public:
CaptureVars(Sema & Actions)5188 CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5189
AlwaysRebuild()5190 bool AlwaysRebuild() { return true; }
5191 };
5192 } // namespace
5193
precomputeExpr(Sema & Actions,SmallVectorImpl<Stmt * > & BodyStmts,Expr * E,StringRef Name)5194 static VarDecl *precomputeExpr(Sema &Actions,
5195 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5196 StringRef Name) {
5197 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5198 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5199 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5200 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5201 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5202 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5203 BodyStmts.push_back(NewDeclStmt);
5204 return NewVar;
5205 }
5206
5207 /// Create a closure that computes the number of iterations of a loop.
5208 ///
5209 /// \param Actions The Sema object.
5210 /// \param LogicalTy Type for the logical iteration number.
5211 /// \param Rel Comparison operator of the loop condition.
5212 /// \param StartExpr Value of the loop counter at the first iteration.
5213 /// \param StopExpr Expression the loop counter is compared against in the loop
5214 /// condition. \param StepExpr Amount of increment after each iteration.
5215 ///
5216 /// \return Closure (CapturedStmt) of the distance calculation.
buildDistanceFunc(Sema & Actions,QualType LogicalTy,BinaryOperator::Opcode Rel,Expr * StartExpr,Expr * StopExpr,Expr * StepExpr)5217 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5218 BinaryOperator::Opcode Rel,
5219 Expr *StartExpr, Expr *StopExpr,
5220 Expr *StepExpr) {
5221 ASTContext &Ctx = Actions.getASTContext();
5222 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5223
5224 // Captured regions currently don't support return values, we use an
5225 // out-parameter instead. All inputs are implicit captures.
5226 // TODO: Instead of capturing each DeclRefExpr occurring in
5227 // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5228 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5229 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5230 {StringRef(), QualType()}};
5231 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5232
5233 Stmt *Body;
5234 {
5235 Sema::CompoundScopeRAII CompoundScope(Actions);
5236 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5237
5238 // Get the LValue expression for the result.
5239 ImplicitParamDecl *DistParam = CS->getParam(0);
5240 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5241 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5242
5243 SmallVector<Stmt *, 4> BodyStmts;
5244
5245 // Capture all referenced variable references.
5246 // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5247 // CapturedStmt, we could compute them before and capture the result, to be
5248 // used jointly with the LoopVar function.
5249 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5250 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5251 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5252 auto BuildVarRef = [&](VarDecl *VD) {
5253 return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5254 };
5255
5256 IntegerLiteral *Zero = IntegerLiteral::Create(
5257 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5258 Expr *Dist;
5259 if (Rel == BO_NE) {
5260 // When using a != comparison, the increment can be +1 or -1. This can be
5261 // dynamic at runtime, so we need to check for the direction.
5262 Expr *IsNegStep = AssertSuccess(
5263 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5264
5265 // Positive increment.
5266 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5267 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5268 ForwardRange = AssertSuccess(
5269 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5270 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5271 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5272
5273 // Negative increment.
5274 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5275 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5276 BackwardRange = AssertSuccess(
5277 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5278 Expr *NegIncAmount = AssertSuccess(
5279 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5280 Expr *BackwardDist = AssertSuccess(
5281 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5282
5283 // Use the appropriate case.
5284 Dist = AssertSuccess(Actions.ActOnConditionalOp(
5285 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5286 } else {
5287 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5288 "Expected one of these relational operators");
5289
5290 // We can derive the direction from any other comparison operator. It is
5291 // non well-formed OpenMP if Step increments/decrements in the other
5292 // directions. Whether at least the first iteration passes the loop
5293 // condition.
5294 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5295 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5296
5297 // Compute the range between first and last counter value.
5298 Expr *Range;
5299 if (Rel == BO_GE || Rel == BO_GT)
5300 Range = AssertSuccess(Actions.BuildBinOp(
5301 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5302 else
5303 Range = AssertSuccess(Actions.BuildBinOp(
5304 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5305
5306 // Ensure unsigned range space.
5307 Range =
5308 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5309
5310 if (Rel == BO_LE || Rel == BO_GE) {
5311 // Add one to the range if the relational operator is inclusive.
5312 Range =
5313 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_PreInc, Range));
5314 }
5315
5316 // Divide by the absolute step amount.
5317 Expr *Divisor = BuildVarRef(NewStep);
5318 if (Rel == BO_GE || Rel == BO_GT)
5319 Divisor =
5320 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5321 Dist = AssertSuccess(
5322 Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
5323
5324 // If there is not at least one iteration, the range contains garbage. Fix
5325 // to zero in this case.
5326 Dist = AssertSuccess(
5327 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5328 }
5329
5330 // Assign the result to the out-parameter.
5331 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5332 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5333 BodyStmts.push_back(ResultAssign);
5334
5335 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5336 }
5337
5338 return cast<CapturedStmt>(
5339 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5340 }
5341
5342 /// Create a closure that computes the loop variable from the logical iteration
5343 /// number.
5344 ///
5345 /// \param Actions The Sema object.
5346 /// \param LoopVarTy Type for the loop variable used for result value.
5347 /// \param LogicalTy Type for the logical iteration number.
5348 /// \param StartExpr Value of the loop counter at the first iteration.
5349 /// \param Step Amount of increment after each iteration.
5350 /// \param Deref Whether the loop variable is a dereference of the loop
5351 /// counter variable.
5352 ///
5353 /// \return Closure (CapturedStmt) of the loop value calculation.
buildLoopVarFunc(Sema & Actions,QualType LoopVarTy,QualType LogicalTy,DeclRefExpr * StartExpr,Expr * Step,bool Deref)5354 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5355 QualType LogicalTy,
5356 DeclRefExpr *StartExpr, Expr *Step,
5357 bool Deref) {
5358 ASTContext &Ctx = Actions.getASTContext();
5359
5360 // Pass the result as an out-parameter. Passing as return value would require
5361 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5362 // invoke a copy constructor.
5363 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5364 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5365 {"Logical", LogicalTy},
5366 {StringRef(), QualType()}};
5367 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5368
5369 // Capture the initial iterator which represents the LoopVar value at the
5370 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5371 // it in every iteration, capture it by value before it is modified.
5372 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5373 bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5374 Sema::TryCapture_ExplicitByVal, {});
5375 (void)Invalid;
5376 assert(!Invalid && "Expecting capture-by-value to work.");
5377
5378 Expr *Body;
5379 {
5380 Sema::CompoundScopeRAII CompoundScope(Actions);
5381 auto *CS = cast<CapturedDecl>(Actions.CurContext);
5382
5383 ImplicitParamDecl *TargetParam = CS->getParam(0);
5384 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5385 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5386 ImplicitParamDecl *IndvarParam = CS->getParam(1);
5387 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5388 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5389
5390 // Capture the Start expression.
5391 CaptureVars Recap(Actions);
5392 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5393 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5394
5395 Expr *Skip = AssertSuccess(
5396 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5397 // TODO: Explicitly cast to the iterator's difference_type instead of
5398 // relying on implicit conversion.
5399 Expr *Advanced =
5400 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5401
5402 if (Deref) {
5403 // For range-based for-loops convert the loop counter value to a concrete
5404 // loop variable value by dereferencing the iterator.
5405 Advanced =
5406 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5407 }
5408
5409 // Assign the result to the output parameter.
5410 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5411 BO_Assign, TargetRef, Advanced));
5412 }
5413 return cast<CapturedStmt>(
5414 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5415 }
5416
ActOnOpenMPCanonicalLoop(Stmt * AStmt)5417 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5418 ASTContext &Ctx = getASTContext();
5419
5420 // Extract the common elements of ForStmt and CXXForRangeStmt:
5421 // Loop variable, repeat condition, increment
5422 Expr *Cond, *Inc;
5423 VarDecl *LIVDecl, *LUVDecl;
5424 if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5425 Stmt *Init = For->getInit();
5426 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5427 // For statement declares loop variable.
5428 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5429 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5430 // For statement reuses variable.
5431 assert(LCAssign->getOpcode() == BO_Assign &&
5432 "init part must be a loop variable assignment");
5433 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5434 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5435 } else
5436 llvm_unreachable("Cannot determine loop variable");
5437 LUVDecl = LIVDecl;
5438
5439 Cond = For->getCond();
5440 Inc = For->getInc();
5441 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5442 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5443 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5444 LUVDecl = RangeFor->getLoopVariable();
5445
5446 Cond = RangeFor->getCond();
5447 Inc = RangeFor->getInc();
5448 } else
5449 llvm_unreachable("unhandled kind of loop");
5450
5451 QualType CounterTy = LIVDecl->getType();
5452 QualType LVTy = LUVDecl->getType();
5453
5454 // Analyze the loop condition.
5455 Expr *LHS, *RHS;
5456 BinaryOperator::Opcode CondRel;
5457 Cond = Cond->IgnoreImplicit();
5458 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5459 LHS = CondBinExpr->getLHS();
5460 RHS = CondBinExpr->getRHS();
5461 CondRel = CondBinExpr->getOpcode();
5462 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5463 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5464 LHS = CondCXXOp->getArg(0);
5465 RHS = CondCXXOp->getArg(1);
5466 switch (CondCXXOp->getOperator()) {
5467 case OO_ExclaimEqual:
5468 CondRel = BO_NE;
5469 break;
5470 case OO_Less:
5471 CondRel = BO_LT;
5472 break;
5473 case OO_LessEqual:
5474 CondRel = BO_LE;
5475 break;
5476 case OO_Greater:
5477 CondRel = BO_GT;
5478 break;
5479 case OO_GreaterEqual:
5480 CondRel = BO_GE;
5481 break;
5482 default:
5483 llvm_unreachable("unexpected iterator operator");
5484 }
5485 } else
5486 llvm_unreachable("unexpected loop condition");
5487
5488 // Normalize such that the loop counter is on the LHS.
5489 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5490 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5491 std::swap(LHS, RHS);
5492 CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5493 }
5494 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5495
5496 // Decide the bit width for the logical iteration counter. By default use the
5497 // unsigned ptrdiff_t integer size (for iterators and pointers).
5498 // TODO: For iterators, use iterator::difference_type,
5499 // std::iterator_traits<>::difference_type or decltype(it - end).
5500 QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5501 if (CounterTy->isIntegerType()) {
5502 unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5503 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5504 }
5505
5506 // Analyze the loop increment.
5507 Expr *Step;
5508 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5509 int Direction;
5510 switch (IncUn->getOpcode()) {
5511 case UO_PreInc:
5512 case UO_PostInc:
5513 Direction = 1;
5514 break;
5515 case UO_PreDec:
5516 case UO_PostDec:
5517 Direction = -1;
5518 break;
5519 default:
5520 llvm_unreachable("unhandled unary increment operator");
5521 }
5522 Step = IntegerLiteral::Create(
5523 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5524 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5525 if (IncBin->getOpcode() == BO_AddAssign) {
5526 Step = IncBin->getRHS();
5527 } else if (IncBin->getOpcode() == BO_SubAssign) {
5528 Step =
5529 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5530 } else
5531 llvm_unreachable("unhandled binary increment operator");
5532 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5533 switch (CondCXXOp->getOperator()) {
5534 case OO_PlusPlus:
5535 Step = IntegerLiteral::Create(
5536 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5537 break;
5538 case OO_MinusMinus:
5539 Step = IntegerLiteral::Create(
5540 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5541 break;
5542 case OO_PlusEqual:
5543 Step = CondCXXOp->getArg(1);
5544 break;
5545 case OO_MinusEqual:
5546 Step = AssertSuccess(
5547 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5548 break;
5549 default:
5550 llvm_unreachable("unhandled overloaded increment operator");
5551 }
5552 } else
5553 llvm_unreachable("unknown increment expression");
5554
5555 CapturedStmt *DistanceFunc =
5556 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5557 CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5558 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5559 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5560 {}, nullptr, nullptr, {}, nullptr);
5561 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5562 LoopVarFunc, LVRef);
5563 }
5564
5565 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5566 CXXScopeSpec &MapperIdScopeSpec,
5567 const DeclarationNameInfo &MapperId,
5568 QualType Type,
5569 Expr *UnresolvedMapper);
5570
5571 /// Perform DFS through the structure/class data members trying to find
5572 /// member(s) with user-defined 'default' mapper and generate implicit map
5573 /// clauses for such members with the found 'default' mapper.
5574 static void
processImplicitMapsWithDefaultMappers(Sema & S,DSAStackTy * Stack,SmallVectorImpl<OMPClause * > & Clauses)5575 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5576 SmallVectorImpl<OMPClause *> &Clauses) {
5577 // Check for the deault mapper for data members.
5578 if (S.getLangOpts().OpenMP < 50)
5579 return;
5580 SmallVector<OMPClause *, 4> ImplicitMaps;
5581 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5582 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5583 if (!C)
5584 continue;
5585 SmallVector<Expr *, 4> SubExprs;
5586 auto *MI = C->mapperlist_begin();
5587 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5588 ++I, ++MI) {
5589 // Expression is mapped using mapper - skip it.
5590 if (*MI)
5591 continue;
5592 Expr *E = *I;
5593 // Expression is dependent - skip it, build the mapper when it gets
5594 // instantiated.
5595 if (E->isTypeDependent() || E->isValueDependent() ||
5596 E->containsUnexpandedParameterPack())
5597 continue;
5598 // Array section - need to check for the mapping of the array section
5599 // element.
5600 QualType CanonType = E->getType().getCanonicalType();
5601 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5602 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5603 QualType BaseType =
5604 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5605 QualType ElemType;
5606 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5607 ElemType = ATy->getElementType();
5608 else
5609 ElemType = BaseType->getPointeeType();
5610 CanonType = ElemType;
5611 }
5612
5613 // DFS over data members in structures/classes.
5614 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5615 1, {CanonType, nullptr});
5616 llvm::DenseMap<const Type *, Expr *> Visited;
5617 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5618 1, {nullptr, 1});
5619 while (!Types.empty()) {
5620 QualType BaseType;
5621 FieldDecl *CurFD;
5622 std::tie(BaseType, CurFD) = Types.pop_back_val();
5623 while (ParentChain.back().second == 0)
5624 ParentChain.pop_back();
5625 --ParentChain.back().second;
5626 if (BaseType.isNull())
5627 continue;
5628 // Only structs/classes are allowed to have mappers.
5629 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5630 if (!RD)
5631 continue;
5632 auto It = Visited.find(BaseType.getTypePtr());
5633 if (It == Visited.end()) {
5634 // Try to find the associated user-defined mapper.
5635 CXXScopeSpec MapperIdScopeSpec;
5636 DeclarationNameInfo DefaultMapperId;
5637 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5638 &S.Context.Idents.get("default")));
5639 DefaultMapperId.setLoc(E->getExprLoc());
5640 ExprResult ER = buildUserDefinedMapperRef(
5641 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5642 BaseType, /*UnresolvedMapper=*/nullptr);
5643 if (ER.isInvalid())
5644 continue;
5645 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5646 }
5647 // Found default mapper.
5648 if (It->second) {
5649 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5650 VK_LValue, OK_Ordinary, E);
5651 OE->setIsUnique(/*V=*/true);
5652 Expr *BaseExpr = OE;
5653 for (const auto &P : ParentChain) {
5654 if (P.first) {
5655 BaseExpr = S.BuildMemberExpr(
5656 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5657 NestedNameSpecifierLoc(), SourceLocation(), P.first,
5658 DeclAccessPair::make(P.first, P.first->getAccess()),
5659 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5660 P.first->getType(), VK_LValue, OK_Ordinary);
5661 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5662 }
5663 }
5664 if (CurFD)
5665 BaseExpr = S.BuildMemberExpr(
5666 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5667 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5668 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5669 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5670 CurFD->getType(), VK_LValue, OK_Ordinary);
5671 SubExprs.push_back(BaseExpr);
5672 continue;
5673 }
5674 // Check for the "default" mapper for data memebers.
5675 bool FirstIter = true;
5676 for (FieldDecl *FD : RD->fields()) {
5677 if (!FD)
5678 continue;
5679 QualType FieldTy = FD->getType();
5680 if (FieldTy.isNull() ||
5681 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5682 continue;
5683 if (FirstIter) {
5684 FirstIter = false;
5685 ParentChain.emplace_back(CurFD, 1);
5686 } else {
5687 ++ParentChain.back().second;
5688 }
5689 Types.emplace_back(FieldTy, FD);
5690 }
5691 }
5692 }
5693 if (SubExprs.empty())
5694 continue;
5695 CXXScopeSpec MapperIdScopeSpec;
5696 DeclarationNameInfo MapperId;
5697 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5698 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5699 MapperIdScopeSpec, MapperId, C->getMapType(),
5700 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5701 SubExprs, OMPVarListLocTy()))
5702 Clauses.push_back(NewClause);
5703 }
5704 }
5705
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5706 StmtResult Sema::ActOnOpenMPExecutableDirective(
5707 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5708 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5709 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5710 StmtResult Res = StmtError();
5711 // First check CancelRegion which is then used in checkNestingOfRegions.
5712 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5713 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5714 StartLoc))
5715 return StmtError();
5716
5717 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5718 VarsWithInheritedDSAType VarsWithInheritedDSA;
5719 bool ErrorFound = false;
5720 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5721 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5722 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5723 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5724 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5725
5726 // Check default data sharing attributes for referenced variables.
5727 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5728 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5729 Stmt *S = AStmt;
5730 while (--ThisCaptureLevel >= 0)
5731 S = cast<CapturedStmt>(S)->getCapturedStmt();
5732 DSAChecker.Visit(S);
5733 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5734 !isOpenMPTaskingDirective(Kind)) {
5735 // Visit subcaptures to generate implicit clauses for captured vars.
5736 auto *CS = cast<CapturedStmt>(AStmt);
5737 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5738 getOpenMPCaptureRegions(CaptureRegions, Kind);
5739 // Ignore outer tasking regions for target directives.
5740 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5741 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5742 DSAChecker.visitSubCaptures(CS);
5743 }
5744 if (DSAChecker.isErrorFound())
5745 return StmtError();
5746 // Generate list of implicitly defined firstprivate variables.
5747 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5748
5749 SmallVector<Expr *, 4> ImplicitFirstprivates(
5750 DSAChecker.getImplicitFirstprivate().begin(),
5751 DSAChecker.getImplicitFirstprivate().end());
5752 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5753 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5754 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5755 ImplicitMapModifiers[DefaultmapKindNum];
5756 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5757 ImplicitMapModifiersLoc[DefaultmapKindNum];
5758 // Get the original location of present modifier from Defaultmap clause.
5759 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5760 for (OMPClause *C : Clauses) {
5761 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5762 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5763 PresentModifierLocs[DMC->getDefaultmapKind()] =
5764 DMC->getDefaultmapModifierLoc();
5765 }
5766 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5767 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5768 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5769 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5770 Kind, static_cast<OpenMPMapClauseKind>(I));
5771 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5772 }
5773 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5774 DSAChecker.getImplicitMapModifier(Kind);
5775 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5776 ImplicitModifier.end());
5777 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5778 ImplicitModifier.size(), PresentModifierLocs[VC]);
5779 }
5780 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5781 for (OMPClause *C : Clauses) {
5782 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5783 for (Expr *E : IRC->taskgroup_descriptors())
5784 if (E)
5785 ImplicitFirstprivates.emplace_back(E);
5786 }
5787 // OpenMP 5.0, 2.10.1 task Construct
5788 // [detach clause]... The event-handle will be considered as if it was
5789 // specified on a firstprivate clause.
5790 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5791 ImplicitFirstprivates.push_back(DC->getEventHandler());
5792 }
5793 if (!ImplicitFirstprivates.empty()) {
5794 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5795 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5796 SourceLocation())) {
5797 ClausesWithImplicit.push_back(Implicit);
5798 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5799 ImplicitFirstprivates.size();
5800 } else {
5801 ErrorFound = true;
5802 }
5803 }
5804 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5805 int ClauseKindCnt = -1;
5806 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5807 ++ClauseKindCnt;
5808 if (ImplicitMap.empty())
5809 continue;
5810 CXXScopeSpec MapperIdScopeSpec;
5811 DeclarationNameInfo MapperId;
5812 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5813 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5814 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5815 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5816 SourceLocation(), SourceLocation(), ImplicitMap,
5817 OMPVarListLocTy())) {
5818 ClausesWithImplicit.emplace_back(Implicit);
5819 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5820 ImplicitMap.size();
5821 } else {
5822 ErrorFound = true;
5823 }
5824 }
5825 }
5826 // Build expressions for implicit maps of data members with 'default'
5827 // mappers.
5828 if (LangOpts.OpenMP >= 50)
5829 processImplicitMapsWithDefaultMappers(*this, DSAStack,
5830 ClausesWithImplicit);
5831 }
5832
5833 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5834 switch (Kind) {
5835 case OMPD_parallel:
5836 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5837 EndLoc);
5838 AllowedNameModifiers.push_back(OMPD_parallel);
5839 break;
5840 case OMPD_simd:
5841 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5842 VarsWithInheritedDSA);
5843 if (LangOpts.OpenMP >= 50)
5844 AllowedNameModifiers.push_back(OMPD_simd);
5845 break;
5846 case OMPD_tile:
5847 Res =
5848 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5849 break;
5850 case OMPD_for:
5851 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5852 VarsWithInheritedDSA);
5853 break;
5854 case OMPD_for_simd:
5855 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5856 EndLoc, VarsWithInheritedDSA);
5857 if (LangOpts.OpenMP >= 50)
5858 AllowedNameModifiers.push_back(OMPD_simd);
5859 break;
5860 case OMPD_sections:
5861 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5862 EndLoc);
5863 break;
5864 case OMPD_section:
5865 assert(ClausesWithImplicit.empty() &&
5866 "No clauses are allowed for 'omp section' directive");
5867 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5868 break;
5869 case OMPD_single:
5870 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5871 EndLoc);
5872 break;
5873 case OMPD_master:
5874 assert(ClausesWithImplicit.empty() &&
5875 "No clauses are allowed for 'omp master' directive");
5876 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5877 break;
5878 case OMPD_masked:
5879 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
5880 EndLoc);
5881 break;
5882 case OMPD_critical:
5883 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5884 StartLoc, EndLoc);
5885 break;
5886 case OMPD_parallel_for:
5887 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5888 EndLoc, VarsWithInheritedDSA);
5889 AllowedNameModifiers.push_back(OMPD_parallel);
5890 break;
5891 case OMPD_parallel_for_simd:
5892 Res = ActOnOpenMPParallelForSimdDirective(
5893 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5894 AllowedNameModifiers.push_back(OMPD_parallel);
5895 if (LangOpts.OpenMP >= 50)
5896 AllowedNameModifiers.push_back(OMPD_simd);
5897 break;
5898 case OMPD_parallel_master:
5899 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5900 StartLoc, EndLoc);
5901 AllowedNameModifiers.push_back(OMPD_parallel);
5902 break;
5903 case OMPD_parallel_sections:
5904 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5905 StartLoc, EndLoc);
5906 AllowedNameModifiers.push_back(OMPD_parallel);
5907 break;
5908 case OMPD_task:
5909 Res =
5910 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5911 AllowedNameModifiers.push_back(OMPD_task);
5912 break;
5913 case OMPD_taskyield:
5914 assert(ClausesWithImplicit.empty() &&
5915 "No clauses are allowed for 'omp taskyield' directive");
5916 assert(AStmt == nullptr &&
5917 "No associated statement allowed for 'omp taskyield' directive");
5918 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5919 break;
5920 case OMPD_barrier:
5921 assert(ClausesWithImplicit.empty() &&
5922 "No clauses are allowed for 'omp barrier' directive");
5923 assert(AStmt == nullptr &&
5924 "No associated statement allowed for 'omp barrier' directive");
5925 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5926 break;
5927 case OMPD_taskwait:
5928 assert(ClausesWithImplicit.empty() &&
5929 "No clauses are allowed for 'omp taskwait' directive");
5930 assert(AStmt == nullptr &&
5931 "No associated statement allowed for 'omp taskwait' directive");
5932 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5933 break;
5934 case OMPD_taskgroup:
5935 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5936 EndLoc);
5937 break;
5938 case OMPD_flush:
5939 assert(AStmt == nullptr &&
5940 "No associated statement allowed for 'omp flush' directive");
5941 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5942 break;
5943 case OMPD_depobj:
5944 assert(AStmt == nullptr &&
5945 "No associated statement allowed for 'omp depobj' directive");
5946 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5947 break;
5948 case OMPD_scan:
5949 assert(AStmt == nullptr &&
5950 "No associated statement allowed for 'omp scan' directive");
5951 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5952 break;
5953 case OMPD_ordered:
5954 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5955 EndLoc);
5956 break;
5957 case OMPD_atomic:
5958 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5959 EndLoc);
5960 break;
5961 case OMPD_teams:
5962 Res =
5963 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5964 break;
5965 case OMPD_target:
5966 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5967 EndLoc);
5968 AllowedNameModifiers.push_back(OMPD_target);
5969 break;
5970 case OMPD_target_parallel:
5971 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5972 StartLoc, EndLoc);
5973 AllowedNameModifiers.push_back(OMPD_target);
5974 AllowedNameModifiers.push_back(OMPD_parallel);
5975 break;
5976 case OMPD_target_parallel_for:
5977 Res = ActOnOpenMPTargetParallelForDirective(
5978 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5979 AllowedNameModifiers.push_back(OMPD_target);
5980 AllowedNameModifiers.push_back(OMPD_parallel);
5981 break;
5982 case OMPD_cancellation_point:
5983 assert(ClausesWithImplicit.empty() &&
5984 "No clauses are allowed for 'omp cancellation point' directive");
5985 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5986 "cancellation point' directive");
5987 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5988 break;
5989 case OMPD_cancel:
5990 assert(AStmt == nullptr &&
5991 "No associated statement allowed for 'omp cancel' directive");
5992 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5993 CancelRegion);
5994 AllowedNameModifiers.push_back(OMPD_cancel);
5995 break;
5996 case OMPD_target_data:
5997 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5998 EndLoc);
5999 AllowedNameModifiers.push_back(OMPD_target_data);
6000 break;
6001 case OMPD_target_enter_data:
6002 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6003 EndLoc, AStmt);
6004 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6005 break;
6006 case OMPD_target_exit_data:
6007 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6008 EndLoc, AStmt);
6009 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6010 break;
6011 case OMPD_taskloop:
6012 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6013 EndLoc, VarsWithInheritedDSA);
6014 AllowedNameModifiers.push_back(OMPD_taskloop);
6015 break;
6016 case OMPD_taskloop_simd:
6017 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6018 EndLoc, VarsWithInheritedDSA);
6019 AllowedNameModifiers.push_back(OMPD_taskloop);
6020 if (LangOpts.OpenMP >= 50)
6021 AllowedNameModifiers.push_back(OMPD_simd);
6022 break;
6023 case OMPD_master_taskloop:
6024 Res = ActOnOpenMPMasterTaskLoopDirective(
6025 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6026 AllowedNameModifiers.push_back(OMPD_taskloop);
6027 break;
6028 case OMPD_master_taskloop_simd:
6029 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6030 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6031 AllowedNameModifiers.push_back(OMPD_taskloop);
6032 if (LangOpts.OpenMP >= 50)
6033 AllowedNameModifiers.push_back(OMPD_simd);
6034 break;
6035 case OMPD_parallel_master_taskloop:
6036 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6037 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6038 AllowedNameModifiers.push_back(OMPD_taskloop);
6039 AllowedNameModifiers.push_back(OMPD_parallel);
6040 break;
6041 case OMPD_parallel_master_taskloop_simd:
6042 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6043 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6044 AllowedNameModifiers.push_back(OMPD_taskloop);
6045 AllowedNameModifiers.push_back(OMPD_parallel);
6046 if (LangOpts.OpenMP >= 50)
6047 AllowedNameModifiers.push_back(OMPD_simd);
6048 break;
6049 case OMPD_distribute:
6050 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6051 EndLoc, VarsWithInheritedDSA);
6052 break;
6053 case OMPD_target_update:
6054 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6055 EndLoc, AStmt);
6056 AllowedNameModifiers.push_back(OMPD_target_update);
6057 break;
6058 case OMPD_distribute_parallel_for:
6059 Res = ActOnOpenMPDistributeParallelForDirective(
6060 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6061 AllowedNameModifiers.push_back(OMPD_parallel);
6062 break;
6063 case OMPD_distribute_parallel_for_simd:
6064 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6065 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6066 AllowedNameModifiers.push_back(OMPD_parallel);
6067 if (LangOpts.OpenMP >= 50)
6068 AllowedNameModifiers.push_back(OMPD_simd);
6069 break;
6070 case OMPD_distribute_simd:
6071 Res = ActOnOpenMPDistributeSimdDirective(
6072 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6073 if (LangOpts.OpenMP >= 50)
6074 AllowedNameModifiers.push_back(OMPD_simd);
6075 break;
6076 case OMPD_target_parallel_for_simd:
6077 Res = ActOnOpenMPTargetParallelForSimdDirective(
6078 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6079 AllowedNameModifiers.push_back(OMPD_target);
6080 AllowedNameModifiers.push_back(OMPD_parallel);
6081 if (LangOpts.OpenMP >= 50)
6082 AllowedNameModifiers.push_back(OMPD_simd);
6083 break;
6084 case OMPD_target_simd:
6085 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6086 EndLoc, VarsWithInheritedDSA);
6087 AllowedNameModifiers.push_back(OMPD_target);
6088 if (LangOpts.OpenMP >= 50)
6089 AllowedNameModifiers.push_back(OMPD_simd);
6090 break;
6091 case OMPD_teams_distribute:
6092 Res = ActOnOpenMPTeamsDistributeDirective(
6093 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6094 break;
6095 case OMPD_teams_distribute_simd:
6096 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6097 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6098 if (LangOpts.OpenMP >= 50)
6099 AllowedNameModifiers.push_back(OMPD_simd);
6100 break;
6101 case OMPD_teams_distribute_parallel_for_simd:
6102 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6103 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6104 AllowedNameModifiers.push_back(OMPD_parallel);
6105 if (LangOpts.OpenMP >= 50)
6106 AllowedNameModifiers.push_back(OMPD_simd);
6107 break;
6108 case OMPD_teams_distribute_parallel_for:
6109 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6110 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6111 AllowedNameModifiers.push_back(OMPD_parallel);
6112 break;
6113 case OMPD_target_teams:
6114 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6115 EndLoc);
6116 AllowedNameModifiers.push_back(OMPD_target);
6117 break;
6118 case OMPD_target_teams_distribute:
6119 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6120 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6121 AllowedNameModifiers.push_back(OMPD_target);
6122 break;
6123 case OMPD_target_teams_distribute_parallel_for:
6124 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6125 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6126 AllowedNameModifiers.push_back(OMPD_target);
6127 AllowedNameModifiers.push_back(OMPD_parallel);
6128 break;
6129 case OMPD_target_teams_distribute_parallel_for_simd:
6130 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6131 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6132 AllowedNameModifiers.push_back(OMPD_target);
6133 AllowedNameModifiers.push_back(OMPD_parallel);
6134 if (LangOpts.OpenMP >= 50)
6135 AllowedNameModifiers.push_back(OMPD_simd);
6136 break;
6137 case OMPD_target_teams_distribute_simd:
6138 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6139 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6140 AllowedNameModifiers.push_back(OMPD_target);
6141 if (LangOpts.OpenMP >= 50)
6142 AllowedNameModifiers.push_back(OMPD_simd);
6143 break;
6144 case OMPD_interop:
6145 assert(AStmt == nullptr &&
6146 "No associated statement allowed for 'omp interop' directive");
6147 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6148 break;
6149 case OMPD_dispatch:
6150 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6151 EndLoc);
6152 break;
6153 case OMPD_declare_target:
6154 case OMPD_end_declare_target:
6155 case OMPD_threadprivate:
6156 case OMPD_allocate:
6157 case OMPD_declare_reduction:
6158 case OMPD_declare_mapper:
6159 case OMPD_declare_simd:
6160 case OMPD_requires:
6161 case OMPD_declare_variant:
6162 case OMPD_begin_declare_variant:
6163 case OMPD_end_declare_variant:
6164 llvm_unreachable("OpenMP Directive is not allowed");
6165 case OMPD_unknown:
6166 default:
6167 llvm_unreachable("Unknown OpenMP directive");
6168 }
6169
6170 ErrorFound = Res.isInvalid() || ErrorFound;
6171
6172 // Check variables in the clauses if default(none) or
6173 // default(firstprivate) was specified.
6174 if (DSAStack->getDefaultDSA() == DSA_none ||
6175 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6176 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6177 for (OMPClause *C : Clauses) {
6178 switch (C->getClauseKind()) {
6179 case OMPC_num_threads:
6180 case OMPC_dist_schedule:
6181 // Do not analyse if no parent teams directive.
6182 if (isOpenMPTeamsDirective(Kind))
6183 break;
6184 continue;
6185 case OMPC_if:
6186 if (isOpenMPTeamsDirective(Kind) &&
6187 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6188 break;
6189 if (isOpenMPParallelDirective(Kind) &&
6190 isOpenMPTaskLoopDirective(Kind) &&
6191 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6192 break;
6193 continue;
6194 case OMPC_schedule:
6195 case OMPC_detach:
6196 break;
6197 case OMPC_grainsize:
6198 case OMPC_num_tasks:
6199 case OMPC_final:
6200 case OMPC_priority:
6201 case OMPC_novariants:
6202 case OMPC_nocontext:
6203 // Do not analyze if no parent parallel directive.
6204 if (isOpenMPParallelDirective(Kind))
6205 break;
6206 continue;
6207 case OMPC_ordered:
6208 case OMPC_device:
6209 case OMPC_num_teams:
6210 case OMPC_thread_limit:
6211 case OMPC_hint:
6212 case OMPC_collapse:
6213 case OMPC_safelen:
6214 case OMPC_simdlen:
6215 case OMPC_sizes:
6216 case OMPC_default:
6217 case OMPC_proc_bind:
6218 case OMPC_private:
6219 case OMPC_firstprivate:
6220 case OMPC_lastprivate:
6221 case OMPC_shared:
6222 case OMPC_reduction:
6223 case OMPC_task_reduction:
6224 case OMPC_in_reduction:
6225 case OMPC_linear:
6226 case OMPC_aligned:
6227 case OMPC_copyin:
6228 case OMPC_copyprivate:
6229 case OMPC_nowait:
6230 case OMPC_untied:
6231 case OMPC_mergeable:
6232 case OMPC_allocate:
6233 case OMPC_read:
6234 case OMPC_write:
6235 case OMPC_update:
6236 case OMPC_capture:
6237 case OMPC_seq_cst:
6238 case OMPC_acq_rel:
6239 case OMPC_acquire:
6240 case OMPC_release:
6241 case OMPC_relaxed:
6242 case OMPC_depend:
6243 case OMPC_threads:
6244 case OMPC_simd:
6245 case OMPC_map:
6246 case OMPC_nogroup:
6247 case OMPC_defaultmap:
6248 case OMPC_to:
6249 case OMPC_from:
6250 case OMPC_use_device_ptr:
6251 case OMPC_use_device_addr:
6252 case OMPC_is_device_ptr:
6253 case OMPC_nontemporal:
6254 case OMPC_order:
6255 case OMPC_destroy:
6256 case OMPC_inclusive:
6257 case OMPC_exclusive:
6258 case OMPC_uses_allocators:
6259 case OMPC_affinity:
6260 continue;
6261 case OMPC_allocator:
6262 case OMPC_flush:
6263 case OMPC_depobj:
6264 case OMPC_threadprivate:
6265 case OMPC_uniform:
6266 case OMPC_unknown:
6267 case OMPC_unified_address:
6268 case OMPC_unified_shared_memory:
6269 case OMPC_reverse_offload:
6270 case OMPC_dynamic_allocators:
6271 case OMPC_atomic_default_mem_order:
6272 case OMPC_device_type:
6273 case OMPC_match:
6274 default:
6275 llvm_unreachable("Unexpected clause");
6276 }
6277 for (Stmt *CC : C->children()) {
6278 if (CC)
6279 DSAChecker.Visit(CC);
6280 }
6281 }
6282 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6283 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6284 }
6285 for (const auto &P : VarsWithInheritedDSA) {
6286 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6287 continue;
6288 ErrorFound = true;
6289 if (DSAStack->getDefaultDSA() == DSA_none ||
6290 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6291 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6292 << P.first << P.second->getSourceRange();
6293 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6294 } else if (getLangOpts().OpenMP >= 50) {
6295 Diag(P.second->getExprLoc(),
6296 diag::err_omp_defaultmap_no_attr_for_variable)
6297 << P.first << P.second->getSourceRange();
6298 Diag(DSAStack->getDefaultDSALocation(),
6299 diag::note_omp_defaultmap_attr_none);
6300 }
6301 }
6302
6303 if (!AllowedNameModifiers.empty())
6304 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6305 ErrorFound;
6306
6307 if (ErrorFound)
6308 return StmtError();
6309
6310 if (!CurContext->isDependentContext() &&
6311 isOpenMPTargetExecutionDirective(Kind) &&
6312 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6313 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6314 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6315 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6316 // Register target to DSA Stack.
6317 DSAStack->addTargetDirLocation(StartLoc);
6318 }
6319
6320 return Res;
6321 }
6322
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)6323 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6324 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6325 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6326 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6327 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6328 assert(Aligneds.size() == Alignments.size());
6329 assert(Linears.size() == LinModifiers.size());
6330 assert(Linears.size() == Steps.size());
6331 if (!DG || DG.get().isNull())
6332 return DeclGroupPtrTy();
6333
6334 const int SimdId = 0;
6335 if (!DG.get().isSingleDecl()) {
6336 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6337 << SimdId;
6338 return DG;
6339 }
6340 Decl *ADecl = DG.get().getSingleDecl();
6341 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6342 ADecl = FTD->getTemplatedDecl();
6343
6344 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6345 if (!FD) {
6346 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6347 return DeclGroupPtrTy();
6348 }
6349
6350 // OpenMP [2.8.2, declare simd construct, Description]
6351 // The parameter of the simdlen clause must be a constant positive integer
6352 // expression.
6353 ExprResult SL;
6354 if (Simdlen)
6355 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6356 // OpenMP [2.8.2, declare simd construct, Description]
6357 // The special this pointer can be used as if was one of the arguments to the
6358 // function in any of the linear, aligned, or uniform clauses.
6359 // The uniform clause declares one or more arguments to have an invariant
6360 // value for all concurrent invocations of the function in the execution of a
6361 // single SIMD loop.
6362 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6363 const Expr *UniformedLinearThis = nullptr;
6364 for (const Expr *E : Uniforms) {
6365 E = E->IgnoreParenImpCasts();
6366 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6367 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6368 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6369 FD->getParamDecl(PVD->getFunctionScopeIndex())
6370 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6371 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6372 continue;
6373 }
6374 if (isa<CXXThisExpr>(E)) {
6375 UniformedLinearThis = E;
6376 continue;
6377 }
6378 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6379 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6380 }
6381 // OpenMP [2.8.2, declare simd construct, Description]
6382 // The aligned clause declares that the object to which each list item points
6383 // is aligned to the number of bytes expressed in the optional parameter of
6384 // the aligned clause.
6385 // The special this pointer can be used as if was one of the arguments to the
6386 // function in any of the linear, aligned, or uniform clauses.
6387 // The type of list items appearing in the aligned clause must be array,
6388 // pointer, reference to array, or reference to pointer.
6389 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6390 const Expr *AlignedThis = nullptr;
6391 for (const Expr *E : Aligneds) {
6392 E = E->IgnoreParenImpCasts();
6393 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6394 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6395 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6396 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6397 FD->getParamDecl(PVD->getFunctionScopeIndex())
6398 ->getCanonicalDecl() == CanonPVD) {
6399 // OpenMP [2.8.1, simd construct, Restrictions]
6400 // A list-item cannot appear in more than one aligned clause.
6401 if (AlignedArgs.count(CanonPVD) > 0) {
6402 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6403 << 1 << getOpenMPClauseName(OMPC_aligned)
6404 << E->getSourceRange();
6405 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6406 diag::note_omp_explicit_dsa)
6407 << getOpenMPClauseName(OMPC_aligned);
6408 continue;
6409 }
6410 AlignedArgs[CanonPVD] = E;
6411 QualType QTy = PVD->getType()
6412 .getNonReferenceType()
6413 .getUnqualifiedType()
6414 .getCanonicalType();
6415 const Type *Ty = QTy.getTypePtrOrNull();
6416 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6417 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6418 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6419 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6420 }
6421 continue;
6422 }
6423 }
6424 if (isa<CXXThisExpr>(E)) {
6425 if (AlignedThis) {
6426 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6427 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6428 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6429 << getOpenMPClauseName(OMPC_aligned);
6430 }
6431 AlignedThis = E;
6432 continue;
6433 }
6434 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6435 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6436 }
6437 // The optional parameter of the aligned clause, alignment, must be a constant
6438 // positive integer expression. If no optional parameter is specified,
6439 // implementation-defined default alignments for SIMD instructions on the
6440 // target platforms are assumed.
6441 SmallVector<const Expr *, 4> NewAligns;
6442 for (Expr *E : Alignments) {
6443 ExprResult Align;
6444 if (E)
6445 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6446 NewAligns.push_back(Align.get());
6447 }
6448 // OpenMP [2.8.2, declare simd construct, Description]
6449 // The linear clause declares one or more list items to be private to a SIMD
6450 // lane and to have a linear relationship with respect to the iteration space
6451 // of a loop.
6452 // The special this pointer can be used as if was one of the arguments to the
6453 // function in any of the linear, aligned, or uniform clauses.
6454 // When a linear-step expression is specified in a linear clause it must be
6455 // either a constant integer expression or an integer-typed parameter that is
6456 // specified in a uniform clause on the directive.
6457 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6458 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6459 auto MI = LinModifiers.begin();
6460 for (const Expr *E : Linears) {
6461 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6462 ++MI;
6463 E = E->IgnoreParenImpCasts();
6464 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6465 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6466 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6467 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6468 FD->getParamDecl(PVD->getFunctionScopeIndex())
6469 ->getCanonicalDecl() == CanonPVD) {
6470 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6471 // A list-item cannot appear in more than one linear clause.
6472 if (LinearArgs.count(CanonPVD) > 0) {
6473 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6474 << getOpenMPClauseName(OMPC_linear)
6475 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6476 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6477 diag::note_omp_explicit_dsa)
6478 << getOpenMPClauseName(OMPC_linear);
6479 continue;
6480 }
6481 // Each argument can appear in at most one uniform or linear clause.
6482 if (UniformedArgs.count(CanonPVD) > 0) {
6483 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6484 << getOpenMPClauseName(OMPC_linear)
6485 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6486 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6487 diag::note_omp_explicit_dsa)
6488 << getOpenMPClauseName(OMPC_uniform);
6489 continue;
6490 }
6491 LinearArgs[CanonPVD] = E;
6492 if (E->isValueDependent() || E->isTypeDependent() ||
6493 E->isInstantiationDependent() ||
6494 E->containsUnexpandedParameterPack())
6495 continue;
6496 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6497 PVD->getOriginalType(),
6498 /*IsDeclareSimd=*/true);
6499 continue;
6500 }
6501 }
6502 if (isa<CXXThisExpr>(E)) {
6503 if (UniformedLinearThis) {
6504 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6505 << getOpenMPClauseName(OMPC_linear)
6506 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6507 << E->getSourceRange();
6508 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6509 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6510 : OMPC_linear);
6511 continue;
6512 }
6513 UniformedLinearThis = E;
6514 if (E->isValueDependent() || E->isTypeDependent() ||
6515 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6516 continue;
6517 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6518 E->getType(), /*IsDeclareSimd=*/true);
6519 continue;
6520 }
6521 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6522 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6523 }
6524 Expr *Step = nullptr;
6525 Expr *NewStep = nullptr;
6526 SmallVector<Expr *, 4> NewSteps;
6527 for (Expr *E : Steps) {
6528 // Skip the same step expression, it was checked already.
6529 if (Step == E || !E) {
6530 NewSteps.push_back(E ? NewStep : nullptr);
6531 continue;
6532 }
6533 Step = E;
6534 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6535 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6536 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6537 if (UniformedArgs.count(CanonPVD) == 0) {
6538 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6539 << Step->getSourceRange();
6540 } else if (E->isValueDependent() || E->isTypeDependent() ||
6541 E->isInstantiationDependent() ||
6542 E->containsUnexpandedParameterPack() ||
6543 CanonPVD->getType()->hasIntegerRepresentation()) {
6544 NewSteps.push_back(Step);
6545 } else {
6546 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6547 << Step->getSourceRange();
6548 }
6549 continue;
6550 }
6551 NewStep = Step;
6552 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6553 !Step->isInstantiationDependent() &&
6554 !Step->containsUnexpandedParameterPack()) {
6555 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6556 .get();
6557 if (NewStep)
6558 NewStep =
6559 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6560 }
6561 NewSteps.push_back(NewStep);
6562 }
6563 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6564 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6565 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6566 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6567 const_cast<Expr **>(Linears.data()), Linears.size(),
6568 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6569 NewSteps.data(), NewSteps.size(), SR);
6570 ADecl->addAttr(NewAttr);
6571 return DG;
6572 }
6573
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)6574 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6575 QualType NewType) {
6576 assert(NewType->isFunctionProtoType() &&
6577 "Expected function type with prototype.");
6578 assert(FD->getType()->isFunctionNoProtoType() &&
6579 "Expected function with type with no prototype.");
6580 assert(FDWithProto->getType()->isFunctionProtoType() &&
6581 "Expected function with prototype.");
6582 // Synthesize parameters with the same types.
6583 FD->setType(NewType);
6584 SmallVector<ParmVarDecl *, 16> Params;
6585 for (const ParmVarDecl *P : FDWithProto->parameters()) {
6586 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6587 SourceLocation(), nullptr, P->getType(),
6588 /*TInfo=*/nullptr, SC_None, nullptr);
6589 Param->setScopeInfo(0, Params.size());
6590 Param->setImplicit();
6591 Params.push_back(Param);
6592 }
6593
6594 FD->setParams(Params);
6595 }
6596
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl * D)6597 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6598 if (D->isInvalidDecl())
6599 return;
6600 FunctionDecl *FD = nullptr;
6601 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6602 FD = UTemplDecl->getTemplatedDecl();
6603 else
6604 FD = cast<FunctionDecl>(D);
6605 assert(FD && "Expected a function declaration!");
6606
6607 // If we are intantiating templates we do *not* apply scoped assumptions but
6608 // only global ones. We apply scoped assumption to the template definition
6609 // though.
6610 if (!inTemplateInstantiation()) {
6611 for (AssumptionAttr *AA : OMPAssumeScoped)
6612 FD->addAttr(AA);
6613 }
6614 for (AssumptionAttr *AA : OMPAssumeGlobal)
6615 FD->addAttr(AA);
6616 }
6617
OMPDeclareVariantScope(OMPTraitInfo & TI)6618 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6619 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6620
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)6621 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6622 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6623 SmallVectorImpl<FunctionDecl *> &Bases) {
6624 if (!D.getIdentifier())
6625 return;
6626
6627 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6628
6629 // Template specialization is an extension, check if we do it.
6630 bool IsTemplated = !TemplateParamLists.empty();
6631 if (IsTemplated &
6632 !DVScope.TI->isExtensionActive(
6633 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6634 return;
6635
6636 IdentifierInfo *BaseII = D.getIdentifier();
6637 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6638 LookupOrdinaryName);
6639 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6640
6641 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6642 QualType FType = TInfo->getType();
6643
6644 bool IsConstexpr =
6645 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6646 bool IsConsteval =
6647 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6648
6649 for (auto *Candidate : Lookup) {
6650 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6651 FunctionDecl *UDecl = nullptr;
6652 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6653 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6654 else if (!IsTemplated)
6655 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6656 if (!UDecl)
6657 continue;
6658
6659 // Don't specialize constexpr/consteval functions with
6660 // non-constexpr/consteval functions.
6661 if (UDecl->isConstexpr() && !IsConstexpr)
6662 continue;
6663 if (UDecl->isConsteval() && !IsConsteval)
6664 continue;
6665
6666 QualType UDeclTy = UDecl->getType();
6667 if (!UDeclTy->isDependentType()) {
6668 QualType NewType = Context.mergeFunctionTypes(
6669 FType, UDeclTy, /* OfBlockPointer */ false,
6670 /* Unqualified */ false, /* AllowCXX */ true);
6671 if (NewType.isNull())
6672 continue;
6673 }
6674
6675 // Found a base!
6676 Bases.push_back(UDecl);
6677 }
6678
6679 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6680 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6681 // If no base was found we create a declaration that we use as base.
6682 if (Bases.empty() && UseImplicitBase) {
6683 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6684 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6685 BaseD->setImplicit(true);
6686 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6687 Bases.push_back(BaseTemplD->getTemplatedDecl());
6688 else
6689 Bases.push_back(cast<FunctionDecl>(BaseD));
6690 }
6691
6692 std::string MangledName;
6693 MangledName += D.getIdentifier()->getName();
6694 MangledName += getOpenMPVariantManglingSeparatorStr();
6695 MangledName += DVScope.NameSuffix;
6696 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6697
6698 VariantII.setMangledOpenMPVariantName(true);
6699 D.SetIdentifier(&VariantII, D.getBeginLoc());
6700 }
6701
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)6702 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6703 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6704 // Do not mark function as is used to prevent its emission if this is the
6705 // only place where it is used.
6706 EnterExpressionEvaluationContext Unevaluated(
6707 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6708
6709 FunctionDecl *FD = nullptr;
6710 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6711 FD = UTemplDecl->getTemplatedDecl();
6712 else
6713 FD = cast<FunctionDecl>(D);
6714 auto *VariantFuncRef = DeclRefExpr::Create(
6715 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6716 /* RefersToEnclosingVariableOrCapture */ false,
6717 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
6718
6719 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6720 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6721 Context, VariantFuncRef, DVScope.TI);
6722 for (FunctionDecl *BaseFD : Bases)
6723 BaseFD->addAttr(OMPDeclareVariantA);
6724 }
6725
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)6726 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6727 SourceLocation LParenLoc,
6728 MultiExprArg ArgExprs,
6729 SourceLocation RParenLoc, Expr *ExecConfig) {
6730 // The common case is a regular call we do not want to specialize at all. Try
6731 // to make that case fast by bailing early.
6732 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6733 if (!CE)
6734 return Call;
6735
6736 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6737 if (!CalleeFnDecl)
6738 return Call;
6739
6740 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6741 return Call;
6742
6743 ASTContext &Context = getASTContext();
6744 std::function<void(StringRef)> DiagUnknownTrait = [this,
6745 CE](StringRef ISATrait) {
6746 // TODO Track the selector locations in a way that is accessible here to
6747 // improve the diagnostic location.
6748 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6749 << ISATrait;
6750 };
6751 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6752 getCurFunctionDecl());
6753
6754 QualType CalleeFnType = CalleeFnDecl->getType();
6755
6756 SmallVector<Expr *, 4> Exprs;
6757 SmallVector<VariantMatchInfo, 4> VMIs;
6758 while (CalleeFnDecl) {
6759 for (OMPDeclareVariantAttr *A :
6760 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6761 Expr *VariantRef = A->getVariantFuncRef();
6762
6763 VariantMatchInfo VMI;
6764 OMPTraitInfo &TI = A->getTraitInfo();
6765 TI.getAsVariantMatchInfo(Context, VMI);
6766 if (!isVariantApplicableInContext(VMI, OMPCtx,
6767 /* DeviceSetOnly */ false))
6768 continue;
6769
6770 VMIs.push_back(VMI);
6771 Exprs.push_back(VariantRef);
6772 }
6773
6774 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6775 }
6776
6777 ExprResult NewCall;
6778 do {
6779 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6780 if (BestIdx < 0)
6781 return Call;
6782 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6783 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6784
6785 {
6786 // Try to build a (member) call expression for the current best applicable
6787 // variant expression. We allow this to fail in which case we continue
6788 // with the next best variant expression. The fail case is part of the
6789 // implementation defined behavior in the OpenMP standard when it talks
6790 // about what differences in the function prototypes: "Any differences
6791 // that the specific OpenMP context requires in the prototype of the
6792 // variant from the base function prototype are implementation defined."
6793 // This wording is there to allow the specialized variant to have a
6794 // different type than the base function. This is intended and OK but if
6795 // we cannot create a call the difference is not in the "implementation
6796 // defined range" we allow.
6797 Sema::TentativeAnalysisScope Trap(*this);
6798
6799 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6800 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6801 BestExpr = MemberExpr::CreateImplicit(
6802 Context, MemberCall->getImplicitObjectArgument(),
6803 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6804 MemberCall->getValueKind(), MemberCall->getObjectKind());
6805 }
6806 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6807 ExecConfig);
6808 if (NewCall.isUsable()) {
6809 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6810 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6811 QualType NewType = Context.mergeFunctionTypes(
6812 CalleeFnType, NewCalleeFnDecl->getType(),
6813 /* OfBlockPointer */ false,
6814 /* Unqualified */ false, /* AllowCXX */ true);
6815 if (!NewType.isNull())
6816 break;
6817 // Don't use the call if the function type was not compatible.
6818 NewCall = nullptr;
6819 }
6820 }
6821 }
6822
6823 VMIs.erase(VMIs.begin() + BestIdx);
6824 Exprs.erase(Exprs.begin() + BestIdx);
6825 } while (!VMIs.empty());
6826
6827 if (!NewCall.isUsable())
6828 return Call;
6829 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6830 }
6831
6832 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6833 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6834 Expr *VariantRef, OMPTraitInfo &TI,
6835 SourceRange SR) {
6836 if (!DG || DG.get().isNull())
6837 return None;
6838
6839 const int VariantId = 1;
6840 // Must be applied only to single decl.
6841 if (!DG.get().isSingleDecl()) {
6842 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6843 << VariantId << SR;
6844 return None;
6845 }
6846 Decl *ADecl = DG.get().getSingleDecl();
6847 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6848 ADecl = FTD->getTemplatedDecl();
6849
6850 // Decl must be a function.
6851 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6852 if (!FD) {
6853 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6854 << VariantId << SR;
6855 return None;
6856 }
6857
6858 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6859 return FD->hasAttrs() &&
6860 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6861 FD->hasAttr<TargetAttr>());
6862 };
6863 // OpenMP is not compatible with CPU-specific attributes.
6864 if (HasMultiVersionAttributes(FD)) {
6865 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6866 << SR;
6867 return None;
6868 }
6869
6870 // Allow #pragma omp declare variant only if the function is not used.
6871 if (FD->isUsed(false))
6872 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6873 << FD->getLocation();
6874
6875 // Check if the function was emitted already.
6876 const FunctionDecl *Definition;
6877 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6878 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6879 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6880 << FD->getLocation();
6881
6882 // The VariantRef must point to function.
6883 if (!VariantRef) {
6884 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6885 return None;
6886 }
6887
6888 auto ShouldDelayChecks = [](Expr *&E, bool) {
6889 return E && (E->isTypeDependent() || E->isValueDependent() ||
6890 E->containsUnexpandedParameterPack() ||
6891 E->isInstantiationDependent());
6892 };
6893 // Do not check templates, wait until instantiation.
6894 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6895 TI.anyScoreOrCondition(ShouldDelayChecks))
6896 return std::make_pair(FD, VariantRef);
6897
6898 // Deal with non-constant score and user condition expressions.
6899 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6900 bool IsScore) -> bool {
6901 if (!E || E->isIntegerConstantExpr(Context))
6902 return false;
6903
6904 if (IsScore) {
6905 // We warn on non-constant scores and pretend they were not present.
6906 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6907 << E;
6908 E = nullptr;
6909 } else {
6910 // We could replace a non-constant user condition with "false" but we
6911 // will soon need to handle these anyway for the dynamic version of
6912 // OpenMP context selectors.
6913 Diag(E->getExprLoc(),
6914 diag::err_omp_declare_variant_user_condition_not_constant)
6915 << E;
6916 }
6917 return true;
6918 };
6919 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6920 return None;
6921
6922 // Convert VariantRef expression to the type of the original function to
6923 // resolve possible conflicts.
6924 ExprResult VariantRefCast = VariantRef;
6925 if (LangOpts.CPlusPlus) {
6926 QualType FnPtrType;
6927 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6928 if (Method && !Method->isStatic()) {
6929 const Type *ClassType =
6930 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6931 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6932 ExprResult ER;
6933 {
6934 // Build adrr_of unary op to correctly handle type checks for member
6935 // functions.
6936 Sema::TentativeAnalysisScope Trap(*this);
6937 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6938 VariantRef);
6939 }
6940 if (!ER.isUsable()) {
6941 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6942 << VariantId << VariantRef->getSourceRange();
6943 return None;
6944 }
6945 VariantRef = ER.get();
6946 } else {
6947 FnPtrType = Context.getPointerType(FD->getType());
6948 }
6949 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6950 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6951 ImplicitConversionSequence ICS = TryImplicitConversion(
6952 VariantRef, FnPtrType.getUnqualifiedType(),
6953 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6954 /*InOverloadResolution=*/false,
6955 /*CStyle=*/false,
6956 /*AllowObjCWritebackConversion=*/false);
6957 if (ICS.isFailure()) {
6958 Diag(VariantRef->getExprLoc(),
6959 diag::err_omp_declare_variant_incompat_types)
6960 << VariantRef->getType()
6961 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6962 << VariantRef->getSourceRange();
6963 return None;
6964 }
6965 VariantRefCast = PerformImplicitConversion(
6966 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6967 if (!VariantRefCast.isUsable())
6968 return None;
6969 }
6970 // Drop previously built artificial addr_of unary op for member functions.
6971 if (Method && !Method->isStatic()) {
6972 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6973 if (auto *UO = dyn_cast<UnaryOperator>(
6974 PossibleAddrOfVariantRef->IgnoreImplicit()))
6975 VariantRefCast = UO->getSubExpr();
6976 }
6977 }
6978
6979 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6980 if (!ER.isUsable() ||
6981 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6982 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6983 << VariantId << VariantRef->getSourceRange();
6984 return None;
6985 }
6986
6987 // The VariantRef must point to function.
6988 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6989 if (!DRE) {
6990 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6991 << VariantId << VariantRef->getSourceRange();
6992 return None;
6993 }
6994 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6995 if (!NewFD) {
6996 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6997 << VariantId << VariantRef->getSourceRange();
6998 return None;
6999 }
7000
7001 // Check if function types are compatible in C.
7002 if (!LangOpts.CPlusPlus) {
7003 QualType NewType =
7004 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
7005 if (NewType.isNull()) {
7006 Diag(VariantRef->getExprLoc(),
7007 diag::err_omp_declare_variant_incompat_types)
7008 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
7009 return None;
7010 }
7011 if (NewType->isFunctionProtoType()) {
7012 if (FD->getType()->isFunctionNoProtoType())
7013 setPrototype(*this, FD, NewFD, NewType);
7014 else if (NewFD->getType()->isFunctionNoProtoType())
7015 setPrototype(*this, NewFD, FD, NewType);
7016 }
7017 }
7018
7019 // Check if variant function is not marked with declare variant directive.
7020 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7021 Diag(VariantRef->getExprLoc(),
7022 diag::warn_omp_declare_variant_marked_as_declare_variant)
7023 << VariantRef->getSourceRange();
7024 SourceRange SR =
7025 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7026 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7027 return None;
7028 }
7029
7030 enum DoesntSupport {
7031 VirtFuncs = 1,
7032 Constructors = 3,
7033 Destructors = 4,
7034 DeletedFuncs = 5,
7035 DefaultedFuncs = 6,
7036 ConstexprFuncs = 7,
7037 ConstevalFuncs = 8,
7038 };
7039 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7040 if (CXXFD->isVirtual()) {
7041 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7042 << VirtFuncs;
7043 return None;
7044 }
7045
7046 if (isa<CXXConstructorDecl>(FD)) {
7047 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7048 << Constructors;
7049 return None;
7050 }
7051
7052 if (isa<CXXDestructorDecl>(FD)) {
7053 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7054 << Destructors;
7055 return None;
7056 }
7057 }
7058
7059 if (FD->isDeleted()) {
7060 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7061 << DeletedFuncs;
7062 return None;
7063 }
7064
7065 if (FD->isDefaulted()) {
7066 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7067 << DefaultedFuncs;
7068 return None;
7069 }
7070
7071 if (FD->isConstexpr()) {
7072 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7073 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7074 return None;
7075 }
7076
7077 // Check general compatibility.
7078 if (areMultiversionVariantFunctionsCompatible(
7079 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7080 PartialDiagnosticAt(SourceLocation(),
7081 PartialDiagnostic::NullDiagnostic()),
7082 PartialDiagnosticAt(
7083 VariantRef->getExprLoc(),
7084 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7085 PartialDiagnosticAt(VariantRef->getExprLoc(),
7086 PDiag(diag::err_omp_declare_variant_diff)
7087 << FD->getLocation()),
7088 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7089 /*CLinkageMayDiffer=*/true))
7090 return None;
7091 return std::make_pair(FD, cast<Expr>(DRE));
7092 }
7093
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)7094 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
7095 Expr *VariantRef,
7096 OMPTraitInfo &TI,
7097 SourceRange SR) {
7098 auto *NewAttr =
7099 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
7100 FD->addAttr(NewAttr);
7101 }
7102
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7103 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7104 Stmt *AStmt,
7105 SourceLocation StartLoc,
7106 SourceLocation EndLoc) {
7107 if (!AStmt)
7108 return StmtError();
7109
7110 auto *CS = cast<CapturedStmt>(AStmt);
7111 // 1.2.2 OpenMP Language Terminology
7112 // Structured block - An executable statement with a single entry at the
7113 // top and a single exit at the bottom.
7114 // The point of exit cannot be a branch out of the structured block.
7115 // longjmp() and throw() must not violate the entry/exit criteria.
7116 CS->getCapturedDecl()->setNothrow();
7117
7118 setFunctionHasBranchProtectedScope();
7119
7120 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7121 DSAStack->getTaskgroupReductionRef(),
7122 DSAStack->isCancelRegion());
7123 }
7124
7125 namespace {
7126 /// Iteration space of a single for loop.
7127 struct LoopIterationSpace final {
7128 /// True if the condition operator is the strict compare operator (<, > or
7129 /// !=).
7130 bool IsStrictCompare = false;
7131 /// Condition of the loop.
7132 Expr *PreCond = nullptr;
7133 /// This expression calculates the number of iterations in the loop.
7134 /// It is always possible to calculate it before starting the loop.
7135 Expr *NumIterations = nullptr;
7136 /// The loop counter variable.
7137 Expr *CounterVar = nullptr;
7138 /// Private loop counter variable.
7139 Expr *PrivateCounterVar = nullptr;
7140 /// This is initializer for the initial value of #CounterVar.
7141 Expr *CounterInit = nullptr;
7142 /// This is step for the #CounterVar used to generate its update:
7143 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7144 Expr *CounterStep = nullptr;
7145 /// Should step be subtracted?
7146 bool Subtract = false;
7147 /// Source range of the loop init.
7148 SourceRange InitSrcRange;
7149 /// Source range of the loop condition.
7150 SourceRange CondSrcRange;
7151 /// Source range of the loop increment.
7152 SourceRange IncSrcRange;
7153 /// Minimum value that can have the loop control variable. Used to support
7154 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7155 /// since only such variables can be used in non-loop invariant expressions.
7156 Expr *MinValue = nullptr;
7157 /// Maximum value that can have the loop control variable. Used to support
7158 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7159 /// since only such variables can be used in non-loop invariant expressions.
7160 Expr *MaxValue = nullptr;
7161 /// true, if the lower bound depends on the outer loop control var.
7162 bool IsNonRectangularLB = false;
7163 /// true, if the upper bound depends on the outer loop control var.
7164 bool IsNonRectangularUB = false;
7165 /// Index of the loop this loop depends on and forms non-rectangular loop
7166 /// nest.
7167 unsigned LoopDependentIdx = 0;
7168 /// Final condition for the non-rectangular loop nest support. It is used to
7169 /// check that the number of iterations for this particular counter must be
7170 /// finished.
7171 Expr *FinalCondition = nullptr;
7172 };
7173
7174 /// Helper class for checking canonical form of the OpenMP loops and
7175 /// extracting iteration space of each loop in the loop nest, that will be used
7176 /// for IR generation.
7177 class OpenMPIterationSpaceChecker {
7178 /// Reference to Sema.
7179 Sema &SemaRef;
7180 /// Does the loop associated directive support non-rectangular loops?
7181 bool SupportsNonRectangular;
7182 /// Data-sharing stack.
7183 DSAStackTy &Stack;
7184 /// A location for diagnostics (when there is no some better location).
7185 SourceLocation DefaultLoc;
7186 /// A location for diagnostics (when increment is not compatible).
7187 SourceLocation ConditionLoc;
7188 /// A source location for referring to loop init later.
7189 SourceRange InitSrcRange;
7190 /// A source location for referring to condition later.
7191 SourceRange ConditionSrcRange;
7192 /// A source location for referring to increment later.
7193 SourceRange IncrementSrcRange;
7194 /// Loop variable.
7195 ValueDecl *LCDecl = nullptr;
7196 /// Reference to loop variable.
7197 Expr *LCRef = nullptr;
7198 /// Lower bound (initializer for the var).
7199 Expr *LB = nullptr;
7200 /// Upper bound.
7201 Expr *UB = nullptr;
7202 /// Loop step (increment).
7203 Expr *Step = nullptr;
7204 /// This flag is true when condition is one of:
7205 /// Var < UB
7206 /// Var <= UB
7207 /// UB > Var
7208 /// UB >= Var
7209 /// This will have no value when the condition is !=
7210 llvm::Optional<bool> TestIsLessOp;
7211 /// This flag is true when condition is strict ( < or > ).
7212 bool TestIsStrictOp = false;
7213 /// This flag is true when step is subtracted on each iteration.
7214 bool SubtractStep = false;
7215 /// The outer loop counter this loop depends on (if any).
7216 const ValueDecl *DepDecl = nullptr;
7217 /// Contains number of loop (starts from 1) on which loop counter init
7218 /// expression of this loop depends on.
7219 Optional<unsigned> InitDependOnLC;
7220 /// Contains number of loop (starts from 1) on which loop counter condition
7221 /// expression of this loop depends on.
7222 Optional<unsigned> CondDependOnLC;
7223 /// Checks if the provide statement depends on the loop counter.
7224 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7225 /// Original condition required for checking of the exit condition for
7226 /// non-rectangular loop.
7227 Expr *Condition = nullptr;
7228
7229 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,bool SupportsNonRectangular,DSAStackTy & Stack,SourceLocation DefaultLoc)7230 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7231 DSAStackTy &Stack, SourceLocation DefaultLoc)
7232 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7233 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7234 /// Check init-expr for canonical loop form and save loop counter
7235 /// variable - #Var and its initialization value - #LB.
7236 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7237 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7238 /// for less/greater and for strict/non-strict comparison.
7239 bool checkAndSetCond(Expr *S);
7240 /// Check incr-expr for canonical loop form and return true if it
7241 /// does not conform, otherwise save loop step (#Step).
7242 bool checkAndSetInc(Expr *S);
7243 /// Return the loop counter variable.
getLoopDecl() const7244 ValueDecl *getLoopDecl() const { return LCDecl; }
7245 /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const7246 Expr *getLoopDeclRefExpr() const { return LCRef; }
7247 /// Source range of the loop init.
getInitSrcRange() const7248 SourceRange getInitSrcRange() const { return InitSrcRange; }
7249 /// Source range of the loop condition.
getConditionSrcRange() const7250 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7251 /// Source range of the loop increment.
getIncrementSrcRange() const7252 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7253 /// True if the step should be subtracted.
shouldSubtractStep() const7254 bool shouldSubtractStep() const { return SubtractStep; }
7255 /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const7256 bool isStrictTestOp() const { return TestIsStrictOp; }
7257 /// Build the expression to calculate the number of iterations.
7258 Expr *buildNumIterations(
7259 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7260 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7261 /// Build the precondition expression for the loops.
7262 Expr *
7263 buildPreCond(Scope *S, Expr *Cond,
7264 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7265 /// Build reference expression to the counter be used for codegen.
7266 DeclRefExpr *
7267 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7268 DSAStackTy &DSA) const;
7269 /// Build reference expression to the private counter be used for
7270 /// codegen.
7271 Expr *buildPrivateCounterVar() const;
7272 /// Build initialization of the counter be used for codegen.
7273 Expr *buildCounterInit() const;
7274 /// Build step of the counter be used for codegen.
7275 Expr *buildCounterStep() const;
7276 /// Build loop data with counter value for depend clauses in ordered
7277 /// directives.
7278 Expr *
7279 buildOrderedLoopData(Scope *S, Expr *Counter,
7280 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7281 SourceLocation Loc, Expr *Inc = nullptr,
7282 OverloadedOperatorKind OOK = OO_Amp);
7283 /// Builds the minimum value for the loop counter.
7284 std::pair<Expr *, Expr *> buildMinMaxValues(
7285 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7286 /// Builds final condition for the non-rectangular loops.
7287 Expr *buildFinalCondition(Scope *S) const;
7288 /// Return true if any expression is dependent.
7289 bool dependent() const;
7290 /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const7291 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7292 /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const7293 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7294 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const7295 unsigned getLoopDependentIdx() const {
7296 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7297 }
7298
7299 private:
7300 /// Check the right-hand side of an assignment in the increment
7301 /// expression.
7302 bool checkAndSetIncRHS(Expr *RHS);
7303 /// Helper to set loop counter variable and its initializer.
7304 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7305 bool EmitDiags);
7306 /// Helper to set upper bound.
7307 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7308 SourceRange SR, SourceLocation SL);
7309 /// Helper to set loop increment.
7310 bool setStep(Expr *NewStep, bool Subtract);
7311 };
7312
dependent() const7313 bool OpenMPIterationSpaceChecker::dependent() const {
7314 if (!LCDecl) {
7315 assert(!LB && !UB && !Step);
7316 return false;
7317 }
7318 return LCDecl->getType()->isDependentType() ||
7319 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7320 (Step && Step->isValueDependent());
7321 }
7322
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)7323 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7324 Expr *NewLCRefExpr,
7325 Expr *NewLB, bool EmitDiags) {
7326 // State consistency checking to ensure correct usage.
7327 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7328 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7329 if (!NewLCDecl || !NewLB)
7330 return true;
7331 LCDecl = getCanonicalDecl(NewLCDecl);
7332 LCRef = NewLCRefExpr;
7333 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7334 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7335 if ((Ctor->isCopyOrMoveConstructor() ||
7336 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7337 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7338 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7339 LB = NewLB;
7340 if (EmitDiags)
7341 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7342 return false;
7343 }
7344
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)7345 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7346 llvm::Optional<bool> LessOp,
7347 bool StrictOp, SourceRange SR,
7348 SourceLocation SL) {
7349 // State consistency checking to ensure correct usage.
7350 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7351 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7352 if (!NewUB)
7353 return true;
7354 UB = NewUB;
7355 if (LessOp)
7356 TestIsLessOp = LessOp;
7357 TestIsStrictOp = StrictOp;
7358 ConditionSrcRange = SR;
7359 ConditionLoc = SL;
7360 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7361 return false;
7362 }
7363
setStep(Expr * NewStep,bool Subtract)7364 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7365 // State consistency checking to ensure correct usage.
7366 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7367 if (!NewStep)
7368 return true;
7369 if (!NewStep->isValueDependent()) {
7370 // Check that the step is integer expression.
7371 SourceLocation StepLoc = NewStep->getBeginLoc();
7372 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7373 StepLoc, getExprAsWritten(NewStep));
7374 if (Val.isInvalid())
7375 return true;
7376 NewStep = Val.get();
7377
7378 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7379 // If test-expr is of form var relational-op b and relational-op is < or
7380 // <= then incr-expr must cause var to increase on each iteration of the
7381 // loop. If test-expr is of form var relational-op b and relational-op is
7382 // > or >= then incr-expr must cause var to decrease on each iteration of
7383 // the loop.
7384 // If test-expr is of form b relational-op var and relational-op is < or
7385 // <= then incr-expr must cause var to decrease on each iteration of the
7386 // loop. If test-expr is of form b relational-op var and relational-op is
7387 // > or >= then incr-expr must cause var to increase on each iteration of
7388 // the loop.
7389 Optional<llvm::APSInt> Result =
7390 NewStep->getIntegerConstantExpr(SemaRef.Context);
7391 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7392 bool IsConstNeg =
7393 Result && Result->isSigned() && (Subtract != Result->isNegative());
7394 bool IsConstPos =
7395 Result && Result->isSigned() && (Subtract == Result->isNegative());
7396 bool IsConstZero = Result && !Result->getBoolValue();
7397
7398 // != with increment is treated as <; != with decrement is treated as >
7399 if (!TestIsLessOp.hasValue())
7400 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7401 if (UB && (IsConstZero ||
7402 (TestIsLessOp.getValue() ?
7403 (IsConstNeg || (IsUnsigned && Subtract)) :
7404 (IsConstPos || (IsUnsigned && !Subtract))))) {
7405 SemaRef.Diag(NewStep->getExprLoc(),
7406 diag::err_omp_loop_incr_not_compatible)
7407 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7408 SemaRef.Diag(ConditionLoc,
7409 diag::note_omp_loop_cond_requres_compatible_incr)
7410 << TestIsLessOp.getValue() << ConditionSrcRange;
7411 return true;
7412 }
7413 if (TestIsLessOp.getValue() == Subtract) {
7414 NewStep =
7415 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7416 .get();
7417 Subtract = !Subtract;
7418 }
7419 }
7420
7421 Step = NewStep;
7422 SubtractStep = Subtract;
7423 return false;
7424 }
7425
7426 namespace {
7427 /// Checker for the non-rectangular loops. Checks if the initializer or
7428 /// condition expression references loop counter variable.
7429 class LoopCounterRefChecker final
7430 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7431 Sema &SemaRef;
7432 DSAStackTy &Stack;
7433 const ValueDecl *CurLCDecl = nullptr;
7434 const ValueDecl *DepDecl = nullptr;
7435 const ValueDecl *PrevDepDecl = nullptr;
7436 bool IsInitializer = true;
7437 bool SupportsNonRectangular;
7438 unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)7439 bool checkDecl(const Expr *E, const ValueDecl *VD) {
7440 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7441 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7442 << (IsInitializer ? 0 : 1);
7443 return false;
7444 }
7445 const auto &&Data = Stack.isLoopControlVariable(VD);
7446 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7447 // The type of the loop iterator on which we depend may not have a random
7448 // access iterator type.
7449 if (Data.first && VD->getType()->isRecordType()) {
7450 SmallString<128> Name;
7451 llvm::raw_svector_ostream OS(Name);
7452 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7453 /*Qualified=*/true);
7454 SemaRef.Diag(E->getExprLoc(),
7455 diag::err_omp_wrong_dependency_iterator_type)
7456 << OS.str();
7457 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7458 return false;
7459 }
7460 if (Data.first && !SupportsNonRectangular) {
7461 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7462 return false;
7463 }
7464 if (Data.first &&
7465 (DepDecl || (PrevDepDecl &&
7466 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7467 if (!DepDecl && PrevDepDecl)
7468 DepDecl = PrevDepDecl;
7469 SmallString<128> Name;
7470 llvm::raw_svector_ostream OS(Name);
7471 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7472 /*Qualified=*/true);
7473 SemaRef.Diag(E->getExprLoc(),
7474 diag::err_omp_invariant_or_linear_dependency)
7475 << OS.str();
7476 return false;
7477 }
7478 if (Data.first) {
7479 DepDecl = VD;
7480 BaseLoopId = Data.first;
7481 }
7482 return Data.first;
7483 }
7484
7485 public:
VisitDeclRefExpr(const DeclRefExpr * E)7486 bool VisitDeclRefExpr(const DeclRefExpr *E) {
7487 const ValueDecl *VD = E->getDecl();
7488 if (isa<VarDecl>(VD))
7489 return checkDecl(E, VD);
7490 return false;
7491 }
VisitMemberExpr(const MemberExpr * E)7492 bool VisitMemberExpr(const MemberExpr *E) {
7493 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7494 const ValueDecl *VD = E->getMemberDecl();
7495 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7496 return checkDecl(E, VD);
7497 }
7498 return false;
7499 }
VisitStmt(const Stmt * S)7500 bool VisitStmt(const Stmt *S) {
7501 bool Res = false;
7502 for (const Stmt *Child : S->children())
7503 Res = (Child && Visit(Child)) || Res;
7504 return Res;
7505 }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr,bool SupportsNonRectangular=true)7506 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7507 const ValueDecl *CurLCDecl, bool IsInitializer,
7508 const ValueDecl *PrevDepDecl = nullptr,
7509 bool SupportsNonRectangular = true)
7510 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7511 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7512 SupportsNonRectangular(SupportsNonRectangular) {}
getBaseLoopId() const7513 unsigned getBaseLoopId() const {
7514 assert(CurLCDecl && "Expected loop dependency.");
7515 return BaseLoopId;
7516 }
getDepDecl() const7517 const ValueDecl *getDepDecl() const {
7518 assert(CurLCDecl && "Expected loop dependency.");
7519 return DepDecl;
7520 }
7521 };
7522 } // namespace
7523
7524 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)7525 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7526 bool IsInitializer) {
7527 // Check for the non-rectangular loops.
7528 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7529 DepDecl, SupportsNonRectangular);
7530 if (LoopStmtChecker.Visit(S)) {
7531 DepDecl = LoopStmtChecker.getDepDecl();
7532 return LoopStmtChecker.getBaseLoopId();
7533 }
7534 return llvm::None;
7535 }
7536
checkAndSetInit(Stmt * S,bool EmitDiags)7537 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7538 // Check init-expr for canonical loop form and save loop counter
7539 // variable - #Var and its initialization value - #LB.
7540 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7541 // var = lb
7542 // integer-type var = lb
7543 // random-access-iterator-type var = lb
7544 // pointer-type var = lb
7545 //
7546 if (!S) {
7547 if (EmitDiags) {
7548 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7549 }
7550 return true;
7551 }
7552 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7553 if (!ExprTemp->cleanupsHaveSideEffects())
7554 S = ExprTemp->getSubExpr();
7555
7556 InitSrcRange = S->getSourceRange();
7557 if (Expr *E = dyn_cast<Expr>(S))
7558 S = E->IgnoreParens();
7559 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7560 if (BO->getOpcode() == BO_Assign) {
7561 Expr *LHS = BO->getLHS()->IgnoreParens();
7562 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7563 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7564 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7565 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7566 EmitDiags);
7567 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7568 }
7569 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7570 if (ME->isArrow() &&
7571 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7572 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7573 EmitDiags);
7574 }
7575 }
7576 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7577 if (DS->isSingleDecl()) {
7578 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7579 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7580 // Accept non-canonical init form here but emit ext. warning.
7581 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7582 SemaRef.Diag(S->getBeginLoc(),
7583 diag::ext_omp_loop_not_canonical_init)
7584 << S->getSourceRange();
7585 return setLCDeclAndLB(
7586 Var,
7587 buildDeclRefExpr(SemaRef, Var,
7588 Var->getType().getNonReferenceType(),
7589 DS->getBeginLoc()),
7590 Var->getInit(), EmitDiags);
7591 }
7592 }
7593 }
7594 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7595 if (CE->getOperator() == OO_Equal) {
7596 Expr *LHS = CE->getArg(0);
7597 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7598 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7599 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7600 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7601 EmitDiags);
7602 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7603 }
7604 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7605 if (ME->isArrow() &&
7606 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7607 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7608 EmitDiags);
7609 }
7610 }
7611 }
7612
7613 if (dependent() || SemaRef.CurContext->isDependentContext())
7614 return false;
7615 if (EmitDiags) {
7616 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7617 << S->getSourceRange();
7618 }
7619 return true;
7620 }
7621
7622 /// Ignore parenthesizes, implicit casts, copy constructor and return the
7623 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)7624 static const ValueDecl *getInitLCDecl(const Expr *E) {
7625 if (!E)
7626 return nullptr;
7627 E = getExprAsWritten(E);
7628 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7629 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7630 if ((Ctor->isCopyOrMoveConstructor() ||
7631 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7632 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7633 E = CE->getArg(0)->IgnoreParenImpCasts();
7634 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7635 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7636 return getCanonicalDecl(VD);
7637 }
7638 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7639 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7640 return getCanonicalDecl(ME->getMemberDecl());
7641 return nullptr;
7642 }
7643
checkAndSetCond(Expr * S)7644 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7645 // Check test-expr for canonical form, save upper-bound UB, flags for
7646 // less/greater and for strict/non-strict comparison.
7647 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7648 // var relational-op b
7649 // b relational-op var
7650 //
7651 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7652 if (!S) {
7653 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7654 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7655 return true;
7656 }
7657 Condition = S;
7658 S = getExprAsWritten(S);
7659 SourceLocation CondLoc = S->getBeginLoc();
7660 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7661 if (BO->isRelationalOp()) {
7662 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7663 return setUB(BO->getRHS(),
7664 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
7665 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7666 BO->getSourceRange(), BO->getOperatorLoc());
7667 if (getInitLCDecl(BO->getRHS()) == LCDecl)
7668 return setUB(BO->getLHS(),
7669 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
7670 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7671 BO->getSourceRange(), BO->getOperatorLoc());
7672 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
7673 return setUB(
7674 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
7675 /*LessOp=*/llvm::None,
7676 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
7677 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7678 if (CE->getNumArgs() == 2) {
7679 auto Op = CE->getOperator();
7680 switch (Op) {
7681 case OO_Greater:
7682 case OO_GreaterEqual:
7683 case OO_Less:
7684 case OO_LessEqual:
7685 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7686 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
7687 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7688 CE->getOperatorLoc());
7689 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
7690 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
7691 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7692 CE->getOperatorLoc());
7693 break;
7694 case OO_ExclaimEqual:
7695 if (IneqCondIsCanonical)
7696 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
7697 : CE->getArg(0),
7698 /*LessOp=*/llvm::None,
7699 /*StrictOp=*/true, CE->getSourceRange(),
7700 CE->getOperatorLoc());
7701 break;
7702 default:
7703 break;
7704 }
7705 }
7706 }
7707 if (dependent() || SemaRef.CurContext->isDependentContext())
7708 return false;
7709 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7710 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7711 return true;
7712 }
7713
checkAndSetIncRHS(Expr * RHS)7714 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7715 // RHS of canonical loop form increment can be:
7716 // var + incr
7717 // incr + var
7718 // var - incr
7719 //
7720 RHS = RHS->IgnoreParenImpCasts();
7721 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7722 if (BO->isAdditiveOp()) {
7723 bool IsAdd = BO->getOpcode() == BO_Add;
7724 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7725 return setStep(BO->getRHS(), !IsAdd);
7726 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7727 return setStep(BO->getLHS(), /*Subtract=*/false);
7728 }
7729 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7730 bool IsAdd = CE->getOperator() == OO_Plus;
7731 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7732 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7733 return setStep(CE->getArg(1), !IsAdd);
7734 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7735 return setStep(CE->getArg(0), /*Subtract=*/false);
7736 }
7737 }
7738 if (dependent() || SemaRef.CurContext->isDependentContext())
7739 return false;
7740 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7741 << RHS->getSourceRange() << LCDecl;
7742 return true;
7743 }
7744
checkAndSetInc(Expr * S)7745 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7746 // Check incr-expr for canonical loop form and return true if it
7747 // does not conform.
7748 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7749 // ++var
7750 // var++
7751 // --var
7752 // var--
7753 // var += incr
7754 // var -= incr
7755 // var = var + incr
7756 // var = incr + var
7757 // var = var - incr
7758 //
7759 if (!S) {
7760 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7761 return true;
7762 }
7763 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7764 if (!ExprTemp->cleanupsHaveSideEffects())
7765 S = ExprTemp->getSubExpr();
7766
7767 IncrementSrcRange = S->getSourceRange();
7768 S = S->IgnoreParens();
7769 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7770 if (UO->isIncrementDecrementOp() &&
7771 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7772 return setStep(SemaRef
7773 .ActOnIntegerConstant(UO->getBeginLoc(),
7774 (UO->isDecrementOp() ? -1 : 1))
7775 .get(),
7776 /*Subtract=*/false);
7777 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7778 switch (BO->getOpcode()) {
7779 case BO_AddAssign:
7780 case BO_SubAssign:
7781 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7782 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7783 break;
7784 case BO_Assign:
7785 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7786 return checkAndSetIncRHS(BO->getRHS());
7787 break;
7788 default:
7789 break;
7790 }
7791 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7792 switch (CE->getOperator()) {
7793 case OO_PlusPlus:
7794 case OO_MinusMinus:
7795 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7796 return setStep(SemaRef
7797 .ActOnIntegerConstant(
7798 CE->getBeginLoc(),
7799 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7800 .get(),
7801 /*Subtract=*/false);
7802 break;
7803 case OO_PlusEqual:
7804 case OO_MinusEqual:
7805 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7806 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7807 break;
7808 case OO_Equal:
7809 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7810 return checkAndSetIncRHS(CE->getArg(1));
7811 break;
7812 default:
7813 break;
7814 }
7815 }
7816 if (dependent() || SemaRef.CurContext->isDependentContext())
7817 return false;
7818 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7819 << S->getSourceRange() << LCDecl;
7820 return true;
7821 }
7822
7823 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7824 tryBuildCapture(Sema &SemaRef, Expr *Capture,
7825 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7826 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7827 return Capture;
7828 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7829 return SemaRef.PerformImplicitConversion(
7830 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7831 /*AllowExplicit=*/true);
7832 auto I = Captures.find(Capture);
7833 if (I != Captures.end())
7834 return buildCapture(SemaRef, Capture, I->second);
7835 DeclRefExpr *Ref = nullptr;
7836 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7837 Captures[Capture] = Ref;
7838 return Res;
7839 }
7840
7841 /// Calculate number of iterations, transforming to unsigned, if number of
7842 /// iterations may be larger than the original type.
7843 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)7844 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7845 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7846 bool TestIsStrictOp, bool RoundToStep,
7847 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7848 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7849 if (!NewStep.isUsable())
7850 return nullptr;
7851 llvm::APSInt LRes, SRes;
7852 bool IsLowerConst = false, IsStepConst = false;
7853 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7854 LRes = *Res;
7855 IsLowerConst = true;
7856 }
7857 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7858 SRes = *Res;
7859 IsStepConst = true;
7860 }
7861 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7862 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7863 (TestIsStrictOp && LRes.isStrictlyPositive()));
7864 bool NeedToReorganize = false;
7865 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7866 if (!NoNeedToConvert && IsLowerConst &&
7867 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7868 NoNeedToConvert = true;
7869 if (RoundToStep) {
7870 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7871 ? LRes.getBitWidth()
7872 : SRes.getBitWidth();
7873 LRes = LRes.extend(BW + 1);
7874 LRes.setIsSigned(true);
7875 SRes = SRes.extend(BW + 1);
7876 SRes.setIsSigned(true);
7877 LRes -= SRes;
7878 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7879 LRes = LRes.trunc(BW);
7880 }
7881 if (TestIsStrictOp) {
7882 unsigned BW = LRes.getBitWidth();
7883 LRes = LRes.extend(BW + 1);
7884 LRes.setIsSigned(true);
7885 ++LRes;
7886 NoNeedToConvert =
7887 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7888 // truncate to the original bitwidth.
7889 LRes = LRes.trunc(BW);
7890 }
7891 NeedToReorganize = NoNeedToConvert;
7892 }
7893 llvm::APSInt URes;
7894 bool IsUpperConst = false;
7895 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7896 URes = *Res;
7897 IsUpperConst = true;
7898 }
7899 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7900 (!RoundToStep || IsStepConst)) {
7901 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7902 : URes.getBitWidth();
7903 LRes = LRes.extend(BW + 1);
7904 LRes.setIsSigned(true);
7905 URes = URes.extend(BW + 1);
7906 URes.setIsSigned(true);
7907 URes -= LRes;
7908 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7909 NeedToReorganize = NoNeedToConvert;
7910 }
7911 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7912 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7913 // unsigned.
7914 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7915 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7916 QualType LowerTy = Lower->getType();
7917 QualType UpperTy = Upper->getType();
7918 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7919 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7920 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7921 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7922 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7923 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7924 Upper =
7925 SemaRef
7926 .PerformImplicitConversion(
7927 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7928 CastType, Sema::AA_Converting)
7929 .get();
7930 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7931 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7932 }
7933 }
7934 if (!Lower || !Upper || NewStep.isInvalid())
7935 return nullptr;
7936
7937 ExprResult Diff;
7938 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7939 // 1]).
7940 if (NeedToReorganize) {
7941 Diff = Lower;
7942
7943 if (RoundToStep) {
7944 // Lower - Step
7945 Diff =
7946 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7947 if (!Diff.isUsable())
7948 return nullptr;
7949 }
7950
7951 // Lower - Step [+ 1]
7952 if (TestIsStrictOp)
7953 Diff = SemaRef.BuildBinOp(
7954 S, DefaultLoc, BO_Add, Diff.get(),
7955 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7956 if (!Diff.isUsable())
7957 return nullptr;
7958
7959 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7960 if (!Diff.isUsable())
7961 return nullptr;
7962
7963 // Upper - (Lower - Step [+ 1]).
7964 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7965 if (!Diff.isUsable())
7966 return nullptr;
7967 } else {
7968 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7969
7970 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7971 // BuildBinOp already emitted error, this one is to point user to upper
7972 // and lower bound, and to tell what is passed to 'operator-'.
7973 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7974 << Upper->getSourceRange() << Lower->getSourceRange();
7975 return nullptr;
7976 }
7977
7978 if (!Diff.isUsable())
7979 return nullptr;
7980
7981 // Upper - Lower [- 1]
7982 if (TestIsStrictOp)
7983 Diff = SemaRef.BuildBinOp(
7984 S, DefaultLoc, BO_Sub, Diff.get(),
7985 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7986 if (!Diff.isUsable())
7987 return nullptr;
7988
7989 if (RoundToStep) {
7990 // Upper - Lower [- 1] + Step
7991 Diff =
7992 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7993 if (!Diff.isUsable())
7994 return nullptr;
7995 }
7996 }
7997
7998 // Parentheses (for dumping/debugging purposes only).
7999 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8000 if (!Diff.isUsable())
8001 return nullptr;
8002
8003 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8004 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8005 if (!Diff.isUsable())
8006 return nullptr;
8007
8008 return Diff.get();
8009 }
8010
8011 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8012 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8013 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8014 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8015 QualType VarType = LCDecl->getType().getNonReferenceType();
8016 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8017 !SemaRef.getLangOpts().CPlusPlus)
8018 return nullptr;
8019 Expr *LBVal = LB;
8020 Expr *UBVal = UB;
8021 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8022 // max(LB(MinVal), LB(MaxVal))
8023 if (InitDependOnLC) {
8024 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8025 if (!IS.MinValue || !IS.MaxValue)
8026 return nullptr;
8027 // OuterVar = Min
8028 ExprResult MinValue =
8029 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8030 if (!MinValue.isUsable())
8031 return nullptr;
8032
8033 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8034 IS.CounterVar, MinValue.get());
8035 if (!LBMinVal.isUsable())
8036 return nullptr;
8037 // OuterVar = Min, LBVal
8038 LBMinVal =
8039 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8040 if (!LBMinVal.isUsable())
8041 return nullptr;
8042 // (OuterVar = Min, LBVal)
8043 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8044 if (!LBMinVal.isUsable())
8045 return nullptr;
8046
8047 // OuterVar = Max
8048 ExprResult MaxValue =
8049 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8050 if (!MaxValue.isUsable())
8051 return nullptr;
8052
8053 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8054 IS.CounterVar, MaxValue.get());
8055 if (!LBMaxVal.isUsable())
8056 return nullptr;
8057 // OuterVar = Max, LBVal
8058 LBMaxVal =
8059 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8060 if (!LBMaxVal.isUsable())
8061 return nullptr;
8062 // (OuterVar = Max, LBVal)
8063 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8064 if (!LBMaxVal.isUsable())
8065 return nullptr;
8066
8067 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8068 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8069 if (!LBMin || !LBMax)
8070 return nullptr;
8071 // LB(MinVal) < LB(MaxVal)
8072 ExprResult MinLessMaxRes =
8073 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8074 if (!MinLessMaxRes.isUsable())
8075 return nullptr;
8076 Expr *MinLessMax =
8077 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8078 if (!MinLessMax)
8079 return nullptr;
8080 if (TestIsLessOp.getValue()) {
8081 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8082 // LB(MaxVal))
8083 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8084 MinLessMax, LBMin, LBMax);
8085 if (!MinLB.isUsable())
8086 return nullptr;
8087 LBVal = MinLB.get();
8088 } else {
8089 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8090 // LB(MaxVal))
8091 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8092 MinLessMax, LBMax, LBMin);
8093 if (!MaxLB.isUsable())
8094 return nullptr;
8095 LBVal = MaxLB.get();
8096 }
8097 }
8098 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8099 // min(UB(MinVal), UB(MaxVal))
8100 if (CondDependOnLC) {
8101 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8102 if (!IS.MinValue || !IS.MaxValue)
8103 return nullptr;
8104 // OuterVar = Min
8105 ExprResult MinValue =
8106 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8107 if (!MinValue.isUsable())
8108 return nullptr;
8109
8110 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8111 IS.CounterVar, MinValue.get());
8112 if (!UBMinVal.isUsable())
8113 return nullptr;
8114 // OuterVar = Min, UBVal
8115 UBMinVal =
8116 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8117 if (!UBMinVal.isUsable())
8118 return nullptr;
8119 // (OuterVar = Min, UBVal)
8120 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8121 if (!UBMinVal.isUsable())
8122 return nullptr;
8123
8124 // OuterVar = Max
8125 ExprResult MaxValue =
8126 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8127 if (!MaxValue.isUsable())
8128 return nullptr;
8129
8130 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8131 IS.CounterVar, MaxValue.get());
8132 if (!UBMaxVal.isUsable())
8133 return nullptr;
8134 // OuterVar = Max, UBVal
8135 UBMaxVal =
8136 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8137 if (!UBMaxVal.isUsable())
8138 return nullptr;
8139 // (OuterVar = Max, UBVal)
8140 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8141 if (!UBMaxVal.isUsable())
8142 return nullptr;
8143
8144 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8145 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8146 if (!UBMin || !UBMax)
8147 return nullptr;
8148 // UB(MinVal) > UB(MaxVal)
8149 ExprResult MinGreaterMaxRes =
8150 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8151 if (!MinGreaterMaxRes.isUsable())
8152 return nullptr;
8153 Expr *MinGreaterMax =
8154 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8155 if (!MinGreaterMax)
8156 return nullptr;
8157 if (TestIsLessOp.getValue()) {
8158 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8159 // UB(MaxVal))
8160 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8161 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8162 if (!MaxUB.isUsable())
8163 return nullptr;
8164 UBVal = MaxUB.get();
8165 } else {
8166 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8167 // UB(MaxVal))
8168 ExprResult MinUB = SemaRef.ActOnConditionalOp(
8169 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8170 if (!MinUB.isUsable())
8171 return nullptr;
8172 UBVal = MinUB.get();
8173 }
8174 }
8175 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8176 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8177 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8178 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8179 if (!Upper || !Lower)
8180 return nullptr;
8181
8182 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8183 Step, VarType, TestIsStrictOp,
8184 /*RoundToStep=*/true, Captures);
8185 if (!Diff.isUsable())
8186 return nullptr;
8187
8188 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8189 QualType Type = Diff.get()->getType();
8190 ASTContext &C = SemaRef.Context;
8191 bool UseVarType = VarType->hasIntegerRepresentation() &&
8192 C.getTypeSize(Type) > C.getTypeSize(VarType);
8193 if (!Type->isIntegerType() || UseVarType) {
8194 unsigned NewSize =
8195 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8196 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8197 : Type->hasSignedIntegerRepresentation();
8198 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8199 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8200 Diff = SemaRef.PerformImplicitConversion(
8201 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8202 if (!Diff.isUsable())
8203 return nullptr;
8204 }
8205 }
8206 if (LimitedType) {
8207 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8208 if (NewSize != C.getTypeSize(Type)) {
8209 if (NewSize < C.getTypeSize(Type)) {
8210 assert(NewSize == 64 && "incorrect loop var size");
8211 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8212 << InitSrcRange << ConditionSrcRange;
8213 }
8214 QualType NewType = C.getIntTypeForBitwidth(
8215 NewSize, Type->hasSignedIntegerRepresentation() ||
8216 C.getTypeSize(Type) < NewSize);
8217 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8218 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8219 Sema::AA_Converting, true);
8220 if (!Diff.isUsable())
8221 return nullptr;
8222 }
8223 }
8224 }
8225
8226 return Diff.get();
8227 }
8228
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8229 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8230 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8231 // Do not build for iterators, they cannot be used in non-rectangular loop
8232 // nests.
8233 if (LCDecl->getType()->isRecordType())
8234 return std::make_pair(nullptr, nullptr);
8235 // If we subtract, the min is in the condition, otherwise the min is in the
8236 // init value.
8237 Expr *MinExpr = nullptr;
8238 Expr *MaxExpr = nullptr;
8239 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8240 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8241 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8242 : CondDependOnLC.hasValue();
8243 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8244 : InitDependOnLC.hasValue();
8245 Expr *Lower =
8246 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8247 Expr *Upper =
8248 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8249 if (!Upper || !Lower)
8250 return std::make_pair(nullptr, nullptr);
8251
8252 if (TestIsLessOp.getValue())
8253 MinExpr = Lower;
8254 else
8255 MaxExpr = Upper;
8256
8257 // Build minimum/maximum value based on number of iterations.
8258 QualType VarType = LCDecl->getType().getNonReferenceType();
8259
8260 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8261 Step, VarType, TestIsStrictOp,
8262 /*RoundToStep=*/false, Captures);
8263 if (!Diff.isUsable())
8264 return std::make_pair(nullptr, nullptr);
8265
8266 // ((Upper - Lower [- 1]) / Step) * Step
8267 // Parentheses (for dumping/debugging purposes only).
8268 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8269 if (!Diff.isUsable())
8270 return std::make_pair(nullptr, nullptr);
8271
8272 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8273 if (!NewStep.isUsable())
8274 return std::make_pair(nullptr, nullptr);
8275 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8276 if (!Diff.isUsable())
8277 return std::make_pair(nullptr, nullptr);
8278
8279 // Parentheses (for dumping/debugging purposes only).
8280 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8281 if (!Diff.isUsable())
8282 return std::make_pair(nullptr, nullptr);
8283
8284 // Convert to the ptrdiff_t, if original type is pointer.
8285 if (VarType->isAnyPointerType() &&
8286 !SemaRef.Context.hasSameType(
8287 Diff.get()->getType(),
8288 SemaRef.Context.getUnsignedPointerDiffType())) {
8289 Diff = SemaRef.PerformImplicitConversion(
8290 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8291 Sema::AA_Converting, /*AllowExplicit=*/true);
8292 }
8293 if (!Diff.isUsable())
8294 return std::make_pair(nullptr, nullptr);
8295
8296 if (TestIsLessOp.getValue()) {
8297 // MinExpr = Lower;
8298 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8299 Diff = SemaRef.BuildBinOp(
8300 S, DefaultLoc, BO_Add,
8301 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8302 Diff.get());
8303 if (!Diff.isUsable())
8304 return std::make_pair(nullptr, nullptr);
8305 } else {
8306 // MaxExpr = Upper;
8307 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8308 Diff = SemaRef.BuildBinOp(
8309 S, DefaultLoc, BO_Sub,
8310 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8311 Diff.get());
8312 if (!Diff.isUsable())
8313 return std::make_pair(nullptr, nullptr);
8314 }
8315
8316 // Convert to the original type.
8317 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8318 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8319 Sema::AA_Converting,
8320 /*AllowExplicit=*/true);
8321 if (!Diff.isUsable())
8322 return std::make_pair(nullptr, nullptr);
8323
8324 Sema::TentativeAnalysisScope Trap(SemaRef);
8325 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8326 if (!Diff.isUsable())
8327 return std::make_pair(nullptr, nullptr);
8328
8329 if (TestIsLessOp.getValue())
8330 MaxExpr = Diff.get();
8331 else
8332 MinExpr = Diff.get();
8333
8334 return std::make_pair(MinExpr, MaxExpr);
8335 }
8336
buildFinalCondition(Scope * S) const8337 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8338 if (InitDependOnLC || CondDependOnLC)
8339 return Condition;
8340 return nullptr;
8341 }
8342
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8343 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8344 Scope *S, Expr *Cond,
8345 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8346 // Do not build a precondition when the condition/initialization is dependent
8347 // to prevent pessimistic early loop exit.
8348 // TODO: this can be improved by calculating min/max values but not sure that
8349 // it will be very effective.
8350 if (CondDependOnLC || InitDependOnLC)
8351 return SemaRef.PerformImplicitConversion(
8352 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8353 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8354 /*AllowExplicit=*/true).get();
8355
8356 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8357 Sema::TentativeAnalysisScope Trap(SemaRef);
8358
8359 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8360 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8361 if (!NewLB.isUsable() || !NewUB.isUsable())
8362 return nullptr;
8363
8364 ExprResult CondExpr =
8365 SemaRef.BuildBinOp(S, DefaultLoc,
8366 TestIsLessOp.getValue() ?
8367 (TestIsStrictOp ? BO_LT : BO_LE) :
8368 (TestIsStrictOp ? BO_GT : BO_GE),
8369 NewLB.get(), NewUB.get());
8370 if (CondExpr.isUsable()) {
8371 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8372 SemaRef.Context.BoolTy))
8373 CondExpr = SemaRef.PerformImplicitConversion(
8374 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8375 /*AllowExplicit=*/true);
8376 }
8377
8378 // Otherwise use original loop condition and evaluate it in runtime.
8379 return CondExpr.isUsable() ? CondExpr.get() : Cond;
8380 }
8381
8382 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const8383 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8384 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8385 DSAStackTy &DSA) const {
8386 auto *VD = dyn_cast<VarDecl>(LCDecl);
8387 if (!VD) {
8388 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8389 DeclRefExpr *Ref = buildDeclRefExpr(
8390 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8391 const DSAStackTy::DSAVarData Data =
8392 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8393 // If the loop control decl is explicitly marked as private, do not mark it
8394 // as captured again.
8395 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8396 Captures.insert(std::make_pair(LCRef, Ref));
8397 return Ref;
8398 }
8399 return cast<DeclRefExpr>(LCRef);
8400 }
8401
buildPrivateCounterVar() const8402 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8403 if (LCDecl && !LCDecl->isInvalidDecl()) {
8404 QualType Type = LCDecl->getType().getNonReferenceType();
8405 VarDecl *PrivateVar = buildVarDecl(
8406 SemaRef, DefaultLoc, Type, LCDecl->getName(),
8407 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8408 isa<VarDecl>(LCDecl)
8409 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8410 : nullptr);
8411 if (PrivateVar->isInvalidDecl())
8412 return nullptr;
8413 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8414 }
8415 return nullptr;
8416 }
8417
8418 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const8419 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8420
8421 /// Build step of the counter be used for codegen.
buildCounterStep() const8422 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8423
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)8424 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8425 Scope *S, Expr *Counter,
8426 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8427 Expr *Inc, OverloadedOperatorKind OOK) {
8428 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8429 if (!Cnt)
8430 return nullptr;
8431 if (Inc) {
8432 assert((OOK == OO_Plus || OOK == OO_Minus) &&
8433 "Expected only + or - operations for depend clauses.");
8434 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8435 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8436 if (!Cnt)
8437 return nullptr;
8438 }
8439 QualType VarType = LCDecl->getType().getNonReferenceType();
8440 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8441 !SemaRef.getLangOpts().CPlusPlus)
8442 return nullptr;
8443 // Upper - Lower
8444 Expr *Upper = TestIsLessOp.getValue()
8445 ? Cnt
8446 : tryBuildCapture(SemaRef, LB, Captures).get();
8447 Expr *Lower = TestIsLessOp.getValue()
8448 ? tryBuildCapture(SemaRef, LB, Captures).get()
8449 : Cnt;
8450 if (!Upper || !Lower)
8451 return nullptr;
8452
8453 ExprResult Diff = calculateNumIters(
8454 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8455 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8456 if (!Diff.isUsable())
8457 return nullptr;
8458
8459 return Diff.get();
8460 }
8461 } // namespace
8462
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)8463 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8464 assert(getLangOpts().OpenMP && "OpenMP is not active.");
8465 assert(Init && "Expected loop in canonical form.");
8466 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
8467 if (AssociatedLoops > 0 &&
8468 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
8469 DSAStack->loopStart();
8470 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8471 *DSAStack, ForLoc);
8472 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8473 if (ValueDecl *D = ISC.getLoopDecl()) {
8474 auto *VD = dyn_cast<VarDecl>(D);
8475 DeclRefExpr *PrivateRef = nullptr;
8476 if (!VD) {
8477 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8478 VD = Private;
8479 } else {
8480 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8481 /*WithInit=*/false);
8482 VD = cast<VarDecl>(PrivateRef->getDecl());
8483 }
8484 }
8485 DSAStack->addLoopControlVariable(D, VD);
8486 const Decl *LD = DSAStack->getPossiblyLoopCunter();
8487 if (LD != D->getCanonicalDecl()) {
8488 DSAStack->resetPossibleLoopCounter();
8489 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8490 MarkDeclarationsReferencedInExpr(
8491 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8492 Var->getType().getNonLValueExprType(Context),
8493 ForLoc, /*RefersToCapture=*/true));
8494 }
8495 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8496 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8497 // Referenced in a Construct, C/C++]. The loop iteration variable in the
8498 // associated for-loop of a simd construct with just one associated
8499 // for-loop may be listed in a linear clause with a constant-linear-step
8500 // that is the increment of the associated for-loop. The loop iteration
8501 // variable(s) in the associated for-loop(s) of a for or parallel for
8502 // construct may be listed in a private or lastprivate clause.
8503 DSAStackTy::DSAVarData DVar =
8504 DSAStack->getTopDSA(D, /*FromParent=*/false);
8505 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8506 // is declared in the loop and it is predetermined as a private.
8507 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8508 OpenMPClauseKind PredeterminedCKind =
8509 isOpenMPSimdDirective(DKind)
8510 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8511 : OMPC_private;
8512 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8513 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8514 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8515 DVar.CKind != OMPC_private))) ||
8516 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8517 DKind == OMPD_master_taskloop ||
8518 DKind == OMPD_parallel_master_taskloop ||
8519 isOpenMPDistributeDirective(DKind)) &&
8520 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8521 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8522 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8523 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8524 << getOpenMPClauseName(DVar.CKind)
8525 << getOpenMPDirectiveName(DKind)
8526 << getOpenMPClauseName(PredeterminedCKind);
8527 if (DVar.RefExpr == nullptr)
8528 DVar.CKind = PredeterminedCKind;
8529 reportOriginalDsa(*this, DSAStack, D, DVar,
8530 /*IsLoopIterVar=*/true);
8531 } else if (LoopDeclRefExpr) {
8532 // Make the loop iteration variable private (for worksharing
8533 // constructs), linear (for simd directives with the only one
8534 // associated loop) or lastprivate (for simd directives with several
8535 // collapsed or ordered loops).
8536 if (DVar.CKind == OMPC_unknown)
8537 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8538 PrivateRef);
8539 }
8540 }
8541 }
8542 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
8543 }
8544 }
8545
8546 /// Called on a for stmt to check and extract its iteration space
8547 /// 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)8548 static bool checkOpenMPIterationSpace(
8549 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8550 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8551 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8552 Expr *OrderedLoopCountExpr,
8553 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8554 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8555 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8556 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8557 // OpenMP [2.9.1, Canonical Loop Form]
8558 // for (init-expr; test-expr; incr-expr) structured-block
8559 // for (range-decl: range-expr) structured-block
8560 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8561 S = CanonLoop->getLoopStmt();
8562 auto *For = dyn_cast_or_null<ForStmt>(S);
8563 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8564 // Ranged for is supported only in OpenMP 5.0.
8565 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8566 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8567 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8568 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8569 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8570 if (TotalNestedLoopCount > 1) {
8571 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8572 SemaRef.Diag(DSA.getConstructLoc(),
8573 diag::note_omp_collapse_ordered_expr)
8574 << 2 << CollapseLoopCountExpr->getSourceRange()
8575 << OrderedLoopCountExpr->getSourceRange();
8576 else if (CollapseLoopCountExpr)
8577 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8578 diag::note_omp_collapse_ordered_expr)
8579 << 0 << CollapseLoopCountExpr->getSourceRange();
8580 else
8581 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8582 diag::note_omp_collapse_ordered_expr)
8583 << 1 << OrderedLoopCountExpr->getSourceRange();
8584 }
8585 return true;
8586 }
8587 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
8588 "No loop body.");
8589
8590 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8591 For ? For->getForLoc() : CXXFor->getForLoc());
8592
8593 // Check init.
8594 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8595 if (ISC.checkAndSetInit(Init))
8596 return true;
8597
8598 bool HasErrors = false;
8599
8600 // Check loop variable's type.
8601 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8602 // OpenMP [2.6, Canonical Loop Form]
8603 // Var is one of the following:
8604 // A variable of signed or unsigned integer type.
8605 // For C++, a variable of a random access iterator type.
8606 // For C, a variable of a pointer type.
8607 QualType VarType = LCDecl->getType().getNonReferenceType();
8608 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8609 !VarType->isPointerType() &&
8610 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8611 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8612 << SemaRef.getLangOpts().CPlusPlus;
8613 HasErrors = true;
8614 }
8615
8616 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8617 // a Construct
8618 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8619 // parallel for construct is (are) private.
8620 // The loop iteration variable in the associated for-loop of a simd
8621 // construct with just one associated for-loop is linear with a
8622 // constant-linear-step that is the increment of the associated for-loop.
8623 // Exclude loop var from the list of variables with implicitly defined data
8624 // sharing attributes.
8625 VarsWithImplicitDSA.erase(LCDecl);
8626
8627 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8628
8629 // Check test-expr.
8630 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8631
8632 // Check incr-expr.
8633 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8634 }
8635
8636 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8637 return HasErrors;
8638
8639 // Build the loop's iteration space representation.
8640 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8641 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8642 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8643 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8644 (isOpenMPWorksharingDirective(DKind) ||
8645 isOpenMPTaskLoopDirective(DKind) ||
8646 isOpenMPDistributeDirective(DKind) ||
8647 isOpenMPLoopTransformationDirective(DKind)),
8648 Captures);
8649 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8650 ISC.buildCounterVar(Captures, DSA);
8651 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8652 ISC.buildPrivateCounterVar();
8653 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8654 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8655 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8656 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8657 ISC.getConditionSrcRange();
8658 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8659 ISC.getIncrementSrcRange();
8660 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8661 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8662 ISC.isStrictTestOp();
8663 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8664 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8665 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8666 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8667 ISC.buildFinalCondition(DSA.getCurScope());
8668 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8669 ISC.doesInitDependOnLC();
8670 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8671 ISC.doesCondDependOnLC();
8672 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8673 ISC.getLoopDependentIdx();
8674
8675 HasErrors |=
8676 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8677 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8678 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8679 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8680 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8681 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8682 if (!HasErrors && DSA.isOrderedRegion()) {
8683 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8684 if (CurrentNestedLoopCount <
8685 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8686 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8687 CurrentNestedLoopCount,
8688 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8689 DSA.getOrderedRegionParam().second->setLoopCounter(
8690 CurrentNestedLoopCount,
8691 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8692 }
8693 }
8694 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8695 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8696 // Erroneous case - clause has some problems.
8697 continue;
8698 }
8699 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8700 Pair.second.size() <= CurrentNestedLoopCount) {
8701 // Erroneous case - clause has some problems.
8702 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8703 continue;
8704 }
8705 Expr *CntValue;
8706 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8707 CntValue = ISC.buildOrderedLoopData(
8708 DSA.getCurScope(),
8709 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8710 Pair.first->getDependencyLoc());
8711 else
8712 CntValue = ISC.buildOrderedLoopData(
8713 DSA.getCurScope(),
8714 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8715 Pair.first->getDependencyLoc(),
8716 Pair.second[CurrentNestedLoopCount].first,
8717 Pair.second[CurrentNestedLoopCount].second);
8718 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8719 }
8720 }
8721
8722 return HasErrors;
8723 }
8724
8725 /// Build 'VarRef = Start.
8726 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8727 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8728 ExprResult Start, bool IsNonRectangularLB,
8729 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8730 // Build 'VarRef = Start.
8731 ExprResult NewStart = IsNonRectangularLB
8732 ? Start.get()
8733 : tryBuildCapture(SemaRef, Start.get(), Captures);
8734 if (!NewStart.isUsable())
8735 return ExprError();
8736 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8737 VarRef.get()->getType())) {
8738 NewStart = SemaRef.PerformImplicitConversion(
8739 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8740 /*AllowExplicit=*/true);
8741 if (!NewStart.isUsable())
8742 return ExprError();
8743 }
8744
8745 ExprResult Init =
8746 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8747 return Init;
8748 }
8749
8750 /// 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)8751 static ExprResult buildCounterUpdate(
8752 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8753 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8754 bool IsNonRectangularLB,
8755 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8756 // Add parentheses (for debugging purposes only).
8757 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8758 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8759 !Step.isUsable())
8760 return ExprError();
8761
8762 ExprResult NewStep = Step;
8763 if (Captures)
8764 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8765 if (NewStep.isInvalid())
8766 return ExprError();
8767 ExprResult Update =
8768 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8769 if (!Update.isUsable())
8770 return ExprError();
8771
8772 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8773 // 'VarRef = Start (+|-) Iter * Step'.
8774 if (!Start.isUsable())
8775 return ExprError();
8776 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8777 if (!NewStart.isUsable())
8778 return ExprError();
8779 if (Captures && !IsNonRectangularLB)
8780 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8781 if (NewStart.isInvalid())
8782 return ExprError();
8783
8784 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8785 ExprResult SavedUpdate = Update;
8786 ExprResult UpdateVal;
8787 if (VarRef.get()->getType()->isOverloadableType() ||
8788 NewStart.get()->getType()->isOverloadableType() ||
8789 Update.get()->getType()->isOverloadableType()) {
8790 Sema::TentativeAnalysisScope Trap(SemaRef);
8791
8792 Update =
8793 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8794 if (Update.isUsable()) {
8795 UpdateVal =
8796 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8797 VarRef.get(), SavedUpdate.get());
8798 if (UpdateVal.isUsable()) {
8799 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8800 UpdateVal.get());
8801 }
8802 }
8803 }
8804
8805 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8806 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8807 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8808 NewStart.get(), SavedUpdate.get());
8809 if (!Update.isUsable())
8810 return ExprError();
8811
8812 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8813 VarRef.get()->getType())) {
8814 Update = SemaRef.PerformImplicitConversion(
8815 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8816 if (!Update.isUsable())
8817 return ExprError();
8818 }
8819
8820 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8821 }
8822 return Update;
8823 }
8824
8825 /// Convert integer expression \a E to make it have at least \a Bits
8826 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)8827 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8828 if (E == nullptr)
8829 return ExprError();
8830 ASTContext &C = SemaRef.Context;
8831 QualType OldType = E->getType();
8832 unsigned HasBits = C.getTypeSize(OldType);
8833 if (HasBits >= Bits)
8834 return ExprResult(E);
8835 // OK to convert to signed, because new type has more bits than old.
8836 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8837 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8838 true);
8839 }
8840
8841 /// Check if the given expression \a E is a constant integer that fits
8842 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)8843 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8844 if (E == nullptr)
8845 return false;
8846 if (Optional<llvm::APSInt> Result =
8847 E->getIntegerConstantExpr(SemaRef.Context))
8848 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8849 return false;
8850 }
8851
8852 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)8853 static Stmt *buildPreInits(ASTContext &Context,
8854 MutableArrayRef<Decl *> PreInits) {
8855 if (!PreInits.empty()) {
8856 return new (Context) DeclStmt(
8857 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8858 SourceLocation(), SourceLocation());
8859 }
8860 return nullptr;
8861 }
8862
8863 /// Build preinits statement for the given declarations.
8864 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8865 buildPreInits(ASTContext &Context,
8866 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8867 if (!Captures.empty()) {
8868 SmallVector<Decl *, 16> PreInits;
8869 for (const auto &Pair : Captures)
8870 PreInits.push_back(Pair.second->getDecl());
8871 return buildPreInits(Context, PreInits);
8872 }
8873 return nullptr;
8874 }
8875
8876 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)8877 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8878 Expr *PostUpdate = nullptr;
8879 if (!PostUpdates.empty()) {
8880 for (Expr *E : PostUpdates) {
8881 Expr *ConvE = S.BuildCStyleCastExpr(
8882 E->getExprLoc(),
8883 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8884 E->getExprLoc(), E)
8885 .get();
8886 PostUpdate = PostUpdate
8887 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8888 PostUpdate, ConvE)
8889 .get()
8890 : ConvE;
8891 }
8892 }
8893 return PostUpdate;
8894 }
8895
8896 /// Called on a for stmt to check itself and nested loops (if any).
8897 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8898 /// number of collapsed loops otherwise.
8899 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopBasedDirective::HelperExprs & Built)8900 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8901 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8902 DSAStackTy &DSA,
8903 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8904 OMPLoopBasedDirective::HelperExprs &Built) {
8905 unsigned NestedLoopCount = 1;
8906 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8907 !isOpenMPLoopTransformationDirective(DKind);
8908
8909 if (CollapseLoopCountExpr) {
8910 // Found 'collapse' clause - calculate collapse number.
8911 Expr::EvalResult Result;
8912 if (!CollapseLoopCountExpr->isValueDependent() &&
8913 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8914 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8915 } else {
8916 Built.clear(/*Size=*/1);
8917 return 1;
8918 }
8919 }
8920 unsigned OrderedLoopCount = 1;
8921 if (OrderedLoopCountExpr) {
8922 // Found 'ordered' clause - calculate collapse number.
8923 Expr::EvalResult EVResult;
8924 if (!OrderedLoopCountExpr->isValueDependent() &&
8925 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8926 SemaRef.getASTContext())) {
8927 llvm::APSInt Result = EVResult.Val.getInt();
8928 if (Result.getLimitedValue() < NestedLoopCount) {
8929 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8930 diag::err_omp_wrong_ordered_loop_count)
8931 << OrderedLoopCountExpr->getSourceRange();
8932 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8933 diag::note_collapse_loop_count)
8934 << CollapseLoopCountExpr->getSourceRange();
8935 }
8936 OrderedLoopCount = Result.getLimitedValue();
8937 } else {
8938 Built.clear(/*Size=*/1);
8939 return 1;
8940 }
8941 }
8942 // This is helper routine for loop directives (e.g., 'for', 'simd',
8943 // 'for simd', etc.).
8944 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8945 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
8946 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
8947 if (!OMPLoopBasedDirective::doForAllLoops(
8948 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
8949 SupportsNonPerfectlyNested, NumLoops,
8950 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
8951 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
8952 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
8953 if (checkOpenMPIterationSpace(
8954 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8955 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
8956 VarsWithImplicitDSA, IterSpaces, Captures))
8957 return true;
8958 if (Cnt > 0 && Cnt >= NestedLoopCount &&
8959 IterSpaces[Cnt].CounterVar) {
8960 // Handle initialization of captured loop iterator variables.
8961 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8962 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8963 Captures[DRE] = DRE;
8964 }
8965 }
8966 return false;
8967 }))
8968 return 0;
8969
8970 Built.clear(/* size */ NestedLoopCount);
8971
8972 if (SemaRef.CurContext->isDependentContext())
8973 return NestedLoopCount;
8974
8975 // An example of what is generated for the following code:
8976 //
8977 // #pragma omp simd collapse(2) ordered(2)
8978 // for (i = 0; i < NI; ++i)
8979 // for (k = 0; k < NK; ++k)
8980 // for (j = J0; j < NJ; j+=2) {
8981 // <loop body>
8982 // }
8983 //
8984 // We generate the code below.
8985 // Note: the loop body may be outlined in CodeGen.
8986 // Note: some counters may be C++ classes, operator- is used to find number of
8987 // iterations and operator+= to calculate counter value.
8988 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8989 // or i64 is currently supported).
8990 //
8991 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8992 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8993 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8994 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8995 // // similar updates for vars in clauses (e.g. 'linear')
8996 // <loop body (using local i and j)>
8997 // }
8998 // i = NI; // assign final values of counters
8999 // j = NJ;
9000 //
9001
9002 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9003 // the iteration counts of the collapsed for loops.
9004 // Precondition tests if there is at least one iteration (all conditions are
9005 // true).
9006 auto PreCond = ExprResult(IterSpaces[0].PreCond);
9007 Expr *N0 = IterSpaces[0].NumIterations;
9008 ExprResult LastIteration32 =
9009 widenIterationCount(/*Bits=*/32,
9010 SemaRef
9011 .PerformImplicitConversion(
9012 N0->IgnoreImpCasts(), N0->getType(),
9013 Sema::AA_Converting, /*AllowExplicit=*/true)
9014 .get(),
9015 SemaRef);
9016 ExprResult LastIteration64 = widenIterationCount(
9017 /*Bits=*/64,
9018 SemaRef
9019 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9020 Sema::AA_Converting,
9021 /*AllowExplicit=*/true)
9022 .get(),
9023 SemaRef);
9024
9025 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9026 return NestedLoopCount;
9027
9028 ASTContext &C = SemaRef.Context;
9029 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9030
9031 Scope *CurScope = DSA.getCurScope();
9032 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9033 if (PreCond.isUsable()) {
9034 PreCond =
9035 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9036 PreCond.get(), IterSpaces[Cnt].PreCond);
9037 }
9038 Expr *N = IterSpaces[Cnt].NumIterations;
9039 SourceLocation Loc = N->getExprLoc();
9040 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9041 if (LastIteration32.isUsable())
9042 LastIteration32 = SemaRef.BuildBinOp(
9043 CurScope, Loc, BO_Mul, LastIteration32.get(),
9044 SemaRef
9045 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9046 Sema::AA_Converting,
9047 /*AllowExplicit=*/true)
9048 .get());
9049 if (LastIteration64.isUsable())
9050 LastIteration64 = SemaRef.BuildBinOp(
9051 CurScope, Loc, BO_Mul, LastIteration64.get(),
9052 SemaRef
9053 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9054 Sema::AA_Converting,
9055 /*AllowExplicit=*/true)
9056 .get());
9057 }
9058
9059 // Choose either the 32-bit or 64-bit version.
9060 ExprResult LastIteration = LastIteration64;
9061 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9062 (LastIteration32.isUsable() &&
9063 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9064 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9065 fitsInto(
9066 /*Bits=*/32,
9067 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9068 LastIteration64.get(), SemaRef))))
9069 LastIteration = LastIteration32;
9070 QualType VType = LastIteration.get()->getType();
9071 QualType RealVType = VType;
9072 QualType StrideVType = VType;
9073 if (isOpenMPTaskLoopDirective(DKind)) {
9074 VType =
9075 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9076 StrideVType =
9077 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9078 }
9079
9080 if (!LastIteration.isUsable())
9081 return 0;
9082
9083 // Save the number of iterations.
9084 ExprResult NumIterations = LastIteration;
9085 {
9086 LastIteration = SemaRef.BuildBinOp(
9087 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9088 LastIteration.get(),
9089 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9090 if (!LastIteration.isUsable())
9091 return 0;
9092 }
9093
9094 // Calculate the last iteration number beforehand instead of doing this on
9095 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9096 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9097 ExprResult CalcLastIteration;
9098 if (!IsConstant) {
9099 ExprResult SaveRef =
9100 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9101 LastIteration = SaveRef;
9102
9103 // Prepare SaveRef + 1.
9104 NumIterations = SemaRef.BuildBinOp(
9105 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9106 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9107 if (!NumIterations.isUsable())
9108 return 0;
9109 }
9110
9111 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9112
9113 // Build variables passed into runtime, necessary for worksharing directives.
9114 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9115 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9116 isOpenMPDistributeDirective(DKind) ||
9117 isOpenMPLoopTransformationDirective(DKind)) {
9118 // Lower bound variable, initialized with zero.
9119 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9120 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9121 SemaRef.AddInitializerToDecl(LBDecl,
9122 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9123 /*DirectInit*/ false);
9124
9125 // Upper bound variable, initialized with last iteration number.
9126 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9127 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9128 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9129 /*DirectInit*/ false);
9130
9131 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9132 // This will be used to implement clause 'lastprivate'.
9133 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9134 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9135 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9136 SemaRef.AddInitializerToDecl(ILDecl,
9137 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9138 /*DirectInit*/ false);
9139
9140 // Stride variable returned by runtime (we initialize it to 1 by default).
9141 VarDecl *STDecl =
9142 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9143 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9144 SemaRef.AddInitializerToDecl(STDecl,
9145 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9146 /*DirectInit*/ false);
9147
9148 // Build expression: UB = min(UB, LastIteration)
9149 // It is necessary for CodeGen of directives with static scheduling.
9150 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9151 UB.get(), LastIteration.get());
9152 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9153 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9154 LastIteration.get(), UB.get());
9155 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9156 CondOp.get());
9157 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9158
9159 // If we have a combined directive that combines 'distribute', 'for' or
9160 // 'simd' we need to be able to access the bounds of the schedule of the
9161 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9162 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9163 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9164 // Lower bound variable, initialized with zero.
9165 VarDecl *CombLBDecl =
9166 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9167 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9168 SemaRef.AddInitializerToDecl(
9169 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9170 /*DirectInit*/ false);
9171
9172 // Upper bound variable, initialized with last iteration number.
9173 VarDecl *CombUBDecl =
9174 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9175 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9176 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9177 /*DirectInit*/ false);
9178
9179 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9180 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9181 ExprResult CombCondOp =
9182 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9183 LastIteration.get(), CombUB.get());
9184 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9185 CombCondOp.get());
9186 CombEUB =
9187 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9188
9189 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9190 // We expect to have at least 2 more parameters than the 'parallel'
9191 // directive does - the lower and upper bounds of the previous schedule.
9192 assert(CD->getNumParams() >= 4 &&
9193 "Unexpected number of parameters in loop combined directive");
9194
9195 // Set the proper type for the bounds given what we learned from the
9196 // enclosed loops.
9197 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9198 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9199
9200 // Previous lower and upper bounds are obtained from the region
9201 // parameters.
9202 PrevLB =
9203 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9204 PrevUB =
9205 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9206 }
9207 }
9208
9209 // Build the iteration variable and its initialization before loop.
9210 ExprResult IV;
9211 ExprResult Init, CombInit;
9212 {
9213 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9214 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9215 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9216 isOpenMPTaskLoopDirective(DKind) ||
9217 isOpenMPDistributeDirective(DKind) ||
9218 isOpenMPLoopTransformationDirective(DKind))
9219 ? LB.get()
9220 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9221 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9222 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9223
9224 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9225 Expr *CombRHS =
9226 (isOpenMPWorksharingDirective(DKind) ||
9227 isOpenMPTaskLoopDirective(DKind) ||
9228 isOpenMPDistributeDirective(DKind))
9229 ? CombLB.get()
9230 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9231 CombInit =
9232 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9233 CombInit =
9234 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9235 }
9236 }
9237
9238 bool UseStrictCompare =
9239 RealVType->hasUnsignedIntegerRepresentation() &&
9240 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9241 return LIS.IsStrictCompare;
9242 });
9243 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9244 // unsigned IV)) for worksharing loops.
9245 SourceLocation CondLoc = AStmt->getBeginLoc();
9246 Expr *BoundUB = UB.get();
9247 if (UseStrictCompare) {
9248 BoundUB =
9249 SemaRef
9250 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9251 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9252 .get();
9253 BoundUB =
9254 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9255 }
9256 ExprResult Cond =
9257 (isOpenMPWorksharingDirective(DKind) ||
9258 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9259 isOpenMPLoopTransformationDirective(DKind))
9260 ? SemaRef.BuildBinOp(CurScope, CondLoc,
9261 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9262 BoundUB)
9263 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9264 NumIterations.get());
9265 ExprResult CombDistCond;
9266 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9267 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9268 NumIterations.get());
9269 }
9270
9271 ExprResult CombCond;
9272 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9273 Expr *BoundCombUB = CombUB.get();
9274 if (UseStrictCompare) {
9275 BoundCombUB =
9276 SemaRef
9277 .BuildBinOp(
9278 CurScope, CondLoc, BO_Add, BoundCombUB,
9279 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9280 .get();
9281 BoundCombUB =
9282 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9283 .get();
9284 }
9285 CombCond =
9286 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9287 IV.get(), BoundCombUB);
9288 }
9289 // Loop increment (IV = IV + 1)
9290 SourceLocation IncLoc = AStmt->getBeginLoc();
9291 ExprResult Inc =
9292 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9293 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9294 if (!Inc.isUsable())
9295 return 0;
9296 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9297 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9298 if (!Inc.isUsable())
9299 return 0;
9300
9301 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9302 // Used for directives with static scheduling.
9303 // In combined construct, add combined version that use CombLB and CombUB
9304 // base variables for the update
9305 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9306 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9307 isOpenMPDistributeDirective(DKind) ||
9308 isOpenMPLoopTransformationDirective(DKind)) {
9309 // LB + ST
9310 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9311 if (!NextLB.isUsable())
9312 return 0;
9313 // LB = LB + ST
9314 NextLB =
9315 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9316 NextLB =
9317 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9318 if (!NextLB.isUsable())
9319 return 0;
9320 // UB + ST
9321 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9322 if (!NextUB.isUsable())
9323 return 0;
9324 // UB = UB + ST
9325 NextUB =
9326 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9327 NextUB =
9328 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9329 if (!NextUB.isUsable())
9330 return 0;
9331 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9332 CombNextLB =
9333 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9334 if (!NextLB.isUsable())
9335 return 0;
9336 // LB = LB + ST
9337 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9338 CombNextLB.get());
9339 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9340 /*DiscardedValue*/ false);
9341 if (!CombNextLB.isUsable())
9342 return 0;
9343 // UB + ST
9344 CombNextUB =
9345 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9346 if (!CombNextUB.isUsable())
9347 return 0;
9348 // UB = UB + ST
9349 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9350 CombNextUB.get());
9351 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9352 /*DiscardedValue*/ false);
9353 if (!CombNextUB.isUsable())
9354 return 0;
9355 }
9356 }
9357
9358 // Create increment expression for distribute loop when combined in a same
9359 // directive with for as IV = IV + ST; ensure upper bound expression based
9360 // on PrevUB instead of NumIterations - used to implement 'for' when found
9361 // in combination with 'distribute', like in 'distribute parallel for'
9362 SourceLocation DistIncLoc = AStmt->getBeginLoc();
9363 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9364 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9365 DistCond = SemaRef.BuildBinOp(
9366 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9367 assert(DistCond.isUsable() && "distribute cond expr was not built");
9368
9369 DistInc =
9370 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9371 assert(DistInc.isUsable() && "distribute inc expr was not built");
9372 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9373 DistInc.get());
9374 DistInc =
9375 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9376 assert(DistInc.isUsable() && "distribute inc expr was not built");
9377
9378 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9379 // construct
9380 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9381 ExprResult IsUBGreater =
9382 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
9383 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9384 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
9385 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9386 CondOp.get());
9387 PrevEUB =
9388 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9389
9390 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9391 // parallel for is in combination with a distribute directive with
9392 // schedule(static, 1)
9393 Expr *BoundPrevUB = PrevUB.get();
9394 if (UseStrictCompare) {
9395 BoundPrevUB =
9396 SemaRef
9397 .BuildBinOp(
9398 CurScope, CondLoc, BO_Add, BoundPrevUB,
9399 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9400 .get();
9401 BoundPrevUB =
9402 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9403 .get();
9404 }
9405 ParForInDistCond =
9406 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9407 IV.get(), BoundPrevUB);
9408 }
9409
9410 // Build updates and final values of the loop counters.
9411 bool HasErrors = false;
9412 Built.Counters.resize(NestedLoopCount);
9413 Built.Inits.resize(NestedLoopCount);
9414 Built.Updates.resize(NestedLoopCount);
9415 Built.Finals.resize(NestedLoopCount);
9416 Built.DependentCounters.resize(NestedLoopCount);
9417 Built.DependentInits.resize(NestedLoopCount);
9418 Built.FinalsConditions.resize(NestedLoopCount);
9419 {
9420 // We implement the following algorithm for obtaining the
9421 // original loop iteration variable values based on the
9422 // value of the collapsed loop iteration variable IV.
9423 //
9424 // Let n+1 be the number of collapsed loops in the nest.
9425 // Iteration variables (I0, I1, .... In)
9426 // Iteration counts (N0, N1, ... Nn)
9427 //
9428 // Acc = IV;
9429 //
9430 // To compute Ik for loop k, 0 <= k <= n, generate:
9431 // Prod = N(k+1) * N(k+2) * ... * Nn;
9432 // Ik = Acc / Prod;
9433 // Acc -= Ik * Prod;
9434 //
9435 ExprResult Acc = IV;
9436 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9437 LoopIterationSpace &IS = IterSpaces[Cnt];
9438 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9439 ExprResult Iter;
9440
9441 // Compute prod
9442 ExprResult Prod =
9443 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9444 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9445 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9446 IterSpaces[K].NumIterations);
9447
9448 // Iter = Acc / Prod
9449 // If there is at least one more inner loop to avoid
9450 // multiplication by 1.
9451 if (Cnt + 1 < NestedLoopCount)
9452 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9453 Acc.get(), Prod.get());
9454 else
9455 Iter = Acc;
9456 if (!Iter.isUsable()) {
9457 HasErrors = true;
9458 break;
9459 }
9460
9461 // Update Acc:
9462 // Acc -= Iter * Prod
9463 // Check if there is at least one more inner loop to avoid
9464 // multiplication by 1.
9465 if (Cnt + 1 < NestedLoopCount)
9466 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9467 Iter.get(), Prod.get());
9468 else
9469 Prod = Iter;
9470 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9471 Acc.get(), Prod.get());
9472
9473 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9474 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9475 DeclRefExpr *CounterVar = buildDeclRefExpr(
9476 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9477 /*RefersToCapture=*/true);
9478 ExprResult Init =
9479 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9480 IS.CounterInit, IS.IsNonRectangularLB, Captures);
9481 if (!Init.isUsable()) {
9482 HasErrors = true;
9483 break;
9484 }
9485 ExprResult Update = buildCounterUpdate(
9486 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9487 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9488 if (!Update.isUsable()) {
9489 HasErrors = true;
9490 break;
9491 }
9492
9493 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9494 ExprResult Final =
9495 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9496 IS.CounterInit, IS.NumIterations, IS.CounterStep,
9497 IS.Subtract, IS.IsNonRectangularLB, &Captures);
9498 if (!Final.isUsable()) {
9499 HasErrors = true;
9500 break;
9501 }
9502
9503 if (!Update.isUsable() || !Final.isUsable()) {
9504 HasErrors = true;
9505 break;
9506 }
9507 // Save results
9508 Built.Counters[Cnt] = IS.CounterVar;
9509 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9510 Built.Inits[Cnt] = Init.get();
9511 Built.Updates[Cnt] = Update.get();
9512 Built.Finals[Cnt] = Final.get();
9513 Built.DependentCounters[Cnt] = nullptr;
9514 Built.DependentInits[Cnt] = nullptr;
9515 Built.FinalsConditions[Cnt] = nullptr;
9516 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9517 Built.DependentCounters[Cnt] =
9518 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9519 Built.DependentInits[Cnt] =
9520 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9521 Built.FinalsConditions[Cnt] = IS.FinalCondition;
9522 }
9523 }
9524 }
9525
9526 if (HasErrors)
9527 return 0;
9528
9529 // Save results
9530 Built.IterationVarRef = IV.get();
9531 Built.LastIteration = LastIteration.get();
9532 Built.NumIterations = NumIterations.get();
9533 Built.CalcLastIteration = SemaRef
9534 .ActOnFinishFullExpr(CalcLastIteration.get(),
9535 /*DiscardedValue=*/false)
9536 .get();
9537 Built.PreCond = PreCond.get();
9538 Built.PreInits = buildPreInits(C, Captures);
9539 Built.Cond = Cond.get();
9540 Built.Init = Init.get();
9541 Built.Inc = Inc.get();
9542 Built.LB = LB.get();
9543 Built.UB = UB.get();
9544 Built.IL = IL.get();
9545 Built.ST = ST.get();
9546 Built.EUB = EUB.get();
9547 Built.NLB = NextLB.get();
9548 Built.NUB = NextUB.get();
9549 Built.PrevLB = PrevLB.get();
9550 Built.PrevUB = PrevUB.get();
9551 Built.DistInc = DistInc.get();
9552 Built.PrevEUB = PrevEUB.get();
9553 Built.DistCombinedFields.LB = CombLB.get();
9554 Built.DistCombinedFields.UB = CombUB.get();
9555 Built.DistCombinedFields.EUB = CombEUB.get();
9556 Built.DistCombinedFields.Init = CombInit.get();
9557 Built.DistCombinedFields.Cond = CombCond.get();
9558 Built.DistCombinedFields.NLB = CombNextLB.get();
9559 Built.DistCombinedFields.NUB = CombNextUB.get();
9560 Built.DistCombinedFields.DistCond = CombDistCond.get();
9561 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9562
9563 return NestedLoopCount;
9564 }
9565
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)9566 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9567 auto CollapseClauses =
9568 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9569 if (CollapseClauses.begin() != CollapseClauses.end())
9570 return (*CollapseClauses.begin())->getNumForLoops();
9571 return nullptr;
9572 }
9573
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)9574 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9575 auto OrderedClauses =
9576 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9577 if (OrderedClauses.begin() != OrderedClauses.end())
9578 return (*OrderedClauses.begin())->getNumForLoops();
9579 return nullptr;
9580 }
9581
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)9582 static bool checkSimdlenSafelenSpecified(Sema &S,
9583 const ArrayRef<OMPClause *> Clauses) {
9584 const OMPSafelenClause *Safelen = nullptr;
9585 const OMPSimdlenClause *Simdlen = nullptr;
9586
9587 for (const OMPClause *Clause : Clauses) {
9588 if (Clause->getClauseKind() == OMPC_safelen)
9589 Safelen = cast<OMPSafelenClause>(Clause);
9590 else if (Clause->getClauseKind() == OMPC_simdlen)
9591 Simdlen = cast<OMPSimdlenClause>(Clause);
9592 if (Safelen && Simdlen)
9593 break;
9594 }
9595
9596 if (Simdlen && Safelen) {
9597 const Expr *SimdlenLength = Simdlen->getSimdlen();
9598 const Expr *SafelenLength = Safelen->getSafelen();
9599 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9600 SimdlenLength->isInstantiationDependent() ||
9601 SimdlenLength->containsUnexpandedParameterPack())
9602 return false;
9603 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9604 SafelenLength->isInstantiationDependent() ||
9605 SafelenLength->containsUnexpandedParameterPack())
9606 return false;
9607 Expr::EvalResult SimdlenResult, SafelenResult;
9608 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9609 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9610 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9611 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9612 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9613 // If both simdlen and safelen clauses are specified, the value of the
9614 // simdlen parameter must be less than or equal to the value of the safelen
9615 // parameter.
9616 if (SimdlenRes > SafelenRes) {
9617 S.Diag(SimdlenLength->getExprLoc(),
9618 diag::err_omp_wrong_simdlen_safelen_values)
9619 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9620 return true;
9621 }
9622 }
9623 return false;
9624 }
9625
9626 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9627 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9628 SourceLocation StartLoc, SourceLocation EndLoc,
9629 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9630 if (!AStmt)
9631 return StmtError();
9632
9633 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9634 OMPLoopBasedDirective::HelperExprs B;
9635 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9636 // define the nested loops number.
9637 unsigned NestedLoopCount = checkOpenMPLoop(
9638 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9639 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9640 if (NestedLoopCount == 0)
9641 return StmtError();
9642
9643 assert((CurContext->isDependentContext() || B.builtAll()) &&
9644 "omp simd loop exprs were not built");
9645
9646 if (!CurContext->isDependentContext()) {
9647 // Finalize the clauses that need pre-built expressions for CodeGen.
9648 for (OMPClause *C : Clauses) {
9649 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9650 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9651 B.NumIterations, *this, CurScope,
9652 DSAStack))
9653 return StmtError();
9654 }
9655 }
9656
9657 if (checkSimdlenSafelenSpecified(*this, Clauses))
9658 return StmtError();
9659
9660 setFunctionHasBranchProtectedScope();
9661 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9662 Clauses, AStmt, B);
9663 }
9664
9665 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9666 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9667 SourceLocation StartLoc, SourceLocation EndLoc,
9668 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9669 if (!AStmt)
9670 return StmtError();
9671
9672 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9673 OMPLoopBasedDirective::HelperExprs B;
9674 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9675 // define the nested loops number.
9676 unsigned NestedLoopCount = checkOpenMPLoop(
9677 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9678 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9679 if (NestedLoopCount == 0)
9680 return StmtError();
9681
9682 assert((CurContext->isDependentContext() || B.builtAll()) &&
9683 "omp for loop exprs were not built");
9684
9685 if (!CurContext->isDependentContext()) {
9686 // Finalize the clauses that need pre-built expressions for CodeGen.
9687 for (OMPClause *C : Clauses) {
9688 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9689 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9690 B.NumIterations, *this, CurScope,
9691 DSAStack))
9692 return StmtError();
9693 }
9694 }
9695
9696 setFunctionHasBranchProtectedScope();
9697 return OMPForDirective::Create(
9698 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9699 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9700 }
9701
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9702 StmtResult Sema::ActOnOpenMPForSimdDirective(
9703 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9704 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9705 if (!AStmt)
9706 return StmtError();
9707
9708 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9709 OMPLoopBasedDirective::HelperExprs B;
9710 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9711 // define the nested loops number.
9712 unsigned NestedLoopCount =
9713 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9714 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9715 VarsWithImplicitDSA, B);
9716 if (NestedLoopCount == 0)
9717 return StmtError();
9718
9719 assert((CurContext->isDependentContext() || B.builtAll()) &&
9720 "omp for simd loop exprs were not built");
9721
9722 if (!CurContext->isDependentContext()) {
9723 // Finalize the clauses that need pre-built expressions for CodeGen.
9724 for (OMPClause *C : Clauses) {
9725 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9726 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9727 B.NumIterations, *this, CurScope,
9728 DSAStack))
9729 return StmtError();
9730 }
9731 }
9732
9733 if (checkSimdlenSafelenSpecified(*this, Clauses))
9734 return StmtError();
9735
9736 setFunctionHasBranchProtectedScope();
9737 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9738 Clauses, AStmt, B);
9739 }
9740
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9741 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9742 Stmt *AStmt,
9743 SourceLocation StartLoc,
9744 SourceLocation EndLoc) {
9745 if (!AStmt)
9746 return StmtError();
9747
9748 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9749 auto BaseStmt = AStmt;
9750 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9751 BaseStmt = CS->getCapturedStmt();
9752 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9753 auto S = C->children();
9754 if (S.begin() == S.end())
9755 return StmtError();
9756 // All associated statements must be '#pragma omp section' except for
9757 // the first one.
9758 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9759 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9760 if (SectionStmt)
9761 Diag(SectionStmt->getBeginLoc(),
9762 diag::err_omp_sections_substmt_not_section);
9763 return StmtError();
9764 }
9765 cast<OMPSectionDirective>(SectionStmt)
9766 ->setHasCancel(DSAStack->isCancelRegion());
9767 }
9768 } else {
9769 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9770 return StmtError();
9771 }
9772
9773 setFunctionHasBranchProtectedScope();
9774
9775 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9776 DSAStack->getTaskgroupReductionRef(),
9777 DSAStack->isCancelRegion());
9778 }
9779
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9780 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9781 SourceLocation StartLoc,
9782 SourceLocation EndLoc) {
9783 if (!AStmt)
9784 return StmtError();
9785
9786 setFunctionHasBranchProtectedScope();
9787 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9788
9789 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9790 DSAStack->isCancelRegion());
9791 }
9792
getDirectCallExpr(Expr * E)9793 static Expr *getDirectCallExpr(Expr *E) {
9794 E = E->IgnoreParenCasts()->IgnoreImplicit();
9795 if (auto *CE = dyn_cast<CallExpr>(E))
9796 if (CE->getDirectCallee())
9797 return E;
9798 return nullptr;
9799 }
9800
ActOnOpenMPDispatchDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9801 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
9802 Stmt *AStmt,
9803 SourceLocation StartLoc,
9804 SourceLocation EndLoc) {
9805 if (!AStmt)
9806 return StmtError();
9807
9808 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
9809
9810 // 5.1 OpenMP
9811 // expression-stmt : an expression statement with one of the following forms:
9812 // expression = target-call ( [expression-list] );
9813 // target-call ( [expression-list] );
9814
9815 SourceLocation TargetCallLoc;
9816
9817 if (!CurContext->isDependentContext()) {
9818 Expr *TargetCall = nullptr;
9819
9820 auto *E = dyn_cast<Expr>(S);
9821 if (!E) {
9822 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9823 return StmtError();
9824 }
9825
9826 E = E->IgnoreParenCasts()->IgnoreImplicit();
9827
9828 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
9829 if (BO->getOpcode() == BO_Assign)
9830 TargetCall = getDirectCallExpr(BO->getRHS());
9831 } else {
9832 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
9833 if (COCE->getOperator() == OO_Equal)
9834 TargetCall = getDirectCallExpr(COCE->getArg(1));
9835 if (!TargetCall)
9836 TargetCall = getDirectCallExpr(E);
9837 }
9838 if (!TargetCall) {
9839 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9840 return StmtError();
9841 }
9842 TargetCallLoc = TargetCall->getExprLoc();
9843 }
9844
9845 setFunctionHasBranchProtectedScope();
9846
9847 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9848 TargetCallLoc);
9849 }
9850
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9851 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9852 Stmt *AStmt,
9853 SourceLocation StartLoc,
9854 SourceLocation EndLoc) {
9855 if (!AStmt)
9856 return StmtError();
9857
9858 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9859
9860 setFunctionHasBranchProtectedScope();
9861
9862 // OpenMP [2.7.3, single Construct, Restrictions]
9863 // The copyprivate clause must not be used with the nowait clause.
9864 const OMPClause *Nowait = nullptr;
9865 const OMPClause *Copyprivate = nullptr;
9866 for (const OMPClause *Clause : Clauses) {
9867 if (Clause->getClauseKind() == OMPC_nowait)
9868 Nowait = Clause;
9869 else if (Clause->getClauseKind() == OMPC_copyprivate)
9870 Copyprivate = Clause;
9871 if (Copyprivate && Nowait) {
9872 Diag(Copyprivate->getBeginLoc(),
9873 diag::err_omp_single_copyprivate_with_nowait);
9874 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9875 return StmtError();
9876 }
9877 }
9878
9879 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9880 }
9881
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9882 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9883 SourceLocation StartLoc,
9884 SourceLocation EndLoc) {
9885 if (!AStmt)
9886 return StmtError();
9887
9888 setFunctionHasBranchProtectedScope();
9889
9890 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9891 }
9892
ActOnOpenMPMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9893 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
9894 Stmt *AStmt,
9895 SourceLocation StartLoc,
9896 SourceLocation EndLoc) {
9897 if (!AStmt)
9898 return StmtError();
9899
9900 setFunctionHasBranchProtectedScope();
9901
9902 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9903 }
9904
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9905 StmtResult Sema::ActOnOpenMPCriticalDirective(
9906 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9907 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9908 if (!AStmt)
9909 return StmtError();
9910
9911 bool ErrorFound = false;
9912 llvm::APSInt Hint;
9913 SourceLocation HintLoc;
9914 bool DependentHint = false;
9915 for (const OMPClause *C : Clauses) {
9916 if (C->getClauseKind() == OMPC_hint) {
9917 if (!DirName.getName()) {
9918 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9919 ErrorFound = true;
9920 }
9921 Expr *E = cast<OMPHintClause>(C)->getHint();
9922 if (E->isTypeDependent() || E->isValueDependent() ||
9923 E->isInstantiationDependent()) {
9924 DependentHint = true;
9925 } else {
9926 Hint = E->EvaluateKnownConstInt(Context);
9927 HintLoc = C->getBeginLoc();
9928 }
9929 }
9930 }
9931 if (ErrorFound)
9932 return StmtError();
9933 const auto Pair = DSAStack->getCriticalWithHint(DirName);
9934 if (Pair.first && DirName.getName() && !DependentHint) {
9935 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9936 Diag(StartLoc, diag::err_omp_critical_with_hint);
9937 if (HintLoc.isValid())
9938 Diag(HintLoc, diag::note_omp_critical_hint_here)
9939 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9940 else
9941 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9942 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9943 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9944 << 1
9945 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9946 /*Radix=*/10, /*Signed=*/false);
9947 } else {
9948 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9949 }
9950 }
9951 }
9952
9953 setFunctionHasBranchProtectedScope();
9954
9955 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9956 Clauses, AStmt);
9957 if (!Pair.first && DirName.getName() && !DependentHint)
9958 DSAStack->addCriticalWithHint(Dir, Hint);
9959 return Dir;
9960 }
9961
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9962 StmtResult Sema::ActOnOpenMPParallelForDirective(
9963 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9964 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9965 if (!AStmt)
9966 return StmtError();
9967
9968 auto *CS = cast<CapturedStmt>(AStmt);
9969 // 1.2.2 OpenMP Language Terminology
9970 // Structured block - An executable statement with a single entry at the
9971 // top and a single exit at the bottom.
9972 // The point of exit cannot be a branch out of the structured block.
9973 // longjmp() and throw() must not violate the entry/exit criteria.
9974 CS->getCapturedDecl()->setNothrow();
9975
9976 OMPLoopBasedDirective::HelperExprs B;
9977 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9978 // define the nested loops number.
9979 unsigned NestedLoopCount =
9980 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9981 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9982 VarsWithImplicitDSA, B);
9983 if (NestedLoopCount == 0)
9984 return StmtError();
9985
9986 assert((CurContext->isDependentContext() || B.builtAll()) &&
9987 "omp parallel for loop exprs were not built");
9988
9989 if (!CurContext->isDependentContext()) {
9990 // Finalize the clauses that need pre-built expressions for CodeGen.
9991 for (OMPClause *C : Clauses) {
9992 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9993 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9994 B.NumIterations, *this, CurScope,
9995 DSAStack))
9996 return StmtError();
9997 }
9998 }
9999
10000 setFunctionHasBranchProtectedScope();
10001 return OMPParallelForDirective::Create(
10002 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10003 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10004 }
10005
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10006 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10007 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10008 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10009 if (!AStmt)
10010 return StmtError();
10011
10012 auto *CS = cast<CapturedStmt>(AStmt);
10013 // 1.2.2 OpenMP Language Terminology
10014 // Structured block - An executable statement with a single entry at the
10015 // top and a single exit at the bottom.
10016 // The point of exit cannot be a branch out of the structured block.
10017 // longjmp() and throw() must not violate the entry/exit criteria.
10018 CS->getCapturedDecl()->setNothrow();
10019
10020 OMPLoopBasedDirective::HelperExprs B;
10021 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10022 // define the nested loops number.
10023 unsigned NestedLoopCount =
10024 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10025 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10026 VarsWithImplicitDSA, B);
10027 if (NestedLoopCount == 0)
10028 return StmtError();
10029
10030 if (!CurContext->isDependentContext()) {
10031 // Finalize the clauses that need pre-built expressions for CodeGen.
10032 for (OMPClause *C : Clauses) {
10033 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10034 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10035 B.NumIterations, *this, CurScope,
10036 DSAStack))
10037 return StmtError();
10038 }
10039 }
10040
10041 if (checkSimdlenSafelenSpecified(*this, Clauses))
10042 return StmtError();
10043
10044 setFunctionHasBranchProtectedScope();
10045 return OMPParallelForSimdDirective::Create(
10046 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10047 }
10048
10049 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10050 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10051 Stmt *AStmt, SourceLocation StartLoc,
10052 SourceLocation EndLoc) {
10053 if (!AStmt)
10054 return StmtError();
10055
10056 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10057 auto *CS = cast<CapturedStmt>(AStmt);
10058 // 1.2.2 OpenMP Language Terminology
10059 // Structured block - An executable statement with a single entry at the
10060 // top and a single exit at the bottom.
10061 // The point of exit cannot be a branch out of the structured block.
10062 // longjmp() and throw() must not violate the entry/exit criteria.
10063 CS->getCapturedDecl()->setNothrow();
10064
10065 setFunctionHasBranchProtectedScope();
10066
10067 return OMPParallelMasterDirective::Create(
10068 Context, StartLoc, EndLoc, Clauses, AStmt,
10069 DSAStack->getTaskgroupReductionRef());
10070 }
10071
10072 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10073 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10074 Stmt *AStmt, SourceLocation StartLoc,
10075 SourceLocation EndLoc) {
10076 if (!AStmt)
10077 return StmtError();
10078
10079 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10080 auto BaseStmt = AStmt;
10081 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10082 BaseStmt = CS->getCapturedStmt();
10083 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10084 auto S = C->children();
10085 if (S.begin() == S.end())
10086 return StmtError();
10087 // All associated statements must be '#pragma omp section' except for
10088 // the first one.
10089 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
10090 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10091 if (SectionStmt)
10092 Diag(SectionStmt->getBeginLoc(),
10093 diag::err_omp_parallel_sections_substmt_not_section);
10094 return StmtError();
10095 }
10096 cast<OMPSectionDirective>(SectionStmt)
10097 ->setHasCancel(DSAStack->isCancelRegion());
10098 }
10099 } else {
10100 Diag(AStmt->getBeginLoc(),
10101 diag::err_omp_parallel_sections_not_compound_stmt);
10102 return StmtError();
10103 }
10104
10105 setFunctionHasBranchProtectedScope();
10106
10107 return OMPParallelSectionsDirective::Create(
10108 Context, StartLoc, EndLoc, Clauses, AStmt,
10109 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10110 }
10111
10112 /// detach and mergeable clauses are mutially exclusive, check for it.
checkDetachMergeableClauses(Sema & S,ArrayRef<OMPClause * > Clauses)10113 static bool checkDetachMergeableClauses(Sema &S,
10114 ArrayRef<OMPClause *> Clauses) {
10115 const OMPClause *PrevClause = nullptr;
10116 bool ErrorFound = false;
10117 for (const OMPClause *C : Clauses) {
10118 if (C->getClauseKind() == OMPC_detach ||
10119 C->getClauseKind() == OMPC_mergeable) {
10120 if (!PrevClause) {
10121 PrevClause = C;
10122 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10123 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10124 << getOpenMPClauseName(C->getClauseKind())
10125 << getOpenMPClauseName(PrevClause->getClauseKind());
10126 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10127 << getOpenMPClauseName(PrevClause->getClauseKind());
10128 ErrorFound = true;
10129 }
10130 }
10131 }
10132 return ErrorFound;
10133 }
10134
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10135 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10136 Stmt *AStmt, SourceLocation StartLoc,
10137 SourceLocation EndLoc) {
10138 if (!AStmt)
10139 return StmtError();
10140
10141 // OpenMP 5.0, 2.10.1 task Construct
10142 // If a detach clause appears on the directive, then a mergeable clause cannot
10143 // appear on the same directive.
10144 if (checkDetachMergeableClauses(*this, Clauses))
10145 return StmtError();
10146
10147 auto *CS = cast<CapturedStmt>(AStmt);
10148 // 1.2.2 OpenMP Language Terminology
10149 // Structured block - An executable statement with a single entry at the
10150 // top and a single exit at the bottom.
10151 // The point of exit cannot be a branch out of the structured block.
10152 // longjmp() and throw() must not violate the entry/exit criteria.
10153 CS->getCapturedDecl()->setNothrow();
10154
10155 setFunctionHasBranchProtectedScope();
10156
10157 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10158 DSAStack->isCancelRegion());
10159 }
10160
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)10161 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10162 SourceLocation EndLoc) {
10163 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10164 }
10165
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)10166 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10167 SourceLocation EndLoc) {
10168 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10169 }
10170
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)10171 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
10172 SourceLocation EndLoc) {
10173 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
10174 }
10175
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10176 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10177 Stmt *AStmt,
10178 SourceLocation StartLoc,
10179 SourceLocation EndLoc) {
10180 if (!AStmt)
10181 return StmtError();
10182
10183 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10184
10185 setFunctionHasBranchProtectedScope();
10186
10187 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10188 AStmt,
10189 DSAStack->getTaskgroupReductionRef());
10190 }
10191
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10192 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10193 SourceLocation StartLoc,
10194 SourceLocation EndLoc) {
10195 OMPFlushClause *FC = nullptr;
10196 OMPClause *OrderClause = nullptr;
10197 for (OMPClause *C : Clauses) {
10198 if (C->getClauseKind() == OMPC_flush)
10199 FC = cast<OMPFlushClause>(C);
10200 else
10201 OrderClause = C;
10202 }
10203 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10204 SourceLocation MemOrderLoc;
10205 for (const OMPClause *C : Clauses) {
10206 if (C->getClauseKind() == OMPC_acq_rel ||
10207 C->getClauseKind() == OMPC_acquire ||
10208 C->getClauseKind() == OMPC_release) {
10209 if (MemOrderKind != OMPC_unknown) {
10210 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10211 << getOpenMPDirectiveName(OMPD_flush) << 1
10212 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10213 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10214 << getOpenMPClauseName(MemOrderKind);
10215 } else {
10216 MemOrderKind = C->getClauseKind();
10217 MemOrderLoc = C->getBeginLoc();
10218 }
10219 }
10220 }
10221 if (FC && OrderClause) {
10222 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10223 << getOpenMPClauseName(OrderClause->getClauseKind());
10224 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10225 << getOpenMPClauseName(OrderClause->getClauseKind());
10226 return StmtError();
10227 }
10228 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10229 }
10230
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10231 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10232 SourceLocation StartLoc,
10233 SourceLocation EndLoc) {
10234 if (Clauses.empty()) {
10235 Diag(StartLoc, diag::err_omp_depobj_expected);
10236 return StmtError();
10237 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10238 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10239 return StmtError();
10240 }
10241 // Only depobj expression and another single clause is allowed.
10242 if (Clauses.size() > 2) {
10243 Diag(Clauses[2]->getBeginLoc(),
10244 diag::err_omp_depobj_single_clause_expected);
10245 return StmtError();
10246 } else if (Clauses.size() < 1) {
10247 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10248 return StmtError();
10249 }
10250 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10251 }
10252
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10253 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10254 SourceLocation StartLoc,
10255 SourceLocation EndLoc) {
10256 // Check that exactly one clause is specified.
10257 if (Clauses.size() != 1) {
10258 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10259 diag::err_omp_scan_single_clause_expected);
10260 return StmtError();
10261 }
10262 // Check that scan directive is used in the scopeof the OpenMP loop body.
10263 if (Scope *S = DSAStack->getCurScope()) {
10264 Scope *ParentS = S->getParent();
10265 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10266 !ParentS->getBreakParent()->isOpenMPLoopScope())
10267 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10268 << getOpenMPDirectiveName(OMPD_scan) << 5);
10269 }
10270 // Check that only one instance of scan directives is used in the same outer
10271 // region.
10272 if (DSAStack->doesParentHasScanDirective()) {
10273 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10274 Diag(DSAStack->getParentScanDirectiveLoc(),
10275 diag::note_omp_previous_directive)
10276 << "scan";
10277 return StmtError();
10278 }
10279 DSAStack->setParentHasScanDirective(StartLoc);
10280 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10281 }
10282
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10283 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10284 Stmt *AStmt,
10285 SourceLocation StartLoc,
10286 SourceLocation EndLoc) {
10287 const OMPClause *DependFound = nullptr;
10288 const OMPClause *DependSourceClause = nullptr;
10289 const OMPClause *DependSinkClause = nullptr;
10290 bool ErrorFound = false;
10291 const OMPThreadsClause *TC = nullptr;
10292 const OMPSIMDClause *SC = nullptr;
10293 for (const OMPClause *C : Clauses) {
10294 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10295 DependFound = C;
10296 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10297 if (DependSourceClause) {
10298 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10299 << getOpenMPDirectiveName(OMPD_ordered)
10300 << getOpenMPClauseName(OMPC_depend) << 2;
10301 ErrorFound = true;
10302 } else {
10303 DependSourceClause = C;
10304 }
10305 if (DependSinkClause) {
10306 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10307 << 0;
10308 ErrorFound = true;
10309 }
10310 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10311 if (DependSourceClause) {
10312 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10313 << 1;
10314 ErrorFound = true;
10315 }
10316 DependSinkClause = C;
10317 }
10318 } else if (C->getClauseKind() == OMPC_threads) {
10319 TC = cast<OMPThreadsClause>(C);
10320 } else if (C->getClauseKind() == OMPC_simd) {
10321 SC = cast<OMPSIMDClause>(C);
10322 }
10323 }
10324 if (!ErrorFound && !SC &&
10325 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
10326 // OpenMP [2.8.1,simd Construct, Restrictions]
10327 // An ordered construct with the simd clause is the only OpenMP construct
10328 // that can appear in the simd region.
10329 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10330 << (LangOpts.OpenMP >= 50 ? 1 : 0);
10331 ErrorFound = true;
10332 } else if (DependFound && (TC || SC)) {
10333 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10334 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10335 ErrorFound = true;
10336 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
10337 Diag(DependFound->getBeginLoc(),
10338 diag::err_omp_ordered_directive_without_param);
10339 ErrorFound = true;
10340 } else if (TC || Clauses.empty()) {
10341 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
10342 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10343 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10344 << (TC != nullptr);
10345 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10346 ErrorFound = true;
10347 }
10348 }
10349 if ((!AStmt && !DependFound) || ErrorFound)
10350 return StmtError();
10351
10352 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10353 // During execution of an iteration of a worksharing-loop or a loop nest
10354 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10355 // must not execute more than one ordered region corresponding to an ordered
10356 // construct without a depend clause.
10357 if (!DependFound) {
10358 if (DSAStack->doesParentHasOrderedDirective()) {
10359 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10360 Diag(DSAStack->getParentOrderedDirectiveLoc(),
10361 diag::note_omp_previous_directive)
10362 << "ordered";
10363 return StmtError();
10364 }
10365 DSAStack->setParentHasOrderedDirective(StartLoc);
10366 }
10367
10368 if (AStmt) {
10369 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10370
10371 setFunctionHasBranchProtectedScope();
10372 }
10373
10374 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10375 }
10376
10377 namespace {
10378 /// Helper class for checking expression in 'omp atomic [update]'
10379 /// construct.
10380 class OpenMPAtomicUpdateChecker {
10381 /// Error results for atomic update expressions.
10382 enum ExprAnalysisErrorCode {
10383 /// A statement is not an expression statement.
10384 NotAnExpression,
10385 /// Expression is not builtin binary or unary operation.
10386 NotABinaryOrUnaryExpression,
10387 /// Unary operation is not post-/pre- increment/decrement operation.
10388 NotAnUnaryIncDecExpression,
10389 /// An expression is not of scalar type.
10390 NotAScalarType,
10391 /// A binary operation is not an assignment operation.
10392 NotAnAssignmentOp,
10393 /// RHS part of the binary operation is not a binary expression.
10394 NotABinaryExpression,
10395 /// RHS part is not additive/multiplicative/shift/biwise binary
10396 /// expression.
10397 NotABinaryOperator,
10398 /// RHS binary operation does not have reference to the updated LHS
10399 /// part.
10400 NotAnUpdateExpression,
10401 /// No errors is found.
10402 NoError
10403 };
10404 /// Reference to Sema.
10405 Sema &SemaRef;
10406 /// A location for note diagnostics (when error is found).
10407 SourceLocation NoteLoc;
10408 /// 'x' lvalue part of the source atomic expression.
10409 Expr *X;
10410 /// 'expr' rvalue part of the source atomic expression.
10411 Expr *E;
10412 /// Helper expression of the form
10413 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10414 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10415 Expr *UpdateExpr;
10416 /// Is 'x' a LHS in a RHS part of full update expression. It is
10417 /// important for non-associative operations.
10418 bool IsXLHSInRHSPart;
10419 BinaryOperatorKind Op;
10420 SourceLocation OpLoc;
10421 /// true if the source expression is a postfix unary operation, false
10422 /// if it is a prefix unary operation.
10423 bool IsPostfixUpdate;
10424
10425 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)10426 OpenMPAtomicUpdateChecker(Sema &SemaRef)
10427 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10428 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10429 /// Check specified statement that it is suitable for 'atomic update'
10430 /// constructs and extract 'x', 'expr' and Operation from the original
10431 /// expression. If DiagId and NoteId == 0, then only check is performed
10432 /// without error notification.
10433 /// \param DiagId Diagnostic which should be emitted if error is found.
10434 /// \param NoteId Diagnostic note for the main error message.
10435 /// \return true if statement is not an update expression, false otherwise.
10436 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10437 /// Return the 'x' lvalue part of the source atomic expression.
getX() const10438 Expr *getX() const { return X; }
10439 /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const10440 Expr *getExpr() const { return E; }
10441 /// Return the update expression used in calculation of the updated
10442 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10443 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const10444 Expr *getUpdateExpr() const { return UpdateExpr; }
10445 /// Return true if 'x' is LHS in RHS part of full update expression,
10446 /// false otherwise.
isXLHSInRHSPart() const10447 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10448
10449 /// true if the source expression is a postfix unary operation, false
10450 /// if it is a prefix unary operation.
isPostfixUpdate() const10451 bool isPostfixUpdate() const { return IsPostfixUpdate; }
10452
10453 private:
10454 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10455 unsigned NoteId = 0);
10456 };
10457 } // namespace
10458
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)10459 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10460 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10461 ExprAnalysisErrorCode ErrorFound = NoError;
10462 SourceLocation ErrorLoc, NoteLoc;
10463 SourceRange ErrorRange, NoteRange;
10464 // Allowed constructs are:
10465 // x = x binop expr;
10466 // x = expr binop x;
10467 if (AtomicBinOp->getOpcode() == BO_Assign) {
10468 X = AtomicBinOp->getLHS();
10469 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10470 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10471 if (AtomicInnerBinOp->isMultiplicativeOp() ||
10472 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10473 AtomicInnerBinOp->isBitwiseOp()) {
10474 Op = AtomicInnerBinOp->getOpcode();
10475 OpLoc = AtomicInnerBinOp->getOperatorLoc();
10476 Expr *LHS = AtomicInnerBinOp->getLHS();
10477 Expr *RHS = AtomicInnerBinOp->getRHS();
10478 llvm::FoldingSetNodeID XId, LHSId, RHSId;
10479 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10480 /*Canonical=*/true);
10481 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10482 /*Canonical=*/true);
10483 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10484 /*Canonical=*/true);
10485 if (XId == LHSId) {
10486 E = RHS;
10487 IsXLHSInRHSPart = true;
10488 } else if (XId == RHSId) {
10489 E = LHS;
10490 IsXLHSInRHSPart = false;
10491 } else {
10492 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10493 ErrorRange = AtomicInnerBinOp->getSourceRange();
10494 NoteLoc = X->getExprLoc();
10495 NoteRange = X->getSourceRange();
10496 ErrorFound = NotAnUpdateExpression;
10497 }
10498 } else {
10499 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10500 ErrorRange = AtomicInnerBinOp->getSourceRange();
10501 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10502 NoteRange = SourceRange(NoteLoc, NoteLoc);
10503 ErrorFound = NotABinaryOperator;
10504 }
10505 } else {
10506 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10507 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10508 ErrorFound = NotABinaryExpression;
10509 }
10510 } else {
10511 ErrorLoc = AtomicBinOp->getExprLoc();
10512 ErrorRange = AtomicBinOp->getSourceRange();
10513 NoteLoc = AtomicBinOp->getOperatorLoc();
10514 NoteRange = SourceRange(NoteLoc, NoteLoc);
10515 ErrorFound = NotAnAssignmentOp;
10516 }
10517 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10518 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10519 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10520 return true;
10521 }
10522 if (SemaRef.CurContext->isDependentContext())
10523 E = X = UpdateExpr = nullptr;
10524 return ErrorFound != NoError;
10525 }
10526
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)10527 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10528 unsigned NoteId) {
10529 ExprAnalysisErrorCode ErrorFound = NoError;
10530 SourceLocation ErrorLoc, NoteLoc;
10531 SourceRange ErrorRange, NoteRange;
10532 // Allowed constructs are:
10533 // x++;
10534 // x--;
10535 // ++x;
10536 // --x;
10537 // x binop= expr;
10538 // x = x binop expr;
10539 // x = expr binop x;
10540 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10541 AtomicBody = AtomicBody->IgnoreParenImpCasts();
10542 if (AtomicBody->getType()->isScalarType() ||
10543 AtomicBody->isInstantiationDependent()) {
10544 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10545 AtomicBody->IgnoreParenImpCasts())) {
10546 // Check for Compound Assignment Operation
10547 Op = BinaryOperator::getOpForCompoundAssignment(
10548 AtomicCompAssignOp->getOpcode());
10549 OpLoc = AtomicCompAssignOp->getOperatorLoc();
10550 E = AtomicCompAssignOp->getRHS();
10551 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10552 IsXLHSInRHSPart = true;
10553 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10554 AtomicBody->IgnoreParenImpCasts())) {
10555 // Check for Binary Operation
10556 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10557 return true;
10558 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10559 AtomicBody->IgnoreParenImpCasts())) {
10560 // Check for Unary Operation
10561 if (AtomicUnaryOp->isIncrementDecrementOp()) {
10562 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10563 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10564 OpLoc = AtomicUnaryOp->getOperatorLoc();
10565 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10566 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10567 IsXLHSInRHSPart = true;
10568 } else {
10569 ErrorFound = NotAnUnaryIncDecExpression;
10570 ErrorLoc = AtomicUnaryOp->getExprLoc();
10571 ErrorRange = AtomicUnaryOp->getSourceRange();
10572 NoteLoc = AtomicUnaryOp->getOperatorLoc();
10573 NoteRange = SourceRange(NoteLoc, NoteLoc);
10574 }
10575 } else if (!AtomicBody->isInstantiationDependent()) {
10576 ErrorFound = NotABinaryOrUnaryExpression;
10577 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10578 NoteRange = ErrorRange = AtomicBody->getSourceRange();
10579 }
10580 } else {
10581 ErrorFound = NotAScalarType;
10582 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10583 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10584 }
10585 } else {
10586 ErrorFound = NotAnExpression;
10587 NoteLoc = ErrorLoc = S->getBeginLoc();
10588 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10589 }
10590 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10591 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10592 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10593 return true;
10594 }
10595 if (SemaRef.CurContext->isDependentContext())
10596 E = X = UpdateExpr = nullptr;
10597 if (ErrorFound == NoError && E && X) {
10598 // Build an update expression of form 'OpaqueValueExpr(x) binop
10599 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10600 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10601 auto *OVEX = new (SemaRef.getASTContext())
10602 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
10603 auto *OVEExpr = new (SemaRef.getASTContext())
10604 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
10605 ExprResult Update =
10606 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10607 IsXLHSInRHSPart ? OVEExpr : OVEX);
10608 if (Update.isInvalid())
10609 return true;
10610 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10611 Sema::AA_Casting);
10612 if (Update.isInvalid())
10613 return true;
10614 UpdateExpr = Update.get();
10615 }
10616 return ErrorFound != NoError;
10617 }
10618
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10619 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10620 Stmt *AStmt,
10621 SourceLocation StartLoc,
10622 SourceLocation EndLoc) {
10623 // Register location of the first atomic directive.
10624 DSAStack->addAtomicDirectiveLoc(StartLoc);
10625 if (!AStmt)
10626 return StmtError();
10627
10628 // 1.2.2 OpenMP Language Terminology
10629 // Structured block - An executable statement with a single entry at the
10630 // top and a single exit at the bottom.
10631 // The point of exit cannot be a branch out of the structured block.
10632 // longjmp() and throw() must not violate the entry/exit criteria.
10633 OpenMPClauseKind AtomicKind = OMPC_unknown;
10634 SourceLocation AtomicKindLoc;
10635 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10636 SourceLocation MemOrderLoc;
10637 for (const OMPClause *C : Clauses) {
10638 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10639 C->getClauseKind() == OMPC_update ||
10640 C->getClauseKind() == OMPC_capture) {
10641 if (AtomicKind != OMPC_unknown) {
10642 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10643 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10644 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10645 << getOpenMPClauseName(AtomicKind);
10646 } else {
10647 AtomicKind = C->getClauseKind();
10648 AtomicKindLoc = C->getBeginLoc();
10649 }
10650 }
10651 if (C->getClauseKind() == OMPC_seq_cst ||
10652 C->getClauseKind() == OMPC_acq_rel ||
10653 C->getClauseKind() == OMPC_acquire ||
10654 C->getClauseKind() == OMPC_release ||
10655 C->getClauseKind() == OMPC_relaxed) {
10656 if (MemOrderKind != OMPC_unknown) {
10657 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10658 << getOpenMPDirectiveName(OMPD_atomic) << 0
10659 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10660 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10661 << getOpenMPClauseName(MemOrderKind);
10662 } else {
10663 MemOrderKind = C->getClauseKind();
10664 MemOrderLoc = C->getBeginLoc();
10665 }
10666 }
10667 }
10668 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10669 // If atomic-clause is read then memory-order-clause must not be acq_rel or
10670 // release.
10671 // If atomic-clause is write then memory-order-clause must not be acq_rel or
10672 // acquire.
10673 // If atomic-clause is update or not present then memory-order-clause must not
10674 // be acq_rel or acquire.
10675 if ((AtomicKind == OMPC_read &&
10676 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10677 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10678 AtomicKind == OMPC_unknown) &&
10679 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10680 SourceLocation Loc = AtomicKindLoc;
10681 if (AtomicKind == OMPC_unknown)
10682 Loc = StartLoc;
10683 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10684 << getOpenMPClauseName(AtomicKind)
10685 << (AtomicKind == OMPC_unknown ? 1 : 0)
10686 << getOpenMPClauseName(MemOrderKind);
10687 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10688 << getOpenMPClauseName(MemOrderKind);
10689 }
10690
10691 Stmt *Body = AStmt;
10692 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10693 Body = EWC->getSubExpr();
10694
10695 Expr *X = nullptr;
10696 Expr *V = nullptr;
10697 Expr *E = nullptr;
10698 Expr *UE = nullptr;
10699 bool IsXLHSInRHSPart = false;
10700 bool IsPostfixUpdate = false;
10701 // OpenMP [2.12.6, atomic Construct]
10702 // In the next expressions:
10703 // * x and v (as applicable) are both l-value expressions with scalar type.
10704 // * During the execution of an atomic region, multiple syntactic
10705 // occurrences of x must designate the same storage location.
10706 // * Neither of v and expr (as applicable) may access the storage location
10707 // designated by x.
10708 // * Neither of x and expr (as applicable) may access the storage location
10709 // designated by v.
10710 // * expr is an expression with scalar type.
10711 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10712 // * binop, binop=, ++, and -- are not overloaded operators.
10713 // * The expression x binop expr must be numerically equivalent to x binop
10714 // (expr). This requirement is satisfied if the operators in expr have
10715 // precedence greater than binop, or by using parentheses around expr or
10716 // subexpressions of expr.
10717 // * The expression expr binop x must be numerically equivalent to (expr)
10718 // binop x. This requirement is satisfied if the operators in expr have
10719 // precedence equal to or greater than binop, or by using parentheses around
10720 // expr or subexpressions of expr.
10721 // * For forms that allow multiple occurrences of x, the number of times
10722 // that x is evaluated is unspecified.
10723 if (AtomicKind == OMPC_read) {
10724 enum {
10725 NotAnExpression,
10726 NotAnAssignmentOp,
10727 NotAScalarType,
10728 NotAnLValue,
10729 NoError
10730 } ErrorFound = NoError;
10731 SourceLocation ErrorLoc, NoteLoc;
10732 SourceRange ErrorRange, NoteRange;
10733 // If clause is read:
10734 // v = x;
10735 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10736 const auto *AtomicBinOp =
10737 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10738 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10739 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10740 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10741 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10742 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10743 if (!X->isLValue() || !V->isLValue()) {
10744 const Expr *NotLValueExpr = X->isLValue() ? V : X;
10745 ErrorFound = NotAnLValue;
10746 ErrorLoc = AtomicBinOp->getExprLoc();
10747 ErrorRange = AtomicBinOp->getSourceRange();
10748 NoteLoc = NotLValueExpr->getExprLoc();
10749 NoteRange = NotLValueExpr->getSourceRange();
10750 }
10751 } else if (!X->isInstantiationDependent() ||
10752 !V->isInstantiationDependent()) {
10753 const Expr *NotScalarExpr =
10754 (X->isInstantiationDependent() || X->getType()->isScalarType())
10755 ? V
10756 : X;
10757 ErrorFound = NotAScalarType;
10758 ErrorLoc = AtomicBinOp->getExprLoc();
10759 ErrorRange = AtomicBinOp->getSourceRange();
10760 NoteLoc = NotScalarExpr->getExprLoc();
10761 NoteRange = NotScalarExpr->getSourceRange();
10762 }
10763 } else if (!AtomicBody->isInstantiationDependent()) {
10764 ErrorFound = NotAnAssignmentOp;
10765 ErrorLoc = AtomicBody->getExprLoc();
10766 ErrorRange = AtomicBody->getSourceRange();
10767 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10768 : AtomicBody->getExprLoc();
10769 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10770 : AtomicBody->getSourceRange();
10771 }
10772 } else {
10773 ErrorFound = NotAnExpression;
10774 NoteLoc = ErrorLoc = Body->getBeginLoc();
10775 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10776 }
10777 if (ErrorFound != NoError) {
10778 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10779 << ErrorRange;
10780 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10781 << NoteRange;
10782 return StmtError();
10783 }
10784 if (CurContext->isDependentContext())
10785 V = X = nullptr;
10786 } else if (AtomicKind == OMPC_write) {
10787 enum {
10788 NotAnExpression,
10789 NotAnAssignmentOp,
10790 NotAScalarType,
10791 NotAnLValue,
10792 NoError
10793 } ErrorFound = NoError;
10794 SourceLocation ErrorLoc, NoteLoc;
10795 SourceRange ErrorRange, NoteRange;
10796 // If clause is write:
10797 // x = expr;
10798 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10799 const auto *AtomicBinOp =
10800 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10801 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10802 X = AtomicBinOp->getLHS();
10803 E = AtomicBinOp->getRHS();
10804 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10805 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10806 if (!X->isLValue()) {
10807 ErrorFound = NotAnLValue;
10808 ErrorLoc = AtomicBinOp->getExprLoc();
10809 ErrorRange = AtomicBinOp->getSourceRange();
10810 NoteLoc = X->getExprLoc();
10811 NoteRange = X->getSourceRange();
10812 }
10813 } else if (!X->isInstantiationDependent() ||
10814 !E->isInstantiationDependent()) {
10815 const Expr *NotScalarExpr =
10816 (X->isInstantiationDependent() || X->getType()->isScalarType())
10817 ? E
10818 : X;
10819 ErrorFound = NotAScalarType;
10820 ErrorLoc = AtomicBinOp->getExprLoc();
10821 ErrorRange = AtomicBinOp->getSourceRange();
10822 NoteLoc = NotScalarExpr->getExprLoc();
10823 NoteRange = NotScalarExpr->getSourceRange();
10824 }
10825 } else if (!AtomicBody->isInstantiationDependent()) {
10826 ErrorFound = NotAnAssignmentOp;
10827 ErrorLoc = AtomicBody->getExprLoc();
10828 ErrorRange = AtomicBody->getSourceRange();
10829 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10830 : AtomicBody->getExprLoc();
10831 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10832 : AtomicBody->getSourceRange();
10833 }
10834 } else {
10835 ErrorFound = NotAnExpression;
10836 NoteLoc = ErrorLoc = Body->getBeginLoc();
10837 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10838 }
10839 if (ErrorFound != NoError) {
10840 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10841 << ErrorRange;
10842 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10843 << NoteRange;
10844 return StmtError();
10845 }
10846 if (CurContext->isDependentContext())
10847 E = X = nullptr;
10848 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10849 // If clause is update:
10850 // x++;
10851 // x--;
10852 // ++x;
10853 // --x;
10854 // x binop= expr;
10855 // x = x binop expr;
10856 // x = expr binop x;
10857 OpenMPAtomicUpdateChecker Checker(*this);
10858 if (Checker.checkStatement(
10859 Body, (AtomicKind == OMPC_update)
10860 ? diag::err_omp_atomic_update_not_expression_statement
10861 : diag::err_omp_atomic_not_expression_statement,
10862 diag::note_omp_atomic_update))
10863 return StmtError();
10864 if (!CurContext->isDependentContext()) {
10865 E = Checker.getExpr();
10866 X = Checker.getX();
10867 UE = Checker.getUpdateExpr();
10868 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10869 }
10870 } else if (AtomicKind == OMPC_capture) {
10871 enum {
10872 NotAnAssignmentOp,
10873 NotACompoundStatement,
10874 NotTwoSubstatements,
10875 NotASpecificExpression,
10876 NoError
10877 } ErrorFound = NoError;
10878 SourceLocation ErrorLoc, NoteLoc;
10879 SourceRange ErrorRange, NoteRange;
10880 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10881 // If clause is a capture:
10882 // v = x++;
10883 // v = x--;
10884 // v = ++x;
10885 // v = --x;
10886 // v = x binop= expr;
10887 // v = x = x binop expr;
10888 // v = x = expr binop x;
10889 const auto *AtomicBinOp =
10890 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10891 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10892 V = AtomicBinOp->getLHS();
10893 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10894 OpenMPAtomicUpdateChecker Checker(*this);
10895 if (Checker.checkStatement(
10896 Body, diag::err_omp_atomic_capture_not_expression_statement,
10897 diag::note_omp_atomic_update))
10898 return StmtError();
10899 E = Checker.getExpr();
10900 X = Checker.getX();
10901 UE = Checker.getUpdateExpr();
10902 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10903 IsPostfixUpdate = Checker.isPostfixUpdate();
10904 } else if (!AtomicBody->isInstantiationDependent()) {
10905 ErrorLoc = AtomicBody->getExprLoc();
10906 ErrorRange = AtomicBody->getSourceRange();
10907 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10908 : AtomicBody->getExprLoc();
10909 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10910 : AtomicBody->getSourceRange();
10911 ErrorFound = NotAnAssignmentOp;
10912 }
10913 if (ErrorFound != NoError) {
10914 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10915 << ErrorRange;
10916 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10917 return StmtError();
10918 }
10919 if (CurContext->isDependentContext())
10920 UE = V = E = X = nullptr;
10921 } else {
10922 // If clause is a capture:
10923 // { v = x; x = expr; }
10924 // { v = x; x++; }
10925 // { v = x; x--; }
10926 // { v = x; ++x; }
10927 // { v = x; --x; }
10928 // { v = x; x binop= expr; }
10929 // { v = x; x = x binop expr; }
10930 // { v = x; x = expr binop x; }
10931 // { x++; v = x; }
10932 // { x--; v = x; }
10933 // { ++x; v = x; }
10934 // { --x; v = x; }
10935 // { x binop= expr; v = x; }
10936 // { x = x binop expr; v = x; }
10937 // { x = expr binop x; v = x; }
10938 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10939 // Check that this is { expr1; expr2; }
10940 if (CS->size() == 2) {
10941 Stmt *First = CS->body_front();
10942 Stmt *Second = CS->body_back();
10943 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10944 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10945 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10946 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10947 // Need to find what subexpression is 'v' and what is 'x'.
10948 OpenMPAtomicUpdateChecker Checker(*this);
10949 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10950 BinaryOperator *BinOp = nullptr;
10951 if (IsUpdateExprFound) {
10952 BinOp = dyn_cast<BinaryOperator>(First);
10953 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10954 }
10955 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10956 // { v = x; x++; }
10957 // { v = x; x--; }
10958 // { v = x; ++x; }
10959 // { v = x; --x; }
10960 // { v = x; x binop= expr; }
10961 // { v = x; x = x binop expr; }
10962 // { v = x; x = expr binop x; }
10963 // Check that the first expression has form v = x.
10964 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10965 llvm::FoldingSetNodeID XId, PossibleXId;
10966 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10967 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10968 IsUpdateExprFound = XId == PossibleXId;
10969 if (IsUpdateExprFound) {
10970 V = BinOp->getLHS();
10971 X = Checker.getX();
10972 E = Checker.getExpr();
10973 UE = Checker.getUpdateExpr();
10974 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10975 IsPostfixUpdate = true;
10976 }
10977 }
10978 if (!IsUpdateExprFound) {
10979 IsUpdateExprFound = !Checker.checkStatement(First);
10980 BinOp = nullptr;
10981 if (IsUpdateExprFound) {
10982 BinOp = dyn_cast<BinaryOperator>(Second);
10983 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10984 }
10985 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10986 // { x++; v = x; }
10987 // { x--; v = x; }
10988 // { ++x; v = x; }
10989 // { --x; v = x; }
10990 // { x binop= expr; v = x; }
10991 // { x = x binop expr; v = x; }
10992 // { x = expr binop x; v = x; }
10993 // Check that the second expression has form v = x.
10994 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10995 llvm::FoldingSetNodeID XId, PossibleXId;
10996 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10997 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10998 IsUpdateExprFound = XId == PossibleXId;
10999 if (IsUpdateExprFound) {
11000 V = BinOp->getLHS();
11001 X = Checker.getX();
11002 E = Checker.getExpr();
11003 UE = Checker.getUpdateExpr();
11004 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11005 IsPostfixUpdate = false;
11006 }
11007 }
11008 }
11009 if (!IsUpdateExprFound) {
11010 // { v = x; x = expr; }
11011 auto *FirstExpr = dyn_cast<Expr>(First);
11012 auto *SecondExpr = dyn_cast<Expr>(Second);
11013 if (!FirstExpr || !SecondExpr ||
11014 !(FirstExpr->isInstantiationDependent() ||
11015 SecondExpr->isInstantiationDependent())) {
11016 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
11017 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
11018 ErrorFound = NotAnAssignmentOp;
11019 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
11020 : First->getBeginLoc();
11021 NoteRange = ErrorRange = FirstBinOp
11022 ? FirstBinOp->getSourceRange()
11023 : SourceRange(ErrorLoc, ErrorLoc);
11024 } else {
11025 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
11026 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
11027 ErrorFound = NotAnAssignmentOp;
11028 NoteLoc = ErrorLoc = SecondBinOp
11029 ? SecondBinOp->getOperatorLoc()
11030 : Second->getBeginLoc();
11031 NoteRange = ErrorRange =
11032 SecondBinOp ? SecondBinOp->getSourceRange()
11033 : SourceRange(ErrorLoc, ErrorLoc);
11034 } else {
11035 Expr *PossibleXRHSInFirst =
11036 FirstBinOp->getRHS()->IgnoreParenImpCasts();
11037 Expr *PossibleXLHSInSecond =
11038 SecondBinOp->getLHS()->IgnoreParenImpCasts();
11039 llvm::FoldingSetNodeID X1Id, X2Id;
11040 PossibleXRHSInFirst->Profile(X1Id, Context,
11041 /*Canonical=*/true);
11042 PossibleXLHSInSecond->Profile(X2Id, Context,
11043 /*Canonical=*/true);
11044 IsUpdateExprFound = X1Id == X2Id;
11045 if (IsUpdateExprFound) {
11046 V = FirstBinOp->getLHS();
11047 X = SecondBinOp->getLHS();
11048 E = SecondBinOp->getRHS();
11049 UE = nullptr;
11050 IsXLHSInRHSPart = false;
11051 IsPostfixUpdate = true;
11052 } else {
11053 ErrorFound = NotASpecificExpression;
11054 ErrorLoc = FirstBinOp->getExprLoc();
11055 ErrorRange = FirstBinOp->getSourceRange();
11056 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
11057 NoteRange = SecondBinOp->getRHS()->getSourceRange();
11058 }
11059 }
11060 }
11061 }
11062 }
11063 } else {
11064 NoteLoc = ErrorLoc = Body->getBeginLoc();
11065 NoteRange = ErrorRange =
11066 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11067 ErrorFound = NotTwoSubstatements;
11068 }
11069 } else {
11070 NoteLoc = ErrorLoc = Body->getBeginLoc();
11071 NoteRange = ErrorRange =
11072 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11073 ErrorFound = NotACompoundStatement;
11074 }
11075 if (ErrorFound != NoError) {
11076 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
11077 << ErrorRange;
11078 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11079 return StmtError();
11080 }
11081 if (CurContext->isDependentContext())
11082 UE = V = E = X = nullptr;
11083 }
11084 }
11085
11086 setFunctionHasBranchProtectedScope();
11087
11088 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11089 X, V, E, UE, IsXLHSInRHSPart,
11090 IsPostfixUpdate);
11091 }
11092
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11093 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
11094 Stmt *AStmt,
11095 SourceLocation StartLoc,
11096 SourceLocation EndLoc) {
11097 if (!AStmt)
11098 return StmtError();
11099
11100 auto *CS = cast<CapturedStmt>(AStmt);
11101 // 1.2.2 OpenMP Language Terminology
11102 // Structured block - An executable statement with a single entry at the
11103 // top and a single exit at the bottom.
11104 // The point of exit cannot be a branch out of the structured block.
11105 // longjmp() and throw() must not violate the entry/exit criteria.
11106 CS->getCapturedDecl()->setNothrow();
11107 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
11108 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11109 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11110 // 1.2.2 OpenMP Language Terminology
11111 // Structured block - An executable statement with a single entry at the
11112 // top and a single exit at the bottom.
11113 // The point of exit cannot be a branch out of the structured block.
11114 // longjmp() and throw() must not violate the entry/exit criteria.
11115 CS->getCapturedDecl()->setNothrow();
11116 }
11117
11118 // OpenMP [2.16, Nesting of Regions]
11119 // If specified, a teams construct must be contained within a target
11120 // construct. That target construct must contain no statements or directives
11121 // outside of the teams construct.
11122 if (DSAStack->hasInnerTeamsRegion()) {
11123 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
11124 bool OMPTeamsFound = true;
11125 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
11126 auto I = CS->body_begin();
11127 while (I != CS->body_end()) {
11128 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
11129 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
11130 OMPTeamsFound) {
11131
11132 OMPTeamsFound = false;
11133 break;
11134 }
11135 ++I;
11136 }
11137 assert(I != CS->body_end() && "Not found statement");
11138 S = *I;
11139 } else {
11140 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
11141 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
11142 }
11143 if (!OMPTeamsFound) {
11144 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
11145 Diag(DSAStack->getInnerTeamsRegionLoc(),
11146 diag::note_omp_nested_teams_construct_here);
11147 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
11148 << isa<OMPExecutableDirective>(S);
11149 return StmtError();
11150 }
11151 }
11152
11153 setFunctionHasBranchProtectedScope();
11154
11155 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11156 }
11157
11158 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11159 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
11160 Stmt *AStmt, SourceLocation StartLoc,
11161 SourceLocation EndLoc) {
11162 if (!AStmt)
11163 return StmtError();
11164
11165 auto *CS = cast<CapturedStmt>(AStmt);
11166 // 1.2.2 OpenMP Language Terminology
11167 // Structured block - An executable statement with a single entry at the
11168 // top and a single exit at the bottom.
11169 // The point of exit cannot be a branch out of the structured block.
11170 // longjmp() and throw() must not violate the entry/exit criteria.
11171 CS->getCapturedDecl()->setNothrow();
11172 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
11173 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11174 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11175 // 1.2.2 OpenMP Language Terminology
11176 // Structured block - An executable statement with a single entry at the
11177 // top and a single exit at the bottom.
11178 // The point of exit cannot be a branch out of the structured block.
11179 // longjmp() and throw() must not violate the entry/exit criteria.
11180 CS->getCapturedDecl()->setNothrow();
11181 }
11182
11183 setFunctionHasBranchProtectedScope();
11184
11185 return OMPTargetParallelDirective::Create(
11186 Context, StartLoc, EndLoc, Clauses, AStmt,
11187 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11188 }
11189
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11190 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
11191 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11192 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11193 if (!AStmt)
11194 return StmtError();
11195
11196 auto *CS = cast<CapturedStmt>(AStmt);
11197 // 1.2.2 OpenMP Language Terminology
11198 // Structured block - An executable statement with a single entry at the
11199 // top and a single exit at the bottom.
11200 // The point of exit cannot be a branch out of the structured block.
11201 // longjmp() and throw() must not violate the entry/exit criteria.
11202 CS->getCapturedDecl()->setNothrow();
11203 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11204 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11205 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11206 // 1.2.2 OpenMP Language Terminology
11207 // Structured block - An executable statement with a single entry at the
11208 // top and a single exit at the bottom.
11209 // The point of exit cannot be a branch out of the structured block.
11210 // longjmp() and throw() must not violate the entry/exit criteria.
11211 CS->getCapturedDecl()->setNothrow();
11212 }
11213
11214 OMPLoopBasedDirective::HelperExprs B;
11215 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11216 // define the nested loops number.
11217 unsigned NestedLoopCount =
11218 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
11219 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11220 VarsWithImplicitDSA, B);
11221 if (NestedLoopCount == 0)
11222 return StmtError();
11223
11224 assert((CurContext->isDependentContext() || B.builtAll()) &&
11225 "omp target parallel for loop exprs were not built");
11226
11227 if (!CurContext->isDependentContext()) {
11228 // Finalize the clauses that need pre-built expressions for CodeGen.
11229 for (OMPClause *C : Clauses) {
11230 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11231 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11232 B.NumIterations, *this, CurScope,
11233 DSAStack))
11234 return StmtError();
11235 }
11236 }
11237
11238 setFunctionHasBranchProtectedScope();
11239 return OMPTargetParallelForDirective::Create(
11240 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11241 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11242 }
11243
11244 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)11245 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
11246 const OpenMPClauseKind K) {
11247 return llvm::any_of(
11248 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
11249 }
11250
11251 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)11252 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
11253 const Params... ClauseTypes) {
11254 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
11255 }
11256
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11257 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
11258 Stmt *AStmt,
11259 SourceLocation StartLoc,
11260 SourceLocation EndLoc) {
11261 if (!AStmt)
11262 return StmtError();
11263
11264 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11265
11266 // OpenMP [2.12.2, target data Construct, Restrictions]
11267 // At least one map, use_device_addr or use_device_ptr clause must appear on
11268 // the directive.
11269 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
11270 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
11271 StringRef Expected;
11272 if (LangOpts.OpenMP < 50)
11273 Expected = "'map' or 'use_device_ptr'";
11274 else
11275 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
11276 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11277 << Expected << getOpenMPDirectiveName(OMPD_target_data);
11278 return StmtError();
11279 }
11280
11281 setFunctionHasBranchProtectedScope();
11282
11283 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11284 AStmt);
11285 }
11286
11287 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11288 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
11289 SourceLocation StartLoc,
11290 SourceLocation EndLoc, Stmt *AStmt) {
11291 if (!AStmt)
11292 return StmtError();
11293
11294 auto *CS = cast<CapturedStmt>(AStmt);
11295 // 1.2.2 OpenMP Language Terminology
11296 // Structured block - An executable statement with a single entry at the
11297 // top and a single exit at the bottom.
11298 // The point of exit cannot be a branch out of the structured block.
11299 // longjmp() and throw() must not violate the entry/exit criteria.
11300 CS->getCapturedDecl()->setNothrow();
11301 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
11302 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11303 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11304 // 1.2.2 OpenMP Language Terminology
11305 // Structured block - An executable statement with a single entry at the
11306 // top and a single exit at the bottom.
11307 // The point of exit cannot be a branch out of the structured block.
11308 // longjmp() and throw() must not violate the entry/exit criteria.
11309 CS->getCapturedDecl()->setNothrow();
11310 }
11311
11312 // OpenMP [2.10.2, Restrictions, p. 99]
11313 // At least one map clause must appear on the directive.
11314 if (!hasClauses(Clauses, OMPC_map)) {
11315 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11316 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
11317 return StmtError();
11318 }
11319
11320 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11321 AStmt);
11322 }
11323
11324 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11325 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
11326 SourceLocation StartLoc,
11327 SourceLocation EndLoc, Stmt *AStmt) {
11328 if (!AStmt)
11329 return StmtError();
11330
11331 auto *CS = cast<CapturedStmt>(AStmt);
11332 // 1.2.2 OpenMP Language Terminology
11333 // Structured block - An executable statement with a single entry at the
11334 // top and a single exit at the bottom.
11335 // The point of exit cannot be a branch out of the structured block.
11336 // longjmp() and throw() must not violate the entry/exit criteria.
11337 CS->getCapturedDecl()->setNothrow();
11338 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
11339 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11340 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11341 // 1.2.2 OpenMP Language Terminology
11342 // Structured block - An executable statement with a single entry at the
11343 // top and a single exit at the bottom.
11344 // The point of exit cannot be a branch out of the structured block.
11345 // longjmp() and throw() must not violate the entry/exit criteria.
11346 CS->getCapturedDecl()->setNothrow();
11347 }
11348
11349 // OpenMP [2.10.3, Restrictions, p. 102]
11350 // At least one map clause must appear on the directive.
11351 if (!hasClauses(Clauses, OMPC_map)) {
11352 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11353 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
11354 return StmtError();
11355 }
11356
11357 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11358 AStmt);
11359 }
11360
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11361 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
11362 SourceLocation StartLoc,
11363 SourceLocation EndLoc,
11364 Stmt *AStmt) {
11365 if (!AStmt)
11366 return StmtError();
11367
11368 auto *CS = cast<CapturedStmt>(AStmt);
11369 // 1.2.2 OpenMP Language Terminology
11370 // Structured block - An executable statement with a single entry at the
11371 // top and a single exit at the bottom.
11372 // The point of exit cannot be a branch out of the structured block.
11373 // longjmp() and throw() must not violate the entry/exit criteria.
11374 CS->getCapturedDecl()->setNothrow();
11375 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
11376 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11377 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11378 // 1.2.2 OpenMP Language Terminology
11379 // Structured block - An executable statement with a single entry at the
11380 // top and a single exit at the bottom.
11381 // The point of exit cannot be a branch out of the structured block.
11382 // longjmp() and throw() must not violate the entry/exit criteria.
11383 CS->getCapturedDecl()->setNothrow();
11384 }
11385
11386 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
11387 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
11388 return StmtError();
11389 }
11390 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
11391 AStmt);
11392 }
11393
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11394 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
11395 Stmt *AStmt, SourceLocation StartLoc,
11396 SourceLocation EndLoc) {
11397 if (!AStmt)
11398 return StmtError();
11399
11400 auto *CS = cast<CapturedStmt>(AStmt);
11401 // 1.2.2 OpenMP Language Terminology
11402 // Structured block - An executable statement with a single entry at the
11403 // top and a single exit at the bottom.
11404 // The point of exit cannot be a branch out of the structured block.
11405 // longjmp() and throw() must not violate the entry/exit criteria.
11406 CS->getCapturedDecl()->setNothrow();
11407
11408 setFunctionHasBranchProtectedScope();
11409
11410 DSAStack->setParentTeamsRegionLoc(StartLoc);
11411
11412 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11413 }
11414
11415 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11416 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
11417 SourceLocation EndLoc,
11418 OpenMPDirectiveKind CancelRegion) {
11419 if (DSAStack->isParentNowaitRegion()) {
11420 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
11421 return StmtError();
11422 }
11423 if (DSAStack->isParentOrderedRegion()) {
11424 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
11425 return StmtError();
11426 }
11427 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
11428 CancelRegion);
11429 }
11430
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11431 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
11432 SourceLocation StartLoc,
11433 SourceLocation EndLoc,
11434 OpenMPDirectiveKind CancelRegion) {
11435 if (DSAStack->isParentNowaitRegion()) {
11436 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
11437 return StmtError();
11438 }
11439 if (DSAStack->isParentOrderedRegion()) {
11440 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
11441 return StmtError();
11442 }
11443 DSAStack->setParentCancelRegion(/*Cancel=*/true);
11444 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
11445 CancelRegion);
11446 }
11447
checkGrainsizeNumTasksClauses(Sema & S,ArrayRef<OMPClause * > Clauses)11448 static bool checkGrainsizeNumTasksClauses(Sema &S,
11449 ArrayRef<OMPClause *> Clauses) {
11450 const OMPClause *PrevClause = nullptr;
11451 bool ErrorFound = false;
11452 for (const OMPClause *C : Clauses) {
11453 if (C->getClauseKind() == OMPC_grainsize ||
11454 C->getClauseKind() == OMPC_num_tasks) {
11455 if (!PrevClause)
11456 PrevClause = C;
11457 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11458 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11459 << getOpenMPClauseName(C->getClauseKind())
11460 << getOpenMPClauseName(PrevClause->getClauseKind());
11461 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11462 << getOpenMPClauseName(PrevClause->getClauseKind());
11463 ErrorFound = true;
11464 }
11465 }
11466 }
11467 return ErrorFound;
11468 }
11469
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)11470 static bool checkReductionClauseWithNogroup(Sema &S,
11471 ArrayRef<OMPClause *> Clauses) {
11472 const OMPClause *ReductionClause = nullptr;
11473 const OMPClause *NogroupClause = nullptr;
11474 for (const OMPClause *C : Clauses) {
11475 if (C->getClauseKind() == OMPC_reduction) {
11476 ReductionClause = C;
11477 if (NogroupClause)
11478 break;
11479 continue;
11480 }
11481 if (C->getClauseKind() == OMPC_nogroup) {
11482 NogroupClause = C;
11483 if (ReductionClause)
11484 break;
11485 continue;
11486 }
11487 }
11488 if (ReductionClause && NogroupClause) {
11489 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
11490 << SourceRange(NogroupClause->getBeginLoc(),
11491 NogroupClause->getEndLoc());
11492 return true;
11493 }
11494 return false;
11495 }
11496
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11497 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
11498 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11499 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11500 if (!AStmt)
11501 return StmtError();
11502
11503 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11504 OMPLoopBasedDirective::HelperExprs B;
11505 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11506 // define the nested loops number.
11507 unsigned NestedLoopCount =
11508 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11509 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11510 VarsWithImplicitDSA, B);
11511 if (NestedLoopCount == 0)
11512 return StmtError();
11513
11514 assert((CurContext->isDependentContext() || B.builtAll()) &&
11515 "omp for loop exprs were not built");
11516
11517 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11518 // The grainsize clause and num_tasks clause are mutually exclusive and may
11519 // not appear on the same taskloop directive.
11520 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11521 return StmtError();
11522 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11523 // If a reduction clause is present on the taskloop directive, the nogroup
11524 // clause must not be specified.
11525 if (checkReductionClauseWithNogroup(*this, Clauses))
11526 return StmtError();
11527
11528 setFunctionHasBranchProtectedScope();
11529 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11530 NestedLoopCount, Clauses, AStmt, B,
11531 DSAStack->isCancelRegion());
11532 }
11533
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11534 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11535 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11536 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11537 if (!AStmt)
11538 return StmtError();
11539
11540 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11541 OMPLoopBasedDirective::HelperExprs B;
11542 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11543 // define the nested loops number.
11544 unsigned NestedLoopCount =
11545 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11546 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11547 VarsWithImplicitDSA, B);
11548 if (NestedLoopCount == 0)
11549 return StmtError();
11550
11551 assert((CurContext->isDependentContext() || B.builtAll()) &&
11552 "omp for loop exprs were not built");
11553
11554 if (!CurContext->isDependentContext()) {
11555 // Finalize the clauses that need pre-built expressions for CodeGen.
11556 for (OMPClause *C : Clauses) {
11557 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11558 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11559 B.NumIterations, *this, CurScope,
11560 DSAStack))
11561 return StmtError();
11562 }
11563 }
11564
11565 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11566 // The grainsize clause and num_tasks clause are mutually exclusive and may
11567 // not appear on the same taskloop directive.
11568 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11569 return StmtError();
11570 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11571 // If a reduction clause is present on the taskloop directive, the nogroup
11572 // clause must not be specified.
11573 if (checkReductionClauseWithNogroup(*this, Clauses))
11574 return StmtError();
11575 if (checkSimdlenSafelenSpecified(*this, Clauses))
11576 return StmtError();
11577
11578 setFunctionHasBranchProtectedScope();
11579 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11580 NestedLoopCount, Clauses, AStmt, B);
11581 }
11582
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11583 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11584 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11585 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11586 if (!AStmt)
11587 return StmtError();
11588
11589 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11590 OMPLoopBasedDirective::HelperExprs B;
11591 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11592 // define the nested loops number.
11593 unsigned NestedLoopCount =
11594 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11595 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11596 VarsWithImplicitDSA, B);
11597 if (NestedLoopCount == 0)
11598 return StmtError();
11599
11600 assert((CurContext->isDependentContext() || B.builtAll()) &&
11601 "omp for loop exprs were not built");
11602
11603 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11604 // The grainsize clause and num_tasks clause are mutually exclusive and may
11605 // not appear on the same taskloop directive.
11606 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11607 return StmtError();
11608 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11609 // If a reduction clause is present on the taskloop directive, the nogroup
11610 // clause must not be specified.
11611 if (checkReductionClauseWithNogroup(*this, Clauses))
11612 return StmtError();
11613
11614 setFunctionHasBranchProtectedScope();
11615 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11616 NestedLoopCount, Clauses, AStmt, B,
11617 DSAStack->isCancelRegion());
11618 }
11619
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11620 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11621 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11622 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11623 if (!AStmt)
11624 return StmtError();
11625
11626 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11627 OMPLoopBasedDirective::HelperExprs B;
11628 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11629 // define the nested loops number.
11630 unsigned NestedLoopCount =
11631 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11632 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11633 VarsWithImplicitDSA, B);
11634 if (NestedLoopCount == 0)
11635 return StmtError();
11636
11637 assert((CurContext->isDependentContext() || B.builtAll()) &&
11638 "omp for loop exprs were not built");
11639
11640 if (!CurContext->isDependentContext()) {
11641 // Finalize the clauses that need pre-built expressions for CodeGen.
11642 for (OMPClause *C : Clauses) {
11643 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11644 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11645 B.NumIterations, *this, CurScope,
11646 DSAStack))
11647 return StmtError();
11648 }
11649 }
11650
11651 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11652 // The grainsize clause and num_tasks clause are mutually exclusive and may
11653 // not appear on the same taskloop directive.
11654 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11655 return StmtError();
11656 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11657 // If a reduction clause is present on the taskloop directive, the nogroup
11658 // clause must not be specified.
11659 if (checkReductionClauseWithNogroup(*this, Clauses))
11660 return StmtError();
11661 if (checkSimdlenSafelenSpecified(*this, Clauses))
11662 return StmtError();
11663
11664 setFunctionHasBranchProtectedScope();
11665 return OMPMasterTaskLoopSimdDirective::Create(
11666 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11667 }
11668
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11669 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11670 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11671 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11672 if (!AStmt)
11673 return StmtError();
11674
11675 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11676 auto *CS = cast<CapturedStmt>(AStmt);
11677 // 1.2.2 OpenMP Language Terminology
11678 // Structured block - An executable statement with a single entry at the
11679 // top and a single exit at the bottom.
11680 // The point of exit cannot be a branch out of the structured block.
11681 // longjmp() and throw() must not violate the entry/exit criteria.
11682 CS->getCapturedDecl()->setNothrow();
11683 for (int ThisCaptureLevel =
11684 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11685 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11686 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11687 // 1.2.2 OpenMP Language Terminology
11688 // Structured block - An executable statement with a single entry at the
11689 // top and a single exit at the bottom.
11690 // The point of exit cannot be a branch out of the structured block.
11691 // longjmp() and throw() must not violate the entry/exit criteria.
11692 CS->getCapturedDecl()->setNothrow();
11693 }
11694
11695 OMPLoopBasedDirective::HelperExprs B;
11696 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11697 // define the nested loops number.
11698 unsigned NestedLoopCount = checkOpenMPLoop(
11699 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11700 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11701 VarsWithImplicitDSA, B);
11702 if (NestedLoopCount == 0)
11703 return StmtError();
11704
11705 assert((CurContext->isDependentContext() || B.builtAll()) &&
11706 "omp for loop exprs were not built");
11707
11708 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11709 // The grainsize clause and num_tasks clause are mutually exclusive and may
11710 // not appear on the same taskloop directive.
11711 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11712 return StmtError();
11713 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11714 // If a reduction clause is present on the taskloop directive, the nogroup
11715 // clause must not be specified.
11716 if (checkReductionClauseWithNogroup(*this, Clauses))
11717 return StmtError();
11718
11719 setFunctionHasBranchProtectedScope();
11720 return OMPParallelMasterTaskLoopDirective::Create(
11721 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11722 DSAStack->isCancelRegion());
11723 }
11724
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11725 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11726 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11727 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11728 if (!AStmt)
11729 return StmtError();
11730
11731 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11732 auto *CS = cast<CapturedStmt>(AStmt);
11733 // 1.2.2 OpenMP Language Terminology
11734 // Structured block - An executable statement with a single entry at the
11735 // top and a single exit at the bottom.
11736 // The point of exit cannot be a branch out of the structured block.
11737 // longjmp() and throw() must not violate the entry/exit criteria.
11738 CS->getCapturedDecl()->setNothrow();
11739 for (int ThisCaptureLevel =
11740 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11741 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11742 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11743 // 1.2.2 OpenMP Language Terminology
11744 // Structured block - An executable statement with a single entry at the
11745 // top and a single exit at the bottom.
11746 // The point of exit cannot be a branch out of the structured block.
11747 // longjmp() and throw() must not violate the entry/exit criteria.
11748 CS->getCapturedDecl()->setNothrow();
11749 }
11750
11751 OMPLoopBasedDirective::HelperExprs B;
11752 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11753 // define the nested loops number.
11754 unsigned NestedLoopCount = checkOpenMPLoop(
11755 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11756 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11757 VarsWithImplicitDSA, B);
11758 if (NestedLoopCount == 0)
11759 return StmtError();
11760
11761 assert((CurContext->isDependentContext() || B.builtAll()) &&
11762 "omp for loop exprs were not built");
11763
11764 if (!CurContext->isDependentContext()) {
11765 // Finalize the clauses that need pre-built expressions for CodeGen.
11766 for (OMPClause *C : Clauses) {
11767 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11768 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11769 B.NumIterations, *this, CurScope,
11770 DSAStack))
11771 return StmtError();
11772 }
11773 }
11774
11775 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11776 // The grainsize clause and num_tasks clause are mutually exclusive and may
11777 // not appear on the same taskloop directive.
11778 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11779 return StmtError();
11780 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11781 // If a reduction clause is present on the taskloop directive, the nogroup
11782 // clause must not be specified.
11783 if (checkReductionClauseWithNogroup(*this, Clauses))
11784 return StmtError();
11785 if (checkSimdlenSafelenSpecified(*this, Clauses))
11786 return StmtError();
11787
11788 setFunctionHasBranchProtectedScope();
11789 return OMPParallelMasterTaskLoopSimdDirective::Create(
11790 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11791 }
11792
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11793 StmtResult Sema::ActOnOpenMPDistributeDirective(
11794 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11795 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11796 if (!AStmt)
11797 return StmtError();
11798
11799 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11800 OMPLoopBasedDirective::HelperExprs B;
11801 // In presence of clause 'collapse' with number of loops, it will
11802 // define the nested loops number.
11803 unsigned NestedLoopCount =
11804 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11805 nullptr /*ordered not a clause on distribute*/, AStmt,
11806 *this, *DSAStack, VarsWithImplicitDSA, B);
11807 if (NestedLoopCount == 0)
11808 return StmtError();
11809
11810 assert((CurContext->isDependentContext() || B.builtAll()) &&
11811 "omp for loop exprs were not built");
11812
11813 setFunctionHasBranchProtectedScope();
11814 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11815 NestedLoopCount, Clauses, AStmt, B);
11816 }
11817
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11818 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11819 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11820 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11821 if (!AStmt)
11822 return StmtError();
11823
11824 auto *CS = cast<CapturedStmt>(AStmt);
11825 // 1.2.2 OpenMP Language Terminology
11826 // Structured block - An executable statement with a single entry at the
11827 // top and a single exit at the bottom.
11828 // The point of exit cannot be a branch out of the structured block.
11829 // longjmp() and throw() must not violate the entry/exit criteria.
11830 CS->getCapturedDecl()->setNothrow();
11831 for (int ThisCaptureLevel =
11832 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11833 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11834 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11835 // 1.2.2 OpenMP Language Terminology
11836 // Structured block - An executable statement with a single entry at the
11837 // top and a single exit at the bottom.
11838 // The point of exit cannot be a branch out of the structured block.
11839 // longjmp() and throw() must not violate the entry/exit criteria.
11840 CS->getCapturedDecl()->setNothrow();
11841 }
11842
11843 OMPLoopBasedDirective::HelperExprs B;
11844 // In presence of clause 'collapse' with number of loops, it will
11845 // define the nested loops number.
11846 unsigned NestedLoopCount = checkOpenMPLoop(
11847 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11848 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11849 VarsWithImplicitDSA, B);
11850 if (NestedLoopCount == 0)
11851 return StmtError();
11852
11853 assert((CurContext->isDependentContext() || B.builtAll()) &&
11854 "omp for loop exprs were not built");
11855
11856 setFunctionHasBranchProtectedScope();
11857 return OMPDistributeParallelForDirective::Create(
11858 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11859 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11860 }
11861
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11862 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11863 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11864 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11865 if (!AStmt)
11866 return StmtError();
11867
11868 auto *CS = cast<CapturedStmt>(AStmt);
11869 // 1.2.2 OpenMP Language Terminology
11870 // Structured block - An executable statement with a single entry at the
11871 // top and a single exit at the bottom.
11872 // The point of exit cannot be a branch out of the structured block.
11873 // longjmp() and throw() must not violate the entry/exit criteria.
11874 CS->getCapturedDecl()->setNothrow();
11875 for (int ThisCaptureLevel =
11876 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11877 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11878 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11879 // 1.2.2 OpenMP Language Terminology
11880 // Structured block - An executable statement with a single entry at the
11881 // top and a single exit at the bottom.
11882 // The point of exit cannot be a branch out of the structured block.
11883 // longjmp() and throw() must not violate the entry/exit criteria.
11884 CS->getCapturedDecl()->setNothrow();
11885 }
11886
11887 OMPLoopBasedDirective::HelperExprs B;
11888 // In presence of clause 'collapse' with number of loops, it will
11889 // define the nested loops number.
11890 unsigned NestedLoopCount = checkOpenMPLoop(
11891 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11892 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11893 VarsWithImplicitDSA, B);
11894 if (NestedLoopCount == 0)
11895 return StmtError();
11896
11897 assert((CurContext->isDependentContext() || B.builtAll()) &&
11898 "omp for loop exprs were not built");
11899
11900 if (!CurContext->isDependentContext()) {
11901 // Finalize the clauses that need pre-built expressions for CodeGen.
11902 for (OMPClause *C : Clauses) {
11903 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11904 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11905 B.NumIterations, *this, CurScope,
11906 DSAStack))
11907 return StmtError();
11908 }
11909 }
11910
11911 if (checkSimdlenSafelenSpecified(*this, Clauses))
11912 return StmtError();
11913
11914 setFunctionHasBranchProtectedScope();
11915 return OMPDistributeParallelForSimdDirective::Create(
11916 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11917 }
11918
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11919 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11920 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11921 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11922 if (!AStmt)
11923 return StmtError();
11924
11925 auto *CS = cast<CapturedStmt>(AStmt);
11926 // 1.2.2 OpenMP Language Terminology
11927 // Structured block - An executable statement with a single entry at the
11928 // top and a single exit at the bottom.
11929 // The point of exit cannot be a branch out of the structured block.
11930 // longjmp() and throw() must not violate the entry/exit criteria.
11931 CS->getCapturedDecl()->setNothrow();
11932 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11933 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11934 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11935 // 1.2.2 OpenMP Language Terminology
11936 // Structured block - An executable statement with a single entry at the
11937 // top and a single exit at the bottom.
11938 // The point of exit cannot be a branch out of the structured block.
11939 // longjmp() and throw() must not violate the entry/exit criteria.
11940 CS->getCapturedDecl()->setNothrow();
11941 }
11942
11943 OMPLoopBasedDirective::HelperExprs B;
11944 // In presence of clause 'collapse' with number of loops, it will
11945 // define the nested loops number.
11946 unsigned NestedLoopCount =
11947 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11948 nullptr /*ordered not a clause on distribute*/, CS, *this,
11949 *DSAStack, VarsWithImplicitDSA, B);
11950 if (NestedLoopCount == 0)
11951 return StmtError();
11952
11953 assert((CurContext->isDependentContext() || B.builtAll()) &&
11954 "omp for loop exprs were not built");
11955
11956 if (!CurContext->isDependentContext()) {
11957 // Finalize the clauses that need pre-built expressions for CodeGen.
11958 for (OMPClause *C : Clauses) {
11959 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11960 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11961 B.NumIterations, *this, CurScope,
11962 DSAStack))
11963 return StmtError();
11964 }
11965 }
11966
11967 if (checkSimdlenSafelenSpecified(*this, Clauses))
11968 return StmtError();
11969
11970 setFunctionHasBranchProtectedScope();
11971 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11972 NestedLoopCount, Clauses, AStmt, B);
11973 }
11974
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11975 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11976 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11977 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11978 if (!AStmt)
11979 return StmtError();
11980
11981 auto *CS = cast<CapturedStmt>(AStmt);
11982 // 1.2.2 OpenMP Language Terminology
11983 // Structured block - An executable statement with a single entry at the
11984 // top and a single exit at the bottom.
11985 // The point of exit cannot be a branch out of the structured block.
11986 // longjmp() and throw() must not violate the entry/exit criteria.
11987 CS->getCapturedDecl()->setNothrow();
11988 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11989 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11990 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11991 // 1.2.2 OpenMP Language Terminology
11992 // Structured block - An executable statement with a single entry at the
11993 // top and a single exit at the bottom.
11994 // The point of exit cannot be a branch out of the structured block.
11995 // longjmp() and throw() must not violate the entry/exit criteria.
11996 CS->getCapturedDecl()->setNothrow();
11997 }
11998
11999 OMPLoopBasedDirective::HelperExprs B;
12000 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12001 // define the nested loops number.
12002 unsigned NestedLoopCount = checkOpenMPLoop(
12003 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
12004 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12005 VarsWithImplicitDSA, B);
12006 if (NestedLoopCount == 0)
12007 return StmtError();
12008
12009 assert((CurContext->isDependentContext() || B.builtAll()) &&
12010 "omp target parallel for simd loop exprs were not built");
12011
12012 if (!CurContext->isDependentContext()) {
12013 // Finalize the clauses that need pre-built expressions for CodeGen.
12014 for (OMPClause *C : Clauses) {
12015 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12016 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12017 B.NumIterations, *this, CurScope,
12018 DSAStack))
12019 return StmtError();
12020 }
12021 }
12022 if (checkSimdlenSafelenSpecified(*this, Clauses))
12023 return StmtError();
12024
12025 setFunctionHasBranchProtectedScope();
12026 return OMPTargetParallelForSimdDirective::Create(
12027 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12028 }
12029
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12030 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
12031 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12032 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12033 if (!AStmt)
12034 return StmtError();
12035
12036 auto *CS = cast<CapturedStmt>(AStmt);
12037 // 1.2.2 OpenMP Language Terminology
12038 // Structured block - An executable statement with a single entry at the
12039 // top and a single exit at the bottom.
12040 // The point of exit cannot be a branch out of the structured block.
12041 // longjmp() and throw() must not violate the entry/exit criteria.
12042 CS->getCapturedDecl()->setNothrow();
12043 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
12044 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12045 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12046 // 1.2.2 OpenMP Language Terminology
12047 // Structured block - An executable statement with a single entry at the
12048 // top and a single exit at the bottom.
12049 // The point of exit cannot be a branch out of the structured block.
12050 // longjmp() and throw() must not violate the entry/exit criteria.
12051 CS->getCapturedDecl()->setNothrow();
12052 }
12053
12054 OMPLoopBasedDirective::HelperExprs B;
12055 // In presence of clause 'collapse' with number of loops, it will define the
12056 // nested loops number.
12057 unsigned NestedLoopCount =
12058 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
12059 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12060 VarsWithImplicitDSA, B);
12061 if (NestedLoopCount == 0)
12062 return StmtError();
12063
12064 assert((CurContext->isDependentContext() || B.builtAll()) &&
12065 "omp target simd loop exprs were not built");
12066
12067 if (!CurContext->isDependentContext()) {
12068 // Finalize the clauses that need pre-built expressions for CodeGen.
12069 for (OMPClause *C : Clauses) {
12070 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12071 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12072 B.NumIterations, *this, CurScope,
12073 DSAStack))
12074 return StmtError();
12075 }
12076 }
12077
12078 if (checkSimdlenSafelenSpecified(*this, Clauses))
12079 return StmtError();
12080
12081 setFunctionHasBranchProtectedScope();
12082 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
12083 NestedLoopCount, Clauses, AStmt, B);
12084 }
12085
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12086 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
12087 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12088 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12089 if (!AStmt)
12090 return StmtError();
12091
12092 auto *CS = cast<CapturedStmt>(AStmt);
12093 // 1.2.2 OpenMP Language Terminology
12094 // Structured block - An executable statement with a single entry at the
12095 // top and a single exit at the bottom.
12096 // The point of exit cannot be a branch out of the structured block.
12097 // longjmp() and throw() must not violate the entry/exit criteria.
12098 CS->getCapturedDecl()->setNothrow();
12099 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
12100 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12101 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12102 // 1.2.2 OpenMP Language Terminology
12103 // Structured block - An executable statement with a single entry at the
12104 // top and a single exit at the bottom.
12105 // The point of exit cannot be a branch out of the structured block.
12106 // longjmp() and throw() must not violate the entry/exit criteria.
12107 CS->getCapturedDecl()->setNothrow();
12108 }
12109
12110 OMPLoopBasedDirective::HelperExprs B;
12111 // In presence of clause 'collapse' with number of loops, it will
12112 // define the nested loops number.
12113 unsigned NestedLoopCount =
12114 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
12115 nullptr /*ordered not a clause on distribute*/, CS, *this,
12116 *DSAStack, VarsWithImplicitDSA, B);
12117 if (NestedLoopCount == 0)
12118 return StmtError();
12119
12120 assert((CurContext->isDependentContext() || B.builtAll()) &&
12121 "omp teams distribute loop exprs were not built");
12122
12123 setFunctionHasBranchProtectedScope();
12124
12125 DSAStack->setParentTeamsRegionLoc(StartLoc);
12126
12127 return OMPTeamsDistributeDirective::Create(
12128 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12129 }
12130
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12131 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
12132 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12133 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12134 if (!AStmt)
12135 return StmtError();
12136
12137 auto *CS = cast<CapturedStmt>(AStmt);
12138 // 1.2.2 OpenMP Language Terminology
12139 // Structured block - An executable statement with a single entry at the
12140 // top and a single exit at the bottom.
12141 // The point of exit cannot be a branch out of the structured block.
12142 // longjmp() and throw() must not violate the entry/exit criteria.
12143 CS->getCapturedDecl()->setNothrow();
12144 for (int ThisCaptureLevel =
12145 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
12146 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12147 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12148 // 1.2.2 OpenMP Language Terminology
12149 // Structured block - An executable statement with a single entry at the
12150 // top and a single exit at the bottom.
12151 // The point of exit cannot be a branch out of the structured block.
12152 // longjmp() and throw() must not violate the entry/exit criteria.
12153 CS->getCapturedDecl()->setNothrow();
12154 }
12155
12156 OMPLoopBasedDirective::HelperExprs B;
12157 // In presence of clause 'collapse' with number of loops, it will
12158 // define the nested loops number.
12159 unsigned NestedLoopCount = checkOpenMPLoop(
12160 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12161 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12162 VarsWithImplicitDSA, B);
12163
12164 if (NestedLoopCount == 0)
12165 return StmtError();
12166
12167 assert((CurContext->isDependentContext() || B.builtAll()) &&
12168 "omp teams distribute simd loop exprs were not built");
12169
12170 if (!CurContext->isDependentContext()) {
12171 // Finalize the clauses that need pre-built expressions for CodeGen.
12172 for (OMPClause *C : Clauses) {
12173 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12174 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12175 B.NumIterations, *this, CurScope,
12176 DSAStack))
12177 return StmtError();
12178 }
12179 }
12180
12181 if (checkSimdlenSafelenSpecified(*this, Clauses))
12182 return StmtError();
12183
12184 setFunctionHasBranchProtectedScope();
12185
12186 DSAStack->setParentTeamsRegionLoc(StartLoc);
12187
12188 return OMPTeamsDistributeSimdDirective::Create(
12189 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12190 }
12191
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12192 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
12193 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12194 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12195 if (!AStmt)
12196 return StmtError();
12197
12198 auto *CS = cast<CapturedStmt>(AStmt);
12199 // 1.2.2 OpenMP Language Terminology
12200 // Structured block - An executable statement with a single entry at the
12201 // top and a single exit at the bottom.
12202 // The point of exit cannot be a branch out of the structured block.
12203 // longjmp() and throw() must not violate the entry/exit criteria.
12204 CS->getCapturedDecl()->setNothrow();
12205
12206 for (int ThisCaptureLevel =
12207 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
12208 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12209 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12210 // 1.2.2 OpenMP Language Terminology
12211 // Structured block - An executable statement with a single entry at the
12212 // top and a single exit at the bottom.
12213 // The point of exit cannot be a branch out of the structured block.
12214 // longjmp() and throw() must not violate the entry/exit criteria.
12215 CS->getCapturedDecl()->setNothrow();
12216 }
12217
12218 OMPLoopBasedDirective::HelperExprs B;
12219 // In presence of clause 'collapse' with number of loops, it will
12220 // define the nested loops number.
12221 unsigned NestedLoopCount = checkOpenMPLoop(
12222 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
12223 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12224 VarsWithImplicitDSA, B);
12225
12226 if (NestedLoopCount == 0)
12227 return StmtError();
12228
12229 assert((CurContext->isDependentContext() || B.builtAll()) &&
12230 "omp for loop exprs were not built");
12231
12232 if (!CurContext->isDependentContext()) {
12233 // Finalize the clauses that need pre-built expressions for CodeGen.
12234 for (OMPClause *C : Clauses) {
12235 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12236 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12237 B.NumIterations, *this, CurScope,
12238 DSAStack))
12239 return StmtError();
12240 }
12241 }
12242
12243 if (checkSimdlenSafelenSpecified(*this, Clauses))
12244 return StmtError();
12245
12246 setFunctionHasBranchProtectedScope();
12247
12248 DSAStack->setParentTeamsRegionLoc(StartLoc);
12249
12250 return OMPTeamsDistributeParallelForSimdDirective::Create(
12251 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12252 }
12253
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12254 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
12255 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12256 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12257 if (!AStmt)
12258 return StmtError();
12259
12260 auto *CS = cast<CapturedStmt>(AStmt);
12261 // 1.2.2 OpenMP Language Terminology
12262 // Structured block - An executable statement with a single entry at the
12263 // top and a single exit at the bottom.
12264 // The point of exit cannot be a branch out of the structured block.
12265 // longjmp() and throw() must not violate the entry/exit criteria.
12266 CS->getCapturedDecl()->setNothrow();
12267
12268 for (int ThisCaptureLevel =
12269 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
12270 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12271 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12272 // 1.2.2 OpenMP Language Terminology
12273 // Structured block - An executable statement with a single entry at the
12274 // top and a single exit at the bottom.
12275 // The point of exit cannot be a branch out of the structured block.
12276 // longjmp() and throw() must not violate the entry/exit criteria.
12277 CS->getCapturedDecl()->setNothrow();
12278 }
12279
12280 OMPLoopBasedDirective::HelperExprs B;
12281 // In presence of clause 'collapse' with number of loops, it will
12282 // define the nested loops number.
12283 unsigned NestedLoopCount = checkOpenMPLoop(
12284 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12285 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12286 VarsWithImplicitDSA, B);
12287
12288 if (NestedLoopCount == 0)
12289 return StmtError();
12290
12291 assert((CurContext->isDependentContext() || B.builtAll()) &&
12292 "omp for loop exprs were not built");
12293
12294 setFunctionHasBranchProtectedScope();
12295
12296 DSAStack->setParentTeamsRegionLoc(StartLoc);
12297
12298 return OMPTeamsDistributeParallelForDirective::Create(
12299 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12300 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12301 }
12302
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12303 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
12304 Stmt *AStmt,
12305 SourceLocation StartLoc,
12306 SourceLocation EndLoc) {
12307 if (!AStmt)
12308 return StmtError();
12309
12310 auto *CS = cast<CapturedStmt>(AStmt);
12311 // 1.2.2 OpenMP Language Terminology
12312 // Structured block - An executable statement with a single entry at the
12313 // top and a single exit at the bottom.
12314 // The point of exit cannot be a branch out of the structured block.
12315 // longjmp() and throw() must not violate the entry/exit criteria.
12316 CS->getCapturedDecl()->setNothrow();
12317
12318 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
12319 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12320 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12321 // 1.2.2 OpenMP Language Terminology
12322 // Structured block - An executable statement with a single entry at the
12323 // top and a single exit at the bottom.
12324 // The point of exit cannot be a branch out of the structured block.
12325 // longjmp() and throw() must not violate the entry/exit criteria.
12326 CS->getCapturedDecl()->setNothrow();
12327 }
12328 setFunctionHasBranchProtectedScope();
12329
12330 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
12331 AStmt);
12332 }
12333
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12334 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
12335 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12336 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12337 if (!AStmt)
12338 return StmtError();
12339
12340 auto *CS = cast<CapturedStmt>(AStmt);
12341 // 1.2.2 OpenMP Language Terminology
12342 // Structured block - An executable statement with a single entry at the
12343 // top and a single exit at the bottom.
12344 // The point of exit cannot be a branch out of the structured block.
12345 // longjmp() and throw() must not violate the entry/exit criteria.
12346 CS->getCapturedDecl()->setNothrow();
12347 for (int ThisCaptureLevel =
12348 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
12349 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12350 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12351 // 1.2.2 OpenMP Language Terminology
12352 // Structured block - An executable statement with a single entry at the
12353 // top and a single exit at the bottom.
12354 // The point of exit cannot be a branch out of the structured block.
12355 // longjmp() and throw() must not violate the entry/exit criteria.
12356 CS->getCapturedDecl()->setNothrow();
12357 }
12358
12359 OMPLoopBasedDirective::HelperExprs B;
12360 // In presence of clause 'collapse' with number of loops, it will
12361 // define the nested loops number.
12362 unsigned NestedLoopCount = checkOpenMPLoop(
12363 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
12364 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12365 VarsWithImplicitDSA, B);
12366 if (NestedLoopCount == 0)
12367 return StmtError();
12368
12369 assert((CurContext->isDependentContext() || B.builtAll()) &&
12370 "omp target teams distribute loop exprs were not built");
12371
12372 setFunctionHasBranchProtectedScope();
12373 return OMPTargetTeamsDistributeDirective::Create(
12374 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12375 }
12376
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12377 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
12378 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12379 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12380 if (!AStmt)
12381 return StmtError();
12382
12383 auto *CS = cast<CapturedStmt>(AStmt);
12384 // 1.2.2 OpenMP Language Terminology
12385 // Structured block - An executable statement with a single entry at the
12386 // top and a single exit at the bottom.
12387 // The point of exit cannot be a branch out of the structured block.
12388 // longjmp() and throw() must not violate the entry/exit criteria.
12389 CS->getCapturedDecl()->setNothrow();
12390 for (int ThisCaptureLevel =
12391 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
12392 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12393 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12394 // 1.2.2 OpenMP Language Terminology
12395 // Structured block - An executable statement with a single entry at the
12396 // top and a single exit at the bottom.
12397 // The point of exit cannot be a branch out of the structured block.
12398 // longjmp() and throw() must not violate the entry/exit criteria.
12399 CS->getCapturedDecl()->setNothrow();
12400 }
12401
12402 OMPLoopBasedDirective::HelperExprs B;
12403 // In presence of clause 'collapse' with number of loops, it will
12404 // define the nested loops number.
12405 unsigned NestedLoopCount = checkOpenMPLoop(
12406 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12407 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12408 VarsWithImplicitDSA, B);
12409 if (NestedLoopCount == 0)
12410 return StmtError();
12411
12412 assert((CurContext->isDependentContext() || B.builtAll()) &&
12413 "omp target teams distribute parallel for loop exprs were not built");
12414
12415 if (!CurContext->isDependentContext()) {
12416 // Finalize the clauses that need pre-built expressions for CodeGen.
12417 for (OMPClause *C : Clauses) {
12418 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12419 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12420 B.NumIterations, *this, CurScope,
12421 DSAStack))
12422 return StmtError();
12423 }
12424 }
12425
12426 setFunctionHasBranchProtectedScope();
12427 return OMPTargetTeamsDistributeParallelForDirective::Create(
12428 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12429 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12430 }
12431
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12432 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
12433 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12434 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12435 if (!AStmt)
12436 return StmtError();
12437
12438 auto *CS = cast<CapturedStmt>(AStmt);
12439 // 1.2.2 OpenMP Language Terminology
12440 // Structured block - An executable statement with a single entry at the
12441 // top and a single exit at the bottom.
12442 // The point of exit cannot be a branch out of the structured block.
12443 // longjmp() and throw() must not violate the entry/exit criteria.
12444 CS->getCapturedDecl()->setNothrow();
12445 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
12446 OMPD_target_teams_distribute_parallel_for_simd);
12447 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12448 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12449 // 1.2.2 OpenMP Language Terminology
12450 // Structured block - An executable statement with a single entry at the
12451 // top and a single exit at the bottom.
12452 // The point of exit cannot be a branch out of the structured block.
12453 // longjmp() and throw() must not violate the entry/exit criteria.
12454 CS->getCapturedDecl()->setNothrow();
12455 }
12456
12457 OMPLoopBasedDirective::HelperExprs B;
12458 // In presence of clause 'collapse' with number of loops, it will
12459 // define the nested loops number.
12460 unsigned NestedLoopCount =
12461 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
12462 getCollapseNumberExpr(Clauses),
12463 nullptr /*ordered not a clause on distribute*/, CS, *this,
12464 *DSAStack, VarsWithImplicitDSA, B);
12465 if (NestedLoopCount == 0)
12466 return StmtError();
12467
12468 assert((CurContext->isDependentContext() || B.builtAll()) &&
12469 "omp target teams distribute parallel for simd loop exprs were not "
12470 "built");
12471
12472 if (!CurContext->isDependentContext()) {
12473 // Finalize the clauses that need pre-built expressions for CodeGen.
12474 for (OMPClause *C : Clauses) {
12475 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12476 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12477 B.NumIterations, *this, CurScope,
12478 DSAStack))
12479 return StmtError();
12480 }
12481 }
12482
12483 if (checkSimdlenSafelenSpecified(*this, Clauses))
12484 return StmtError();
12485
12486 setFunctionHasBranchProtectedScope();
12487 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
12488 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12489 }
12490
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12491 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
12492 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12493 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12494 if (!AStmt)
12495 return StmtError();
12496
12497 auto *CS = cast<CapturedStmt>(AStmt);
12498 // 1.2.2 OpenMP Language Terminology
12499 // Structured block - An executable statement with a single entry at the
12500 // top and a single exit at the bottom.
12501 // The point of exit cannot be a branch out of the structured block.
12502 // longjmp() and throw() must not violate the entry/exit criteria.
12503 CS->getCapturedDecl()->setNothrow();
12504 for (int ThisCaptureLevel =
12505 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12506 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12507 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12508 // 1.2.2 OpenMP Language Terminology
12509 // Structured block - An executable statement with a single entry at the
12510 // top and a single exit at the bottom.
12511 // The point of exit cannot be a branch out of the structured block.
12512 // longjmp() and throw() must not violate the entry/exit criteria.
12513 CS->getCapturedDecl()->setNothrow();
12514 }
12515
12516 OMPLoopBasedDirective::HelperExprs B;
12517 // In presence of clause 'collapse' with number of loops, it will
12518 // define the nested loops number.
12519 unsigned NestedLoopCount = checkOpenMPLoop(
12520 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12521 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12522 VarsWithImplicitDSA, B);
12523 if (NestedLoopCount == 0)
12524 return StmtError();
12525
12526 assert((CurContext->isDependentContext() || B.builtAll()) &&
12527 "omp target teams distribute simd loop exprs were not built");
12528
12529 if (!CurContext->isDependentContext()) {
12530 // Finalize the clauses that need pre-built expressions for CodeGen.
12531 for (OMPClause *C : Clauses) {
12532 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12533 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12534 B.NumIterations, *this, CurScope,
12535 DSAStack))
12536 return StmtError();
12537 }
12538 }
12539
12540 if (checkSimdlenSafelenSpecified(*this, Clauses))
12541 return StmtError();
12542
12543 setFunctionHasBranchProtectedScope();
12544 return OMPTargetTeamsDistributeSimdDirective::Create(
12545 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12546 }
12547
ActOnOpenMPTileDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12548 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12549 Stmt *AStmt, SourceLocation StartLoc,
12550 SourceLocation EndLoc) {
12551 auto SizesClauses =
12552 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12553 if (SizesClauses.empty()) {
12554 // A missing 'sizes' clause is already reported by the parser.
12555 return StmtError();
12556 }
12557 const OMPSizesClause *SizesClause = *SizesClauses.begin();
12558 unsigned NumLoops = SizesClause->getNumSizes();
12559
12560 // Empty statement should only be possible if there already was an error.
12561 if (!AStmt)
12562 return StmtError();
12563
12564 // Verify and diagnose loop nest.
12565 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12566 Stmt *Body = nullptr;
12567 SmallVector<Stmt *, 4> OriginalInits;
12568 if (!OMPLoopBasedDirective::doForAllLoops(
12569 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false,
12570 NumLoops,
12571 [this, &LoopHelpers, &Body, &OriginalInits](unsigned Cnt,
12572 Stmt *CurStmt) {
12573 VarsWithInheritedDSAType TmpDSA;
12574 unsigned SingleNumLoops =
12575 checkOpenMPLoop(OMPD_tile, nullptr, nullptr, CurStmt, *this,
12576 *DSAStack, TmpDSA, LoopHelpers[Cnt]);
12577 if (SingleNumLoops == 0)
12578 return true;
12579 assert(SingleNumLoops == 1 && "Expect single loop iteration space");
12580 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12581 OriginalInits.push_back(For->getInit());
12582 Body = For->getBody();
12583 } else {
12584 assert(isa<CXXForRangeStmt>(CurStmt) &&
12585 "Expected canonical for or range-based for loops.");
12586 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12587 OriginalInits.push_back(CXXFor->getBeginStmt());
12588 Body = CXXFor->getBody();
12589 }
12590 return false;
12591 }))
12592 return StmtError();
12593
12594 // Delay tiling to when template is completely instantiated.
12595 if (CurContext->isDependentContext())
12596 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12597 NumLoops, AStmt, nullptr, nullptr);
12598
12599 // Collection of generated variable declaration.
12600 SmallVector<Decl *, 4> PreInits;
12601
12602 // Create iteration variables for the generated loops.
12603 SmallVector<VarDecl *, 4> FloorIndVars;
12604 SmallVector<VarDecl *, 4> TileIndVars;
12605 FloorIndVars.resize(NumLoops);
12606 TileIndVars.resize(NumLoops);
12607 for (unsigned I = 0; I < NumLoops; ++I) {
12608 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12609 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12610 PreInits.append(PI->decl_begin(), PI->decl_end());
12611 assert(LoopHelper.Counters.size() == 1 &&
12612 "Expect single-dimensional loop iteration space");
12613 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12614 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12615 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12616 QualType CntTy = IterVarRef->getType();
12617
12618 // Iteration variable for the floor (i.e. outer) loop.
12619 {
12620 std::string FloorCntName =
12621 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12622 VarDecl *FloorCntDecl =
12623 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12624 FloorIndVars[I] = FloorCntDecl;
12625 }
12626
12627 // Iteration variable for the tile (i.e. inner) loop.
12628 {
12629 std::string TileCntName =
12630 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12631
12632 // Reuse the iteration variable created by checkOpenMPLoop. It is also
12633 // used by the expressions to derive the original iteration variable's
12634 // value from the logical iteration number.
12635 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12636 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12637 TileIndVars[I] = TileCntDecl;
12638 }
12639 if (auto *PI = dyn_cast_or_null<DeclStmt>(OriginalInits[I]))
12640 PreInits.append(PI->decl_begin(), PI->decl_end());
12641 // Gather declarations for the data members used as counters.
12642 for (Expr *CounterRef : LoopHelper.Counters) {
12643 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12644 if (isa<OMPCapturedExprDecl>(CounterDecl))
12645 PreInits.push_back(CounterDecl);
12646 }
12647 }
12648
12649 // Once the original iteration values are set, append the innermost body.
12650 Stmt *Inner = Body;
12651
12652 // Create tile loops from the inside to the outside.
12653 for (int I = NumLoops - 1; I >= 0; --I) {
12654 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12655 Expr *NumIterations = LoopHelper.NumIterations;
12656 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12657 QualType CntTy = OrigCntVar->getType();
12658 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12659 Scope *CurScope = getCurScope();
12660
12661 // Commonly used variables.
12662 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12663 OrigCntVar->getExprLoc());
12664 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12665 OrigCntVar->getExprLoc());
12666
12667 // For init-statement: auto .tile.iv = .floor.iv
12668 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12669 /*DirectInit=*/false);
12670 Decl *CounterDecl = TileIndVars[I];
12671 StmtResult InitStmt = new (Context)
12672 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12673 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12674 if (!InitStmt.isUsable())
12675 return StmtError();
12676
12677 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12678 // NumIterations)
12679 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12680 BO_Add, FloorIV, DimTileSize);
12681 if (!EndOfTile.isUsable())
12682 return StmtError();
12683 ExprResult IsPartialTile =
12684 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12685 NumIterations, EndOfTile.get());
12686 if (!IsPartialTile.isUsable())
12687 return StmtError();
12688 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12689 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12690 IsPartialTile.get(), NumIterations, EndOfTile.get());
12691 if (!MinTileAndIterSpace.isUsable())
12692 return StmtError();
12693 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12694 BO_LT, TileIV, MinTileAndIterSpace.get());
12695 if (!CondExpr.isUsable())
12696 return StmtError();
12697
12698 // For incr-statement: ++.tile.iv
12699 ExprResult IncrStmt =
12700 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12701 if (!IncrStmt.isUsable())
12702 return StmtError();
12703
12704 // Statements to set the original iteration variable's value from the
12705 // logical iteration number.
12706 // Generated for loop is:
12707 // Original_for_init;
12708 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12709 // NumIterations); ++.tile.iv) {
12710 // Original_Body;
12711 // Original_counter_update;
12712 // }
12713 // FIXME: If the innermost body is an loop itself, inserting these
12714 // statements stops it being recognized as a perfectly nested loop (e.g.
12715 // for applying tiling again). If this is the case, sink the expressions
12716 // further into the inner loop.
12717 SmallVector<Stmt *, 4> BodyParts;
12718 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12719 BodyParts.push_back(Inner);
12720 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12721 Inner->getEndLoc());
12722 Inner = new (Context)
12723 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12724 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12725 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12726 }
12727
12728 // Create floor loops from the inside to the outside.
12729 for (int I = NumLoops - 1; I >= 0; --I) {
12730 auto &LoopHelper = LoopHelpers[I];
12731 Expr *NumIterations = LoopHelper.NumIterations;
12732 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12733 QualType CntTy = OrigCntVar->getType();
12734 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12735 Scope *CurScope = getCurScope();
12736
12737 // Commonly used variables.
12738 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12739 OrigCntVar->getExprLoc());
12740
12741 // For init-statement: auto .floor.iv = 0
12742 AddInitializerToDecl(
12743 FloorIndVars[I],
12744 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12745 /*DirectInit=*/false);
12746 Decl *CounterDecl = FloorIndVars[I];
12747 StmtResult InitStmt = new (Context)
12748 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12749 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12750 if (!InitStmt.isUsable())
12751 return StmtError();
12752
12753 // For cond-expression: .floor.iv < NumIterations
12754 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12755 BO_LT, FloorIV, NumIterations);
12756 if (!CondExpr.isUsable())
12757 return StmtError();
12758
12759 // For incr-statement: .floor.iv += DimTileSize
12760 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12761 BO_AddAssign, FloorIV, DimTileSize);
12762 if (!IncrStmt.isUsable())
12763 return StmtError();
12764
12765 Inner = new (Context)
12766 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12767 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12768 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12769 }
12770
12771 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12772 AStmt, Inner,
12773 buildPreInits(Context, PreInits));
12774 }
12775
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12776 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
12777 SourceLocation StartLoc,
12778 SourceLocation LParenLoc,
12779 SourceLocation EndLoc) {
12780 OMPClause *Res = nullptr;
12781 switch (Kind) {
12782 case OMPC_final:
12783 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
12784 break;
12785 case OMPC_num_threads:
12786 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
12787 break;
12788 case OMPC_safelen:
12789 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
12790 break;
12791 case OMPC_simdlen:
12792 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
12793 break;
12794 case OMPC_allocator:
12795 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
12796 break;
12797 case OMPC_collapse:
12798 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
12799 break;
12800 case OMPC_ordered:
12801 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
12802 break;
12803 case OMPC_num_teams:
12804 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
12805 break;
12806 case OMPC_thread_limit:
12807 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
12808 break;
12809 case OMPC_priority:
12810 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
12811 break;
12812 case OMPC_grainsize:
12813 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
12814 break;
12815 case OMPC_num_tasks:
12816 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
12817 break;
12818 case OMPC_hint:
12819 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
12820 break;
12821 case OMPC_depobj:
12822 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
12823 break;
12824 case OMPC_detach:
12825 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
12826 break;
12827 case OMPC_novariants:
12828 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
12829 break;
12830 case OMPC_nocontext:
12831 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
12832 break;
12833 case OMPC_filter:
12834 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
12835 break;
12836 case OMPC_device:
12837 case OMPC_if:
12838 case OMPC_default:
12839 case OMPC_proc_bind:
12840 case OMPC_schedule:
12841 case OMPC_private:
12842 case OMPC_firstprivate:
12843 case OMPC_lastprivate:
12844 case OMPC_shared:
12845 case OMPC_reduction:
12846 case OMPC_task_reduction:
12847 case OMPC_in_reduction:
12848 case OMPC_linear:
12849 case OMPC_aligned:
12850 case OMPC_copyin:
12851 case OMPC_copyprivate:
12852 case OMPC_nowait:
12853 case OMPC_untied:
12854 case OMPC_mergeable:
12855 case OMPC_threadprivate:
12856 case OMPC_sizes:
12857 case OMPC_allocate:
12858 case OMPC_flush:
12859 case OMPC_read:
12860 case OMPC_write:
12861 case OMPC_update:
12862 case OMPC_capture:
12863 case OMPC_seq_cst:
12864 case OMPC_acq_rel:
12865 case OMPC_acquire:
12866 case OMPC_release:
12867 case OMPC_relaxed:
12868 case OMPC_depend:
12869 case OMPC_threads:
12870 case OMPC_simd:
12871 case OMPC_map:
12872 case OMPC_nogroup:
12873 case OMPC_dist_schedule:
12874 case OMPC_defaultmap:
12875 case OMPC_unknown:
12876 case OMPC_uniform:
12877 case OMPC_to:
12878 case OMPC_from:
12879 case OMPC_use_device_ptr:
12880 case OMPC_use_device_addr:
12881 case OMPC_is_device_ptr:
12882 case OMPC_unified_address:
12883 case OMPC_unified_shared_memory:
12884 case OMPC_reverse_offload:
12885 case OMPC_dynamic_allocators:
12886 case OMPC_atomic_default_mem_order:
12887 case OMPC_device_type:
12888 case OMPC_match:
12889 case OMPC_nontemporal:
12890 case OMPC_order:
12891 case OMPC_destroy:
12892 case OMPC_inclusive:
12893 case OMPC_exclusive:
12894 case OMPC_uses_allocators:
12895 case OMPC_affinity:
12896 default:
12897 llvm_unreachable("Clause is not allowed.");
12898 }
12899 return Res;
12900 }
12901
12902 // An OpenMP directive such as 'target parallel' has two captured regions:
12903 // for the 'target' and 'parallel' respectively. This function returns
12904 // the region in which to capture expressions associated with a clause.
12905 // A return value of OMPD_unknown signifies that the expression should not
12906 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)12907 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
12908 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
12909 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
12910 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12911 switch (CKind) {
12912 case OMPC_if:
12913 switch (DKind) {
12914 case OMPD_target_parallel_for_simd:
12915 if (OpenMPVersion >= 50 &&
12916 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12917 CaptureRegion = OMPD_parallel;
12918 break;
12919 }
12920 LLVM_FALLTHROUGH;
12921 case OMPD_target_parallel:
12922 case OMPD_target_parallel_for:
12923 // If this clause applies to the nested 'parallel' region, capture within
12924 // the 'target' region, otherwise do not capture.
12925 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12926 CaptureRegion = OMPD_target;
12927 break;
12928 case OMPD_target_teams_distribute_parallel_for_simd:
12929 if (OpenMPVersion >= 50 &&
12930 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12931 CaptureRegion = OMPD_parallel;
12932 break;
12933 }
12934 LLVM_FALLTHROUGH;
12935 case OMPD_target_teams_distribute_parallel_for:
12936 // If this clause applies to the nested 'parallel' region, capture within
12937 // the 'teams' region, otherwise do not capture.
12938 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12939 CaptureRegion = OMPD_teams;
12940 break;
12941 case OMPD_teams_distribute_parallel_for_simd:
12942 if (OpenMPVersion >= 50 &&
12943 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12944 CaptureRegion = OMPD_parallel;
12945 break;
12946 }
12947 LLVM_FALLTHROUGH;
12948 case OMPD_teams_distribute_parallel_for:
12949 CaptureRegion = OMPD_teams;
12950 break;
12951 case OMPD_target_update:
12952 case OMPD_target_enter_data:
12953 case OMPD_target_exit_data:
12954 CaptureRegion = OMPD_task;
12955 break;
12956 case OMPD_parallel_master_taskloop:
12957 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
12958 CaptureRegion = OMPD_parallel;
12959 break;
12960 case OMPD_parallel_master_taskloop_simd:
12961 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
12962 NameModifier == OMPD_taskloop) {
12963 CaptureRegion = OMPD_parallel;
12964 break;
12965 }
12966 if (OpenMPVersion <= 45)
12967 break;
12968 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12969 CaptureRegion = OMPD_taskloop;
12970 break;
12971 case OMPD_parallel_for_simd:
12972 if (OpenMPVersion <= 45)
12973 break;
12974 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12975 CaptureRegion = OMPD_parallel;
12976 break;
12977 case OMPD_taskloop_simd:
12978 case OMPD_master_taskloop_simd:
12979 if (OpenMPVersion <= 45)
12980 break;
12981 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12982 CaptureRegion = OMPD_taskloop;
12983 break;
12984 case OMPD_distribute_parallel_for_simd:
12985 if (OpenMPVersion <= 45)
12986 break;
12987 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12988 CaptureRegion = OMPD_parallel;
12989 break;
12990 case OMPD_target_simd:
12991 if (OpenMPVersion >= 50 &&
12992 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12993 CaptureRegion = OMPD_target;
12994 break;
12995 case OMPD_teams_distribute_simd:
12996 case OMPD_target_teams_distribute_simd:
12997 if (OpenMPVersion >= 50 &&
12998 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12999 CaptureRegion = OMPD_teams;
13000 break;
13001 case OMPD_cancel:
13002 case OMPD_parallel:
13003 case OMPD_parallel_master:
13004 case OMPD_parallel_sections:
13005 case OMPD_parallel_for:
13006 case OMPD_target:
13007 case OMPD_target_teams:
13008 case OMPD_target_teams_distribute:
13009 case OMPD_distribute_parallel_for:
13010 case OMPD_task:
13011 case OMPD_taskloop:
13012 case OMPD_master_taskloop:
13013 case OMPD_target_data:
13014 case OMPD_simd:
13015 case OMPD_for_simd:
13016 case OMPD_distribute_simd:
13017 // Do not capture if-clause expressions.
13018 break;
13019 case OMPD_threadprivate:
13020 case OMPD_allocate:
13021 case OMPD_taskyield:
13022 case OMPD_barrier:
13023 case OMPD_taskwait:
13024 case OMPD_cancellation_point:
13025 case OMPD_flush:
13026 case OMPD_depobj:
13027 case OMPD_scan:
13028 case OMPD_declare_reduction:
13029 case OMPD_declare_mapper:
13030 case OMPD_declare_simd:
13031 case OMPD_declare_variant:
13032 case OMPD_begin_declare_variant:
13033 case OMPD_end_declare_variant:
13034 case OMPD_declare_target:
13035 case OMPD_end_declare_target:
13036 case OMPD_teams:
13037 case OMPD_tile:
13038 case OMPD_for:
13039 case OMPD_sections:
13040 case OMPD_section:
13041 case OMPD_single:
13042 case OMPD_master:
13043 case OMPD_masked:
13044 case OMPD_critical:
13045 case OMPD_taskgroup:
13046 case OMPD_distribute:
13047 case OMPD_ordered:
13048 case OMPD_atomic:
13049 case OMPD_teams_distribute:
13050 case OMPD_requires:
13051 llvm_unreachable("Unexpected OpenMP directive with if-clause");
13052 case OMPD_unknown:
13053 default:
13054 llvm_unreachable("Unknown OpenMP directive");
13055 }
13056 break;
13057 case OMPC_num_threads:
13058 switch (DKind) {
13059 case OMPD_target_parallel:
13060 case OMPD_target_parallel_for:
13061 case OMPD_target_parallel_for_simd:
13062 CaptureRegion = OMPD_target;
13063 break;
13064 case OMPD_teams_distribute_parallel_for:
13065 case OMPD_teams_distribute_parallel_for_simd:
13066 case OMPD_target_teams_distribute_parallel_for:
13067 case OMPD_target_teams_distribute_parallel_for_simd:
13068 CaptureRegion = OMPD_teams;
13069 break;
13070 case OMPD_parallel:
13071 case OMPD_parallel_master:
13072 case OMPD_parallel_sections:
13073 case OMPD_parallel_for:
13074 case OMPD_parallel_for_simd:
13075 case OMPD_distribute_parallel_for:
13076 case OMPD_distribute_parallel_for_simd:
13077 case OMPD_parallel_master_taskloop:
13078 case OMPD_parallel_master_taskloop_simd:
13079 // Do not capture num_threads-clause expressions.
13080 break;
13081 case OMPD_target_data:
13082 case OMPD_target_enter_data:
13083 case OMPD_target_exit_data:
13084 case OMPD_target_update:
13085 case OMPD_target:
13086 case OMPD_target_simd:
13087 case OMPD_target_teams:
13088 case OMPD_target_teams_distribute:
13089 case OMPD_target_teams_distribute_simd:
13090 case OMPD_cancel:
13091 case OMPD_task:
13092 case OMPD_taskloop:
13093 case OMPD_taskloop_simd:
13094 case OMPD_master_taskloop:
13095 case OMPD_master_taskloop_simd:
13096 case OMPD_threadprivate:
13097 case OMPD_allocate:
13098 case OMPD_taskyield:
13099 case OMPD_barrier:
13100 case OMPD_taskwait:
13101 case OMPD_cancellation_point:
13102 case OMPD_flush:
13103 case OMPD_depobj:
13104 case OMPD_scan:
13105 case OMPD_declare_reduction:
13106 case OMPD_declare_mapper:
13107 case OMPD_declare_simd:
13108 case OMPD_declare_variant:
13109 case OMPD_begin_declare_variant:
13110 case OMPD_end_declare_variant:
13111 case OMPD_declare_target:
13112 case OMPD_end_declare_target:
13113 case OMPD_teams:
13114 case OMPD_simd:
13115 case OMPD_tile:
13116 case OMPD_for:
13117 case OMPD_for_simd:
13118 case OMPD_sections:
13119 case OMPD_section:
13120 case OMPD_single:
13121 case OMPD_master:
13122 case OMPD_masked:
13123 case OMPD_critical:
13124 case OMPD_taskgroup:
13125 case OMPD_distribute:
13126 case OMPD_ordered:
13127 case OMPD_atomic:
13128 case OMPD_distribute_simd:
13129 case OMPD_teams_distribute:
13130 case OMPD_teams_distribute_simd:
13131 case OMPD_requires:
13132 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
13133 case OMPD_unknown:
13134 default:
13135 llvm_unreachable("Unknown OpenMP directive");
13136 }
13137 break;
13138 case OMPC_num_teams:
13139 switch (DKind) {
13140 case OMPD_target_teams:
13141 case OMPD_target_teams_distribute:
13142 case OMPD_target_teams_distribute_simd:
13143 case OMPD_target_teams_distribute_parallel_for:
13144 case OMPD_target_teams_distribute_parallel_for_simd:
13145 CaptureRegion = OMPD_target;
13146 break;
13147 case OMPD_teams_distribute_parallel_for:
13148 case OMPD_teams_distribute_parallel_for_simd:
13149 case OMPD_teams:
13150 case OMPD_teams_distribute:
13151 case OMPD_teams_distribute_simd:
13152 // Do not capture num_teams-clause expressions.
13153 break;
13154 case OMPD_distribute_parallel_for:
13155 case OMPD_distribute_parallel_for_simd:
13156 case OMPD_task:
13157 case OMPD_taskloop:
13158 case OMPD_taskloop_simd:
13159 case OMPD_master_taskloop:
13160 case OMPD_master_taskloop_simd:
13161 case OMPD_parallel_master_taskloop:
13162 case OMPD_parallel_master_taskloop_simd:
13163 case OMPD_target_data:
13164 case OMPD_target_enter_data:
13165 case OMPD_target_exit_data:
13166 case OMPD_target_update:
13167 case OMPD_cancel:
13168 case OMPD_parallel:
13169 case OMPD_parallel_master:
13170 case OMPD_parallel_sections:
13171 case OMPD_parallel_for:
13172 case OMPD_parallel_for_simd:
13173 case OMPD_target:
13174 case OMPD_target_simd:
13175 case OMPD_target_parallel:
13176 case OMPD_target_parallel_for:
13177 case OMPD_target_parallel_for_simd:
13178 case OMPD_threadprivate:
13179 case OMPD_allocate:
13180 case OMPD_taskyield:
13181 case OMPD_barrier:
13182 case OMPD_taskwait:
13183 case OMPD_cancellation_point:
13184 case OMPD_flush:
13185 case OMPD_depobj:
13186 case OMPD_scan:
13187 case OMPD_declare_reduction:
13188 case OMPD_declare_mapper:
13189 case OMPD_declare_simd:
13190 case OMPD_declare_variant:
13191 case OMPD_begin_declare_variant:
13192 case OMPD_end_declare_variant:
13193 case OMPD_declare_target:
13194 case OMPD_end_declare_target:
13195 case OMPD_simd:
13196 case OMPD_tile:
13197 case OMPD_for:
13198 case OMPD_for_simd:
13199 case OMPD_sections:
13200 case OMPD_section:
13201 case OMPD_single:
13202 case OMPD_master:
13203 case OMPD_masked:
13204 case OMPD_critical:
13205 case OMPD_taskgroup:
13206 case OMPD_distribute:
13207 case OMPD_ordered:
13208 case OMPD_atomic:
13209 case OMPD_distribute_simd:
13210 case OMPD_requires:
13211 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
13212 case OMPD_unknown:
13213 default:
13214 llvm_unreachable("Unknown OpenMP directive");
13215 }
13216 break;
13217 case OMPC_thread_limit:
13218 switch (DKind) {
13219 case OMPD_target_teams:
13220 case OMPD_target_teams_distribute:
13221 case OMPD_target_teams_distribute_simd:
13222 case OMPD_target_teams_distribute_parallel_for:
13223 case OMPD_target_teams_distribute_parallel_for_simd:
13224 CaptureRegion = OMPD_target;
13225 break;
13226 case OMPD_teams_distribute_parallel_for:
13227 case OMPD_teams_distribute_parallel_for_simd:
13228 case OMPD_teams:
13229 case OMPD_teams_distribute:
13230 case OMPD_teams_distribute_simd:
13231 // Do not capture thread_limit-clause expressions.
13232 break;
13233 case OMPD_distribute_parallel_for:
13234 case OMPD_distribute_parallel_for_simd:
13235 case OMPD_task:
13236 case OMPD_taskloop:
13237 case OMPD_taskloop_simd:
13238 case OMPD_master_taskloop:
13239 case OMPD_master_taskloop_simd:
13240 case OMPD_parallel_master_taskloop:
13241 case OMPD_parallel_master_taskloop_simd:
13242 case OMPD_target_data:
13243 case OMPD_target_enter_data:
13244 case OMPD_target_exit_data:
13245 case OMPD_target_update:
13246 case OMPD_cancel:
13247 case OMPD_parallel:
13248 case OMPD_parallel_master:
13249 case OMPD_parallel_sections:
13250 case OMPD_parallel_for:
13251 case OMPD_parallel_for_simd:
13252 case OMPD_target:
13253 case OMPD_target_simd:
13254 case OMPD_target_parallel:
13255 case OMPD_target_parallel_for:
13256 case OMPD_target_parallel_for_simd:
13257 case OMPD_threadprivate:
13258 case OMPD_allocate:
13259 case OMPD_taskyield:
13260 case OMPD_barrier:
13261 case OMPD_taskwait:
13262 case OMPD_cancellation_point:
13263 case OMPD_flush:
13264 case OMPD_depobj:
13265 case OMPD_scan:
13266 case OMPD_declare_reduction:
13267 case OMPD_declare_mapper:
13268 case OMPD_declare_simd:
13269 case OMPD_declare_variant:
13270 case OMPD_begin_declare_variant:
13271 case OMPD_end_declare_variant:
13272 case OMPD_declare_target:
13273 case OMPD_end_declare_target:
13274 case OMPD_simd:
13275 case OMPD_tile:
13276 case OMPD_for:
13277 case OMPD_for_simd:
13278 case OMPD_sections:
13279 case OMPD_section:
13280 case OMPD_single:
13281 case OMPD_master:
13282 case OMPD_masked:
13283 case OMPD_critical:
13284 case OMPD_taskgroup:
13285 case OMPD_distribute:
13286 case OMPD_ordered:
13287 case OMPD_atomic:
13288 case OMPD_distribute_simd:
13289 case OMPD_requires:
13290 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
13291 case OMPD_unknown:
13292 default:
13293 llvm_unreachable("Unknown OpenMP directive");
13294 }
13295 break;
13296 case OMPC_schedule:
13297 switch (DKind) {
13298 case OMPD_parallel_for:
13299 case OMPD_parallel_for_simd:
13300 case OMPD_distribute_parallel_for:
13301 case OMPD_distribute_parallel_for_simd:
13302 case OMPD_teams_distribute_parallel_for:
13303 case OMPD_teams_distribute_parallel_for_simd:
13304 case OMPD_target_parallel_for:
13305 case OMPD_target_parallel_for_simd:
13306 case OMPD_target_teams_distribute_parallel_for:
13307 case OMPD_target_teams_distribute_parallel_for_simd:
13308 CaptureRegion = OMPD_parallel;
13309 break;
13310 case OMPD_for:
13311 case OMPD_for_simd:
13312 // Do not capture schedule-clause expressions.
13313 break;
13314 case OMPD_task:
13315 case OMPD_taskloop:
13316 case OMPD_taskloop_simd:
13317 case OMPD_master_taskloop:
13318 case OMPD_master_taskloop_simd:
13319 case OMPD_parallel_master_taskloop:
13320 case OMPD_parallel_master_taskloop_simd:
13321 case OMPD_target_data:
13322 case OMPD_target_enter_data:
13323 case OMPD_target_exit_data:
13324 case OMPD_target_update:
13325 case OMPD_teams:
13326 case OMPD_teams_distribute:
13327 case OMPD_teams_distribute_simd:
13328 case OMPD_target_teams_distribute:
13329 case OMPD_target_teams_distribute_simd:
13330 case OMPD_target:
13331 case OMPD_target_simd:
13332 case OMPD_target_parallel:
13333 case OMPD_cancel:
13334 case OMPD_parallel:
13335 case OMPD_parallel_master:
13336 case OMPD_parallel_sections:
13337 case OMPD_threadprivate:
13338 case OMPD_allocate:
13339 case OMPD_taskyield:
13340 case OMPD_barrier:
13341 case OMPD_taskwait:
13342 case OMPD_cancellation_point:
13343 case OMPD_flush:
13344 case OMPD_depobj:
13345 case OMPD_scan:
13346 case OMPD_declare_reduction:
13347 case OMPD_declare_mapper:
13348 case OMPD_declare_simd:
13349 case OMPD_declare_variant:
13350 case OMPD_begin_declare_variant:
13351 case OMPD_end_declare_variant:
13352 case OMPD_declare_target:
13353 case OMPD_end_declare_target:
13354 case OMPD_simd:
13355 case OMPD_tile:
13356 case OMPD_sections:
13357 case OMPD_section:
13358 case OMPD_single:
13359 case OMPD_master:
13360 case OMPD_masked:
13361 case OMPD_critical:
13362 case OMPD_taskgroup:
13363 case OMPD_distribute:
13364 case OMPD_ordered:
13365 case OMPD_atomic:
13366 case OMPD_distribute_simd:
13367 case OMPD_target_teams:
13368 case OMPD_requires:
13369 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
13370 case OMPD_unknown:
13371 default:
13372 llvm_unreachable("Unknown OpenMP directive");
13373 }
13374 break;
13375 case OMPC_dist_schedule:
13376 switch (DKind) {
13377 case OMPD_teams_distribute_parallel_for:
13378 case OMPD_teams_distribute_parallel_for_simd:
13379 case OMPD_teams_distribute:
13380 case OMPD_teams_distribute_simd:
13381 case OMPD_target_teams_distribute_parallel_for:
13382 case OMPD_target_teams_distribute_parallel_for_simd:
13383 case OMPD_target_teams_distribute:
13384 case OMPD_target_teams_distribute_simd:
13385 CaptureRegion = OMPD_teams;
13386 break;
13387 case OMPD_distribute_parallel_for:
13388 case OMPD_distribute_parallel_for_simd:
13389 case OMPD_distribute:
13390 case OMPD_distribute_simd:
13391 // Do not capture dist_schedule-clause expressions.
13392 break;
13393 case OMPD_parallel_for:
13394 case OMPD_parallel_for_simd:
13395 case OMPD_target_parallel_for_simd:
13396 case OMPD_target_parallel_for:
13397 case OMPD_task:
13398 case OMPD_taskloop:
13399 case OMPD_taskloop_simd:
13400 case OMPD_master_taskloop:
13401 case OMPD_master_taskloop_simd:
13402 case OMPD_parallel_master_taskloop:
13403 case OMPD_parallel_master_taskloop_simd:
13404 case OMPD_target_data:
13405 case OMPD_target_enter_data:
13406 case OMPD_target_exit_data:
13407 case OMPD_target_update:
13408 case OMPD_teams:
13409 case OMPD_target:
13410 case OMPD_target_simd:
13411 case OMPD_target_parallel:
13412 case OMPD_cancel:
13413 case OMPD_parallel:
13414 case OMPD_parallel_master:
13415 case OMPD_parallel_sections:
13416 case OMPD_threadprivate:
13417 case OMPD_allocate:
13418 case OMPD_taskyield:
13419 case OMPD_barrier:
13420 case OMPD_taskwait:
13421 case OMPD_cancellation_point:
13422 case OMPD_flush:
13423 case OMPD_depobj:
13424 case OMPD_scan:
13425 case OMPD_declare_reduction:
13426 case OMPD_declare_mapper:
13427 case OMPD_declare_simd:
13428 case OMPD_declare_variant:
13429 case OMPD_begin_declare_variant:
13430 case OMPD_end_declare_variant:
13431 case OMPD_declare_target:
13432 case OMPD_end_declare_target:
13433 case OMPD_simd:
13434 case OMPD_tile:
13435 case OMPD_for:
13436 case OMPD_for_simd:
13437 case OMPD_sections:
13438 case OMPD_section:
13439 case OMPD_single:
13440 case OMPD_master:
13441 case OMPD_masked:
13442 case OMPD_critical:
13443 case OMPD_taskgroup:
13444 case OMPD_ordered:
13445 case OMPD_atomic:
13446 case OMPD_target_teams:
13447 case OMPD_requires:
13448 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
13449 case OMPD_unknown:
13450 default:
13451 llvm_unreachable("Unknown OpenMP directive");
13452 }
13453 break;
13454 case OMPC_device:
13455 switch (DKind) {
13456 case OMPD_target_update:
13457 case OMPD_target_enter_data:
13458 case OMPD_target_exit_data:
13459 case OMPD_target:
13460 case OMPD_target_simd:
13461 case OMPD_target_teams:
13462 case OMPD_target_parallel:
13463 case OMPD_target_teams_distribute:
13464 case OMPD_target_teams_distribute_simd:
13465 case OMPD_target_parallel_for:
13466 case OMPD_target_parallel_for_simd:
13467 case OMPD_target_teams_distribute_parallel_for:
13468 case OMPD_target_teams_distribute_parallel_for_simd:
13469 case OMPD_dispatch:
13470 CaptureRegion = OMPD_task;
13471 break;
13472 case OMPD_target_data:
13473 case OMPD_interop:
13474 // Do not capture device-clause expressions.
13475 break;
13476 case OMPD_teams_distribute_parallel_for:
13477 case OMPD_teams_distribute_parallel_for_simd:
13478 case OMPD_teams:
13479 case OMPD_teams_distribute:
13480 case OMPD_teams_distribute_simd:
13481 case OMPD_distribute_parallel_for:
13482 case OMPD_distribute_parallel_for_simd:
13483 case OMPD_task:
13484 case OMPD_taskloop:
13485 case OMPD_taskloop_simd:
13486 case OMPD_master_taskloop:
13487 case OMPD_master_taskloop_simd:
13488 case OMPD_parallel_master_taskloop:
13489 case OMPD_parallel_master_taskloop_simd:
13490 case OMPD_cancel:
13491 case OMPD_parallel:
13492 case OMPD_parallel_master:
13493 case OMPD_parallel_sections:
13494 case OMPD_parallel_for:
13495 case OMPD_parallel_for_simd:
13496 case OMPD_threadprivate:
13497 case OMPD_allocate:
13498 case OMPD_taskyield:
13499 case OMPD_barrier:
13500 case OMPD_taskwait:
13501 case OMPD_cancellation_point:
13502 case OMPD_flush:
13503 case OMPD_depobj:
13504 case OMPD_scan:
13505 case OMPD_declare_reduction:
13506 case OMPD_declare_mapper:
13507 case OMPD_declare_simd:
13508 case OMPD_declare_variant:
13509 case OMPD_begin_declare_variant:
13510 case OMPD_end_declare_variant:
13511 case OMPD_declare_target:
13512 case OMPD_end_declare_target:
13513 case OMPD_simd:
13514 case OMPD_tile:
13515 case OMPD_for:
13516 case OMPD_for_simd:
13517 case OMPD_sections:
13518 case OMPD_section:
13519 case OMPD_single:
13520 case OMPD_master:
13521 case OMPD_masked:
13522 case OMPD_critical:
13523 case OMPD_taskgroup:
13524 case OMPD_distribute:
13525 case OMPD_ordered:
13526 case OMPD_atomic:
13527 case OMPD_distribute_simd:
13528 case OMPD_requires:
13529 llvm_unreachable("Unexpected OpenMP directive with device-clause");
13530 case OMPD_unknown:
13531 default:
13532 llvm_unreachable("Unknown OpenMP directive");
13533 }
13534 break;
13535 case OMPC_grainsize:
13536 case OMPC_num_tasks:
13537 case OMPC_final:
13538 case OMPC_priority:
13539 switch (DKind) {
13540 case OMPD_task:
13541 case OMPD_taskloop:
13542 case OMPD_taskloop_simd:
13543 case OMPD_master_taskloop:
13544 case OMPD_master_taskloop_simd:
13545 break;
13546 case OMPD_parallel_master_taskloop:
13547 case OMPD_parallel_master_taskloop_simd:
13548 CaptureRegion = OMPD_parallel;
13549 break;
13550 case OMPD_target_update:
13551 case OMPD_target_enter_data:
13552 case OMPD_target_exit_data:
13553 case OMPD_target:
13554 case OMPD_target_simd:
13555 case OMPD_target_teams:
13556 case OMPD_target_parallel:
13557 case OMPD_target_teams_distribute:
13558 case OMPD_target_teams_distribute_simd:
13559 case OMPD_target_parallel_for:
13560 case OMPD_target_parallel_for_simd:
13561 case OMPD_target_teams_distribute_parallel_for:
13562 case OMPD_target_teams_distribute_parallel_for_simd:
13563 case OMPD_target_data:
13564 case OMPD_teams_distribute_parallel_for:
13565 case OMPD_teams_distribute_parallel_for_simd:
13566 case OMPD_teams:
13567 case OMPD_teams_distribute:
13568 case OMPD_teams_distribute_simd:
13569 case OMPD_distribute_parallel_for:
13570 case OMPD_distribute_parallel_for_simd:
13571 case OMPD_cancel:
13572 case OMPD_parallel:
13573 case OMPD_parallel_master:
13574 case OMPD_parallel_sections:
13575 case OMPD_parallel_for:
13576 case OMPD_parallel_for_simd:
13577 case OMPD_threadprivate:
13578 case OMPD_allocate:
13579 case OMPD_taskyield:
13580 case OMPD_barrier:
13581 case OMPD_taskwait:
13582 case OMPD_cancellation_point:
13583 case OMPD_flush:
13584 case OMPD_depobj:
13585 case OMPD_scan:
13586 case OMPD_declare_reduction:
13587 case OMPD_declare_mapper:
13588 case OMPD_declare_simd:
13589 case OMPD_declare_variant:
13590 case OMPD_begin_declare_variant:
13591 case OMPD_end_declare_variant:
13592 case OMPD_declare_target:
13593 case OMPD_end_declare_target:
13594 case OMPD_simd:
13595 case OMPD_tile:
13596 case OMPD_for:
13597 case OMPD_for_simd:
13598 case OMPD_sections:
13599 case OMPD_section:
13600 case OMPD_single:
13601 case OMPD_master:
13602 case OMPD_masked:
13603 case OMPD_critical:
13604 case OMPD_taskgroup:
13605 case OMPD_distribute:
13606 case OMPD_ordered:
13607 case OMPD_atomic:
13608 case OMPD_distribute_simd:
13609 case OMPD_requires:
13610 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
13611 case OMPD_unknown:
13612 default:
13613 llvm_unreachable("Unknown OpenMP directive");
13614 }
13615 break;
13616 case OMPC_novariants:
13617 case OMPC_nocontext:
13618 switch (DKind) {
13619 case OMPD_dispatch:
13620 CaptureRegion = OMPD_task;
13621 break;
13622 default:
13623 llvm_unreachable("Unexpected OpenMP directive");
13624 }
13625 break;
13626 case OMPC_filter:
13627 // Do not capture filter-clause expressions.
13628 break;
13629 case OMPC_firstprivate:
13630 case OMPC_lastprivate:
13631 case OMPC_reduction:
13632 case OMPC_task_reduction:
13633 case OMPC_in_reduction:
13634 case OMPC_linear:
13635 case OMPC_default:
13636 case OMPC_proc_bind:
13637 case OMPC_safelen:
13638 case OMPC_simdlen:
13639 case OMPC_sizes:
13640 case OMPC_allocator:
13641 case OMPC_collapse:
13642 case OMPC_private:
13643 case OMPC_shared:
13644 case OMPC_aligned:
13645 case OMPC_copyin:
13646 case OMPC_copyprivate:
13647 case OMPC_ordered:
13648 case OMPC_nowait:
13649 case OMPC_untied:
13650 case OMPC_mergeable:
13651 case OMPC_threadprivate:
13652 case OMPC_allocate:
13653 case OMPC_flush:
13654 case OMPC_depobj:
13655 case OMPC_read:
13656 case OMPC_write:
13657 case OMPC_update:
13658 case OMPC_capture:
13659 case OMPC_seq_cst:
13660 case OMPC_acq_rel:
13661 case OMPC_acquire:
13662 case OMPC_release:
13663 case OMPC_relaxed:
13664 case OMPC_depend:
13665 case OMPC_threads:
13666 case OMPC_simd:
13667 case OMPC_map:
13668 case OMPC_nogroup:
13669 case OMPC_hint:
13670 case OMPC_defaultmap:
13671 case OMPC_unknown:
13672 case OMPC_uniform:
13673 case OMPC_to:
13674 case OMPC_from:
13675 case OMPC_use_device_ptr:
13676 case OMPC_use_device_addr:
13677 case OMPC_is_device_ptr:
13678 case OMPC_unified_address:
13679 case OMPC_unified_shared_memory:
13680 case OMPC_reverse_offload:
13681 case OMPC_dynamic_allocators:
13682 case OMPC_atomic_default_mem_order:
13683 case OMPC_device_type:
13684 case OMPC_match:
13685 case OMPC_nontemporal:
13686 case OMPC_order:
13687 case OMPC_destroy:
13688 case OMPC_detach:
13689 case OMPC_inclusive:
13690 case OMPC_exclusive:
13691 case OMPC_uses_allocators:
13692 case OMPC_affinity:
13693 default:
13694 llvm_unreachable("Unexpected OpenMP clause.");
13695 }
13696 return CaptureRegion;
13697 }
13698
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)13699 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
13700 Expr *Condition, SourceLocation StartLoc,
13701 SourceLocation LParenLoc,
13702 SourceLocation NameModifierLoc,
13703 SourceLocation ColonLoc,
13704 SourceLocation EndLoc) {
13705 Expr *ValExpr = Condition;
13706 Stmt *HelperValStmt = nullptr;
13707 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13708 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13709 !Condition->isInstantiationDependent() &&
13710 !Condition->containsUnexpandedParameterPack()) {
13711 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13712 if (Val.isInvalid())
13713 return nullptr;
13714
13715 ValExpr = Val.get();
13716
13717 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13718 CaptureRegion = getOpenMPCaptureRegionForClause(
13719 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
13720 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13721 ValExpr = MakeFullExpr(ValExpr).get();
13722 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13723 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13724 HelperValStmt = buildPreInits(Context, Captures);
13725 }
13726 }
13727
13728 return new (Context)
13729 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
13730 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
13731 }
13732
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13733 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
13734 SourceLocation StartLoc,
13735 SourceLocation LParenLoc,
13736 SourceLocation EndLoc) {
13737 Expr *ValExpr = Condition;
13738 Stmt *HelperValStmt = nullptr;
13739 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13740 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13741 !Condition->isInstantiationDependent() &&
13742 !Condition->containsUnexpandedParameterPack()) {
13743 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13744 if (Val.isInvalid())
13745 return nullptr;
13746
13747 ValExpr = MakeFullExpr(Val.get()).get();
13748
13749 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13750 CaptureRegion =
13751 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
13752 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13753 ValExpr = MakeFullExpr(ValExpr).get();
13754 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13755 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13756 HelperValStmt = buildPreInits(Context, Captures);
13757 }
13758 }
13759
13760 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
13761 StartLoc, LParenLoc, EndLoc);
13762 }
13763
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)13764 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
13765 Expr *Op) {
13766 if (!Op)
13767 return ExprError();
13768
13769 class IntConvertDiagnoser : public ICEConvertDiagnoser {
13770 public:
13771 IntConvertDiagnoser()
13772 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
13773 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
13774 QualType T) override {
13775 return S.Diag(Loc, diag::err_omp_not_integral) << T;
13776 }
13777 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
13778 QualType T) override {
13779 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
13780 }
13781 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
13782 QualType T,
13783 QualType ConvTy) override {
13784 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
13785 }
13786 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
13787 QualType ConvTy) override {
13788 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13789 << ConvTy->isEnumeralType() << ConvTy;
13790 }
13791 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
13792 QualType T) override {
13793 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
13794 }
13795 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
13796 QualType ConvTy) override {
13797 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13798 << ConvTy->isEnumeralType() << ConvTy;
13799 }
13800 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
13801 QualType) override {
13802 llvm_unreachable("conversion functions are permitted");
13803 }
13804 } ConvertDiagnoser;
13805 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
13806 }
13807
13808 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)13809 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
13810 bool StrictlyPositive, bool BuildCapture = false,
13811 OpenMPDirectiveKind DKind = OMPD_unknown,
13812 OpenMPDirectiveKind *CaptureRegion = nullptr,
13813 Stmt **HelperValStmt = nullptr) {
13814 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
13815 !ValExpr->isInstantiationDependent()) {
13816 SourceLocation Loc = ValExpr->getExprLoc();
13817 ExprResult Value =
13818 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
13819 if (Value.isInvalid())
13820 return false;
13821
13822 ValExpr = Value.get();
13823 // The expression must evaluate to a non-negative integer value.
13824 if (Optional<llvm::APSInt> Result =
13825 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
13826 if (Result->isSigned() &&
13827 !((!StrictlyPositive && Result->isNonNegative()) ||
13828 (StrictlyPositive && Result->isStrictlyPositive()))) {
13829 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
13830 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13831 << ValExpr->getSourceRange();
13832 return false;
13833 }
13834 }
13835 if (!BuildCapture)
13836 return true;
13837 *CaptureRegion =
13838 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
13839 if (*CaptureRegion != OMPD_unknown &&
13840 !SemaRef.CurContext->isDependentContext()) {
13841 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
13842 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13843 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
13844 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
13845 }
13846 }
13847 return true;
13848 }
13849
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13850 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
13851 SourceLocation StartLoc,
13852 SourceLocation LParenLoc,
13853 SourceLocation EndLoc) {
13854 Expr *ValExpr = NumThreads;
13855 Stmt *HelperValStmt = nullptr;
13856
13857 // OpenMP [2.5, Restrictions]
13858 // The num_threads expression must evaluate to a positive integer value.
13859 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
13860 /*StrictlyPositive=*/true))
13861 return nullptr;
13862
13863 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13864 OpenMPDirectiveKind CaptureRegion =
13865 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
13866 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13867 ValExpr = MakeFullExpr(ValExpr).get();
13868 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13869 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13870 HelperValStmt = buildPreInits(Context, Captures);
13871 }
13872
13873 return new (Context) OMPNumThreadsClause(
13874 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13875 }
13876
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive)13877 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
13878 OpenMPClauseKind CKind,
13879 bool StrictlyPositive) {
13880 if (!E)
13881 return ExprError();
13882 if (E->isValueDependent() || E->isTypeDependent() ||
13883 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
13884 return E;
13885 llvm::APSInt Result;
13886 ExprResult ICE =
13887 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
13888 if (ICE.isInvalid())
13889 return ExprError();
13890 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
13891 (!StrictlyPositive && !Result.isNonNegative())) {
13892 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
13893 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13894 << E->getSourceRange();
13895 return ExprError();
13896 }
13897 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
13898 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
13899 << E->getSourceRange();
13900 return ExprError();
13901 }
13902 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
13903 DSAStack->setAssociatedLoops(Result.getExtValue());
13904 else if (CKind == OMPC_ordered)
13905 DSAStack->setAssociatedLoops(Result.getExtValue());
13906 return ICE;
13907 }
13908
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13909 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
13910 SourceLocation LParenLoc,
13911 SourceLocation EndLoc) {
13912 // OpenMP [2.8.1, simd construct, Description]
13913 // The parameter of the safelen clause must be a constant
13914 // positive integer expression.
13915 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
13916 if (Safelen.isInvalid())
13917 return nullptr;
13918 return new (Context)
13919 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
13920 }
13921
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13922 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
13923 SourceLocation LParenLoc,
13924 SourceLocation EndLoc) {
13925 // OpenMP [2.8.1, simd construct, Description]
13926 // The parameter of the simdlen clause must be a constant
13927 // positive integer expression.
13928 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
13929 if (Simdlen.isInvalid())
13930 return nullptr;
13931 return new (Context)
13932 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
13933 }
13934
13935 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)13936 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
13937 DSAStackTy *Stack) {
13938 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
13939 if (!OMPAllocatorHandleT.isNull())
13940 return true;
13941 // Build the predefined allocator expressions.
13942 bool ErrorFound = false;
13943 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
13944 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
13945 StringRef Allocator =
13946 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
13947 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
13948 auto *VD = dyn_cast_or_null<ValueDecl>(
13949 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
13950 if (!VD) {
13951 ErrorFound = true;
13952 break;
13953 }
13954 QualType AllocatorType =
13955 VD->getType().getNonLValueExprType(S.getASTContext());
13956 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
13957 if (!Res.isUsable()) {
13958 ErrorFound = true;
13959 break;
13960 }
13961 if (OMPAllocatorHandleT.isNull())
13962 OMPAllocatorHandleT = AllocatorType;
13963 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
13964 ErrorFound = true;
13965 break;
13966 }
13967 Stack->setAllocator(AllocatorKind, Res.get());
13968 }
13969 if (ErrorFound) {
13970 S.Diag(Loc, diag::err_omp_implied_type_not_found)
13971 << "omp_allocator_handle_t";
13972 return false;
13973 }
13974 OMPAllocatorHandleT.addConst();
13975 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
13976 return true;
13977 }
13978
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13979 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
13980 SourceLocation LParenLoc,
13981 SourceLocation EndLoc) {
13982 // OpenMP [2.11.3, allocate Directive, Description]
13983 // allocator is an expression of omp_allocator_handle_t type.
13984 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
13985 return nullptr;
13986
13987 ExprResult Allocator = DefaultLvalueConversion(A);
13988 if (Allocator.isInvalid())
13989 return nullptr;
13990 Allocator = PerformImplicitConversion(Allocator.get(),
13991 DSAStack->getOMPAllocatorHandleT(),
13992 Sema::AA_Initializing,
13993 /*AllowExplicit=*/true);
13994 if (Allocator.isInvalid())
13995 return nullptr;
13996 return new (Context)
13997 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
13998 }
13999
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14000 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
14001 SourceLocation StartLoc,
14002 SourceLocation LParenLoc,
14003 SourceLocation EndLoc) {
14004 // OpenMP [2.7.1, loop construct, Description]
14005 // OpenMP [2.8.1, simd construct, Description]
14006 // OpenMP [2.9.6, distribute construct, Description]
14007 // The parameter of the collapse clause must be a constant
14008 // positive integer expression.
14009 ExprResult NumForLoopsResult =
14010 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
14011 if (NumForLoopsResult.isInvalid())
14012 return nullptr;
14013 return new (Context)
14014 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
14015 }
14016
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)14017 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
14018 SourceLocation EndLoc,
14019 SourceLocation LParenLoc,
14020 Expr *NumForLoops) {
14021 // OpenMP [2.7.1, loop construct, Description]
14022 // OpenMP [2.8.1, simd construct, Description]
14023 // OpenMP [2.9.6, distribute construct, Description]
14024 // The parameter of the ordered clause must be a constant
14025 // positive integer expression if any.
14026 if (NumForLoops && LParenLoc.isValid()) {
14027 ExprResult NumForLoopsResult =
14028 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
14029 if (NumForLoopsResult.isInvalid())
14030 return nullptr;
14031 NumForLoops = NumForLoopsResult.get();
14032 } else {
14033 NumForLoops = nullptr;
14034 }
14035 auto *Clause = OMPOrderedClause::Create(
14036 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
14037 StartLoc, LParenLoc, EndLoc);
14038 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
14039 return Clause;
14040 }
14041
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14042 OMPClause *Sema::ActOnOpenMPSimpleClause(
14043 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
14044 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14045 OMPClause *Res = nullptr;
14046 switch (Kind) {
14047 case OMPC_default:
14048 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
14049 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14050 break;
14051 case OMPC_proc_bind:
14052 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
14053 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14054 break;
14055 case OMPC_atomic_default_mem_order:
14056 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
14057 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
14058 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14059 break;
14060 case OMPC_order:
14061 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
14062 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14063 break;
14064 case OMPC_update:
14065 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
14066 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14067 break;
14068 case OMPC_if:
14069 case OMPC_final:
14070 case OMPC_num_threads:
14071 case OMPC_safelen:
14072 case OMPC_simdlen:
14073 case OMPC_sizes:
14074 case OMPC_allocator:
14075 case OMPC_collapse:
14076 case OMPC_schedule:
14077 case OMPC_private:
14078 case OMPC_firstprivate:
14079 case OMPC_lastprivate:
14080 case OMPC_shared:
14081 case OMPC_reduction:
14082 case OMPC_task_reduction:
14083 case OMPC_in_reduction:
14084 case OMPC_linear:
14085 case OMPC_aligned:
14086 case OMPC_copyin:
14087 case OMPC_copyprivate:
14088 case OMPC_ordered:
14089 case OMPC_nowait:
14090 case OMPC_untied:
14091 case OMPC_mergeable:
14092 case OMPC_threadprivate:
14093 case OMPC_allocate:
14094 case OMPC_flush:
14095 case OMPC_depobj:
14096 case OMPC_read:
14097 case OMPC_write:
14098 case OMPC_capture:
14099 case OMPC_seq_cst:
14100 case OMPC_acq_rel:
14101 case OMPC_acquire:
14102 case OMPC_release:
14103 case OMPC_relaxed:
14104 case OMPC_depend:
14105 case OMPC_device:
14106 case OMPC_threads:
14107 case OMPC_simd:
14108 case OMPC_map:
14109 case OMPC_num_teams:
14110 case OMPC_thread_limit:
14111 case OMPC_priority:
14112 case OMPC_grainsize:
14113 case OMPC_nogroup:
14114 case OMPC_num_tasks:
14115 case OMPC_hint:
14116 case OMPC_dist_schedule:
14117 case OMPC_defaultmap:
14118 case OMPC_unknown:
14119 case OMPC_uniform:
14120 case OMPC_to:
14121 case OMPC_from:
14122 case OMPC_use_device_ptr:
14123 case OMPC_use_device_addr:
14124 case OMPC_is_device_ptr:
14125 case OMPC_unified_address:
14126 case OMPC_unified_shared_memory:
14127 case OMPC_reverse_offload:
14128 case OMPC_dynamic_allocators:
14129 case OMPC_device_type:
14130 case OMPC_match:
14131 case OMPC_nontemporal:
14132 case OMPC_destroy:
14133 case OMPC_novariants:
14134 case OMPC_nocontext:
14135 case OMPC_detach:
14136 case OMPC_inclusive:
14137 case OMPC_exclusive:
14138 case OMPC_uses_allocators:
14139 case OMPC_affinity:
14140 default:
14141 llvm_unreachable("Clause is not allowed.");
14142 }
14143 return Res;
14144 }
14145
14146 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)14147 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
14148 ArrayRef<unsigned> Exclude = llvm::None) {
14149 SmallString<256> Buffer;
14150 llvm::raw_svector_ostream Out(Buffer);
14151 unsigned Skipped = Exclude.size();
14152 auto S = Exclude.begin(), E = Exclude.end();
14153 for (unsigned I = First; I < Last; ++I) {
14154 if (std::find(S, E, I) != E) {
14155 --Skipped;
14156 continue;
14157 }
14158 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
14159 if (I + Skipped + 2 == Last)
14160 Out << " or ";
14161 else if (I + Skipped + 1 != Last)
14162 Out << ", ";
14163 }
14164 return std::string(Out.str());
14165 }
14166
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14167 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
14168 SourceLocation KindKwLoc,
14169 SourceLocation StartLoc,
14170 SourceLocation LParenLoc,
14171 SourceLocation EndLoc) {
14172 if (Kind == OMP_DEFAULT_unknown) {
14173 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14174 << getListOfPossibleValues(OMPC_default, /*First=*/0,
14175 /*Last=*/unsigned(OMP_DEFAULT_unknown))
14176 << getOpenMPClauseName(OMPC_default);
14177 return nullptr;
14178 }
14179
14180 switch (Kind) {
14181 case OMP_DEFAULT_none:
14182 DSAStack->setDefaultDSANone(KindKwLoc);
14183 break;
14184 case OMP_DEFAULT_shared:
14185 DSAStack->setDefaultDSAShared(KindKwLoc);
14186 break;
14187 case OMP_DEFAULT_firstprivate:
14188 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
14189 break;
14190 default:
14191 llvm_unreachable("DSA unexpected in OpenMP default clause");
14192 }
14193
14194 return new (Context)
14195 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14196 }
14197
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14198 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
14199 SourceLocation KindKwLoc,
14200 SourceLocation StartLoc,
14201 SourceLocation LParenLoc,
14202 SourceLocation EndLoc) {
14203 if (Kind == OMP_PROC_BIND_unknown) {
14204 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14205 << getListOfPossibleValues(OMPC_proc_bind,
14206 /*First=*/unsigned(OMP_PROC_BIND_master),
14207 /*Last=*/
14208 unsigned(LangOpts.OpenMP > 50
14209 ? OMP_PROC_BIND_primary
14210 : OMP_PROC_BIND_spread) +
14211 1)
14212 << getOpenMPClauseName(OMPC_proc_bind);
14213 return nullptr;
14214 }
14215 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
14216 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14217 << getListOfPossibleValues(OMPC_proc_bind,
14218 /*First=*/unsigned(OMP_PROC_BIND_master),
14219 /*Last=*/
14220 unsigned(OMP_PROC_BIND_spread) + 1)
14221 << getOpenMPClauseName(OMPC_proc_bind);
14222 return new (Context)
14223 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14224 }
14225
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14226 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
14227 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
14228 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14229 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
14230 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14231 << getListOfPossibleValues(
14232 OMPC_atomic_default_mem_order, /*First=*/0,
14233 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
14234 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
14235 return nullptr;
14236 }
14237 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
14238 LParenLoc, EndLoc);
14239 }
14240
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14241 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
14242 SourceLocation KindKwLoc,
14243 SourceLocation StartLoc,
14244 SourceLocation LParenLoc,
14245 SourceLocation EndLoc) {
14246 if (Kind == OMPC_ORDER_unknown) {
14247 static_assert(OMPC_ORDER_unknown > 0,
14248 "OMPC_ORDER_unknown not greater than 0");
14249 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14250 << getListOfPossibleValues(OMPC_order, /*First=*/0,
14251 /*Last=*/OMPC_ORDER_unknown)
14252 << getOpenMPClauseName(OMPC_order);
14253 return nullptr;
14254 }
14255 return new (Context)
14256 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14257 }
14258
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14259 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
14260 SourceLocation KindKwLoc,
14261 SourceLocation StartLoc,
14262 SourceLocation LParenLoc,
14263 SourceLocation EndLoc) {
14264 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
14265 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
14266 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
14267 OMPC_DEPEND_depobj};
14268 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14269 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14270 /*Last=*/OMPC_DEPEND_unknown, Except)
14271 << getOpenMPClauseName(OMPC_update);
14272 return nullptr;
14273 }
14274 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
14275 EndLoc);
14276 }
14277
ActOnOpenMPSizesClause(ArrayRef<Expr * > SizeExprs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14278 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
14279 SourceLocation StartLoc,
14280 SourceLocation LParenLoc,
14281 SourceLocation EndLoc) {
14282 for (Expr *SizeExpr : SizeExprs) {
14283 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
14284 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
14285 if (!NumForLoopsResult.isUsable())
14286 return nullptr;
14287 }
14288
14289 DSAStack->setAssociatedLoops(SizeExprs.size());
14290 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14291 SizeExprs);
14292 }
14293
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)14294 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
14295 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
14296 SourceLocation StartLoc, SourceLocation LParenLoc,
14297 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
14298 SourceLocation EndLoc) {
14299 OMPClause *Res = nullptr;
14300 switch (Kind) {
14301 case OMPC_schedule:
14302 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
14303 assert(Argument.size() == NumberOfElements &&
14304 ArgumentLoc.size() == NumberOfElements);
14305 Res = ActOnOpenMPScheduleClause(
14306 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
14307 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
14308 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
14309 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
14310 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
14311 break;
14312 case OMPC_if:
14313 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14314 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
14315 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
14316 DelimLoc, EndLoc);
14317 break;
14318 case OMPC_dist_schedule:
14319 Res = ActOnOpenMPDistScheduleClause(
14320 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
14321 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
14322 break;
14323 case OMPC_defaultmap:
14324 enum { Modifier, DefaultmapKind };
14325 Res = ActOnOpenMPDefaultmapClause(
14326 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
14327 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
14328 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
14329 EndLoc);
14330 break;
14331 case OMPC_device:
14332 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14333 Res = ActOnOpenMPDeviceClause(
14334 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
14335 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
14336 break;
14337 case OMPC_final:
14338 case OMPC_num_threads:
14339 case OMPC_safelen:
14340 case OMPC_simdlen:
14341 case OMPC_sizes:
14342 case OMPC_allocator:
14343 case OMPC_collapse:
14344 case OMPC_default:
14345 case OMPC_proc_bind:
14346 case OMPC_private:
14347 case OMPC_firstprivate:
14348 case OMPC_lastprivate:
14349 case OMPC_shared:
14350 case OMPC_reduction:
14351 case OMPC_task_reduction:
14352 case OMPC_in_reduction:
14353 case OMPC_linear:
14354 case OMPC_aligned:
14355 case OMPC_copyin:
14356 case OMPC_copyprivate:
14357 case OMPC_ordered:
14358 case OMPC_nowait:
14359 case OMPC_untied:
14360 case OMPC_mergeable:
14361 case OMPC_threadprivate:
14362 case OMPC_allocate:
14363 case OMPC_flush:
14364 case OMPC_depobj:
14365 case OMPC_read:
14366 case OMPC_write:
14367 case OMPC_update:
14368 case OMPC_capture:
14369 case OMPC_seq_cst:
14370 case OMPC_acq_rel:
14371 case OMPC_acquire:
14372 case OMPC_release:
14373 case OMPC_relaxed:
14374 case OMPC_depend:
14375 case OMPC_threads:
14376 case OMPC_simd:
14377 case OMPC_map:
14378 case OMPC_num_teams:
14379 case OMPC_thread_limit:
14380 case OMPC_priority:
14381 case OMPC_grainsize:
14382 case OMPC_nogroup:
14383 case OMPC_num_tasks:
14384 case OMPC_hint:
14385 case OMPC_unknown:
14386 case OMPC_uniform:
14387 case OMPC_to:
14388 case OMPC_from:
14389 case OMPC_use_device_ptr:
14390 case OMPC_use_device_addr:
14391 case OMPC_is_device_ptr:
14392 case OMPC_unified_address:
14393 case OMPC_unified_shared_memory:
14394 case OMPC_reverse_offload:
14395 case OMPC_dynamic_allocators:
14396 case OMPC_atomic_default_mem_order:
14397 case OMPC_device_type:
14398 case OMPC_match:
14399 case OMPC_nontemporal:
14400 case OMPC_order:
14401 case OMPC_destroy:
14402 case OMPC_novariants:
14403 case OMPC_nocontext:
14404 case OMPC_detach:
14405 case OMPC_inclusive:
14406 case OMPC_exclusive:
14407 case OMPC_uses_allocators:
14408 case OMPC_affinity:
14409 default:
14410 llvm_unreachable("Clause is not allowed.");
14411 }
14412 return Res;
14413 }
14414
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)14415 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
14416 OpenMPScheduleClauseModifier M2,
14417 SourceLocation M1Loc, SourceLocation M2Loc) {
14418 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
14419 SmallVector<unsigned, 2> Excluded;
14420 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
14421 Excluded.push_back(M2);
14422 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
14423 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
14424 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
14425 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
14426 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
14427 << getListOfPossibleValues(OMPC_schedule,
14428 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
14429 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14430 Excluded)
14431 << getOpenMPClauseName(OMPC_schedule);
14432 return true;
14433 }
14434 return false;
14435 }
14436
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)14437 OMPClause *Sema::ActOnOpenMPScheduleClause(
14438 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
14439 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14440 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
14441 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
14442 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
14443 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
14444 return nullptr;
14445 // OpenMP, 2.7.1, Loop Construct, Restrictions
14446 // Either the monotonic modifier or the nonmonotonic modifier can be specified
14447 // but not both.
14448 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
14449 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
14450 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
14451 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
14452 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
14453 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
14454 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
14455 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
14456 return nullptr;
14457 }
14458 if (Kind == OMPC_SCHEDULE_unknown) {
14459 std::string Values;
14460 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
14461 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
14462 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14463 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14464 Exclude);
14465 } else {
14466 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14467 /*Last=*/OMPC_SCHEDULE_unknown);
14468 }
14469 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14470 << Values << getOpenMPClauseName(OMPC_schedule);
14471 return nullptr;
14472 }
14473 // OpenMP, 2.7.1, Loop Construct, Restrictions
14474 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
14475 // schedule(guided).
14476 // OpenMP 5.0 does not have this restriction.
14477 if (LangOpts.OpenMP < 50 &&
14478 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
14479 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
14480 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
14481 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
14482 diag::err_omp_schedule_nonmonotonic_static);
14483 return nullptr;
14484 }
14485 Expr *ValExpr = ChunkSize;
14486 Stmt *HelperValStmt = nullptr;
14487 if (ChunkSize) {
14488 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14489 !ChunkSize->isInstantiationDependent() &&
14490 !ChunkSize->containsUnexpandedParameterPack()) {
14491 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14492 ExprResult Val =
14493 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14494 if (Val.isInvalid())
14495 return nullptr;
14496
14497 ValExpr = Val.get();
14498
14499 // OpenMP [2.7.1, Restrictions]
14500 // chunk_size must be a loop invariant integer expression with a positive
14501 // value.
14502 if (Optional<llvm::APSInt> Result =
14503 ValExpr->getIntegerConstantExpr(Context)) {
14504 if (Result->isSigned() && !Result->isStrictlyPositive()) {
14505 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14506 << "schedule" << 1 << ChunkSize->getSourceRange();
14507 return nullptr;
14508 }
14509 } else if (getOpenMPCaptureRegionForClause(
14510 DSAStack->getCurrentDirective(), OMPC_schedule,
14511 LangOpts.OpenMP) != OMPD_unknown &&
14512 !CurContext->isDependentContext()) {
14513 ValExpr = MakeFullExpr(ValExpr).get();
14514 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14515 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14516 HelperValStmt = buildPreInits(Context, Captures);
14517 }
14518 }
14519 }
14520
14521 return new (Context)
14522 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
14523 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
14524 }
14525
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)14526 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
14527 SourceLocation StartLoc,
14528 SourceLocation EndLoc) {
14529 OMPClause *Res = nullptr;
14530 switch (Kind) {
14531 case OMPC_ordered:
14532 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
14533 break;
14534 case OMPC_nowait:
14535 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
14536 break;
14537 case OMPC_untied:
14538 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
14539 break;
14540 case OMPC_mergeable:
14541 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
14542 break;
14543 case OMPC_read:
14544 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
14545 break;
14546 case OMPC_write:
14547 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
14548 break;
14549 case OMPC_update:
14550 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
14551 break;
14552 case OMPC_capture:
14553 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
14554 break;
14555 case OMPC_seq_cst:
14556 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
14557 break;
14558 case OMPC_acq_rel:
14559 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
14560 break;
14561 case OMPC_acquire:
14562 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
14563 break;
14564 case OMPC_release:
14565 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
14566 break;
14567 case OMPC_relaxed:
14568 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
14569 break;
14570 case OMPC_threads:
14571 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
14572 break;
14573 case OMPC_simd:
14574 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
14575 break;
14576 case OMPC_nogroup:
14577 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
14578 break;
14579 case OMPC_unified_address:
14580 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
14581 break;
14582 case OMPC_unified_shared_memory:
14583 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14584 break;
14585 case OMPC_reverse_offload:
14586 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
14587 break;
14588 case OMPC_dynamic_allocators:
14589 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
14590 break;
14591 case OMPC_destroy:
14592 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
14593 /*LParenLoc=*/SourceLocation(),
14594 /*VarLoc=*/SourceLocation(), EndLoc);
14595 break;
14596 case OMPC_if:
14597 case OMPC_final:
14598 case OMPC_num_threads:
14599 case OMPC_safelen:
14600 case OMPC_simdlen:
14601 case OMPC_sizes:
14602 case OMPC_allocator:
14603 case OMPC_collapse:
14604 case OMPC_schedule:
14605 case OMPC_private:
14606 case OMPC_firstprivate:
14607 case OMPC_lastprivate:
14608 case OMPC_shared:
14609 case OMPC_reduction:
14610 case OMPC_task_reduction:
14611 case OMPC_in_reduction:
14612 case OMPC_linear:
14613 case OMPC_aligned:
14614 case OMPC_copyin:
14615 case OMPC_copyprivate:
14616 case OMPC_default:
14617 case OMPC_proc_bind:
14618 case OMPC_threadprivate:
14619 case OMPC_allocate:
14620 case OMPC_flush:
14621 case OMPC_depobj:
14622 case OMPC_depend:
14623 case OMPC_device:
14624 case OMPC_map:
14625 case OMPC_num_teams:
14626 case OMPC_thread_limit:
14627 case OMPC_priority:
14628 case OMPC_grainsize:
14629 case OMPC_num_tasks:
14630 case OMPC_hint:
14631 case OMPC_dist_schedule:
14632 case OMPC_defaultmap:
14633 case OMPC_unknown:
14634 case OMPC_uniform:
14635 case OMPC_to:
14636 case OMPC_from:
14637 case OMPC_use_device_ptr:
14638 case OMPC_use_device_addr:
14639 case OMPC_is_device_ptr:
14640 case OMPC_atomic_default_mem_order:
14641 case OMPC_device_type:
14642 case OMPC_match:
14643 case OMPC_nontemporal:
14644 case OMPC_order:
14645 case OMPC_novariants:
14646 case OMPC_nocontext:
14647 case OMPC_detach:
14648 case OMPC_inclusive:
14649 case OMPC_exclusive:
14650 case OMPC_uses_allocators:
14651 case OMPC_affinity:
14652 default:
14653 llvm_unreachable("Clause is not allowed.");
14654 }
14655 return Res;
14656 }
14657
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)14658 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
14659 SourceLocation EndLoc) {
14660 DSAStack->setNowaitRegion();
14661 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
14662 }
14663
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)14664 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
14665 SourceLocation EndLoc) {
14666 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
14667 }
14668
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)14669 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
14670 SourceLocation EndLoc) {
14671 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
14672 }
14673
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)14674 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
14675 SourceLocation EndLoc) {
14676 return new (Context) OMPReadClause(StartLoc, EndLoc);
14677 }
14678
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)14679 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
14680 SourceLocation EndLoc) {
14681 return new (Context) OMPWriteClause(StartLoc, EndLoc);
14682 }
14683
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)14684 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
14685 SourceLocation EndLoc) {
14686 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
14687 }
14688
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)14689 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
14690 SourceLocation EndLoc) {
14691 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
14692 }
14693
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)14694 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
14695 SourceLocation EndLoc) {
14696 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
14697 }
14698
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)14699 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
14700 SourceLocation EndLoc) {
14701 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
14702 }
14703
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)14704 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
14705 SourceLocation EndLoc) {
14706 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
14707 }
14708
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)14709 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
14710 SourceLocation EndLoc) {
14711 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
14712 }
14713
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)14714 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
14715 SourceLocation EndLoc) {
14716 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
14717 }
14718
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)14719 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
14720 SourceLocation EndLoc) {
14721 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
14722 }
14723
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)14724 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
14725 SourceLocation EndLoc) {
14726 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
14727 }
14728
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)14729 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
14730 SourceLocation EndLoc) {
14731 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
14732 }
14733
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)14734 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
14735 SourceLocation EndLoc) {
14736 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
14737 }
14738
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)14739 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
14740 SourceLocation EndLoc) {
14741 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14742 }
14743
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)14744 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
14745 SourceLocation EndLoc) {
14746 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
14747 }
14748
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)14749 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
14750 SourceLocation EndLoc) {
14751 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
14752 }
14753
ActOnOpenMPInteropDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)14754 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
14755 SourceLocation StartLoc,
14756 SourceLocation EndLoc) {
14757
14758 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14759 // At least one action-clause must appear on a directive.
14760 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
14761 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
14762 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
14763 << Expected << getOpenMPDirectiveName(OMPD_interop);
14764 return StmtError();
14765 }
14766
14767 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14768 // A depend clause can only appear on the directive if a targetsync
14769 // interop-type is present or the interop-var was initialized with
14770 // the targetsync interop-type.
14771
14772 // If there is any 'init' clause diagnose if there is no 'init' clause with
14773 // interop-type of 'targetsync'. Cases involving other directives cannot be
14774 // diagnosed.
14775 const OMPDependClause *DependClause = nullptr;
14776 bool HasInitClause = false;
14777 bool IsTargetSync = false;
14778 for (const OMPClause *C : Clauses) {
14779 if (IsTargetSync)
14780 break;
14781 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
14782 HasInitClause = true;
14783 if (InitClause->getIsTargetSync())
14784 IsTargetSync = true;
14785 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
14786 DependClause = DC;
14787 }
14788 }
14789 if (DependClause && HasInitClause && !IsTargetSync) {
14790 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
14791 return StmtError();
14792 }
14793
14794 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14795 // Each interop-var may be specified for at most one action-clause of each
14796 // interop construct.
14797 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
14798 for (const OMPClause *C : Clauses) {
14799 OpenMPClauseKind ClauseKind = C->getClauseKind();
14800 const DeclRefExpr *DRE = nullptr;
14801 SourceLocation VarLoc;
14802
14803 if (ClauseKind == OMPC_init) {
14804 const auto *IC = cast<OMPInitClause>(C);
14805 VarLoc = IC->getVarLoc();
14806 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
14807 } else if (ClauseKind == OMPC_use) {
14808 const auto *UC = cast<OMPUseClause>(C);
14809 VarLoc = UC->getVarLoc();
14810 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
14811 } else if (ClauseKind == OMPC_destroy) {
14812 const auto *DC = cast<OMPDestroyClause>(C);
14813 VarLoc = DC->getVarLoc();
14814 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
14815 }
14816
14817 if (!DRE)
14818 continue;
14819
14820 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
14821 if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
14822 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
14823 return StmtError();
14824 }
14825 }
14826 }
14827
14828 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
14829 }
14830
isValidInteropVariable(Sema & SemaRef,Expr * InteropVarExpr,SourceLocation VarLoc,OpenMPClauseKind Kind)14831 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
14832 SourceLocation VarLoc,
14833 OpenMPClauseKind Kind) {
14834 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
14835 InteropVarExpr->isInstantiationDependent() ||
14836 InteropVarExpr->containsUnexpandedParameterPack())
14837 return true;
14838
14839 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
14840 if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
14841 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
14842 return false;
14843 }
14844
14845 // Interop variable should be of type omp_interop_t.
14846 bool HasError = false;
14847 QualType InteropType;
14848 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
14849 VarLoc, Sema::LookupOrdinaryName);
14850 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
14851 NamedDecl *ND = Result.getFoundDecl();
14852 if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
14853 InteropType = QualType(TD->getTypeForDecl(), 0);
14854 } else {
14855 HasError = true;
14856 }
14857 } else {
14858 HasError = true;
14859 }
14860
14861 if (HasError) {
14862 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
14863 << "omp_interop_t";
14864 return false;
14865 }
14866
14867 QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
14868 if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
14869 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
14870 return false;
14871 }
14872
14873 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14874 // The interop-var passed to init or destroy must be non-const.
14875 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
14876 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
14877 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
14878 << /*non-const*/ 1;
14879 return false;
14880 }
14881 return true;
14882 }
14883
14884 OMPClause *
ActOnOpenMPInitClause(Expr * InteropVar,ArrayRef<Expr * > PrefExprs,bool IsTarget,bool IsTargetSync,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)14885 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
14886 bool IsTarget, bool IsTargetSync,
14887 SourceLocation StartLoc, SourceLocation LParenLoc,
14888 SourceLocation VarLoc, SourceLocation EndLoc) {
14889
14890 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
14891 return nullptr;
14892
14893 // Check prefer_type values. These foreign-runtime-id values are either
14894 // string literals or constant integral expressions.
14895 for (const Expr *E : PrefExprs) {
14896 if (E->isValueDependent() || E->isTypeDependent() ||
14897 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
14898 continue;
14899 if (E->isIntegerConstantExpr(Context))
14900 continue;
14901 if (isa<StringLiteral>(E))
14902 continue;
14903 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
14904 return nullptr;
14905 }
14906
14907 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
14908 IsTargetSync, StartLoc, LParenLoc, VarLoc,
14909 EndLoc);
14910 }
14911
ActOnOpenMPUseClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)14912 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
14913 SourceLocation LParenLoc,
14914 SourceLocation VarLoc,
14915 SourceLocation EndLoc) {
14916
14917 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
14918 return nullptr;
14919
14920 return new (Context)
14921 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
14922 }
14923
ActOnOpenMPDestroyClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)14924 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
14925 SourceLocation StartLoc,
14926 SourceLocation LParenLoc,
14927 SourceLocation VarLoc,
14928 SourceLocation EndLoc) {
14929 if (InteropVar &&
14930 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
14931 return nullptr;
14932
14933 return new (Context)
14934 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
14935 }
14936
ActOnOpenMPNovariantsClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14937 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
14938 SourceLocation StartLoc,
14939 SourceLocation LParenLoc,
14940 SourceLocation EndLoc) {
14941 Expr *ValExpr = Condition;
14942 Stmt *HelperValStmt = nullptr;
14943 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14944 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14945 !Condition->isInstantiationDependent() &&
14946 !Condition->containsUnexpandedParameterPack()) {
14947 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14948 if (Val.isInvalid())
14949 return nullptr;
14950
14951 ValExpr = MakeFullExpr(Val.get()).get();
14952
14953 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14954 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
14955 LangOpts.OpenMP);
14956 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14957 ValExpr = MakeFullExpr(ValExpr).get();
14958 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14959 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14960 HelperValStmt = buildPreInits(Context, Captures);
14961 }
14962 }
14963
14964 return new (Context) OMPNovariantsClause(
14965 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14966 }
14967
ActOnOpenMPNocontextClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14968 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
14969 SourceLocation StartLoc,
14970 SourceLocation LParenLoc,
14971 SourceLocation EndLoc) {
14972 Expr *ValExpr = Condition;
14973 Stmt *HelperValStmt = nullptr;
14974 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14975 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14976 !Condition->isInstantiationDependent() &&
14977 !Condition->containsUnexpandedParameterPack()) {
14978 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14979 if (Val.isInvalid())
14980 return nullptr;
14981
14982 ValExpr = MakeFullExpr(Val.get()).get();
14983
14984 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14985 CaptureRegion =
14986 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
14987 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14988 ValExpr = MakeFullExpr(ValExpr).get();
14989 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14990 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14991 HelperValStmt = buildPreInits(Context, Captures);
14992 }
14993 }
14994
14995 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
14996 StartLoc, LParenLoc, EndLoc);
14997 }
14998
ActOnOpenMPFilterClause(Expr * ThreadID,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14999 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
15000 SourceLocation StartLoc,
15001 SourceLocation LParenLoc,
15002 SourceLocation EndLoc) {
15003 Expr *ValExpr = ThreadID;
15004 Stmt *HelperValStmt = nullptr;
15005
15006 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15007 OpenMPDirectiveKind CaptureRegion =
15008 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
15009 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15010 ValExpr = MakeFullExpr(ValExpr).get();
15011 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15012 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15013 HelperValStmt = buildPreInits(Context, Captures);
15014 }
15015
15016 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
15017 StartLoc, LParenLoc, EndLoc);
15018 }
15019
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)15020 OMPClause *Sema::ActOnOpenMPVarListClause(
15021 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
15022 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
15023 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
15024 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
15025 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15026 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
15027 SourceLocation ExtraModifierLoc,
15028 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
15029 ArrayRef<SourceLocation> MotionModifiersLoc) {
15030 SourceLocation StartLoc = Locs.StartLoc;
15031 SourceLocation LParenLoc = Locs.LParenLoc;
15032 SourceLocation EndLoc = Locs.EndLoc;
15033 OMPClause *Res = nullptr;
15034 switch (Kind) {
15035 case OMPC_private:
15036 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15037 break;
15038 case OMPC_firstprivate:
15039 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15040 break;
15041 case OMPC_lastprivate:
15042 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
15043 "Unexpected lastprivate modifier.");
15044 Res = ActOnOpenMPLastprivateClause(
15045 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
15046 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
15047 break;
15048 case OMPC_shared:
15049 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
15050 break;
15051 case OMPC_reduction:
15052 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
15053 "Unexpected lastprivate modifier.");
15054 Res = ActOnOpenMPReductionClause(
15055 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
15056 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
15057 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
15058 break;
15059 case OMPC_task_reduction:
15060 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15061 EndLoc, ReductionOrMapperIdScopeSpec,
15062 ReductionOrMapperId);
15063 break;
15064 case OMPC_in_reduction:
15065 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15066 EndLoc, ReductionOrMapperIdScopeSpec,
15067 ReductionOrMapperId);
15068 break;
15069 case OMPC_linear:
15070 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
15071 "Unexpected linear modifier.");
15072 Res = ActOnOpenMPLinearClause(
15073 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
15074 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
15075 ColonLoc, EndLoc);
15076 break;
15077 case OMPC_aligned:
15078 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
15079 LParenLoc, ColonLoc, EndLoc);
15080 break;
15081 case OMPC_copyin:
15082 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
15083 break;
15084 case OMPC_copyprivate:
15085 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15086 break;
15087 case OMPC_flush:
15088 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
15089 break;
15090 case OMPC_depend:
15091 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
15092 "Unexpected depend modifier.");
15093 Res = ActOnOpenMPDependClause(
15094 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
15095 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
15096 break;
15097 case OMPC_map:
15098 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
15099 "Unexpected map modifier.");
15100 Res = ActOnOpenMPMapClause(
15101 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
15102 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
15103 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
15104 break;
15105 case OMPC_to:
15106 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
15107 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
15108 ColonLoc, VarList, Locs);
15109 break;
15110 case OMPC_from:
15111 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
15112 ReductionOrMapperIdScopeSpec,
15113 ReductionOrMapperId, ColonLoc, VarList, Locs);
15114 break;
15115 case OMPC_use_device_ptr:
15116 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
15117 break;
15118 case OMPC_use_device_addr:
15119 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
15120 break;
15121 case OMPC_is_device_ptr:
15122 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
15123 break;
15124 case OMPC_allocate:
15125 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
15126 LParenLoc, ColonLoc, EndLoc);
15127 break;
15128 case OMPC_nontemporal:
15129 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
15130 break;
15131 case OMPC_inclusive:
15132 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15133 break;
15134 case OMPC_exclusive:
15135 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15136 break;
15137 case OMPC_affinity:
15138 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
15139 DepModOrTailExpr, VarList);
15140 break;
15141 case OMPC_if:
15142 case OMPC_depobj:
15143 case OMPC_final:
15144 case OMPC_num_threads:
15145 case OMPC_safelen:
15146 case OMPC_simdlen:
15147 case OMPC_sizes:
15148 case OMPC_allocator:
15149 case OMPC_collapse:
15150 case OMPC_default:
15151 case OMPC_proc_bind:
15152 case OMPC_schedule:
15153 case OMPC_ordered:
15154 case OMPC_nowait:
15155 case OMPC_untied:
15156 case OMPC_mergeable:
15157 case OMPC_threadprivate:
15158 case OMPC_read:
15159 case OMPC_write:
15160 case OMPC_update:
15161 case OMPC_capture:
15162 case OMPC_seq_cst:
15163 case OMPC_acq_rel:
15164 case OMPC_acquire:
15165 case OMPC_release:
15166 case OMPC_relaxed:
15167 case OMPC_device:
15168 case OMPC_threads:
15169 case OMPC_simd:
15170 case OMPC_num_teams:
15171 case OMPC_thread_limit:
15172 case OMPC_priority:
15173 case OMPC_grainsize:
15174 case OMPC_nogroup:
15175 case OMPC_num_tasks:
15176 case OMPC_hint:
15177 case OMPC_dist_schedule:
15178 case OMPC_defaultmap:
15179 case OMPC_unknown:
15180 case OMPC_uniform:
15181 case OMPC_unified_address:
15182 case OMPC_unified_shared_memory:
15183 case OMPC_reverse_offload:
15184 case OMPC_dynamic_allocators:
15185 case OMPC_atomic_default_mem_order:
15186 case OMPC_device_type:
15187 case OMPC_match:
15188 case OMPC_order:
15189 case OMPC_destroy:
15190 case OMPC_novariants:
15191 case OMPC_nocontext:
15192 case OMPC_detach:
15193 case OMPC_uses_allocators:
15194 default:
15195 llvm_unreachable("Clause is not allowed.");
15196 }
15197 return Res;
15198 }
15199
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)15200 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
15201 ExprObjectKind OK, SourceLocation Loc) {
15202 ExprResult Res = BuildDeclRefExpr(
15203 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
15204 if (!Res.isUsable())
15205 return ExprError();
15206 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
15207 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
15208 if (!Res.isUsable())
15209 return ExprError();
15210 }
15211 if (VK != VK_LValue && Res.get()->isGLValue()) {
15212 Res = DefaultLvalueConversion(Res.get());
15213 if (!Res.isUsable())
15214 return ExprError();
15215 }
15216 return Res;
15217 }
15218
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15219 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
15220 SourceLocation StartLoc,
15221 SourceLocation LParenLoc,
15222 SourceLocation EndLoc) {
15223 SmallVector<Expr *, 8> Vars;
15224 SmallVector<Expr *, 8> PrivateCopies;
15225 for (Expr *RefExpr : VarList) {
15226 assert(RefExpr && "NULL expr in OpenMP private clause.");
15227 SourceLocation ELoc;
15228 SourceRange ERange;
15229 Expr *SimpleRefExpr = RefExpr;
15230 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15231 if (Res.second) {
15232 // It will be analyzed later.
15233 Vars.push_back(RefExpr);
15234 PrivateCopies.push_back(nullptr);
15235 }
15236 ValueDecl *D = Res.first;
15237 if (!D)
15238 continue;
15239
15240 QualType Type = D->getType();
15241 auto *VD = dyn_cast<VarDecl>(D);
15242
15243 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15244 // A variable that appears in a private clause must not have an incomplete
15245 // type or a reference type.
15246 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
15247 continue;
15248 Type = Type.getNonReferenceType();
15249
15250 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15251 // A variable that is privatized must not have a const-qualified type
15252 // unless it is of class type with a mutable member. This restriction does
15253 // not apply to the firstprivate clause.
15254 //
15255 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
15256 // A variable that appears in a private clause must not have a
15257 // const-qualified type unless it is of class type with a mutable member.
15258 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
15259 continue;
15260
15261 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15262 // in a Construct]
15263 // Variables with the predetermined data-sharing attributes may not be
15264 // listed in data-sharing attributes clauses, except for the cases
15265 // listed below. For these exceptions only, listing a predetermined
15266 // variable in a data-sharing attribute clause is allowed and overrides
15267 // the variable's predetermined data-sharing attributes.
15268 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15269 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
15270 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15271 << getOpenMPClauseName(OMPC_private);
15272 reportOriginalDsa(*this, DSAStack, D, DVar);
15273 continue;
15274 }
15275
15276 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15277 // Variably modified types are not supported for tasks.
15278 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15279 isOpenMPTaskingDirective(CurrDir)) {
15280 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15281 << getOpenMPClauseName(OMPC_private) << Type
15282 << getOpenMPDirectiveName(CurrDir);
15283 bool IsDecl =
15284 !VD ||
15285 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15286 Diag(D->getLocation(),
15287 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15288 << D;
15289 continue;
15290 }
15291
15292 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15293 // A list item cannot appear in both a map clause and a data-sharing
15294 // attribute clause on the same construct
15295 //
15296 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15297 // A list item cannot appear in both a map clause and a data-sharing
15298 // attribute clause on the same construct unless the construct is a
15299 // combined construct.
15300 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
15301 CurrDir == OMPD_target) {
15302 OpenMPClauseKind ConflictKind;
15303 if (DSAStack->checkMappableExprComponentListsForDecl(
15304 VD, /*CurrentRegionOnly=*/true,
15305 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
15306 OpenMPClauseKind WhereFoundClauseKind) -> bool {
15307 ConflictKind = WhereFoundClauseKind;
15308 return true;
15309 })) {
15310 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15311 << getOpenMPClauseName(OMPC_private)
15312 << getOpenMPClauseName(ConflictKind)
15313 << getOpenMPDirectiveName(CurrDir);
15314 reportOriginalDsa(*this, DSAStack, D, DVar);
15315 continue;
15316 }
15317 }
15318
15319 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
15320 // A variable of class type (or array thereof) that appears in a private
15321 // clause requires an accessible, unambiguous default constructor for the
15322 // class type.
15323 // Generate helper private variable and initialize it with the default
15324 // value. The address of the original variable is replaced by the address of
15325 // the new private variable in CodeGen. This new variable is not added to
15326 // IdResolver, so the code in the OpenMP region uses original variable for
15327 // proper diagnostics.
15328 Type = Type.getUnqualifiedType();
15329 VarDecl *VDPrivate =
15330 buildVarDecl(*this, ELoc, Type, D->getName(),
15331 D->hasAttrs() ? &D->getAttrs() : nullptr,
15332 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15333 ActOnUninitializedDecl(VDPrivate);
15334 if (VDPrivate->isInvalidDecl())
15335 continue;
15336 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15337 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15338
15339 DeclRefExpr *Ref = nullptr;
15340 if (!VD && !CurContext->isDependentContext())
15341 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15342 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
15343 Vars.push_back((VD || CurContext->isDependentContext())
15344 ? RefExpr->IgnoreParens()
15345 : Ref);
15346 PrivateCopies.push_back(VDPrivateRefExpr);
15347 }
15348
15349 if (Vars.empty())
15350 return nullptr;
15351
15352 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15353 PrivateCopies);
15354 }
15355
15356 namespace {
15357 class DiagsUninitializedSeveretyRAII {
15358 private:
15359 DiagnosticsEngine &Diags;
15360 SourceLocation SavedLoc;
15361 bool IsIgnored = false;
15362
15363 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)15364 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
15365 bool IsIgnored)
15366 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
15367 if (!IsIgnored) {
15368 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
15369 /*Map*/ diag::Severity::Ignored, Loc);
15370 }
15371 }
~DiagsUninitializedSeveretyRAII()15372 ~DiagsUninitializedSeveretyRAII() {
15373 if (!IsIgnored)
15374 Diags.popMappings(SavedLoc);
15375 }
15376 };
15377 }
15378
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15379 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
15380 SourceLocation StartLoc,
15381 SourceLocation LParenLoc,
15382 SourceLocation EndLoc) {
15383 SmallVector<Expr *, 8> Vars;
15384 SmallVector<Expr *, 8> PrivateCopies;
15385 SmallVector<Expr *, 8> Inits;
15386 SmallVector<Decl *, 4> ExprCaptures;
15387 bool IsImplicitClause =
15388 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
15389 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
15390
15391 for (Expr *RefExpr : VarList) {
15392 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
15393 SourceLocation ELoc;
15394 SourceRange ERange;
15395 Expr *SimpleRefExpr = RefExpr;
15396 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15397 if (Res.second) {
15398 // It will be analyzed later.
15399 Vars.push_back(RefExpr);
15400 PrivateCopies.push_back(nullptr);
15401 Inits.push_back(nullptr);
15402 }
15403 ValueDecl *D = Res.first;
15404 if (!D)
15405 continue;
15406
15407 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
15408 QualType Type = D->getType();
15409 auto *VD = dyn_cast<VarDecl>(D);
15410
15411 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15412 // A variable that appears in a private clause must not have an incomplete
15413 // type or a reference type.
15414 if (RequireCompleteType(ELoc, Type,
15415 diag::err_omp_firstprivate_incomplete_type))
15416 continue;
15417 Type = Type.getNonReferenceType();
15418
15419 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
15420 // A variable of class type (or array thereof) that appears in a private
15421 // clause requires an accessible, unambiguous copy constructor for the
15422 // class type.
15423 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15424
15425 // If an implicit firstprivate variable found it was checked already.
15426 DSAStackTy::DSAVarData TopDVar;
15427 if (!IsImplicitClause) {
15428 DSAStackTy::DSAVarData DVar =
15429 DSAStack->getTopDSA(D, /*FromParent=*/false);
15430 TopDVar = DVar;
15431 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15432 bool IsConstant = ElemType.isConstant(Context);
15433 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
15434 // A list item that specifies a given variable may not appear in more
15435 // than one clause on the same directive, except that a variable may be
15436 // specified in both firstprivate and lastprivate clauses.
15437 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15438 // A list item may appear in a firstprivate or lastprivate clause but not
15439 // both.
15440 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
15441 (isOpenMPDistributeDirective(CurrDir) ||
15442 DVar.CKind != OMPC_lastprivate) &&
15443 DVar.RefExpr) {
15444 Diag(ELoc, diag::err_omp_wrong_dsa)
15445 << getOpenMPClauseName(DVar.CKind)
15446 << getOpenMPClauseName(OMPC_firstprivate);
15447 reportOriginalDsa(*this, DSAStack, D, DVar);
15448 continue;
15449 }
15450
15451 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15452 // in a Construct]
15453 // Variables with the predetermined data-sharing attributes may not be
15454 // listed in data-sharing attributes clauses, except for the cases
15455 // listed below. For these exceptions only, listing a predetermined
15456 // variable in a data-sharing attribute clause is allowed and overrides
15457 // the variable's predetermined data-sharing attributes.
15458 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15459 // in a Construct, C/C++, p.2]
15460 // Variables with const-qualified type having no mutable member may be
15461 // listed in a firstprivate clause, even if they are static data members.
15462 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
15463 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
15464 Diag(ELoc, diag::err_omp_wrong_dsa)
15465 << getOpenMPClauseName(DVar.CKind)
15466 << getOpenMPClauseName(OMPC_firstprivate);
15467 reportOriginalDsa(*this, DSAStack, D, DVar);
15468 continue;
15469 }
15470
15471 // OpenMP [2.9.3.4, Restrictions, p.2]
15472 // A list item that is private within a parallel region must not appear
15473 // in a firstprivate clause on a worksharing construct if any of the
15474 // worksharing regions arising from the worksharing construct ever bind
15475 // to any of the parallel regions arising from the parallel construct.
15476 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15477 // A list item that is private within a teams region must not appear in a
15478 // firstprivate clause on a distribute construct if any of the distribute
15479 // regions arising from the distribute construct ever bind to any of the
15480 // teams regions arising from the teams construct.
15481 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15482 // A list item that appears in a reduction clause of a teams construct
15483 // must not appear in a firstprivate clause on a distribute construct if
15484 // any of the distribute regions arising from the distribute construct
15485 // ever bind to any of the teams regions arising from the teams construct.
15486 if ((isOpenMPWorksharingDirective(CurrDir) ||
15487 isOpenMPDistributeDirective(CurrDir)) &&
15488 !isOpenMPParallelDirective(CurrDir) &&
15489 !isOpenMPTeamsDirective(CurrDir)) {
15490 DVar = DSAStack->getImplicitDSA(D, true);
15491 if (DVar.CKind != OMPC_shared &&
15492 (isOpenMPParallelDirective(DVar.DKind) ||
15493 isOpenMPTeamsDirective(DVar.DKind) ||
15494 DVar.DKind == OMPD_unknown)) {
15495 Diag(ELoc, diag::err_omp_required_access)
15496 << getOpenMPClauseName(OMPC_firstprivate)
15497 << getOpenMPClauseName(OMPC_shared);
15498 reportOriginalDsa(*this, DSAStack, D, DVar);
15499 continue;
15500 }
15501 }
15502 // OpenMP [2.9.3.4, Restrictions, p.3]
15503 // A list item that appears in a reduction clause of a parallel construct
15504 // must not appear in a firstprivate clause on a worksharing or task
15505 // construct if any of the worksharing or task regions arising from the
15506 // worksharing or task construct ever bind to any of the parallel regions
15507 // arising from the parallel construct.
15508 // OpenMP [2.9.3.4, Restrictions, p.4]
15509 // A list item that appears in a reduction clause in worksharing
15510 // construct must not appear in a firstprivate clause in a task construct
15511 // encountered during execution of any of the worksharing regions arising
15512 // from the worksharing construct.
15513 if (isOpenMPTaskingDirective(CurrDir)) {
15514 DVar = DSAStack->hasInnermostDSA(
15515 D,
15516 [](OpenMPClauseKind C, bool AppliedToPointee) {
15517 return C == OMPC_reduction && !AppliedToPointee;
15518 },
15519 [](OpenMPDirectiveKind K) {
15520 return isOpenMPParallelDirective(K) ||
15521 isOpenMPWorksharingDirective(K) ||
15522 isOpenMPTeamsDirective(K);
15523 },
15524 /*FromParent=*/true);
15525 if (DVar.CKind == OMPC_reduction &&
15526 (isOpenMPParallelDirective(DVar.DKind) ||
15527 isOpenMPWorksharingDirective(DVar.DKind) ||
15528 isOpenMPTeamsDirective(DVar.DKind))) {
15529 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
15530 << getOpenMPDirectiveName(DVar.DKind);
15531 reportOriginalDsa(*this, DSAStack, D, DVar);
15532 continue;
15533 }
15534 }
15535
15536 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15537 // A list item cannot appear in both a map clause and a data-sharing
15538 // attribute clause on the same construct
15539 //
15540 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15541 // A list item cannot appear in both a map clause and a data-sharing
15542 // attribute clause on the same construct unless the construct is a
15543 // combined construct.
15544 if ((LangOpts.OpenMP <= 45 &&
15545 isOpenMPTargetExecutionDirective(CurrDir)) ||
15546 CurrDir == OMPD_target) {
15547 OpenMPClauseKind ConflictKind;
15548 if (DSAStack->checkMappableExprComponentListsForDecl(
15549 VD, /*CurrentRegionOnly=*/true,
15550 [&ConflictKind](
15551 OMPClauseMappableExprCommon::MappableExprComponentListRef,
15552 OpenMPClauseKind WhereFoundClauseKind) {
15553 ConflictKind = WhereFoundClauseKind;
15554 return true;
15555 })) {
15556 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15557 << getOpenMPClauseName(OMPC_firstprivate)
15558 << getOpenMPClauseName(ConflictKind)
15559 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
15560 reportOriginalDsa(*this, DSAStack, D, DVar);
15561 continue;
15562 }
15563 }
15564 }
15565
15566 // Variably modified types are not supported for tasks.
15567 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15568 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
15569 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15570 << getOpenMPClauseName(OMPC_firstprivate) << Type
15571 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
15572 bool IsDecl =
15573 !VD ||
15574 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15575 Diag(D->getLocation(),
15576 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15577 << D;
15578 continue;
15579 }
15580
15581 Type = Type.getUnqualifiedType();
15582 VarDecl *VDPrivate =
15583 buildVarDecl(*this, ELoc, Type, D->getName(),
15584 D->hasAttrs() ? &D->getAttrs() : nullptr,
15585 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15586 // Generate helper private variable and initialize it with the value of the
15587 // original variable. The address of the original variable is replaced by
15588 // the address of the new private variable in the CodeGen. This new variable
15589 // is not added to IdResolver, so the code in the OpenMP region uses
15590 // original variable for proper diagnostics and variable capturing.
15591 Expr *VDInitRefExpr = nullptr;
15592 // For arrays generate initializer for single element and replace it by the
15593 // original array element in CodeGen.
15594 if (Type->isArrayType()) {
15595 VarDecl *VDInit =
15596 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
15597 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
15598 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
15599 ElemType = ElemType.getUnqualifiedType();
15600 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
15601 ".firstprivate.temp");
15602 InitializedEntity Entity =
15603 InitializedEntity::InitializeVariable(VDInitTemp);
15604 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
15605
15606 InitializationSequence InitSeq(*this, Entity, Kind, Init);
15607 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
15608 if (Result.isInvalid())
15609 VDPrivate->setInvalidDecl();
15610 else
15611 VDPrivate->setInit(Result.getAs<Expr>());
15612 // Remove temp variable declaration.
15613 Context.Deallocate(VDInitTemp);
15614 } else {
15615 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
15616 ".firstprivate.temp");
15617 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
15618 RefExpr->getExprLoc());
15619 AddInitializerToDecl(VDPrivate,
15620 DefaultLvalueConversion(VDInitRefExpr).get(),
15621 /*DirectInit=*/false);
15622 }
15623 if (VDPrivate->isInvalidDecl()) {
15624 if (IsImplicitClause) {
15625 Diag(RefExpr->getExprLoc(),
15626 diag::note_omp_task_predetermined_firstprivate_here);
15627 }
15628 continue;
15629 }
15630 CurContext->addDecl(VDPrivate);
15631 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15632 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
15633 RefExpr->getExprLoc());
15634 DeclRefExpr *Ref = nullptr;
15635 if (!VD && !CurContext->isDependentContext()) {
15636 if (TopDVar.CKind == OMPC_lastprivate) {
15637 Ref = TopDVar.PrivateCopy;
15638 } else {
15639 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15640 if (!isOpenMPCapturedDecl(D))
15641 ExprCaptures.push_back(Ref->getDecl());
15642 }
15643 }
15644 if (!IsImplicitClause)
15645 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
15646 Vars.push_back((VD || CurContext->isDependentContext())
15647 ? RefExpr->IgnoreParens()
15648 : Ref);
15649 PrivateCopies.push_back(VDPrivateRefExpr);
15650 Inits.push_back(VDInitRefExpr);
15651 }
15652
15653 if (Vars.empty())
15654 return nullptr;
15655
15656 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15657 Vars, PrivateCopies, Inits,
15658 buildPreInits(Context, ExprCaptures));
15659 }
15660
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15661 OMPClause *Sema::ActOnOpenMPLastprivateClause(
15662 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
15663 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
15664 SourceLocation LParenLoc, SourceLocation EndLoc) {
15665 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
15666 assert(ColonLoc.isValid() && "Colon location must be valid.");
15667 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
15668 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
15669 /*Last=*/OMPC_LASTPRIVATE_unknown)
15670 << getOpenMPClauseName(OMPC_lastprivate);
15671 return nullptr;
15672 }
15673
15674 SmallVector<Expr *, 8> Vars;
15675 SmallVector<Expr *, 8> SrcExprs;
15676 SmallVector<Expr *, 8> DstExprs;
15677 SmallVector<Expr *, 8> AssignmentOps;
15678 SmallVector<Decl *, 4> ExprCaptures;
15679 SmallVector<Expr *, 4> ExprPostUpdates;
15680 for (Expr *RefExpr : VarList) {
15681 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
15682 SourceLocation ELoc;
15683 SourceRange ERange;
15684 Expr *SimpleRefExpr = RefExpr;
15685 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15686 if (Res.second) {
15687 // It will be analyzed later.
15688 Vars.push_back(RefExpr);
15689 SrcExprs.push_back(nullptr);
15690 DstExprs.push_back(nullptr);
15691 AssignmentOps.push_back(nullptr);
15692 }
15693 ValueDecl *D = Res.first;
15694 if (!D)
15695 continue;
15696
15697 QualType Type = D->getType();
15698 auto *VD = dyn_cast<VarDecl>(D);
15699
15700 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
15701 // A variable that appears in a lastprivate clause must not have an
15702 // incomplete type or a reference type.
15703 if (RequireCompleteType(ELoc, Type,
15704 diag::err_omp_lastprivate_incomplete_type))
15705 continue;
15706 Type = Type.getNonReferenceType();
15707
15708 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15709 // A variable that is privatized must not have a const-qualified type
15710 // unless it is of class type with a mutable member. This restriction does
15711 // not apply to the firstprivate clause.
15712 //
15713 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
15714 // A variable that appears in a lastprivate clause must not have a
15715 // const-qualified type unless it is of class type with a mutable member.
15716 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
15717 continue;
15718
15719 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
15720 // A list item that appears in a lastprivate clause with the conditional
15721 // modifier must be a scalar variable.
15722 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
15723 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
15724 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15725 VarDecl::DeclarationOnly;
15726 Diag(D->getLocation(),
15727 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15728 << D;
15729 continue;
15730 }
15731
15732 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15733 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15734 // in a Construct]
15735 // Variables with the predetermined data-sharing attributes may not be
15736 // listed in data-sharing attributes clauses, except for the cases
15737 // listed below.
15738 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15739 // A list item may appear in a firstprivate or lastprivate clause but not
15740 // both.
15741 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15742 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
15743 (isOpenMPDistributeDirective(CurrDir) ||
15744 DVar.CKind != OMPC_firstprivate) &&
15745 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
15746 Diag(ELoc, diag::err_omp_wrong_dsa)
15747 << getOpenMPClauseName(DVar.CKind)
15748 << getOpenMPClauseName(OMPC_lastprivate);
15749 reportOriginalDsa(*this, DSAStack, D, DVar);
15750 continue;
15751 }
15752
15753 // OpenMP [2.14.3.5, Restrictions, p.2]
15754 // A list item that is private within a parallel region, or that appears in
15755 // the reduction clause of a parallel construct, must not appear in a
15756 // lastprivate clause on a worksharing construct if any of the corresponding
15757 // worksharing regions ever binds to any of the corresponding parallel
15758 // regions.
15759 DSAStackTy::DSAVarData TopDVar = DVar;
15760 if (isOpenMPWorksharingDirective(CurrDir) &&
15761 !isOpenMPParallelDirective(CurrDir) &&
15762 !isOpenMPTeamsDirective(CurrDir)) {
15763 DVar = DSAStack->getImplicitDSA(D, true);
15764 if (DVar.CKind != OMPC_shared) {
15765 Diag(ELoc, diag::err_omp_required_access)
15766 << getOpenMPClauseName(OMPC_lastprivate)
15767 << getOpenMPClauseName(OMPC_shared);
15768 reportOriginalDsa(*this, DSAStack, D, DVar);
15769 continue;
15770 }
15771 }
15772
15773 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
15774 // A variable of class type (or array thereof) that appears in a
15775 // lastprivate clause requires an accessible, unambiguous default
15776 // constructor for the class type, unless the list item is also specified
15777 // in a firstprivate clause.
15778 // A variable of class type (or array thereof) that appears in a
15779 // lastprivate clause requires an accessible, unambiguous copy assignment
15780 // operator for the class type.
15781 Type = Context.getBaseElementType(Type).getNonReferenceType();
15782 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
15783 Type.getUnqualifiedType(), ".lastprivate.src",
15784 D->hasAttrs() ? &D->getAttrs() : nullptr);
15785 DeclRefExpr *PseudoSrcExpr =
15786 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
15787 VarDecl *DstVD =
15788 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
15789 D->hasAttrs() ? &D->getAttrs() : nullptr);
15790 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
15791 // For arrays generate assignment operation for single element and replace
15792 // it by the original array element in CodeGen.
15793 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
15794 PseudoDstExpr, PseudoSrcExpr);
15795 if (AssignmentOp.isInvalid())
15796 continue;
15797 AssignmentOp =
15798 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
15799 if (AssignmentOp.isInvalid())
15800 continue;
15801
15802 DeclRefExpr *Ref = nullptr;
15803 if (!VD && !CurContext->isDependentContext()) {
15804 if (TopDVar.CKind == OMPC_firstprivate) {
15805 Ref = TopDVar.PrivateCopy;
15806 } else {
15807 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15808 if (!isOpenMPCapturedDecl(D))
15809 ExprCaptures.push_back(Ref->getDecl());
15810 }
15811 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
15812 (!isOpenMPCapturedDecl(D) &&
15813 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
15814 ExprResult RefRes = DefaultLvalueConversion(Ref);
15815 if (!RefRes.isUsable())
15816 continue;
15817 ExprResult PostUpdateRes =
15818 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15819 RefRes.get());
15820 if (!PostUpdateRes.isUsable())
15821 continue;
15822 ExprPostUpdates.push_back(
15823 IgnoredValueConversions(PostUpdateRes.get()).get());
15824 }
15825 }
15826 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
15827 Vars.push_back((VD || CurContext->isDependentContext())
15828 ? RefExpr->IgnoreParens()
15829 : Ref);
15830 SrcExprs.push_back(PseudoSrcExpr);
15831 DstExprs.push_back(PseudoDstExpr);
15832 AssignmentOps.push_back(AssignmentOp.get());
15833 }
15834
15835 if (Vars.empty())
15836 return nullptr;
15837
15838 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15839 Vars, SrcExprs, DstExprs, AssignmentOps,
15840 LPKind, LPKindLoc, ColonLoc,
15841 buildPreInits(Context, ExprCaptures),
15842 buildPostUpdate(*this, ExprPostUpdates));
15843 }
15844
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15845 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
15846 SourceLocation StartLoc,
15847 SourceLocation LParenLoc,
15848 SourceLocation EndLoc) {
15849 SmallVector<Expr *, 8> Vars;
15850 for (Expr *RefExpr : VarList) {
15851 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
15852 SourceLocation ELoc;
15853 SourceRange ERange;
15854 Expr *SimpleRefExpr = RefExpr;
15855 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15856 if (Res.second) {
15857 // It will be analyzed later.
15858 Vars.push_back(RefExpr);
15859 }
15860 ValueDecl *D = Res.first;
15861 if (!D)
15862 continue;
15863
15864 auto *VD = dyn_cast<VarDecl>(D);
15865 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15866 // in a Construct]
15867 // Variables with the predetermined data-sharing attributes may not be
15868 // listed in data-sharing attributes clauses, except for the cases
15869 // listed below. For these exceptions only, listing a predetermined
15870 // variable in a data-sharing attribute clause is allowed and overrides
15871 // the variable's predetermined data-sharing attributes.
15872 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15873 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
15874 DVar.RefExpr) {
15875 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15876 << getOpenMPClauseName(OMPC_shared);
15877 reportOriginalDsa(*this, DSAStack, D, DVar);
15878 continue;
15879 }
15880
15881 DeclRefExpr *Ref = nullptr;
15882 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
15883 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15884 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
15885 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
15886 ? RefExpr->IgnoreParens()
15887 : Ref);
15888 }
15889
15890 if (Vars.empty())
15891 return nullptr;
15892
15893 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
15894 }
15895
15896 namespace {
15897 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
15898 DSAStackTy *Stack;
15899
15900 public:
VisitDeclRefExpr(DeclRefExpr * E)15901 bool VisitDeclRefExpr(DeclRefExpr *E) {
15902 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
15903 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
15904 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
15905 return false;
15906 if (DVar.CKind != OMPC_unknown)
15907 return true;
15908 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
15909 VD,
15910 [](OpenMPClauseKind C, bool AppliedToPointee) {
15911 return isOpenMPPrivate(C) && !AppliedToPointee;
15912 },
15913 [](OpenMPDirectiveKind) { return true; },
15914 /*FromParent=*/true);
15915 return DVarPrivate.CKind != OMPC_unknown;
15916 }
15917 return false;
15918 }
VisitStmt(Stmt * S)15919 bool VisitStmt(Stmt *S) {
15920 for (Stmt *Child : S->children()) {
15921 if (Child && Visit(Child))
15922 return true;
15923 }
15924 return false;
15925 }
DSARefChecker(DSAStackTy * S)15926 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
15927 };
15928 } // namespace
15929
15930 namespace {
15931 // Transform MemberExpression for specified FieldDecl of current class to
15932 // DeclRefExpr to specified OMPCapturedExprDecl.
15933 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
15934 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
15935 ValueDecl *Field = nullptr;
15936 DeclRefExpr *CapturedExpr = nullptr;
15937
15938 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)15939 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
15940 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
15941
TransformMemberExpr(MemberExpr * E)15942 ExprResult TransformMemberExpr(MemberExpr *E) {
15943 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
15944 E->getMemberDecl() == Field) {
15945 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
15946 return CapturedExpr;
15947 }
15948 return BaseTransform::TransformMemberExpr(E);
15949 }
getCapturedExpr()15950 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
15951 };
15952 } // namespace
15953
15954 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)15955 static T filterLookupForUDReductionAndMapper(
15956 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
15957 for (U &Set : Lookups) {
15958 for (auto *D : Set) {
15959 if (T Res = Gen(cast<ValueDecl>(D)))
15960 return Res;
15961 }
15962 }
15963 return T();
15964 }
15965
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)15966 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
15967 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
15968
15969 for (auto RD : D->redecls()) {
15970 // Don't bother with extra checks if we already know this one isn't visible.
15971 if (RD == D)
15972 continue;
15973
15974 auto ND = cast<NamedDecl>(RD);
15975 if (LookupResult::isVisible(SemaRef, ND))
15976 return ND;
15977 }
15978
15979 return nullptr;
15980 }
15981
15982 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)15983 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
15984 SourceLocation Loc, QualType Ty,
15985 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
15986 // Find all of the associated namespaces and classes based on the
15987 // arguments we have.
15988 Sema::AssociatedNamespaceSet AssociatedNamespaces;
15989 Sema::AssociatedClassSet AssociatedClasses;
15990 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
15991 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
15992 AssociatedClasses);
15993
15994 // C++ [basic.lookup.argdep]p3:
15995 // Let X be the lookup set produced by unqualified lookup (3.4.1)
15996 // and let Y be the lookup set produced by argument dependent
15997 // lookup (defined as follows). If X contains [...] then Y is
15998 // empty. Otherwise Y is the set of declarations found in the
15999 // namespaces associated with the argument types as described
16000 // below. The set of declarations found by the lookup of the name
16001 // is the union of X and Y.
16002 //
16003 // Here, we compute Y and add its members to the overloaded
16004 // candidate set.
16005 for (auto *NS : AssociatedNamespaces) {
16006 // When considering an associated namespace, the lookup is the
16007 // same as the lookup performed when the associated namespace is
16008 // used as a qualifier (3.4.3.2) except that:
16009 //
16010 // -- Any using-directives in the associated namespace are
16011 // ignored.
16012 //
16013 // -- Any namespace-scope friend functions declared in
16014 // associated classes are visible within their respective
16015 // namespaces even if they are not visible during an ordinary
16016 // lookup (11.4).
16017 DeclContext::lookup_result R = NS->lookup(Id.getName());
16018 for (auto *D : R) {
16019 auto *Underlying = D;
16020 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16021 Underlying = USD->getTargetDecl();
16022
16023 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
16024 !isa<OMPDeclareMapperDecl>(Underlying))
16025 continue;
16026
16027 if (!SemaRef.isVisible(D)) {
16028 D = findAcceptableDecl(SemaRef, D);
16029 if (!D)
16030 continue;
16031 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16032 Underlying = USD->getTargetDecl();
16033 }
16034 Lookups.emplace_back();
16035 Lookups.back().addDecl(Underlying);
16036 }
16037 }
16038 }
16039
16040 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)16041 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
16042 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
16043 const DeclarationNameInfo &ReductionId, QualType Ty,
16044 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
16045 if (ReductionIdScopeSpec.isInvalid())
16046 return ExprError();
16047 SmallVector<UnresolvedSet<8>, 4> Lookups;
16048 if (S) {
16049 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16050 Lookup.suppressDiagnostics();
16051 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
16052 NamedDecl *D = Lookup.getRepresentativeDecl();
16053 do {
16054 S = S->getParent();
16055 } while (S && !S->isDeclScope(D));
16056 if (S)
16057 S = S->getParent();
16058 Lookups.emplace_back();
16059 Lookups.back().append(Lookup.begin(), Lookup.end());
16060 Lookup.clear();
16061 }
16062 } else if (auto *ULE =
16063 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
16064 Lookups.push_back(UnresolvedSet<8>());
16065 Decl *PrevD = nullptr;
16066 for (NamedDecl *D : ULE->decls()) {
16067 if (D == PrevD)
16068 Lookups.push_back(UnresolvedSet<8>());
16069 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
16070 Lookups.back().addDecl(DRD);
16071 PrevD = D;
16072 }
16073 }
16074 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
16075 Ty->isInstantiationDependentType() ||
16076 Ty->containsUnexpandedParameterPack() ||
16077 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
16078 return !D->isInvalidDecl() &&
16079 (D->getType()->isDependentType() ||
16080 D->getType()->isInstantiationDependentType() ||
16081 D->getType()->containsUnexpandedParameterPack());
16082 })) {
16083 UnresolvedSet<8> ResSet;
16084 for (const UnresolvedSet<8> &Set : Lookups) {
16085 if (Set.empty())
16086 continue;
16087 ResSet.append(Set.begin(), Set.end());
16088 // The last item marks the end of all declarations at the specified scope.
16089 ResSet.addDecl(Set[Set.size() - 1]);
16090 }
16091 return UnresolvedLookupExpr::Create(
16092 SemaRef.Context, /*NamingClass=*/nullptr,
16093 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
16094 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
16095 }
16096 // Lookup inside the classes.
16097 // C++ [over.match.oper]p3:
16098 // For a unary operator @ with an operand of a type whose
16099 // cv-unqualified version is T1, and for a binary operator @ with
16100 // a left operand of a type whose cv-unqualified version is T1 and
16101 // a right operand of a type whose cv-unqualified version is T2,
16102 // three sets of candidate functions, designated member
16103 // candidates, non-member candidates and built-in candidates, are
16104 // constructed as follows:
16105 // -- If T1 is a complete class type or a class currently being
16106 // defined, the set of member candidates is the result of the
16107 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
16108 // the set of member candidates is empty.
16109 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16110 Lookup.suppressDiagnostics();
16111 if (const auto *TyRec = Ty->getAs<RecordType>()) {
16112 // Complete the type if it can be completed.
16113 // If the type is neither complete nor being defined, bail out now.
16114 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
16115 TyRec->getDecl()->getDefinition()) {
16116 Lookup.clear();
16117 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
16118 if (Lookup.empty()) {
16119 Lookups.emplace_back();
16120 Lookups.back().append(Lookup.begin(), Lookup.end());
16121 }
16122 }
16123 }
16124 // Perform ADL.
16125 if (SemaRef.getLangOpts().CPlusPlus)
16126 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
16127 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16128 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
16129 if (!D->isInvalidDecl() &&
16130 SemaRef.Context.hasSameType(D->getType(), Ty))
16131 return D;
16132 return nullptr;
16133 }))
16134 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
16135 VK_LValue, Loc);
16136 if (SemaRef.getLangOpts().CPlusPlus) {
16137 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16138 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
16139 if (!D->isInvalidDecl() &&
16140 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
16141 !Ty.isMoreQualifiedThan(D->getType()))
16142 return D;
16143 return nullptr;
16144 })) {
16145 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16146 /*DetectVirtual=*/false);
16147 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
16148 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16149 VD->getType().getUnqualifiedType()))) {
16150 if (SemaRef.CheckBaseClassAccess(
16151 Loc, VD->getType(), Ty, Paths.front(),
16152 /*DiagID=*/0) != Sema::AR_inaccessible) {
16153 SemaRef.BuildBasePathArray(Paths, BasePath);
16154 return SemaRef.BuildDeclRefExpr(
16155 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
16156 }
16157 }
16158 }
16159 }
16160 }
16161 if (ReductionIdScopeSpec.isSet()) {
16162 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
16163 << Ty << Range;
16164 return ExprError();
16165 }
16166 return ExprEmpty();
16167 }
16168
16169 namespace {
16170 /// Data for the reduction-based clauses.
16171 struct ReductionData {
16172 /// List of original reduction items.
16173 SmallVector<Expr *, 8> Vars;
16174 /// List of private copies of the reduction items.
16175 SmallVector<Expr *, 8> Privates;
16176 /// LHS expressions for the reduction_op expressions.
16177 SmallVector<Expr *, 8> LHSs;
16178 /// RHS expressions for the reduction_op expressions.
16179 SmallVector<Expr *, 8> RHSs;
16180 /// Reduction operation expression.
16181 SmallVector<Expr *, 8> ReductionOps;
16182 /// inscan copy operation expressions.
16183 SmallVector<Expr *, 8> InscanCopyOps;
16184 /// inscan copy temp array expressions for prefix sums.
16185 SmallVector<Expr *, 8> InscanCopyArrayTemps;
16186 /// inscan copy temp array element expressions for prefix sums.
16187 SmallVector<Expr *, 8> InscanCopyArrayElems;
16188 /// Taskgroup descriptors for the corresponding reduction items in
16189 /// in_reduction clauses.
16190 SmallVector<Expr *, 8> TaskgroupDescriptors;
16191 /// List of captures for clause.
16192 SmallVector<Decl *, 4> ExprCaptures;
16193 /// List of postupdate expressions.
16194 SmallVector<Expr *, 4> ExprPostUpdates;
16195 /// Reduction modifier.
16196 unsigned RedModifier = 0;
16197 ReductionData() = delete;
16198 /// Reserves required memory for the reduction data.
ReductionData__anon5b04668f4c11::ReductionData16199 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
16200 Vars.reserve(Size);
16201 Privates.reserve(Size);
16202 LHSs.reserve(Size);
16203 RHSs.reserve(Size);
16204 ReductionOps.reserve(Size);
16205 if (RedModifier == OMPC_REDUCTION_inscan) {
16206 InscanCopyOps.reserve(Size);
16207 InscanCopyArrayTemps.reserve(Size);
16208 InscanCopyArrayElems.reserve(Size);
16209 }
16210 TaskgroupDescriptors.reserve(Size);
16211 ExprCaptures.reserve(Size);
16212 ExprPostUpdates.reserve(Size);
16213 }
16214 /// Stores reduction item and reduction operation only (required for dependent
16215 /// reduction item).
push__anon5b04668f4c11::ReductionData16216 void push(Expr *Item, Expr *ReductionOp) {
16217 Vars.emplace_back(Item);
16218 Privates.emplace_back(nullptr);
16219 LHSs.emplace_back(nullptr);
16220 RHSs.emplace_back(nullptr);
16221 ReductionOps.emplace_back(ReductionOp);
16222 TaskgroupDescriptors.emplace_back(nullptr);
16223 if (RedModifier == OMPC_REDUCTION_inscan) {
16224 InscanCopyOps.push_back(nullptr);
16225 InscanCopyArrayTemps.push_back(nullptr);
16226 InscanCopyArrayElems.push_back(nullptr);
16227 }
16228 }
16229 /// Stores reduction data.
push__anon5b04668f4c11::ReductionData16230 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
16231 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
16232 Expr *CopyArrayElem) {
16233 Vars.emplace_back(Item);
16234 Privates.emplace_back(Private);
16235 LHSs.emplace_back(LHS);
16236 RHSs.emplace_back(RHS);
16237 ReductionOps.emplace_back(ReductionOp);
16238 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
16239 if (RedModifier == OMPC_REDUCTION_inscan) {
16240 InscanCopyOps.push_back(CopyOp);
16241 InscanCopyArrayTemps.push_back(CopyArrayTemp);
16242 InscanCopyArrayElems.push_back(CopyArrayElem);
16243 } else {
16244 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
16245 CopyArrayElem == nullptr &&
16246 "Copy operation must be used for inscan reductions only.");
16247 }
16248 }
16249 };
16250 } // namespace
16251
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)16252 static bool checkOMPArraySectionConstantForReduction(
16253 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
16254 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
16255 const Expr *Length = OASE->getLength();
16256 if (Length == nullptr) {
16257 // For array sections of the form [1:] or [:], we would need to analyze
16258 // the lower bound...
16259 if (OASE->getColonLocFirst().isValid())
16260 return false;
16261
16262 // This is an array subscript which has implicit length 1!
16263 SingleElement = true;
16264 ArraySizes.push_back(llvm::APSInt::get(1));
16265 } else {
16266 Expr::EvalResult Result;
16267 if (!Length->EvaluateAsInt(Result, Context))
16268 return false;
16269
16270 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16271 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
16272 ArraySizes.push_back(ConstantLengthValue);
16273 }
16274
16275 // Get the base of this array section and walk up from there.
16276 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
16277
16278 // We require length = 1 for all array sections except the right-most to
16279 // guarantee that the memory region is contiguous and has no holes in it.
16280 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
16281 Length = TempOASE->getLength();
16282 if (Length == nullptr) {
16283 // For array sections of the form [1:] or [:], we would need to analyze
16284 // the lower bound...
16285 if (OASE->getColonLocFirst().isValid())
16286 return false;
16287
16288 // This is an array subscript which has implicit length 1!
16289 ArraySizes.push_back(llvm::APSInt::get(1));
16290 } else {
16291 Expr::EvalResult Result;
16292 if (!Length->EvaluateAsInt(Result, Context))
16293 return false;
16294
16295 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16296 if (ConstantLengthValue.getSExtValue() != 1)
16297 return false;
16298
16299 ArraySizes.push_back(ConstantLengthValue);
16300 }
16301 Base = TempOASE->getBase()->IgnoreParenImpCasts();
16302 }
16303
16304 // If we have a single element, we don't need to add the implicit lengths.
16305 if (!SingleElement) {
16306 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
16307 // Has implicit length 1!
16308 ArraySizes.push_back(llvm::APSInt::get(1));
16309 Base = TempASE->getBase()->IgnoreParenImpCasts();
16310 }
16311 }
16312
16313 // This array section can be privatized as a single value or as a constant
16314 // sized array.
16315 return true;
16316 }
16317
16318 static BinaryOperatorKind
getRelatedCompoundReductionOp(BinaryOperatorKind BOK)16319 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
16320 if (BOK == BO_Add)
16321 return BO_AddAssign;
16322 if (BOK == BO_Mul)
16323 return BO_MulAssign;
16324 if (BOK == BO_And)
16325 return BO_AndAssign;
16326 if (BOK == BO_Or)
16327 return BO_OrAssign;
16328 if (BOK == BO_Xor)
16329 return BO_XorAssign;
16330 return BOK;
16331 }
16332
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)16333 static bool actOnOMPReductionKindClause(
16334 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
16335 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16336 SourceLocation ColonLoc, SourceLocation EndLoc,
16337 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16338 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
16339 DeclarationName DN = ReductionId.getName();
16340 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
16341 BinaryOperatorKind BOK = BO_Comma;
16342
16343 ASTContext &Context = S.Context;
16344 // OpenMP [2.14.3.6, reduction clause]
16345 // C
16346 // reduction-identifier is either an identifier or one of the following
16347 // operators: +, -, *, &, |, ^, && and ||
16348 // C++
16349 // reduction-identifier is either an id-expression or one of the following
16350 // operators: +, -, *, &, |, ^, && and ||
16351 switch (OOK) {
16352 case OO_Plus:
16353 case OO_Minus:
16354 BOK = BO_Add;
16355 break;
16356 case OO_Star:
16357 BOK = BO_Mul;
16358 break;
16359 case OO_Amp:
16360 BOK = BO_And;
16361 break;
16362 case OO_Pipe:
16363 BOK = BO_Or;
16364 break;
16365 case OO_Caret:
16366 BOK = BO_Xor;
16367 break;
16368 case OO_AmpAmp:
16369 BOK = BO_LAnd;
16370 break;
16371 case OO_PipePipe:
16372 BOK = BO_LOr;
16373 break;
16374 case OO_New:
16375 case OO_Delete:
16376 case OO_Array_New:
16377 case OO_Array_Delete:
16378 case OO_Slash:
16379 case OO_Percent:
16380 case OO_Tilde:
16381 case OO_Exclaim:
16382 case OO_Equal:
16383 case OO_Less:
16384 case OO_Greater:
16385 case OO_LessEqual:
16386 case OO_GreaterEqual:
16387 case OO_PlusEqual:
16388 case OO_MinusEqual:
16389 case OO_StarEqual:
16390 case OO_SlashEqual:
16391 case OO_PercentEqual:
16392 case OO_CaretEqual:
16393 case OO_AmpEqual:
16394 case OO_PipeEqual:
16395 case OO_LessLess:
16396 case OO_GreaterGreater:
16397 case OO_LessLessEqual:
16398 case OO_GreaterGreaterEqual:
16399 case OO_EqualEqual:
16400 case OO_ExclaimEqual:
16401 case OO_Spaceship:
16402 case OO_PlusPlus:
16403 case OO_MinusMinus:
16404 case OO_Comma:
16405 case OO_ArrowStar:
16406 case OO_Arrow:
16407 case OO_Call:
16408 case OO_Subscript:
16409 case OO_Conditional:
16410 case OO_Coawait:
16411 case NUM_OVERLOADED_OPERATORS:
16412 llvm_unreachable("Unexpected reduction identifier");
16413 case OO_None:
16414 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
16415 if (II->isStr("max"))
16416 BOK = BO_GT;
16417 else if (II->isStr("min"))
16418 BOK = BO_LT;
16419 }
16420 break;
16421 }
16422 SourceRange ReductionIdRange;
16423 if (ReductionIdScopeSpec.isValid())
16424 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
16425 else
16426 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
16427 ReductionIdRange.setEnd(ReductionId.getEndLoc());
16428
16429 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
16430 bool FirstIter = true;
16431 for (Expr *RefExpr : VarList) {
16432 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
16433 // OpenMP [2.1, C/C++]
16434 // A list item is a variable or array section, subject to the restrictions
16435 // specified in Section 2.4 on page 42 and in each of the sections
16436 // describing clauses and directives for which a list appears.
16437 // OpenMP [2.14.3.3, Restrictions, p.1]
16438 // A variable that is part of another variable (as an array or
16439 // structure element) cannot appear in a private clause.
16440 if (!FirstIter && IR != ER)
16441 ++IR;
16442 FirstIter = false;
16443 SourceLocation ELoc;
16444 SourceRange ERange;
16445 Expr *SimpleRefExpr = RefExpr;
16446 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
16447 /*AllowArraySection=*/true);
16448 if (Res.second) {
16449 // Try to find 'declare reduction' corresponding construct before using
16450 // builtin/overloaded operators.
16451 QualType Type = Context.DependentTy;
16452 CXXCastPath BasePath;
16453 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16454 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16455 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16456 Expr *ReductionOp = nullptr;
16457 if (S.CurContext->isDependentContext() &&
16458 (DeclareReductionRef.isUnset() ||
16459 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
16460 ReductionOp = DeclareReductionRef.get();
16461 // It will be analyzed later.
16462 RD.push(RefExpr, ReductionOp);
16463 }
16464 ValueDecl *D = Res.first;
16465 if (!D)
16466 continue;
16467
16468 Expr *TaskgroupDescriptor = nullptr;
16469 QualType Type;
16470 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
16471 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
16472 if (ASE) {
16473 Type = ASE->getType().getNonReferenceType();
16474 } else if (OASE) {
16475 QualType BaseType =
16476 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16477 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16478 Type = ATy->getElementType();
16479 else
16480 Type = BaseType->getPointeeType();
16481 Type = Type.getNonReferenceType();
16482 } else {
16483 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
16484 }
16485 auto *VD = dyn_cast<VarDecl>(D);
16486
16487 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16488 // A variable that appears in a private clause must not have an incomplete
16489 // type or a reference type.
16490 if (S.RequireCompleteType(ELoc, D->getType(),
16491 diag::err_omp_reduction_incomplete_type))
16492 continue;
16493 // OpenMP [2.14.3.6, reduction clause, Restrictions]
16494 // A list item that appears in a reduction clause must not be
16495 // const-qualified.
16496 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
16497 /*AcceptIfMutable*/ false, ASE || OASE))
16498 continue;
16499
16500 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
16501 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
16502 // If a list-item is a reference type then it must bind to the same object
16503 // for all threads of the team.
16504 if (!ASE && !OASE) {
16505 if (VD) {
16506 VarDecl *VDDef = VD->getDefinition();
16507 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
16508 DSARefChecker Check(Stack);
16509 if (Check.Visit(VDDef->getInit())) {
16510 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
16511 << getOpenMPClauseName(ClauseKind) << ERange;
16512 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
16513 continue;
16514 }
16515 }
16516 }
16517
16518 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16519 // in a Construct]
16520 // Variables with the predetermined data-sharing attributes may not be
16521 // listed in data-sharing attributes clauses, except for the cases
16522 // listed below. For these exceptions only, listing a predetermined
16523 // variable in a data-sharing attribute clause is allowed and overrides
16524 // the variable's predetermined data-sharing attributes.
16525 // OpenMP [2.14.3.6, Restrictions, p.3]
16526 // Any number of reduction clauses can be specified on the directive,
16527 // but a list item can appear only once in the reduction clauses for that
16528 // directive.
16529 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16530 if (DVar.CKind == OMPC_reduction) {
16531 S.Diag(ELoc, diag::err_omp_once_referenced)
16532 << getOpenMPClauseName(ClauseKind);
16533 if (DVar.RefExpr)
16534 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
16535 continue;
16536 }
16537 if (DVar.CKind != OMPC_unknown) {
16538 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16539 << getOpenMPClauseName(DVar.CKind)
16540 << getOpenMPClauseName(OMPC_reduction);
16541 reportOriginalDsa(S, Stack, D, DVar);
16542 continue;
16543 }
16544
16545 // OpenMP [2.14.3.6, Restrictions, p.1]
16546 // A list item that appears in a reduction clause of a worksharing
16547 // construct must be shared in the parallel regions to which any of the
16548 // worksharing regions arising from the worksharing construct bind.
16549 if (isOpenMPWorksharingDirective(CurrDir) &&
16550 !isOpenMPParallelDirective(CurrDir) &&
16551 !isOpenMPTeamsDirective(CurrDir)) {
16552 DVar = Stack->getImplicitDSA(D, true);
16553 if (DVar.CKind != OMPC_shared) {
16554 S.Diag(ELoc, diag::err_omp_required_access)
16555 << getOpenMPClauseName(OMPC_reduction)
16556 << getOpenMPClauseName(OMPC_shared);
16557 reportOriginalDsa(S, Stack, D, DVar);
16558 continue;
16559 }
16560 }
16561 } else {
16562 // Threadprivates cannot be shared between threads, so dignose if the base
16563 // is a threadprivate variable.
16564 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16565 if (DVar.CKind == OMPC_threadprivate) {
16566 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16567 << getOpenMPClauseName(DVar.CKind)
16568 << getOpenMPClauseName(OMPC_reduction);
16569 reportOriginalDsa(S, Stack, D, DVar);
16570 continue;
16571 }
16572 }
16573
16574 // Try to find 'declare reduction' corresponding construct before using
16575 // builtin/overloaded operators.
16576 CXXCastPath BasePath;
16577 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16578 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16579 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16580 if (DeclareReductionRef.isInvalid())
16581 continue;
16582 if (S.CurContext->isDependentContext() &&
16583 (DeclareReductionRef.isUnset() ||
16584 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
16585 RD.push(RefExpr, DeclareReductionRef.get());
16586 continue;
16587 }
16588 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
16589 // Not allowed reduction identifier is found.
16590 S.Diag(ReductionId.getBeginLoc(),
16591 diag::err_omp_unknown_reduction_identifier)
16592 << Type << ReductionIdRange;
16593 continue;
16594 }
16595
16596 // OpenMP [2.14.3.6, reduction clause, Restrictions]
16597 // The type of a list item that appears in a reduction clause must be valid
16598 // for the reduction-identifier. For a max or min reduction in C, the type
16599 // of the list item must be an allowed arithmetic data type: char, int,
16600 // float, double, or _Bool, possibly modified with long, short, signed, or
16601 // unsigned. For a max or min reduction in C++, the type of the list item
16602 // must be an allowed arithmetic data type: char, wchar_t, int, float,
16603 // double, or bool, possibly modified with long, short, signed, or unsigned.
16604 if (DeclareReductionRef.isUnset()) {
16605 if ((BOK == BO_GT || BOK == BO_LT) &&
16606 !(Type->isScalarType() ||
16607 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
16608 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
16609 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
16610 if (!ASE && !OASE) {
16611 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16612 VarDecl::DeclarationOnly;
16613 S.Diag(D->getLocation(),
16614 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16615 << D;
16616 }
16617 continue;
16618 }
16619 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
16620 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
16621 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
16622 << getOpenMPClauseName(ClauseKind);
16623 if (!ASE && !OASE) {
16624 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16625 VarDecl::DeclarationOnly;
16626 S.Diag(D->getLocation(),
16627 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16628 << D;
16629 }
16630 continue;
16631 }
16632 }
16633
16634 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
16635 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
16636 D->hasAttrs() ? &D->getAttrs() : nullptr);
16637 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
16638 D->hasAttrs() ? &D->getAttrs() : nullptr);
16639 QualType PrivateTy = Type;
16640
16641 // Try if we can determine constant lengths for all array sections and avoid
16642 // the VLA.
16643 bool ConstantLengthOASE = false;
16644 if (OASE) {
16645 bool SingleElement;
16646 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
16647 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
16648 Context, OASE, SingleElement, ArraySizes);
16649
16650 // If we don't have a single element, we must emit a constant array type.
16651 if (ConstantLengthOASE && !SingleElement) {
16652 for (llvm::APSInt &Size : ArraySizes)
16653 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
16654 ArrayType::Normal,
16655 /*IndexTypeQuals=*/0);
16656 }
16657 }
16658
16659 if ((OASE && !ConstantLengthOASE) ||
16660 (!OASE && !ASE &&
16661 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
16662 if (!Context.getTargetInfo().isVLASupported()) {
16663 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
16664 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
16665 S.Diag(ELoc, diag::note_vla_unsupported);
16666 continue;
16667 } else {
16668 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
16669 S.targetDiag(ELoc, diag::note_vla_unsupported);
16670 }
16671 }
16672 // For arrays/array sections only:
16673 // Create pseudo array type for private copy. The size for this array will
16674 // be generated during codegen.
16675 // For array subscripts or single variables Private Ty is the same as Type
16676 // (type of the variable or single array element).
16677 PrivateTy = Context.getVariableArrayType(
16678 Type,
16679 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
16680 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
16681 } else if (!ASE && !OASE &&
16682 Context.getAsArrayType(D->getType().getNonReferenceType())) {
16683 PrivateTy = D->getType().getNonReferenceType();
16684 }
16685 // Private copy.
16686 VarDecl *PrivateVD =
16687 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
16688 D->hasAttrs() ? &D->getAttrs() : nullptr,
16689 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
16690 // Add initializer for private variable.
16691 Expr *Init = nullptr;
16692 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
16693 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
16694 if (DeclareReductionRef.isUsable()) {
16695 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
16696 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
16697 if (DRD->getInitializer()) {
16698 S.ActOnUninitializedDecl(PrivateVD);
16699 Init = DRDRef;
16700 RHSVD->setInit(DRDRef);
16701 RHSVD->setInitStyle(VarDecl::CallInit);
16702 }
16703 } else {
16704 switch (BOK) {
16705 case BO_Add:
16706 case BO_Xor:
16707 case BO_Or:
16708 case BO_LOr:
16709 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
16710 if (Type->isScalarType() || Type->isAnyComplexType())
16711 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
16712 break;
16713 case BO_Mul:
16714 case BO_LAnd:
16715 if (Type->isScalarType() || Type->isAnyComplexType()) {
16716 // '*' and '&&' reduction ops - initializer is '1'.
16717 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
16718 }
16719 break;
16720 case BO_And: {
16721 // '&' reduction op - initializer is '~0'.
16722 QualType OrigType = Type;
16723 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
16724 Type = ComplexTy->getElementType();
16725 if (Type->isRealFloatingType()) {
16726 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
16727 Context.getFloatTypeSemantics(Type),
16728 Context.getTypeSize(Type));
16729 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
16730 Type, ELoc);
16731 } else if (Type->isScalarType()) {
16732 uint64_t Size = Context.getTypeSize(Type);
16733 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
16734 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
16735 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
16736 }
16737 if (Init && OrigType->isAnyComplexType()) {
16738 // Init = 0xFFFF + 0xFFFFi;
16739 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
16740 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
16741 }
16742 Type = OrigType;
16743 break;
16744 }
16745 case BO_LT:
16746 case BO_GT: {
16747 // 'min' reduction op - initializer is 'Largest representable number in
16748 // the reduction list item type'.
16749 // 'max' reduction op - initializer is 'Least representable number in
16750 // the reduction list item type'.
16751 if (Type->isIntegerType() || Type->isPointerType()) {
16752 bool IsSigned = Type->hasSignedIntegerRepresentation();
16753 uint64_t Size = Context.getTypeSize(Type);
16754 QualType IntTy =
16755 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
16756 llvm::APInt InitValue =
16757 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
16758 : llvm::APInt::getMinValue(Size)
16759 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
16760 : llvm::APInt::getMaxValue(Size);
16761 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
16762 if (Type->isPointerType()) {
16763 // Cast to pointer type.
16764 ExprResult CastExpr = S.BuildCStyleCastExpr(
16765 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
16766 if (CastExpr.isInvalid())
16767 continue;
16768 Init = CastExpr.get();
16769 }
16770 } else if (Type->isRealFloatingType()) {
16771 llvm::APFloat InitValue = llvm::APFloat::getLargest(
16772 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
16773 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
16774 Type, ELoc);
16775 }
16776 break;
16777 }
16778 case BO_PtrMemD:
16779 case BO_PtrMemI:
16780 case BO_MulAssign:
16781 case BO_Div:
16782 case BO_Rem:
16783 case BO_Sub:
16784 case BO_Shl:
16785 case BO_Shr:
16786 case BO_LE:
16787 case BO_GE:
16788 case BO_EQ:
16789 case BO_NE:
16790 case BO_Cmp:
16791 case BO_AndAssign:
16792 case BO_XorAssign:
16793 case BO_OrAssign:
16794 case BO_Assign:
16795 case BO_AddAssign:
16796 case BO_SubAssign:
16797 case BO_DivAssign:
16798 case BO_RemAssign:
16799 case BO_ShlAssign:
16800 case BO_ShrAssign:
16801 case BO_Comma:
16802 llvm_unreachable("Unexpected reduction operation");
16803 }
16804 }
16805 if (Init && DeclareReductionRef.isUnset()) {
16806 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
16807 // Store initializer for single element in private copy. Will be used
16808 // during codegen.
16809 PrivateVD->setInit(RHSVD->getInit());
16810 PrivateVD->setInitStyle(RHSVD->getInitStyle());
16811 } else if (!Init) {
16812 S.ActOnUninitializedDecl(RHSVD);
16813 // Store initializer for single element in private copy. Will be used
16814 // during codegen.
16815 PrivateVD->setInit(RHSVD->getInit());
16816 PrivateVD->setInitStyle(RHSVD->getInitStyle());
16817 }
16818 if (RHSVD->isInvalidDecl())
16819 continue;
16820 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
16821 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
16822 << Type << ReductionIdRange;
16823 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16824 VarDecl::DeclarationOnly;
16825 S.Diag(D->getLocation(),
16826 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16827 << D;
16828 continue;
16829 }
16830 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
16831 ExprResult ReductionOp;
16832 if (DeclareReductionRef.isUsable()) {
16833 QualType RedTy = DeclareReductionRef.get()->getType();
16834 QualType PtrRedTy = Context.getPointerType(RedTy);
16835 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
16836 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
16837 if (!BasePath.empty()) {
16838 LHS = S.DefaultLvalueConversion(LHS.get());
16839 RHS = S.DefaultLvalueConversion(RHS.get());
16840 LHS = ImplicitCastExpr::Create(
16841 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
16842 LHS.get()->getValueKind(), FPOptionsOverride());
16843 RHS = ImplicitCastExpr::Create(
16844 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
16845 RHS.get()->getValueKind(), FPOptionsOverride());
16846 }
16847 FunctionProtoType::ExtProtoInfo EPI;
16848 QualType Params[] = {PtrRedTy, PtrRedTy};
16849 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
16850 auto *OVE = new (Context) OpaqueValueExpr(
16851 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
16852 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
16853 Expr *Args[] = {LHS.get(), RHS.get()};
16854 ReductionOp =
16855 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
16856 S.CurFPFeatureOverrides());
16857 } else {
16858 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
16859 if (Type->isRecordType() && CombBOK != BOK) {
16860 Sema::TentativeAnalysisScope Trap(S);
16861 ReductionOp =
16862 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16863 CombBOK, LHSDRE, RHSDRE);
16864 }
16865 if (!ReductionOp.isUsable()) {
16866 ReductionOp =
16867 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
16868 LHSDRE, RHSDRE);
16869 if (ReductionOp.isUsable()) {
16870 if (BOK != BO_LT && BOK != BO_GT) {
16871 ReductionOp =
16872 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16873 BO_Assign, LHSDRE, ReductionOp.get());
16874 } else {
16875 auto *ConditionalOp = new (Context)
16876 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
16877 RHSDRE, Type, VK_LValue, OK_Ordinary);
16878 ReductionOp =
16879 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16880 BO_Assign, LHSDRE, ConditionalOp);
16881 }
16882 }
16883 }
16884 if (ReductionOp.isUsable())
16885 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
16886 /*DiscardedValue*/ false);
16887 if (!ReductionOp.isUsable())
16888 continue;
16889 }
16890
16891 // Add copy operations for inscan reductions.
16892 // LHS = RHS;
16893 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
16894 if (ClauseKind == OMPC_reduction &&
16895 RD.RedModifier == OMPC_REDUCTION_inscan) {
16896 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
16897 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
16898 RHS.get());
16899 if (!CopyOpRes.isUsable())
16900 continue;
16901 CopyOpRes =
16902 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
16903 if (!CopyOpRes.isUsable())
16904 continue;
16905 // For simd directive and simd-based directives in simd mode no need to
16906 // construct temp array, need just a single temp element.
16907 if (Stack->getCurrentDirective() == OMPD_simd ||
16908 (S.getLangOpts().OpenMPSimd &&
16909 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
16910 VarDecl *TempArrayVD =
16911 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
16912 D->hasAttrs() ? &D->getAttrs() : nullptr);
16913 // Add a constructor to the temp decl.
16914 S.ActOnUninitializedDecl(TempArrayVD);
16915 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
16916 } else {
16917 // Build temp array for prefix sum.
16918 auto *Dim = new (S.Context)
16919 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16920 QualType ArrayTy =
16921 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
16922 /*IndexTypeQuals=*/0, {ELoc, ELoc});
16923 VarDecl *TempArrayVD =
16924 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
16925 D->hasAttrs() ? &D->getAttrs() : nullptr);
16926 // Add a constructor to the temp decl.
16927 S.ActOnUninitializedDecl(TempArrayVD);
16928 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
16929 TempArrayElem =
16930 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
16931 auto *Idx = new (S.Context)
16932 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16933 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
16934 ELoc, Idx, ELoc);
16935 }
16936 }
16937
16938 // OpenMP [2.15.4.6, Restrictions, p.2]
16939 // A list item that appears in an in_reduction clause of a task construct
16940 // must appear in a task_reduction clause of a construct associated with a
16941 // taskgroup region that includes the participating task in its taskgroup
16942 // set. The construct associated with the innermost region that meets this
16943 // condition must specify the same reduction-identifier as the in_reduction
16944 // clause.
16945 if (ClauseKind == OMPC_in_reduction) {
16946 SourceRange ParentSR;
16947 BinaryOperatorKind ParentBOK;
16948 const Expr *ParentReductionOp = nullptr;
16949 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
16950 DSAStackTy::DSAVarData ParentBOKDSA =
16951 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
16952 ParentBOKTD);
16953 DSAStackTy::DSAVarData ParentReductionOpDSA =
16954 Stack->getTopMostTaskgroupReductionData(
16955 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
16956 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
16957 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
16958 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
16959 (DeclareReductionRef.isUsable() && IsParentBOK) ||
16960 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
16961 bool EmitError = true;
16962 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
16963 llvm::FoldingSetNodeID RedId, ParentRedId;
16964 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
16965 DeclareReductionRef.get()->Profile(RedId, Context,
16966 /*Canonical=*/true);
16967 EmitError = RedId != ParentRedId;
16968 }
16969 if (EmitError) {
16970 S.Diag(ReductionId.getBeginLoc(),
16971 diag::err_omp_reduction_identifier_mismatch)
16972 << ReductionIdRange << RefExpr->getSourceRange();
16973 S.Diag(ParentSR.getBegin(),
16974 diag::note_omp_previous_reduction_identifier)
16975 << ParentSR
16976 << (IsParentBOK ? ParentBOKDSA.RefExpr
16977 : ParentReductionOpDSA.RefExpr)
16978 ->getSourceRange();
16979 continue;
16980 }
16981 }
16982 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
16983 }
16984
16985 DeclRefExpr *Ref = nullptr;
16986 Expr *VarsExpr = RefExpr->IgnoreParens();
16987 if (!VD && !S.CurContext->isDependentContext()) {
16988 if (ASE || OASE) {
16989 TransformExprToCaptures RebuildToCapture(S, D);
16990 VarsExpr =
16991 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
16992 Ref = RebuildToCapture.getCapturedExpr();
16993 } else {
16994 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
16995 }
16996 if (!S.isOpenMPCapturedDecl(D)) {
16997 RD.ExprCaptures.emplace_back(Ref->getDecl());
16998 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
16999 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
17000 if (!RefRes.isUsable())
17001 continue;
17002 ExprResult PostUpdateRes =
17003 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17004 RefRes.get());
17005 if (!PostUpdateRes.isUsable())
17006 continue;
17007 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
17008 Stack->getCurrentDirective() == OMPD_taskgroup) {
17009 S.Diag(RefExpr->getExprLoc(),
17010 diag::err_omp_reduction_non_addressable_expression)
17011 << RefExpr->getSourceRange();
17012 continue;
17013 }
17014 RD.ExprPostUpdates.emplace_back(
17015 S.IgnoredValueConversions(PostUpdateRes.get()).get());
17016 }
17017 }
17018 }
17019 // All reduction items are still marked as reduction (to do not increase
17020 // code base size).
17021 unsigned Modifier = RD.RedModifier;
17022 // Consider task_reductions as reductions with task modifier. Required for
17023 // correct analysis of in_reduction clauses.
17024 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
17025 Modifier = OMPC_REDUCTION_task;
17026 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
17027 ASE || OASE);
17028 if (Modifier == OMPC_REDUCTION_task &&
17029 (CurrDir == OMPD_taskgroup ||
17030 ((isOpenMPParallelDirective(CurrDir) ||
17031 isOpenMPWorksharingDirective(CurrDir)) &&
17032 !isOpenMPSimdDirective(CurrDir)))) {
17033 if (DeclareReductionRef.isUsable())
17034 Stack->addTaskgroupReductionData(D, ReductionIdRange,
17035 DeclareReductionRef.get());
17036 else
17037 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
17038 }
17039 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
17040 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
17041 TempArrayElem.get());
17042 }
17043 return RD.Vars.empty();
17044 }
17045
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17046 OMPClause *Sema::ActOnOpenMPReductionClause(
17047 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
17048 SourceLocation StartLoc, SourceLocation LParenLoc,
17049 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
17050 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17051 ArrayRef<Expr *> UnresolvedReductions) {
17052 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
17053 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
17054 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
17055 /*Last=*/OMPC_REDUCTION_unknown)
17056 << getOpenMPClauseName(OMPC_reduction);
17057 return nullptr;
17058 }
17059 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
17060 // A reduction clause with the inscan reduction-modifier may only appear on a
17061 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
17062 // construct, a parallel worksharing-loop construct or a parallel
17063 // worksharing-loop SIMD construct.
17064 if (Modifier == OMPC_REDUCTION_inscan &&
17065 (DSAStack->getCurrentDirective() != OMPD_for &&
17066 DSAStack->getCurrentDirective() != OMPD_for_simd &&
17067 DSAStack->getCurrentDirective() != OMPD_simd &&
17068 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
17069 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
17070 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
17071 return nullptr;
17072 }
17073
17074 ReductionData RD(VarList.size(), Modifier);
17075 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
17076 StartLoc, LParenLoc, ColonLoc, EndLoc,
17077 ReductionIdScopeSpec, ReductionId,
17078 UnresolvedReductions, RD))
17079 return nullptr;
17080
17081 return OMPReductionClause::Create(
17082 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
17083 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17084 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
17085 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
17086 buildPreInits(Context, RD.ExprCaptures),
17087 buildPostUpdate(*this, RD.ExprPostUpdates));
17088 }
17089
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17090 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
17091 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17092 SourceLocation ColonLoc, SourceLocation EndLoc,
17093 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17094 ArrayRef<Expr *> UnresolvedReductions) {
17095 ReductionData RD(VarList.size());
17096 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
17097 StartLoc, LParenLoc, ColonLoc, EndLoc,
17098 ReductionIdScopeSpec, ReductionId,
17099 UnresolvedReductions, RD))
17100 return nullptr;
17101
17102 return OMPTaskReductionClause::Create(
17103 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17104 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17105 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
17106 buildPreInits(Context, RD.ExprCaptures),
17107 buildPostUpdate(*this, RD.ExprPostUpdates));
17108 }
17109
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17110 OMPClause *Sema::ActOnOpenMPInReductionClause(
17111 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17112 SourceLocation ColonLoc, SourceLocation EndLoc,
17113 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17114 ArrayRef<Expr *> UnresolvedReductions) {
17115 ReductionData RD(VarList.size());
17116 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
17117 StartLoc, LParenLoc, ColonLoc, EndLoc,
17118 ReductionIdScopeSpec, ReductionId,
17119 UnresolvedReductions, RD))
17120 return nullptr;
17121
17122 return OMPInReductionClause::Create(
17123 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17124 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17125 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
17126 buildPreInits(Context, RD.ExprCaptures),
17127 buildPostUpdate(*this, RD.ExprPostUpdates));
17128 }
17129
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)17130 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
17131 SourceLocation LinLoc) {
17132 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
17133 LinKind == OMPC_LINEAR_unknown) {
17134 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
17135 return true;
17136 }
17137 return false;
17138 }
17139
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)17140 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
17141 OpenMPLinearClauseKind LinKind, QualType Type,
17142 bool IsDeclareSimd) {
17143 const auto *VD = dyn_cast_or_null<VarDecl>(D);
17144 // A variable must not have an incomplete type or a reference type.
17145 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
17146 return true;
17147 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
17148 !Type->isReferenceType()) {
17149 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
17150 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
17151 return true;
17152 }
17153 Type = Type.getNonReferenceType();
17154
17155 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17156 // A variable that is privatized must not have a const-qualified type
17157 // unless it is of class type with a mutable member. This restriction does
17158 // not apply to the firstprivate clause, nor to the linear clause on
17159 // declarative directives (like declare simd).
17160 if (!IsDeclareSimd &&
17161 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
17162 return true;
17163
17164 // A list item must be of integral or pointer type.
17165 Type = Type.getUnqualifiedType().getCanonicalType();
17166 const auto *Ty = Type.getTypePtrOrNull();
17167 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
17168 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
17169 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
17170 if (D) {
17171 bool IsDecl =
17172 !VD ||
17173 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17174 Diag(D->getLocation(),
17175 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17176 << D;
17177 }
17178 return true;
17179 }
17180 return false;
17181 }
17182
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17183 OMPClause *Sema::ActOnOpenMPLinearClause(
17184 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
17185 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
17186 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17187 SmallVector<Expr *, 8> Vars;
17188 SmallVector<Expr *, 8> Privates;
17189 SmallVector<Expr *, 8> Inits;
17190 SmallVector<Decl *, 4> ExprCaptures;
17191 SmallVector<Expr *, 4> ExprPostUpdates;
17192 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
17193 LinKind = OMPC_LINEAR_val;
17194 for (Expr *RefExpr : VarList) {
17195 assert(RefExpr && "NULL expr in OpenMP linear clause.");
17196 SourceLocation ELoc;
17197 SourceRange ERange;
17198 Expr *SimpleRefExpr = RefExpr;
17199 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17200 if (Res.second) {
17201 // It will be analyzed later.
17202 Vars.push_back(RefExpr);
17203 Privates.push_back(nullptr);
17204 Inits.push_back(nullptr);
17205 }
17206 ValueDecl *D = Res.first;
17207 if (!D)
17208 continue;
17209
17210 QualType Type = D->getType();
17211 auto *VD = dyn_cast<VarDecl>(D);
17212
17213 // OpenMP [2.14.3.7, linear clause]
17214 // A list-item cannot appear in more than one linear clause.
17215 // A list-item that appears in a linear clause cannot appear in any
17216 // other data-sharing attribute clause.
17217 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17218 if (DVar.RefExpr) {
17219 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17220 << getOpenMPClauseName(OMPC_linear);
17221 reportOriginalDsa(*this, DSAStack, D, DVar);
17222 continue;
17223 }
17224
17225 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
17226 continue;
17227 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17228
17229 // Build private copy of original var.
17230 VarDecl *Private =
17231 buildVarDecl(*this, ELoc, Type, D->getName(),
17232 D->hasAttrs() ? &D->getAttrs() : nullptr,
17233 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17234 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
17235 // Build var to save initial value.
17236 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
17237 Expr *InitExpr;
17238 DeclRefExpr *Ref = nullptr;
17239 if (!VD && !CurContext->isDependentContext()) {
17240 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17241 if (!isOpenMPCapturedDecl(D)) {
17242 ExprCaptures.push_back(Ref->getDecl());
17243 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17244 ExprResult RefRes = DefaultLvalueConversion(Ref);
17245 if (!RefRes.isUsable())
17246 continue;
17247 ExprResult PostUpdateRes =
17248 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
17249 SimpleRefExpr, RefRes.get());
17250 if (!PostUpdateRes.isUsable())
17251 continue;
17252 ExprPostUpdates.push_back(
17253 IgnoredValueConversions(PostUpdateRes.get()).get());
17254 }
17255 }
17256 }
17257 if (LinKind == OMPC_LINEAR_uval)
17258 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
17259 else
17260 InitExpr = VD ? SimpleRefExpr : Ref;
17261 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
17262 /*DirectInit=*/false);
17263 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
17264
17265 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
17266 Vars.push_back((VD || CurContext->isDependentContext())
17267 ? RefExpr->IgnoreParens()
17268 : Ref);
17269 Privates.push_back(PrivateRef);
17270 Inits.push_back(InitRef);
17271 }
17272
17273 if (Vars.empty())
17274 return nullptr;
17275
17276 Expr *StepExpr = Step;
17277 Expr *CalcStepExpr = nullptr;
17278 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
17279 !Step->isInstantiationDependent() &&
17280 !Step->containsUnexpandedParameterPack()) {
17281 SourceLocation StepLoc = Step->getBeginLoc();
17282 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
17283 if (Val.isInvalid())
17284 return nullptr;
17285 StepExpr = Val.get();
17286
17287 // Build var to save the step value.
17288 VarDecl *SaveVar =
17289 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
17290 ExprResult SaveRef =
17291 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
17292 ExprResult CalcStep =
17293 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
17294 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
17295
17296 // Warn about zero linear step (it would be probably better specified as
17297 // making corresponding variables 'const').
17298 if (Optional<llvm::APSInt> Result =
17299 StepExpr->getIntegerConstantExpr(Context)) {
17300 if (!Result->isNegative() && !Result->isStrictlyPositive())
17301 Diag(StepLoc, diag::warn_omp_linear_step_zero)
17302 << Vars[0] << (Vars.size() > 1);
17303 } else if (CalcStep.isUsable()) {
17304 // Calculate the step beforehand instead of doing this on each iteration.
17305 // (This is not used if the number of iterations may be kfold-ed).
17306 CalcStepExpr = CalcStep.get();
17307 }
17308 }
17309
17310 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
17311 ColonLoc, EndLoc, Vars, Privates, Inits,
17312 StepExpr, CalcStepExpr,
17313 buildPreInits(Context, ExprCaptures),
17314 buildPostUpdate(*this, ExprPostUpdates));
17315 }
17316
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)17317 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
17318 Expr *NumIterations, Sema &SemaRef,
17319 Scope *S, DSAStackTy *Stack) {
17320 // Walk the vars and build update/final expressions for the CodeGen.
17321 SmallVector<Expr *, 8> Updates;
17322 SmallVector<Expr *, 8> Finals;
17323 SmallVector<Expr *, 8> UsedExprs;
17324 Expr *Step = Clause.getStep();
17325 Expr *CalcStep = Clause.getCalcStep();
17326 // OpenMP [2.14.3.7, linear clause]
17327 // If linear-step is not specified it is assumed to be 1.
17328 if (!Step)
17329 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
17330 else if (CalcStep)
17331 Step = cast<BinaryOperator>(CalcStep)->getLHS();
17332 bool HasErrors = false;
17333 auto CurInit = Clause.inits().begin();
17334 auto CurPrivate = Clause.privates().begin();
17335 OpenMPLinearClauseKind LinKind = Clause.getModifier();
17336 for (Expr *RefExpr : Clause.varlists()) {
17337 SourceLocation ELoc;
17338 SourceRange ERange;
17339 Expr *SimpleRefExpr = RefExpr;
17340 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17341 ValueDecl *D = Res.first;
17342 if (Res.second || !D) {
17343 Updates.push_back(nullptr);
17344 Finals.push_back(nullptr);
17345 HasErrors = true;
17346 continue;
17347 }
17348 auto &&Info = Stack->isLoopControlVariable(D);
17349 // OpenMP [2.15.11, distribute simd Construct]
17350 // A list item may not appear in a linear clause, unless it is the loop
17351 // iteration variable.
17352 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
17353 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
17354 SemaRef.Diag(ELoc,
17355 diag::err_omp_linear_distribute_var_non_loop_iteration);
17356 Updates.push_back(nullptr);
17357 Finals.push_back(nullptr);
17358 HasErrors = true;
17359 continue;
17360 }
17361 Expr *InitExpr = *CurInit;
17362
17363 // Build privatized reference to the current linear var.
17364 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
17365 Expr *CapturedRef;
17366 if (LinKind == OMPC_LINEAR_uval)
17367 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
17368 else
17369 CapturedRef =
17370 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
17371 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
17372 /*RefersToCapture=*/true);
17373
17374 // Build update: Var = InitExpr + IV * Step
17375 ExprResult Update;
17376 if (!Info.first)
17377 Update = buildCounterUpdate(
17378 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
17379 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
17380 else
17381 Update = *CurPrivate;
17382 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
17383 /*DiscardedValue*/ false);
17384
17385 // Build final: Var = InitExpr + NumIterations * Step
17386 ExprResult Final;
17387 if (!Info.first)
17388 Final =
17389 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
17390 InitExpr, NumIterations, Step, /*Subtract=*/false,
17391 /*IsNonRectangularLB=*/false);
17392 else
17393 Final = *CurPrivate;
17394 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
17395 /*DiscardedValue*/ false);
17396
17397 if (!Update.isUsable() || !Final.isUsable()) {
17398 Updates.push_back(nullptr);
17399 Finals.push_back(nullptr);
17400 UsedExprs.push_back(nullptr);
17401 HasErrors = true;
17402 } else {
17403 Updates.push_back(Update.get());
17404 Finals.push_back(Final.get());
17405 if (!Info.first)
17406 UsedExprs.push_back(SimpleRefExpr);
17407 }
17408 ++CurInit;
17409 ++CurPrivate;
17410 }
17411 if (Expr *S = Clause.getStep())
17412 UsedExprs.push_back(S);
17413 // Fill the remaining part with the nullptr.
17414 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
17415 Clause.setUpdates(Updates);
17416 Clause.setFinals(Finals);
17417 Clause.setUsedExprs(UsedExprs);
17418 return HasErrors;
17419 }
17420
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17421 OMPClause *Sema::ActOnOpenMPAlignedClause(
17422 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
17423 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17424 SmallVector<Expr *, 8> Vars;
17425 for (Expr *RefExpr : VarList) {
17426 assert(RefExpr && "NULL expr in OpenMP linear clause.");
17427 SourceLocation ELoc;
17428 SourceRange ERange;
17429 Expr *SimpleRefExpr = RefExpr;
17430 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17431 if (Res.second) {
17432 // It will be analyzed later.
17433 Vars.push_back(RefExpr);
17434 }
17435 ValueDecl *D = Res.first;
17436 if (!D)
17437 continue;
17438
17439 QualType QType = D->getType();
17440 auto *VD = dyn_cast<VarDecl>(D);
17441
17442 // OpenMP [2.8.1, simd construct, Restrictions]
17443 // The type of list items appearing in the aligned clause must be
17444 // array, pointer, reference to array, or reference to pointer.
17445 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17446 const Type *Ty = QType.getTypePtrOrNull();
17447 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
17448 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
17449 << QType << getLangOpts().CPlusPlus << ERange;
17450 bool IsDecl =
17451 !VD ||
17452 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17453 Diag(D->getLocation(),
17454 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17455 << D;
17456 continue;
17457 }
17458
17459 // OpenMP [2.8.1, simd construct, Restrictions]
17460 // A list-item cannot appear in more than one aligned clause.
17461 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
17462 Diag(ELoc, diag::err_omp_used_in_clause_twice)
17463 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
17464 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17465 << getOpenMPClauseName(OMPC_aligned);
17466 continue;
17467 }
17468
17469 DeclRefExpr *Ref = nullptr;
17470 if (!VD && isOpenMPCapturedDecl(D))
17471 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17472 Vars.push_back(DefaultFunctionArrayConversion(
17473 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
17474 .get());
17475 }
17476
17477 // OpenMP [2.8.1, simd construct, Description]
17478 // The parameter of the aligned clause, alignment, must be a constant
17479 // positive integer expression.
17480 // If no optional parameter is specified, implementation-defined default
17481 // alignments for SIMD instructions on the target platforms are assumed.
17482 if (Alignment != nullptr) {
17483 ExprResult AlignResult =
17484 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
17485 if (AlignResult.isInvalid())
17486 return nullptr;
17487 Alignment = AlignResult.get();
17488 }
17489 if (Vars.empty())
17490 return nullptr;
17491
17492 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
17493 EndLoc, Vars, Alignment);
17494 }
17495
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17496 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
17497 SourceLocation StartLoc,
17498 SourceLocation LParenLoc,
17499 SourceLocation EndLoc) {
17500 SmallVector<Expr *, 8> Vars;
17501 SmallVector<Expr *, 8> SrcExprs;
17502 SmallVector<Expr *, 8> DstExprs;
17503 SmallVector<Expr *, 8> AssignmentOps;
17504 for (Expr *RefExpr : VarList) {
17505 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
17506 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17507 // It will be analyzed later.
17508 Vars.push_back(RefExpr);
17509 SrcExprs.push_back(nullptr);
17510 DstExprs.push_back(nullptr);
17511 AssignmentOps.push_back(nullptr);
17512 continue;
17513 }
17514
17515 SourceLocation ELoc = RefExpr->getExprLoc();
17516 // OpenMP [2.1, C/C++]
17517 // A list item is a variable name.
17518 // OpenMP [2.14.4.1, Restrictions, p.1]
17519 // A list item that appears in a copyin clause must be threadprivate.
17520 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
17521 if (!DE || !isa<VarDecl>(DE->getDecl())) {
17522 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
17523 << 0 << RefExpr->getSourceRange();
17524 continue;
17525 }
17526
17527 Decl *D = DE->getDecl();
17528 auto *VD = cast<VarDecl>(D);
17529
17530 QualType Type = VD->getType();
17531 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
17532 // It will be analyzed later.
17533 Vars.push_back(DE);
17534 SrcExprs.push_back(nullptr);
17535 DstExprs.push_back(nullptr);
17536 AssignmentOps.push_back(nullptr);
17537 continue;
17538 }
17539
17540 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
17541 // A list item that appears in a copyin clause must be threadprivate.
17542 if (!DSAStack->isThreadPrivate(VD)) {
17543 Diag(ELoc, diag::err_omp_required_access)
17544 << getOpenMPClauseName(OMPC_copyin)
17545 << getOpenMPDirectiveName(OMPD_threadprivate);
17546 continue;
17547 }
17548
17549 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17550 // A variable of class type (or array thereof) that appears in a
17551 // copyin clause requires an accessible, unambiguous copy assignment
17552 // operator for the class type.
17553 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17554 VarDecl *SrcVD =
17555 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
17556 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17557 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
17558 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
17559 VarDecl *DstVD =
17560 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
17561 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17562 DeclRefExpr *PseudoDstExpr =
17563 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
17564 // For arrays generate assignment operation for single element and replace
17565 // it by the original array element in CodeGen.
17566 ExprResult AssignmentOp =
17567 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
17568 PseudoSrcExpr);
17569 if (AssignmentOp.isInvalid())
17570 continue;
17571 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
17572 /*DiscardedValue*/ false);
17573 if (AssignmentOp.isInvalid())
17574 continue;
17575
17576 DSAStack->addDSA(VD, DE, OMPC_copyin);
17577 Vars.push_back(DE);
17578 SrcExprs.push_back(PseudoSrcExpr);
17579 DstExprs.push_back(PseudoDstExpr);
17580 AssignmentOps.push_back(AssignmentOp.get());
17581 }
17582
17583 if (Vars.empty())
17584 return nullptr;
17585
17586 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17587 SrcExprs, DstExprs, AssignmentOps);
17588 }
17589
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17590 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
17591 SourceLocation StartLoc,
17592 SourceLocation LParenLoc,
17593 SourceLocation EndLoc) {
17594 SmallVector<Expr *, 8> Vars;
17595 SmallVector<Expr *, 8> SrcExprs;
17596 SmallVector<Expr *, 8> DstExprs;
17597 SmallVector<Expr *, 8> AssignmentOps;
17598 for (Expr *RefExpr : VarList) {
17599 assert(RefExpr && "NULL expr in OpenMP linear clause.");
17600 SourceLocation ELoc;
17601 SourceRange ERange;
17602 Expr *SimpleRefExpr = RefExpr;
17603 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17604 if (Res.second) {
17605 // It will be analyzed later.
17606 Vars.push_back(RefExpr);
17607 SrcExprs.push_back(nullptr);
17608 DstExprs.push_back(nullptr);
17609 AssignmentOps.push_back(nullptr);
17610 }
17611 ValueDecl *D = Res.first;
17612 if (!D)
17613 continue;
17614
17615 QualType Type = D->getType();
17616 auto *VD = dyn_cast<VarDecl>(D);
17617
17618 // OpenMP [2.14.4.2, Restrictions, p.2]
17619 // A list item that appears in a copyprivate clause may not appear in a
17620 // private or firstprivate clause on the single construct.
17621 if (!VD || !DSAStack->isThreadPrivate(VD)) {
17622 DSAStackTy::DSAVarData DVar =
17623 DSAStack->getTopDSA(D, /*FromParent=*/false);
17624 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
17625 DVar.RefExpr) {
17626 Diag(ELoc, diag::err_omp_wrong_dsa)
17627 << getOpenMPClauseName(DVar.CKind)
17628 << getOpenMPClauseName(OMPC_copyprivate);
17629 reportOriginalDsa(*this, DSAStack, D, DVar);
17630 continue;
17631 }
17632
17633 // OpenMP [2.11.4.2, Restrictions, p.1]
17634 // All list items that appear in a copyprivate clause must be either
17635 // threadprivate or private in the enclosing context.
17636 if (DVar.CKind == OMPC_unknown) {
17637 DVar = DSAStack->getImplicitDSA(D, false);
17638 if (DVar.CKind == OMPC_shared) {
17639 Diag(ELoc, diag::err_omp_required_access)
17640 << getOpenMPClauseName(OMPC_copyprivate)
17641 << "threadprivate or private in the enclosing context";
17642 reportOriginalDsa(*this, DSAStack, D, DVar);
17643 continue;
17644 }
17645 }
17646 }
17647
17648 // Variably modified types are not supported.
17649 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
17650 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17651 << getOpenMPClauseName(OMPC_copyprivate) << Type
17652 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17653 bool IsDecl =
17654 !VD ||
17655 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17656 Diag(D->getLocation(),
17657 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17658 << D;
17659 continue;
17660 }
17661
17662 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17663 // A variable of class type (or array thereof) that appears in a
17664 // copyin clause requires an accessible, unambiguous copy assignment
17665 // operator for the class type.
17666 Type = Context.getBaseElementType(Type.getNonReferenceType())
17667 .getUnqualifiedType();
17668 VarDecl *SrcVD =
17669 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
17670 D->hasAttrs() ? &D->getAttrs() : nullptr);
17671 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
17672 VarDecl *DstVD =
17673 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
17674 D->hasAttrs() ? &D->getAttrs() : nullptr);
17675 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
17676 ExprResult AssignmentOp = BuildBinOp(
17677 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
17678 if (AssignmentOp.isInvalid())
17679 continue;
17680 AssignmentOp =
17681 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
17682 if (AssignmentOp.isInvalid())
17683 continue;
17684
17685 // No need to mark vars as copyprivate, they are already threadprivate or
17686 // implicitly private.
17687 assert(VD || isOpenMPCapturedDecl(D));
17688 Vars.push_back(
17689 VD ? RefExpr->IgnoreParens()
17690 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
17691 SrcExprs.push_back(PseudoSrcExpr);
17692 DstExprs.push_back(PseudoDstExpr);
17693 AssignmentOps.push_back(AssignmentOp.get());
17694 }
17695
17696 if (Vars.empty())
17697 return nullptr;
17698
17699 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17700 Vars, SrcExprs, DstExprs, AssignmentOps);
17701 }
17702
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17703 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
17704 SourceLocation StartLoc,
17705 SourceLocation LParenLoc,
17706 SourceLocation EndLoc) {
17707 if (VarList.empty())
17708 return nullptr;
17709
17710 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
17711 }
17712
17713 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)17714 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
17715 bool Diagnose = true) {
17716 QualType OMPDependT = Stack->getOMPDependT();
17717 if (!OMPDependT.isNull())
17718 return true;
17719 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
17720 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
17721 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
17722 if (Diagnose)
17723 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
17724 return false;
17725 }
17726 Stack->setOMPDependT(PT.get());
17727 return true;
17728 }
17729
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17730 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
17731 SourceLocation LParenLoc,
17732 SourceLocation EndLoc) {
17733 if (!Depobj)
17734 return nullptr;
17735
17736 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
17737
17738 // OpenMP 5.0, 2.17.10.1 depobj Construct
17739 // depobj is an lvalue expression of type omp_depend_t.
17740 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
17741 !Depobj->isInstantiationDependent() &&
17742 !Depobj->containsUnexpandedParameterPack() &&
17743 (OMPDependTFound &&
17744 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
17745 /*CompareUnqualified=*/true))) {
17746 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
17747 << 0 << Depobj->getType() << Depobj->getSourceRange();
17748 }
17749
17750 if (!Depobj->isLValue()) {
17751 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
17752 << 1 << Depobj->getSourceRange();
17753 }
17754
17755 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
17756 }
17757
17758 OMPClause *
ActOnOpenMPDependClause(Expr * DepModifier,OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17759 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
17760 SourceLocation DepLoc, SourceLocation ColonLoc,
17761 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
17762 SourceLocation LParenLoc, SourceLocation EndLoc) {
17763 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
17764 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
17765 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
17766 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
17767 return nullptr;
17768 }
17769 if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
17770 DSAStack->getCurrentDirective() == OMPD_depobj) &&
17771 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
17772 DepKind == OMPC_DEPEND_sink ||
17773 ((LangOpts.OpenMP < 50 ||
17774 DSAStack->getCurrentDirective() == OMPD_depobj) &&
17775 DepKind == OMPC_DEPEND_depobj))) {
17776 SmallVector<unsigned, 3> Except;
17777 Except.push_back(OMPC_DEPEND_source);
17778 Except.push_back(OMPC_DEPEND_sink);
17779 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
17780 Except.push_back(OMPC_DEPEND_depobj);
17781 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
17782 ? "depend modifier(iterator) or "
17783 : "";
17784 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
17785 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
17786 /*Last=*/OMPC_DEPEND_unknown,
17787 Except)
17788 << getOpenMPClauseName(OMPC_depend);
17789 return nullptr;
17790 }
17791 if (DepModifier &&
17792 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
17793 Diag(DepModifier->getExprLoc(),
17794 diag::err_omp_depend_sink_source_with_modifier);
17795 return nullptr;
17796 }
17797 if (DepModifier &&
17798 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
17799 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
17800
17801 SmallVector<Expr *, 8> Vars;
17802 DSAStackTy::OperatorOffsetTy OpsOffs;
17803 llvm::APSInt DepCounter(/*BitWidth=*/32);
17804 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
17805 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
17806 if (const Expr *OrderedCountExpr =
17807 DSAStack->getParentOrderedRegionParam().first) {
17808 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
17809 TotalDepCount.setIsUnsigned(/*Val=*/true);
17810 }
17811 }
17812 for (Expr *RefExpr : VarList) {
17813 assert(RefExpr && "NULL expr in OpenMP shared clause.");
17814 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17815 // It will be analyzed later.
17816 Vars.push_back(RefExpr);
17817 continue;
17818 }
17819
17820 SourceLocation ELoc = RefExpr->getExprLoc();
17821 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
17822 if (DepKind == OMPC_DEPEND_sink) {
17823 if (DSAStack->getParentOrderedRegionParam().first &&
17824 DepCounter >= TotalDepCount) {
17825 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
17826 continue;
17827 }
17828 ++DepCounter;
17829 // OpenMP [2.13.9, Summary]
17830 // depend(dependence-type : vec), where dependence-type is:
17831 // 'sink' and where vec is the iteration vector, which has the form:
17832 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
17833 // where n is the value specified by the ordered clause in the loop
17834 // directive, xi denotes the loop iteration variable of the i-th nested
17835 // loop associated with the loop directive, and di is a constant
17836 // non-negative integer.
17837 if (CurContext->isDependentContext()) {
17838 // It will be analyzed later.
17839 Vars.push_back(RefExpr);
17840 continue;
17841 }
17842 SimpleExpr = SimpleExpr->IgnoreImplicit();
17843 OverloadedOperatorKind OOK = OO_None;
17844 SourceLocation OOLoc;
17845 Expr *LHS = SimpleExpr;
17846 Expr *RHS = nullptr;
17847 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
17848 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
17849 OOLoc = BO->getOperatorLoc();
17850 LHS = BO->getLHS()->IgnoreParenImpCasts();
17851 RHS = BO->getRHS()->IgnoreParenImpCasts();
17852 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
17853 OOK = OCE->getOperator();
17854 OOLoc = OCE->getOperatorLoc();
17855 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17856 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
17857 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
17858 OOK = MCE->getMethodDecl()
17859 ->getNameInfo()
17860 .getName()
17861 .getCXXOverloadedOperator();
17862 OOLoc = MCE->getCallee()->getExprLoc();
17863 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
17864 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17865 }
17866 SourceLocation ELoc;
17867 SourceRange ERange;
17868 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
17869 if (Res.second) {
17870 // It will be analyzed later.
17871 Vars.push_back(RefExpr);
17872 }
17873 ValueDecl *D = Res.first;
17874 if (!D)
17875 continue;
17876
17877 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
17878 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
17879 continue;
17880 }
17881 if (RHS) {
17882 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
17883 RHS, OMPC_depend, /*StrictlyPositive=*/false);
17884 if (RHSRes.isInvalid())
17885 continue;
17886 }
17887 if (!CurContext->isDependentContext() &&
17888 DSAStack->getParentOrderedRegionParam().first &&
17889 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
17890 const ValueDecl *VD =
17891 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
17892 if (VD)
17893 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
17894 << 1 << VD;
17895 else
17896 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
17897 continue;
17898 }
17899 OpsOffs.emplace_back(RHS, OOK);
17900 } else {
17901 bool OMPDependTFound = LangOpts.OpenMP >= 50;
17902 if (OMPDependTFound)
17903 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
17904 DepKind == OMPC_DEPEND_depobj);
17905 if (DepKind == OMPC_DEPEND_depobj) {
17906 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17907 // List items used in depend clauses with the depobj dependence type
17908 // must be expressions of the omp_depend_t type.
17909 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17910 !RefExpr->isInstantiationDependent() &&
17911 !RefExpr->containsUnexpandedParameterPack() &&
17912 (OMPDependTFound &&
17913 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
17914 RefExpr->getType()))) {
17915 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17916 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
17917 continue;
17918 }
17919 if (!RefExpr->isLValue()) {
17920 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17921 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
17922 continue;
17923 }
17924 } else {
17925 // OpenMP 5.0 [2.17.11, Restrictions]
17926 // List items used in depend clauses cannot be zero-length array
17927 // sections.
17928 QualType ExprTy = RefExpr->getType().getNonReferenceType();
17929 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
17930 if (OASE) {
17931 QualType BaseType =
17932 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17933 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17934 ExprTy = ATy->getElementType();
17935 else
17936 ExprTy = BaseType->getPointeeType();
17937 ExprTy = ExprTy.getNonReferenceType();
17938 const Expr *Length = OASE->getLength();
17939 Expr::EvalResult Result;
17940 if (Length && !Length->isValueDependent() &&
17941 Length->EvaluateAsInt(Result, Context) &&
17942 Result.Val.getInt().isNullValue()) {
17943 Diag(ELoc,
17944 diag::err_omp_depend_zero_length_array_section_not_allowed)
17945 << SimpleExpr->getSourceRange();
17946 continue;
17947 }
17948 }
17949
17950 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17951 // List items used in depend clauses with the in, out, inout or
17952 // mutexinoutset dependence types cannot be expressions of the
17953 // omp_depend_t type.
17954 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17955 !RefExpr->isInstantiationDependent() &&
17956 !RefExpr->containsUnexpandedParameterPack() &&
17957 (OMPDependTFound &&
17958 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
17959 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17960 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
17961 << RefExpr->getSourceRange();
17962 continue;
17963 }
17964
17965 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
17966 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
17967 (ASE && !ASE->getBase()->isTypeDependent() &&
17968 !ASE->getBase()
17969 ->getType()
17970 .getNonReferenceType()
17971 ->isPointerType() &&
17972 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
17973 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17974 << (LangOpts.OpenMP >= 50 ? 1 : 0)
17975 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17976 continue;
17977 }
17978
17979 ExprResult Res;
17980 {
17981 Sema::TentativeAnalysisScope Trap(*this);
17982 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
17983 RefExpr->IgnoreParenImpCasts());
17984 }
17985 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
17986 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
17987 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17988 << (LangOpts.OpenMP >= 50 ? 1 : 0)
17989 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17990 continue;
17991 }
17992 }
17993 }
17994 Vars.push_back(RefExpr->IgnoreParenImpCasts());
17995 }
17996
17997 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
17998 TotalDepCount > VarList.size() &&
17999 DSAStack->getParentOrderedRegionParam().first &&
18000 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
18001 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
18002 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
18003 }
18004 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
18005 Vars.empty())
18006 return nullptr;
18007
18008 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18009 DepModifier, DepKind, DepLoc, ColonLoc,
18010 Vars, TotalDepCount.getZExtValue());
18011 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
18012 DSAStack->isParentOrderedRegion())
18013 DSAStack->addDoacrossDependClause(C, OpsOffs);
18014 return C;
18015 }
18016
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)18017 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
18018 Expr *Device, SourceLocation StartLoc,
18019 SourceLocation LParenLoc,
18020 SourceLocation ModifierLoc,
18021 SourceLocation EndLoc) {
18022 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
18023 "Unexpected device modifier in OpenMP < 50.");
18024
18025 bool ErrorFound = false;
18026 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
18027 std::string Values =
18028 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
18029 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
18030 << Values << getOpenMPClauseName(OMPC_device);
18031 ErrorFound = true;
18032 }
18033
18034 Expr *ValExpr = Device;
18035 Stmt *HelperValStmt = nullptr;
18036
18037 // OpenMP [2.9.1, Restrictions]
18038 // The device expression must evaluate to a non-negative integer value.
18039 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
18040 /*StrictlyPositive=*/false) ||
18041 ErrorFound;
18042 if (ErrorFound)
18043 return nullptr;
18044
18045 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18046 OpenMPDirectiveKind CaptureRegion =
18047 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
18048 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18049 ValExpr = MakeFullExpr(ValExpr).get();
18050 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18051 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18052 HelperValStmt = buildPreInits(Context, Captures);
18053 }
18054
18055 return new (Context)
18056 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
18057 LParenLoc, ModifierLoc, EndLoc);
18058 }
18059
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)18060 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
18061 DSAStackTy *Stack, QualType QTy,
18062 bool FullCheck = true) {
18063 NamedDecl *ND;
18064 if (QTy->isIncompleteType(&ND)) {
18065 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
18066 return false;
18067 }
18068 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
18069 !QTy.isTriviallyCopyableType(SemaRef.Context))
18070 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
18071 return true;
18072 }
18073
18074 /// Return true if it can be proven that the provided array expression
18075 /// (array section or array subscript) does NOT specify the whole size of the
18076 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18077 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
18078 const Expr *E,
18079 QualType BaseQTy) {
18080 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18081
18082 // If this is an array subscript, it refers to the whole size if the size of
18083 // the dimension is constant and equals 1. Also, an array section assumes the
18084 // format of an array subscript if no colon is used.
18085 if (isa<ArraySubscriptExpr>(E) ||
18086 (OASE && OASE->getColonLocFirst().isInvalid())) {
18087 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18088 return ATy->getSize().getSExtValue() != 1;
18089 // Size can't be evaluated statically.
18090 return false;
18091 }
18092
18093 assert(OASE && "Expecting array section if not an array subscript.");
18094 const Expr *LowerBound = OASE->getLowerBound();
18095 const Expr *Length = OASE->getLength();
18096
18097 // If there is a lower bound that does not evaluates to zero, we are not
18098 // covering the whole dimension.
18099 if (LowerBound) {
18100 Expr::EvalResult Result;
18101 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
18102 return false; // Can't get the integer value as a constant.
18103
18104 llvm::APSInt ConstLowerBound = Result.Val.getInt();
18105 if (ConstLowerBound.getSExtValue())
18106 return true;
18107 }
18108
18109 // If we don't have a length we covering the whole dimension.
18110 if (!Length)
18111 return false;
18112
18113 // If the base is a pointer, we don't have a way to get the size of the
18114 // pointee.
18115 if (BaseQTy->isPointerType())
18116 return false;
18117
18118 // We can only check if the length is the same as the size of the dimension
18119 // if we have a constant array.
18120 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
18121 if (!CATy)
18122 return false;
18123
18124 Expr::EvalResult Result;
18125 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18126 return false; // Can't get the integer value as a constant.
18127
18128 llvm::APSInt ConstLength = Result.Val.getInt();
18129 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
18130 }
18131
18132 // Return true if it can be proven that the provided array expression (array
18133 // section or array subscript) does NOT specify a single element of the array
18134 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18135 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
18136 const Expr *E,
18137 QualType BaseQTy) {
18138 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18139
18140 // An array subscript always refer to a single element. Also, an array section
18141 // assumes the format of an array subscript if no colon is used.
18142 if (isa<ArraySubscriptExpr>(E) ||
18143 (OASE && OASE->getColonLocFirst().isInvalid()))
18144 return false;
18145
18146 assert(OASE && "Expecting array section if not an array subscript.");
18147 const Expr *Length = OASE->getLength();
18148
18149 // If we don't have a length we have to check if the array has unitary size
18150 // for this dimension. Also, we should always expect a length if the base type
18151 // is pointer.
18152 if (!Length) {
18153 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18154 return ATy->getSize().getSExtValue() != 1;
18155 // We cannot assume anything.
18156 return false;
18157 }
18158
18159 // Check if the length evaluates to 1.
18160 Expr::EvalResult Result;
18161 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18162 return false; // Can't get the integer value as a constant.
18163
18164 llvm::APSInt ConstLength = Result.Val.getInt();
18165 return ConstLength.getSExtValue() != 1;
18166 }
18167
18168 // The base of elements of list in a map clause have to be either:
18169 // - a reference to variable or field.
18170 // - a member expression.
18171 // - an array expression.
18172 //
18173 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
18174 // reference to 'r'.
18175 //
18176 // If we have:
18177 //
18178 // struct SS {
18179 // Bla S;
18180 // foo() {
18181 // #pragma omp target map (S.Arr[:12]);
18182 // }
18183 // }
18184 //
18185 // We want to retrieve the member expression 'this->S';
18186
18187 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
18188 // If a list item is an array section, it must specify contiguous storage.
18189 //
18190 // For this restriction it is sufficient that we make sure only references
18191 // to variables or fields and array expressions, and that no array sections
18192 // exist except in the rightmost expression (unless they cover the whole
18193 // dimension of the array). E.g. these would be invalid:
18194 //
18195 // r.ArrS[3:5].Arr[6:7]
18196 //
18197 // r.ArrS[3:5].x
18198 //
18199 // but these would be valid:
18200 // r.ArrS[3].Arr[6:7]
18201 //
18202 // r.ArrS[3].x
18203 namespace {
18204 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
18205 Sema &SemaRef;
18206 OpenMPClauseKind CKind = OMPC_unknown;
18207 OpenMPDirectiveKind DKind = OMPD_unknown;
18208 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
18209 bool IsNonContiguous = false;
18210 bool NoDiagnose = false;
18211 const Expr *RelevantExpr = nullptr;
18212 bool AllowUnitySizeArraySection = true;
18213 bool AllowWholeSizeArraySection = true;
18214 bool AllowAnotherPtr = true;
18215 SourceLocation ELoc;
18216 SourceRange ERange;
18217
emitErrorMsg()18218 void emitErrorMsg() {
18219 // If nothing else worked, this is not a valid map clause expression.
18220 if (SemaRef.getLangOpts().OpenMP < 50) {
18221 SemaRef.Diag(ELoc,
18222 diag::err_omp_expected_named_var_member_or_array_expression)
18223 << ERange;
18224 } else {
18225 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18226 << getOpenMPClauseName(CKind) << ERange;
18227 }
18228 }
18229
18230 public:
VisitDeclRefExpr(DeclRefExpr * DRE)18231 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
18232 if (!isa<VarDecl>(DRE->getDecl())) {
18233 emitErrorMsg();
18234 return false;
18235 }
18236 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18237 RelevantExpr = DRE;
18238 // Record the component.
18239 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
18240 return true;
18241 }
18242
VisitMemberExpr(MemberExpr * ME)18243 bool VisitMemberExpr(MemberExpr *ME) {
18244 Expr *E = ME;
18245 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
18246
18247 if (isa<CXXThisExpr>(BaseE)) {
18248 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18249 // We found a base expression: this->Val.
18250 RelevantExpr = ME;
18251 } else {
18252 E = BaseE;
18253 }
18254
18255 if (!isa<FieldDecl>(ME->getMemberDecl())) {
18256 if (!NoDiagnose) {
18257 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
18258 << ME->getSourceRange();
18259 return false;
18260 }
18261 if (RelevantExpr)
18262 return false;
18263 return Visit(E);
18264 }
18265
18266 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
18267
18268 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
18269 // A bit-field cannot appear in a map clause.
18270 //
18271 if (FD->isBitField()) {
18272 if (!NoDiagnose) {
18273 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
18274 << ME->getSourceRange() << getOpenMPClauseName(CKind);
18275 return false;
18276 }
18277 if (RelevantExpr)
18278 return false;
18279 return Visit(E);
18280 }
18281
18282 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18283 // If the type of a list item is a reference to a type T then the type
18284 // will be considered to be T for all purposes of this clause.
18285 QualType CurType = BaseE->getType().getNonReferenceType();
18286
18287 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
18288 // A list item cannot be a variable that is a member of a structure with
18289 // a union type.
18290 //
18291 if (CurType->isUnionType()) {
18292 if (!NoDiagnose) {
18293 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
18294 << ME->getSourceRange();
18295 return false;
18296 }
18297 return RelevantExpr || Visit(E);
18298 }
18299
18300 // If we got a member expression, we should not expect any array section
18301 // before that:
18302 //
18303 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
18304 // If a list item is an element of a structure, only the rightmost symbol
18305 // of the variable reference can be an array section.
18306 //
18307 AllowUnitySizeArraySection = false;
18308 AllowWholeSizeArraySection = false;
18309
18310 // Record the component.
18311 Components.emplace_back(ME, FD, IsNonContiguous);
18312 return RelevantExpr || Visit(E);
18313 }
18314
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)18315 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
18316 Expr *E = AE->getBase()->IgnoreParenImpCasts();
18317
18318 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
18319 if (!NoDiagnose) {
18320 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18321 << 0 << AE->getSourceRange();
18322 return false;
18323 }
18324 return RelevantExpr || Visit(E);
18325 }
18326
18327 // If we got an array subscript that express the whole dimension we
18328 // can have any array expressions before. If it only expressing part of
18329 // the dimension, we can only have unitary-size array expressions.
18330 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
18331 E->getType()))
18332 AllowWholeSizeArraySection = false;
18333
18334 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
18335 Expr::EvalResult Result;
18336 if (!AE->getIdx()->isValueDependent() &&
18337 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
18338 !Result.Val.getInt().isNullValue()) {
18339 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18340 diag::err_omp_invalid_map_this_expr);
18341 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18342 diag::note_omp_invalid_subscript_on_this_ptr_map);
18343 }
18344 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18345 RelevantExpr = TE;
18346 }
18347
18348 // Record the component - we don't have any declaration associated.
18349 Components.emplace_back(AE, nullptr, IsNonContiguous);
18350
18351 return RelevantExpr || Visit(E);
18352 }
18353
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)18354 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
18355 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
18356 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18357 QualType CurType =
18358 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18359
18360 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18361 // If the type of a list item is a reference to a type T then the type
18362 // will be considered to be T for all purposes of this clause.
18363 if (CurType->isReferenceType())
18364 CurType = CurType->getPointeeType();
18365
18366 bool IsPointer = CurType->isAnyPointerType();
18367
18368 if (!IsPointer && !CurType->isArrayType()) {
18369 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18370 << 0 << OASE->getSourceRange();
18371 return false;
18372 }
18373
18374 bool NotWhole =
18375 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
18376 bool NotUnity =
18377 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
18378
18379 if (AllowWholeSizeArraySection) {
18380 // Any array section is currently allowed. Allowing a whole size array
18381 // section implies allowing a unity array section as well.
18382 //
18383 // If this array section refers to the whole dimension we can still
18384 // accept other array sections before this one, except if the base is a
18385 // pointer. Otherwise, only unitary sections are accepted.
18386 if (NotWhole || IsPointer)
18387 AllowWholeSizeArraySection = false;
18388 } else if (DKind == OMPD_target_update &&
18389 SemaRef.getLangOpts().OpenMP >= 50) {
18390 if (IsPointer && !AllowAnotherPtr)
18391 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
18392 << /*array of unknown bound */ 1;
18393 else
18394 IsNonContiguous = true;
18395 } else if (AllowUnitySizeArraySection && NotUnity) {
18396 // A unity or whole array section is not allowed and that is not
18397 // compatible with the properties of the current array section.
18398 SemaRef.Diag(
18399 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
18400 << OASE->getSourceRange();
18401 return false;
18402 }
18403
18404 if (IsPointer)
18405 AllowAnotherPtr = false;
18406
18407 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
18408 Expr::EvalResult ResultR;
18409 Expr::EvalResult ResultL;
18410 if (!OASE->getLength()->isValueDependent() &&
18411 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
18412 !ResultR.Val.getInt().isOneValue()) {
18413 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18414 diag::err_omp_invalid_map_this_expr);
18415 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18416 diag::note_omp_invalid_length_on_this_ptr_mapping);
18417 }
18418 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
18419 OASE->getLowerBound()->EvaluateAsInt(ResultL,
18420 SemaRef.getASTContext()) &&
18421 !ResultL.Val.getInt().isNullValue()) {
18422 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18423 diag::err_omp_invalid_map_this_expr);
18424 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18425 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
18426 }
18427 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18428 RelevantExpr = TE;
18429 }
18430
18431 // Record the component - we don't have any declaration associated.
18432 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
18433 return RelevantExpr || Visit(E);
18434 }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)18435 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
18436 Expr *Base = E->getBase();
18437
18438 // Record the component - we don't have any declaration associated.
18439 Components.emplace_back(E, nullptr, IsNonContiguous);
18440
18441 return Visit(Base->IgnoreParenImpCasts());
18442 }
18443
VisitUnaryOperator(UnaryOperator * UO)18444 bool VisitUnaryOperator(UnaryOperator *UO) {
18445 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
18446 UO->getOpcode() != UO_Deref) {
18447 emitErrorMsg();
18448 return false;
18449 }
18450 if (!RelevantExpr) {
18451 // Record the component if haven't found base decl.
18452 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
18453 }
18454 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
18455 }
VisitBinaryOperator(BinaryOperator * BO)18456 bool VisitBinaryOperator(BinaryOperator *BO) {
18457 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
18458 emitErrorMsg();
18459 return false;
18460 }
18461
18462 // Pointer arithmetic is the only thing we expect to happen here so after we
18463 // make sure the binary operator is a pointer type, the we only thing need
18464 // to to is to visit the subtree that has the same type as root (so that we
18465 // know the other subtree is just an offset)
18466 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
18467 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
18468 Components.emplace_back(BO, nullptr, false);
18469 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
18470 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
18471 "Either LHS or RHS have base decl inside");
18472 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
18473 return RelevantExpr || Visit(LE);
18474 return RelevantExpr || Visit(RE);
18475 }
VisitCXXThisExpr(CXXThisExpr * CTE)18476 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
18477 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18478 RelevantExpr = CTE;
18479 Components.emplace_back(CTE, nullptr, IsNonContiguous);
18480 return true;
18481 }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)18482 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
18483 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18484 Components.emplace_back(COCE, nullptr, IsNonContiguous);
18485 return true;
18486 }
VisitOpaqueValueExpr(OpaqueValueExpr * E)18487 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
18488 Expr *Source = E->getSourceExpr();
18489 if (!Source) {
18490 emitErrorMsg();
18491 return false;
18492 }
18493 return Visit(Source);
18494 }
VisitStmt(Stmt *)18495 bool VisitStmt(Stmt *) {
18496 emitErrorMsg();
18497 return false;
18498 }
getFoundBase() const18499 const Expr *getFoundBase() const {
18500 return RelevantExpr;
18501 }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)18502 explicit MapBaseChecker(
18503 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
18504 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
18505 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
18506 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
18507 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
18508 };
18509 } // namespace
18510
18511 /// Return the expression of the base of the mappable expression or null if it
18512 /// cannot be determined and do all the necessary checks to see if the expression
18513 /// is valid as a standalone mappable expression. In the process, record all the
18514 /// components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)18515 static const Expr *checkMapClauseExpressionBase(
18516 Sema &SemaRef, Expr *E,
18517 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
18518 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
18519 SourceLocation ELoc = E->getExprLoc();
18520 SourceRange ERange = E->getSourceRange();
18521 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
18522 ERange);
18523 if (Checker.Visit(E->IgnoreParens())) {
18524 // Check if the highest dimension array section has length specified
18525 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
18526 (CKind == OMPC_to || CKind == OMPC_from)) {
18527 auto CI = CurComponents.rbegin();
18528 auto CE = CurComponents.rend();
18529 for (; CI != CE; ++CI) {
18530 const auto *OASE =
18531 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
18532 if (!OASE)
18533 continue;
18534 if (OASE && OASE->getLength())
18535 break;
18536 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
18537 << ERange;
18538 }
18539 }
18540 return Checker.getFoundBase();
18541 }
18542 return nullptr;
18543 }
18544
18545 // Return true if expression E associated with value VD has conflicts with other
18546 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)18547 static bool checkMapConflicts(
18548 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
18549 bool CurrentRegionOnly,
18550 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
18551 OpenMPClauseKind CKind) {
18552 assert(VD && E);
18553 SourceLocation ELoc = E->getExprLoc();
18554 SourceRange ERange = E->getSourceRange();
18555
18556 // In order to easily check the conflicts we need to match each component of
18557 // the expression under test with the components of the expressions that are
18558 // already in the stack.
18559
18560 assert(!CurComponents.empty() && "Map clause expression with no components!");
18561 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
18562 "Map clause expression with unexpected base!");
18563
18564 // Variables to help detecting enclosing problems in data environment nests.
18565 bool IsEnclosedByDataEnvironmentExpr = false;
18566 const Expr *EnclosingExpr = nullptr;
18567
18568 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
18569 VD, CurrentRegionOnly,
18570 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
18571 ERange, CKind, &EnclosingExpr,
18572 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
18573 StackComponents,
18574 OpenMPClauseKind Kind) {
18575 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
18576 return false;
18577 assert(!StackComponents.empty() &&
18578 "Map clause expression with no components!");
18579 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
18580 "Map clause expression with unexpected base!");
18581 (void)VD;
18582
18583 // The whole expression in the stack.
18584 const Expr *RE = StackComponents.front().getAssociatedExpression();
18585
18586 // Expressions must start from the same base. Here we detect at which
18587 // point both expressions diverge from each other and see if we can
18588 // detect if the memory referred to both expressions is contiguous and
18589 // do not overlap.
18590 auto CI = CurComponents.rbegin();
18591 auto CE = CurComponents.rend();
18592 auto SI = StackComponents.rbegin();
18593 auto SE = StackComponents.rend();
18594 for (; CI != CE && SI != SE; ++CI, ++SI) {
18595
18596 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
18597 // At most one list item can be an array item derived from a given
18598 // variable in map clauses of the same construct.
18599 if (CurrentRegionOnly &&
18600 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
18601 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
18602 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
18603 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
18604 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
18605 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
18606 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
18607 diag::err_omp_multiple_array_items_in_map_clause)
18608 << CI->getAssociatedExpression()->getSourceRange();
18609 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
18610 diag::note_used_here)
18611 << SI->getAssociatedExpression()->getSourceRange();
18612 return true;
18613 }
18614
18615 // Do both expressions have the same kind?
18616 if (CI->getAssociatedExpression()->getStmtClass() !=
18617 SI->getAssociatedExpression()->getStmtClass())
18618 break;
18619
18620 // Are we dealing with different variables/fields?
18621 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
18622 break;
18623 }
18624 // Check if the extra components of the expressions in the enclosing
18625 // data environment are redundant for the current base declaration.
18626 // If they are, the maps completely overlap, which is legal.
18627 for (; SI != SE; ++SI) {
18628 QualType Type;
18629 if (const auto *ASE =
18630 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
18631 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
18632 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
18633 SI->getAssociatedExpression())) {
18634 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18635 Type =
18636 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18637 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
18638 SI->getAssociatedExpression())) {
18639 Type = OASE->getBase()->getType()->getPointeeType();
18640 }
18641 if (Type.isNull() || Type->isAnyPointerType() ||
18642 checkArrayExpressionDoesNotReferToWholeSize(
18643 SemaRef, SI->getAssociatedExpression(), Type))
18644 break;
18645 }
18646
18647 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
18648 // List items of map clauses in the same construct must not share
18649 // original storage.
18650 //
18651 // If the expressions are exactly the same or one is a subset of the
18652 // other, it means they are sharing storage.
18653 if (CI == CE && SI == SE) {
18654 if (CurrentRegionOnly) {
18655 if (CKind == OMPC_map) {
18656 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
18657 } else {
18658 assert(CKind == OMPC_to || CKind == OMPC_from);
18659 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
18660 << ERange;
18661 }
18662 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18663 << RE->getSourceRange();
18664 return true;
18665 }
18666 // If we find the same expression in the enclosing data environment,
18667 // that is legal.
18668 IsEnclosedByDataEnvironmentExpr = true;
18669 return false;
18670 }
18671
18672 QualType DerivedType =
18673 std::prev(CI)->getAssociatedDeclaration()->getType();
18674 SourceLocation DerivedLoc =
18675 std::prev(CI)->getAssociatedExpression()->getExprLoc();
18676
18677 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18678 // If the type of a list item is a reference to a type T then the type
18679 // will be considered to be T for all purposes of this clause.
18680 DerivedType = DerivedType.getNonReferenceType();
18681
18682 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
18683 // A variable for which the type is pointer and an array section
18684 // derived from that variable must not appear as list items of map
18685 // clauses of the same construct.
18686 //
18687 // Also, cover one of the cases in:
18688 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
18689 // If any part of the original storage of a list item has corresponding
18690 // storage in the device data environment, all of the original storage
18691 // must have corresponding storage in the device data environment.
18692 //
18693 if (DerivedType->isAnyPointerType()) {
18694 if (CI == CE || SI == SE) {
18695 SemaRef.Diag(
18696 DerivedLoc,
18697 diag::err_omp_pointer_mapped_along_with_derived_section)
18698 << DerivedLoc;
18699 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18700 << RE->getSourceRange();
18701 return true;
18702 }
18703 if (CI->getAssociatedExpression()->getStmtClass() !=
18704 SI->getAssociatedExpression()->getStmtClass() ||
18705 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
18706 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
18707 assert(CI != CE && SI != SE);
18708 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
18709 << DerivedLoc;
18710 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18711 << RE->getSourceRange();
18712 return true;
18713 }
18714 }
18715
18716 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
18717 // List items of map clauses in the same construct must not share
18718 // original storage.
18719 //
18720 // An expression is a subset of the other.
18721 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
18722 if (CKind == OMPC_map) {
18723 if (CI != CE || SI != SE) {
18724 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
18725 // a pointer.
18726 auto Begin =
18727 CI != CE ? CurComponents.begin() : StackComponents.begin();
18728 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
18729 auto It = Begin;
18730 while (It != End && !It->getAssociatedDeclaration())
18731 std::advance(It, 1);
18732 assert(It != End &&
18733 "Expected at least one component with the declaration.");
18734 if (It != Begin && It->getAssociatedDeclaration()
18735 ->getType()
18736 .getCanonicalType()
18737 ->isAnyPointerType()) {
18738 IsEnclosedByDataEnvironmentExpr = false;
18739 EnclosingExpr = nullptr;
18740 return false;
18741 }
18742 }
18743 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
18744 } else {
18745 assert(CKind == OMPC_to || CKind == OMPC_from);
18746 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
18747 << ERange;
18748 }
18749 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18750 << RE->getSourceRange();
18751 return true;
18752 }
18753
18754 // The current expression uses the same base as other expression in the
18755 // data environment but does not contain it completely.
18756 if (!CurrentRegionOnly && SI != SE)
18757 EnclosingExpr = RE;
18758
18759 // The current expression is a subset of the expression in the data
18760 // environment.
18761 IsEnclosedByDataEnvironmentExpr |=
18762 (!CurrentRegionOnly && CI != CE && SI == SE);
18763
18764 return false;
18765 });
18766
18767 if (CurrentRegionOnly)
18768 return FoundError;
18769
18770 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
18771 // If any part of the original storage of a list item has corresponding
18772 // storage in the device data environment, all of the original storage must
18773 // have corresponding storage in the device data environment.
18774 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
18775 // If a list item is an element of a structure, and a different element of
18776 // the structure has a corresponding list item in the device data environment
18777 // prior to a task encountering the construct associated with the map clause,
18778 // then the list item must also have a corresponding list item in the device
18779 // data environment prior to the task encountering the construct.
18780 //
18781 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
18782 SemaRef.Diag(ELoc,
18783 diag::err_omp_original_storage_is_shared_and_does_not_contain)
18784 << ERange;
18785 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
18786 << EnclosingExpr->getSourceRange();
18787 return true;
18788 }
18789
18790 return FoundError;
18791 }
18792
18793 // Look up the user-defined mapper given the mapper name and mapped type, and
18794 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)18795 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
18796 CXXScopeSpec &MapperIdScopeSpec,
18797 const DeclarationNameInfo &MapperId,
18798 QualType Type,
18799 Expr *UnresolvedMapper) {
18800 if (MapperIdScopeSpec.isInvalid())
18801 return ExprError();
18802 // Get the actual type for the array type.
18803 if (Type->isArrayType()) {
18804 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
18805 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
18806 }
18807 // Find all user-defined mappers with the given MapperId.
18808 SmallVector<UnresolvedSet<8>, 4> Lookups;
18809 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
18810 Lookup.suppressDiagnostics();
18811 if (S) {
18812 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
18813 NamedDecl *D = Lookup.getRepresentativeDecl();
18814 while (S && !S->isDeclScope(D))
18815 S = S->getParent();
18816 if (S)
18817 S = S->getParent();
18818 Lookups.emplace_back();
18819 Lookups.back().append(Lookup.begin(), Lookup.end());
18820 Lookup.clear();
18821 }
18822 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
18823 // Extract the user-defined mappers with the given MapperId.
18824 Lookups.push_back(UnresolvedSet<8>());
18825 for (NamedDecl *D : ULE->decls()) {
18826 auto *DMD = cast<OMPDeclareMapperDecl>(D);
18827 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
18828 Lookups.back().addDecl(DMD);
18829 }
18830 }
18831 // Defer the lookup for dependent types. The results will be passed through
18832 // UnresolvedMapper on instantiation.
18833 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
18834 Type->isInstantiationDependentType() ||
18835 Type->containsUnexpandedParameterPack() ||
18836 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18837 return !D->isInvalidDecl() &&
18838 (D->getType()->isDependentType() ||
18839 D->getType()->isInstantiationDependentType() ||
18840 D->getType()->containsUnexpandedParameterPack());
18841 })) {
18842 UnresolvedSet<8> URS;
18843 for (const UnresolvedSet<8> &Set : Lookups) {
18844 if (Set.empty())
18845 continue;
18846 URS.append(Set.begin(), Set.end());
18847 }
18848 return UnresolvedLookupExpr::Create(
18849 SemaRef.Context, /*NamingClass=*/nullptr,
18850 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
18851 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
18852 }
18853 SourceLocation Loc = MapperId.getLoc();
18854 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18855 // The type must be of struct, union or class type in C and C++
18856 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
18857 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
18858 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
18859 return ExprError();
18860 }
18861 // Perform argument dependent lookup.
18862 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
18863 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
18864 // Return the first user-defined mapper with the desired type.
18865 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18866 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
18867 if (!D->isInvalidDecl() &&
18868 SemaRef.Context.hasSameType(D->getType(), Type))
18869 return D;
18870 return nullptr;
18871 }))
18872 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18873 // Find the first user-defined mapper with a type derived from the desired
18874 // type.
18875 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18876 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
18877 if (!D->isInvalidDecl() &&
18878 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
18879 !Type.isMoreQualifiedThan(D->getType()))
18880 return D;
18881 return nullptr;
18882 })) {
18883 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18884 /*DetectVirtual=*/false);
18885 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
18886 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18887 VD->getType().getUnqualifiedType()))) {
18888 if (SemaRef.CheckBaseClassAccess(
18889 Loc, VD->getType(), Type, Paths.front(),
18890 /*DiagID=*/0) != Sema::AR_inaccessible) {
18891 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18892 }
18893 }
18894 }
18895 }
18896 // Report error if a mapper is specified, but cannot be found.
18897 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
18898 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
18899 << Type << MapperId.getName();
18900 return ExprError();
18901 }
18902 return ExprEmpty();
18903 }
18904
18905 namespace {
18906 // Utility struct that gathers all the related lists associated with a mappable
18907 // expression.
18908 struct MappableVarListInfo {
18909 // The list of expressions.
18910 ArrayRef<Expr *> VarList;
18911 // The list of processed expressions.
18912 SmallVector<Expr *, 16> ProcessedVarList;
18913 // The mappble components for each expression.
18914 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
18915 // The base declaration of the variable.
18916 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
18917 // The reference to the user-defined mapper associated with every expression.
18918 SmallVector<Expr *, 16> UDMapperList;
18919
MappableVarListInfo__anon5b04668f5211::MappableVarListInfo18920 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
18921 // We have a list of components and base declarations for each entry in the
18922 // variable list.
18923 VarComponents.reserve(VarList.size());
18924 VarBaseDeclarations.reserve(VarList.size());
18925 }
18926 };
18927 }
18928
18929 // Check the validity of the provided variable list for the provided clause kind
18930 // \a CKind. In the check process the valid expressions, mappable expression
18931 // components, variables, and user-defined mappers are extracted and used to
18932 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
18933 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
18934 // 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)18935 static void checkMappableExpressionList(
18936 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
18937 MappableVarListInfo &MVLI, SourceLocation StartLoc,
18938 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
18939 ArrayRef<Expr *> UnresolvedMappers,
18940 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
18941 bool IsMapTypeImplicit = false) {
18942 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
18943 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
18944 "Unexpected clause kind with mappable expressions!");
18945
18946 // If the identifier of user-defined mapper is not specified, it is "default".
18947 // We do not change the actual name in this clause to distinguish whether a
18948 // mapper is specified explicitly, i.e., it is not explicitly specified when
18949 // MapperId.getName() is empty.
18950 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
18951 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
18952 MapperId.setName(DeclNames.getIdentifier(
18953 &SemaRef.getASTContext().Idents.get("default")));
18954 MapperId.setLoc(StartLoc);
18955 }
18956
18957 // Iterators to find the current unresolved mapper expression.
18958 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
18959 bool UpdateUMIt = false;
18960 Expr *UnresolvedMapper = nullptr;
18961
18962 // Keep track of the mappable components and base declarations in this clause.
18963 // Each entry in the list is going to have a list of components associated. We
18964 // record each set of the components so that we can build the clause later on.
18965 // In the end we should have the same amount of declarations and component
18966 // lists.
18967
18968 for (Expr *RE : MVLI.VarList) {
18969 assert(RE && "Null expr in omp to/from/map clause");
18970 SourceLocation ELoc = RE->getExprLoc();
18971
18972 // Find the current unresolved mapper expression.
18973 if (UpdateUMIt && UMIt != UMEnd) {
18974 UMIt++;
18975 assert(
18976 UMIt != UMEnd &&
18977 "Expect the size of UnresolvedMappers to match with that of VarList");
18978 }
18979 UpdateUMIt = true;
18980 if (UMIt != UMEnd)
18981 UnresolvedMapper = *UMIt;
18982
18983 const Expr *VE = RE->IgnoreParenLValueCasts();
18984
18985 if (VE->isValueDependent() || VE->isTypeDependent() ||
18986 VE->isInstantiationDependent() ||
18987 VE->containsUnexpandedParameterPack()) {
18988 // Try to find the associated user-defined mapper.
18989 ExprResult ER = buildUserDefinedMapperRef(
18990 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
18991 VE->getType().getCanonicalType(), UnresolvedMapper);
18992 if (ER.isInvalid())
18993 continue;
18994 MVLI.UDMapperList.push_back(ER.get());
18995 // We can only analyze this information once the missing information is
18996 // resolved.
18997 MVLI.ProcessedVarList.push_back(RE);
18998 continue;
18999 }
19000
19001 Expr *SimpleExpr = RE->IgnoreParenCasts();
19002
19003 if (!RE->isLValue()) {
19004 if (SemaRef.getLangOpts().OpenMP < 50) {
19005 SemaRef.Diag(
19006 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
19007 << RE->getSourceRange();
19008 } else {
19009 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
19010 << getOpenMPClauseName(CKind) << RE->getSourceRange();
19011 }
19012 continue;
19013 }
19014
19015 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
19016 ValueDecl *CurDeclaration = nullptr;
19017
19018 // Obtain the array or member expression bases if required. Also, fill the
19019 // components array with all the components identified in the process.
19020 const Expr *BE = checkMapClauseExpressionBase(
19021 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
19022 /*NoDiagnose=*/false);
19023 if (!BE)
19024 continue;
19025
19026 assert(!CurComponents.empty() &&
19027 "Invalid mappable expression information.");
19028
19029 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
19030 // Add store "this" pointer to class in DSAStackTy for future checking
19031 DSAS->addMappedClassesQualTypes(TE->getType());
19032 // Try to find the associated user-defined mapper.
19033 ExprResult ER = buildUserDefinedMapperRef(
19034 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19035 VE->getType().getCanonicalType(), UnresolvedMapper);
19036 if (ER.isInvalid())
19037 continue;
19038 MVLI.UDMapperList.push_back(ER.get());
19039 // Skip restriction checking for variable or field declarations
19040 MVLI.ProcessedVarList.push_back(RE);
19041 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19042 MVLI.VarComponents.back().append(CurComponents.begin(),
19043 CurComponents.end());
19044 MVLI.VarBaseDeclarations.push_back(nullptr);
19045 continue;
19046 }
19047
19048 // For the following checks, we rely on the base declaration which is
19049 // expected to be associated with the last component. The declaration is
19050 // expected to be a variable or a field (if 'this' is being mapped).
19051 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
19052 assert(CurDeclaration && "Null decl on map clause.");
19053 assert(
19054 CurDeclaration->isCanonicalDecl() &&
19055 "Expecting components to have associated only canonical declarations.");
19056
19057 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
19058 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
19059
19060 assert((VD || FD) && "Only variables or fields are expected here!");
19061 (void)FD;
19062
19063 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
19064 // threadprivate variables cannot appear in a map clause.
19065 // OpenMP 4.5 [2.10.5, target update Construct]
19066 // threadprivate variables cannot appear in a from clause.
19067 if (VD && DSAS->isThreadPrivate(VD)) {
19068 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19069 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
19070 << getOpenMPClauseName(CKind);
19071 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
19072 continue;
19073 }
19074
19075 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19076 // A list item cannot appear in both a map clause and a data-sharing
19077 // attribute clause on the same construct.
19078
19079 // Check conflicts with other map clause expressions. We check the conflicts
19080 // with the current construct separately from the enclosing data
19081 // environment, because the restrictions are different. We only have to
19082 // check conflicts across regions for the map clauses.
19083 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19084 /*CurrentRegionOnly=*/true, CurComponents, CKind))
19085 break;
19086 if (CKind == OMPC_map &&
19087 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
19088 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19089 /*CurrentRegionOnly=*/false, CurComponents, CKind))
19090 break;
19091
19092 // OpenMP 4.5 [2.10.5, target update Construct]
19093 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19094 // If the type of a list item is a reference to a type T then the type will
19095 // be considered to be T for all purposes of this clause.
19096 auto I = llvm::find_if(
19097 CurComponents,
19098 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
19099 return MC.getAssociatedDeclaration();
19100 });
19101 assert(I != CurComponents.end() && "Null decl on map clause.");
19102 (void)I;
19103 QualType Type;
19104 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
19105 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
19106 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
19107 if (ASE) {
19108 Type = ASE->getType().getNonReferenceType();
19109 } else if (OASE) {
19110 QualType BaseType =
19111 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19112 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19113 Type = ATy->getElementType();
19114 else
19115 Type = BaseType->getPointeeType();
19116 Type = Type.getNonReferenceType();
19117 } else if (OAShE) {
19118 Type = OAShE->getBase()->getType()->getPointeeType();
19119 } else {
19120 Type = VE->getType();
19121 }
19122
19123 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
19124 // A list item in a to or from clause must have a mappable type.
19125 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19126 // A list item must have a mappable type.
19127 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
19128 DSAS, Type))
19129 continue;
19130
19131 if (CKind == OMPC_map) {
19132 // target enter data
19133 // OpenMP [2.10.2, Restrictions, p. 99]
19134 // A map-type must be specified in all map clauses and must be either
19135 // to or alloc.
19136 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
19137 if (DKind == OMPD_target_enter_data &&
19138 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
19139 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19140 << (IsMapTypeImplicit ? 1 : 0)
19141 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19142 << getOpenMPDirectiveName(DKind);
19143 continue;
19144 }
19145
19146 // target exit_data
19147 // OpenMP [2.10.3, Restrictions, p. 102]
19148 // A map-type must be specified in all map clauses and must be either
19149 // from, release, or delete.
19150 if (DKind == OMPD_target_exit_data &&
19151 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
19152 MapType == OMPC_MAP_delete)) {
19153 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19154 << (IsMapTypeImplicit ? 1 : 0)
19155 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19156 << getOpenMPDirectiveName(DKind);
19157 continue;
19158 }
19159
19160 // target, target data
19161 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
19162 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
19163 // A map-type in a map clause must be to, from, tofrom or alloc
19164 if ((DKind == OMPD_target_data ||
19165 isOpenMPTargetExecutionDirective(DKind)) &&
19166 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
19167 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
19168 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19169 << (IsMapTypeImplicit ? 1 : 0)
19170 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19171 << getOpenMPDirectiveName(DKind);
19172 continue;
19173 }
19174
19175 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
19176 // A list item cannot appear in both a map clause and a data-sharing
19177 // attribute clause on the same construct
19178 //
19179 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
19180 // A list item cannot appear in both a map clause and a data-sharing
19181 // attribute clause on the same construct unless the construct is a
19182 // combined construct.
19183 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
19184 isOpenMPTargetExecutionDirective(DKind)) ||
19185 DKind == OMPD_target)) {
19186 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19187 if (isOpenMPPrivate(DVar.CKind)) {
19188 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19189 << getOpenMPClauseName(DVar.CKind)
19190 << getOpenMPClauseName(OMPC_map)
19191 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
19192 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
19193 continue;
19194 }
19195 }
19196 }
19197
19198 // Try to find the associated user-defined mapper.
19199 ExprResult ER = buildUserDefinedMapperRef(
19200 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19201 Type.getCanonicalType(), UnresolvedMapper);
19202 if (ER.isInvalid())
19203 continue;
19204 MVLI.UDMapperList.push_back(ER.get());
19205
19206 // Save the current expression.
19207 MVLI.ProcessedVarList.push_back(RE);
19208
19209 // Store the components in the stack so that they can be used to check
19210 // against other clauses later on.
19211 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
19212 /*WhereFoundClauseKind=*/OMPC_map);
19213
19214 // Save the components and declaration to create the clause. For purposes of
19215 // the clause creation, any component list that has has base 'this' uses
19216 // null as base declaration.
19217 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19218 MVLI.VarComponents.back().append(CurComponents.begin(),
19219 CurComponents.end());
19220 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
19221 : CurDeclaration);
19222 }
19223 }
19224
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)19225 OMPClause *Sema::ActOnOpenMPMapClause(
19226 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
19227 ArrayRef<SourceLocation> MapTypeModifiersLoc,
19228 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19229 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
19230 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19231 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
19232 OpenMPMapModifierKind Modifiers[] = {
19233 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19234 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
19235 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
19236
19237 // Process map-type-modifiers, flag errors for duplicate modifiers.
19238 unsigned Count = 0;
19239 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
19240 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
19241 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
19242 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
19243 continue;
19244 }
19245 assert(Count < NumberOfOMPMapClauseModifiers &&
19246 "Modifiers exceed the allowed number of map type modifiers");
19247 Modifiers[Count] = MapTypeModifiers[I];
19248 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
19249 ++Count;
19250 }
19251
19252 MappableVarListInfo MVLI(VarList);
19253 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
19254 MapperIdScopeSpec, MapperId, UnresolvedMappers,
19255 MapType, IsMapTypeImplicit);
19256
19257 // We need to produce a map clause even if we don't have variables so that
19258 // other diagnostics related with non-existing map clauses are accurate.
19259 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
19260 MVLI.VarBaseDeclarations, MVLI.VarComponents,
19261 MVLI.UDMapperList, Modifiers, ModifiersLoc,
19262 MapperIdScopeSpec.getWithLocInContext(Context),
19263 MapperId, MapType, IsMapTypeImplicit, MapLoc);
19264 }
19265
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)19266 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
19267 TypeResult ParsedType) {
19268 assert(ParsedType.isUsable());
19269
19270 QualType ReductionType = GetTypeFromParser(ParsedType.get());
19271 if (ReductionType.isNull())
19272 return QualType();
19273
19274 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
19275 // A type name in a declare reduction directive cannot be a function type, an
19276 // array type, a reference type, or a type qualified with const, volatile or
19277 // restrict.
19278 if (ReductionType.hasQualifiers()) {
19279 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
19280 return QualType();
19281 }
19282
19283 if (ReductionType->isFunctionType()) {
19284 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
19285 return QualType();
19286 }
19287 if (ReductionType->isReferenceType()) {
19288 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
19289 return QualType();
19290 }
19291 if (ReductionType->isArrayType()) {
19292 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
19293 return QualType();
19294 }
19295 return ReductionType;
19296 }
19297
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)19298 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
19299 Scope *S, DeclContext *DC, DeclarationName Name,
19300 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
19301 AccessSpecifier AS, Decl *PrevDeclInScope) {
19302 SmallVector<Decl *, 8> Decls;
19303 Decls.reserve(ReductionTypes.size());
19304
19305 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
19306 forRedeclarationInCurContext());
19307 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
19308 // A reduction-identifier may not be re-declared in the current scope for the
19309 // same type or for a type that is compatible according to the base language
19310 // rules.
19311 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19312 OMPDeclareReductionDecl *PrevDRD = nullptr;
19313 bool InCompoundScope = true;
19314 if (S != nullptr) {
19315 // Find previous declaration with the same name not referenced in other
19316 // declarations.
19317 FunctionScopeInfo *ParentFn = getEnclosingFunction();
19318 InCompoundScope =
19319 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19320 LookupName(Lookup, S);
19321 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19322 /*AllowInlineNamespace=*/false);
19323 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
19324 LookupResult::Filter Filter = Lookup.makeFilter();
19325 while (Filter.hasNext()) {
19326 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
19327 if (InCompoundScope) {
19328 auto I = UsedAsPrevious.find(PrevDecl);
19329 if (I == UsedAsPrevious.end())
19330 UsedAsPrevious[PrevDecl] = false;
19331 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
19332 UsedAsPrevious[D] = true;
19333 }
19334 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19335 PrevDecl->getLocation();
19336 }
19337 Filter.done();
19338 if (InCompoundScope) {
19339 for (const auto &PrevData : UsedAsPrevious) {
19340 if (!PrevData.second) {
19341 PrevDRD = PrevData.first;
19342 break;
19343 }
19344 }
19345 }
19346 } else if (PrevDeclInScope != nullptr) {
19347 auto *PrevDRDInScope = PrevDRD =
19348 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
19349 do {
19350 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
19351 PrevDRDInScope->getLocation();
19352 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
19353 } while (PrevDRDInScope != nullptr);
19354 }
19355 for (const auto &TyData : ReductionTypes) {
19356 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
19357 bool Invalid = false;
19358 if (I != PreviousRedeclTypes.end()) {
19359 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
19360 << TyData.first;
19361 Diag(I->second, diag::note_previous_definition);
19362 Invalid = true;
19363 }
19364 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
19365 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
19366 Name, TyData.first, PrevDRD);
19367 DC->addDecl(DRD);
19368 DRD->setAccess(AS);
19369 Decls.push_back(DRD);
19370 if (Invalid)
19371 DRD->setInvalidDecl();
19372 else
19373 PrevDRD = DRD;
19374 }
19375
19376 return DeclGroupPtrTy::make(
19377 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
19378 }
19379
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)19380 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
19381 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19382
19383 // Enter new function scope.
19384 PushFunctionScope();
19385 setFunctionHasBranchProtectedScope();
19386 getCurFunction()->setHasOMPDeclareReductionCombiner();
19387
19388 if (S != nullptr)
19389 PushDeclContext(S, DRD);
19390 else
19391 CurContext = DRD;
19392
19393 PushExpressionEvaluationContext(
19394 ExpressionEvaluationContext::PotentiallyEvaluated);
19395
19396 QualType ReductionType = DRD->getType();
19397 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
19398 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
19399 // uses semantics of argument handles by value, but it should be passed by
19400 // reference. C lang does not support references, so pass all parameters as
19401 // pointers.
19402 // Create 'T omp_in;' variable.
19403 VarDecl *OmpInParm =
19404 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
19405 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
19406 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
19407 // uses semantics of argument handles by value, but it should be passed by
19408 // reference. C lang does not support references, so pass all parameters as
19409 // pointers.
19410 // Create 'T omp_out;' variable.
19411 VarDecl *OmpOutParm =
19412 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
19413 if (S != nullptr) {
19414 PushOnScopeChains(OmpInParm, S);
19415 PushOnScopeChains(OmpOutParm, S);
19416 } else {
19417 DRD->addDecl(OmpInParm);
19418 DRD->addDecl(OmpOutParm);
19419 }
19420 Expr *InE =
19421 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
19422 Expr *OutE =
19423 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
19424 DRD->setCombinerData(InE, OutE);
19425 }
19426
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)19427 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
19428 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19429 DiscardCleanupsInEvaluationContext();
19430 PopExpressionEvaluationContext();
19431
19432 PopDeclContext();
19433 PopFunctionScopeInfo();
19434
19435 if (Combiner != nullptr)
19436 DRD->setCombiner(Combiner);
19437 else
19438 DRD->setInvalidDecl();
19439 }
19440
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)19441 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
19442 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19443
19444 // Enter new function scope.
19445 PushFunctionScope();
19446 setFunctionHasBranchProtectedScope();
19447
19448 if (S != nullptr)
19449 PushDeclContext(S, DRD);
19450 else
19451 CurContext = DRD;
19452
19453 PushExpressionEvaluationContext(
19454 ExpressionEvaluationContext::PotentiallyEvaluated);
19455
19456 QualType ReductionType = DRD->getType();
19457 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
19458 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
19459 // uses semantics of argument handles by value, but it should be passed by
19460 // reference. C lang does not support references, so pass all parameters as
19461 // pointers.
19462 // Create 'T omp_priv;' variable.
19463 VarDecl *OmpPrivParm =
19464 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
19465 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
19466 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
19467 // uses semantics of argument handles by value, but it should be passed by
19468 // reference. C lang does not support references, so pass all parameters as
19469 // pointers.
19470 // Create 'T omp_orig;' variable.
19471 VarDecl *OmpOrigParm =
19472 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
19473 if (S != nullptr) {
19474 PushOnScopeChains(OmpPrivParm, S);
19475 PushOnScopeChains(OmpOrigParm, S);
19476 } else {
19477 DRD->addDecl(OmpPrivParm);
19478 DRD->addDecl(OmpOrigParm);
19479 }
19480 Expr *OrigE =
19481 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
19482 Expr *PrivE =
19483 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
19484 DRD->setInitializerData(OrigE, PrivE);
19485 return OmpPrivParm;
19486 }
19487
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)19488 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
19489 VarDecl *OmpPrivParm) {
19490 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19491 DiscardCleanupsInEvaluationContext();
19492 PopExpressionEvaluationContext();
19493
19494 PopDeclContext();
19495 PopFunctionScopeInfo();
19496
19497 if (Initializer != nullptr) {
19498 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
19499 } else if (OmpPrivParm->hasInit()) {
19500 DRD->setInitializer(OmpPrivParm->getInit(),
19501 OmpPrivParm->isDirectInit()
19502 ? OMPDeclareReductionDecl::DirectInit
19503 : OMPDeclareReductionDecl::CopyInit);
19504 } else {
19505 DRD->setInvalidDecl();
19506 }
19507 }
19508
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)19509 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
19510 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
19511 for (Decl *D : DeclReductions.get()) {
19512 if (IsValid) {
19513 if (S)
19514 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
19515 /*AddToContext=*/false);
19516 } else {
19517 D->setInvalidDecl();
19518 }
19519 }
19520 return DeclReductions;
19521 }
19522
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)19523 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
19524 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
19525 QualType T = TInfo->getType();
19526 if (D.isInvalidType())
19527 return true;
19528
19529 if (getLangOpts().CPlusPlus) {
19530 // Check that there are no default arguments (C++ only).
19531 CheckExtraCXXDefaultArguments(D);
19532 }
19533
19534 return CreateParsedType(T, TInfo);
19535 }
19536
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)19537 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
19538 TypeResult ParsedType) {
19539 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
19540
19541 QualType MapperType = GetTypeFromParser(ParsedType.get());
19542 assert(!MapperType.isNull() && "Expect valid mapper type");
19543
19544 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19545 // The type must be of struct, union or class type in C and C++
19546 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
19547 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
19548 return QualType();
19549 }
19550 return MapperType;
19551 }
19552
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)19553 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
19554 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
19555 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
19556 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
19557 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
19558 forRedeclarationInCurContext());
19559 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19560 // A mapper-identifier may not be redeclared in the current scope for the
19561 // same type or for a type that is compatible according to the base language
19562 // rules.
19563 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19564 OMPDeclareMapperDecl *PrevDMD = nullptr;
19565 bool InCompoundScope = true;
19566 if (S != nullptr) {
19567 // Find previous declaration with the same name not referenced in other
19568 // declarations.
19569 FunctionScopeInfo *ParentFn = getEnclosingFunction();
19570 InCompoundScope =
19571 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19572 LookupName(Lookup, S);
19573 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19574 /*AllowInlineNamespace=*/false);
19575 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
19576 LookupResult::Filter Filter = Lookup.makeFilter();
19577 while (Filter.hasNext()) {
19578 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
19579 if (InCompoundScope) {
19580 auto I = UsedAsPrevious.find(PrevDecl);
19581 if (I == UsedAsPrevious.end())
19582 UsedAsPrevious[PrevDecl] = false;
19583 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
19584 UsedAsPrevious[D] = true;
19585 }
19586 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19587 PrevDecl->getLocation();
19588 }
19589 Filter.done();
19590 if (InCompoundScope) {
19591 for (const auto &PrevData : UsedAsPrevious) {
19592 if (!PrevData.second) {
19593 PrevDMD = PrevData.first;
19594 break;
19595 }
19596 }
19597 }
19598 } else if (PrevDeclInScope) {
19599 auto *PrevDMDInScope = PrevDMD =
19600 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
19601 do {
19602 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
19603 PrevDMDInScope->getLocation();
19604 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
19605 } while (PrevDMDInScope != nullptr);
19606 }
19607 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
19608 bool Invalid = false;
19609 if (I != PreviousRedeclTypes.end()) {
19610 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
19611 << MapperType << Name;
19612 Diag(I->second, diag::note_previous_definition);
19613 Invalid = true;
19614 }
19615 // Build expressions for implicit maps of data members with 'default'
19616 // mappers.
19617 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
19618 Clauses.end());
19619 if (LangOpts.OpenMP >= 50)
19620 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
19621 auto *DMD =
19622 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
19623 ClausesWithImplicit, PrevDMD);
19624 if (S)
19625 PushOnScopeChains(DMD, S);
19626 else
19627 DC->addDecl(DMD);
19628 DMD->setAccess(AS);
19629 if (Invalid)
19630 DMD->setInvalidDecl();
19631
19632 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
19633 VD->setDeclContext(DMD);
19634 VD->setLexicalDeclContext(DMD);
19635 DMD->addDecl(VD);
19636 DMD->setMapperVarRef(MapperVarRef);
19637
19638 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
19639 }
19640
19641 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)19642 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
19643 SourceLocation StartLoc,
19644 DeclarationName VN) {
19645 TypeSourceInfo *TInfo =
19646 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
19647 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
19648 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
19649 MapperType, TInfo, SC_None);
19650 if (S)
19651 PushOnScopeChains(VD, S, /*AddToContext=*/false);
19652 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
19653 DSAStack->addDeclareMapperVarRef(E);
19654 return E;
19655 }
19656
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const19657 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
19658 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
19659 const Expr *Ref = DSAStack->getDeclareMapperVarRef();
19660 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
19661 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
19662 return true;
19663 }
19664
getOpenMPDeclareMapperVarName() const19665 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
19666 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
19667 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
19668 }
19669
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19670 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
19671 SourceLocation StartLoc,
19672 SourceLocation LParenLoc,
19673 SourceLocation EndLoc) {
19674 Expr *ValExpr = NumTeams;
19675 Stmt *HelperValStmt = nullptr;
19676
19677 // OpenMP [teams Constrcut, Restrictions]
19678 // The num_teams expression must evaluate to a positive integer value.
19679 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
19680 /*StrictlyPositive=*/true))
19681 return nullptr;
19682
19683 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
19684 OpenMPDirectiveKind CaptureRegion =
19685 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
19686 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19687 ValExpr = MakeFullExpr(ValExpr).get();
19688 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19689 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19690 HelperValStmt = buildPreInits(Context, Captures);
19691 }
19692
19693 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
19694 StartLoc, LParenLoc, EndLoc);
19695 }
19696
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19697 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
19698 SourceLocation StartLoc,
19699 SourceLocation LParenLoc,
19700 SourceLocation EndLoc) {
19701 Expr *ValExpr = ThreadLimit;
19702 Stmt *HelperValStmt = nullptr;
19703
19704 // OpenMP [teams Constrcut, Restrictions]
19705 // The thread_limit expression must evaluate to a positive integer value.
19706 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
19707 /*StrictlyPositive=*/true))
19708 return nullptr;
19709
19710 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
19711 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
19712 DKind, OMPC_thread_limit, LangOpts.OpenMP);
19713 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19714 ValExpr = MakeFullExpr(ValExpr).get();
19715 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19716 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19717 HelperValStmt = buildPreInits(Context, Captures);
19718 }
19719
19720 return new (Context) OMPThreadLimitClause(
19721 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
19722 }
19723
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19724 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
19725 SourceLocation StartLoc,
19726 SourceLocation LParenLoc,
19727 SourceLocation EndLoc) {
19728 Expr *ValExpr = Priority;
19729 Stmt *HelperValStmt = nullptr;
19730 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19731
19732 // OpenMP [2.9.1, task Constrcut]
19733 // The priority-value is a non-negative numerical scalar expression.
19734 if (!isNonNegativeIntegerValue(
19735 ValExpr, *this, OMPC_priority,
19736 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
19737 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19738 return nullptr;
19739
19740 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
19741 StartLoc, LParenLoc, EndLoc);
19742 }
19743
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19744 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
19745 SourceLocation StartLoc,
19746 SourceLocation LParenLoc,
19747 SourceLocation EndLoc) {
19748 Expr *ValExpr = Grainsize;
19749 Stmt *HelperValStmt = nullptr;
19750 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19751
19752 // OpenMP [2.9.2, taskloop Constrcut]
19753 // The parameter of the grainsize clause must be a positive integer
19754 // expression.
19755 if (!isNonNegativeIntegerValue(
19756 ValExpr, *this, OMPC_grainsize,
19757 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
19758 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19759 return nullptr;
19760
19761 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
19762 StartLoc, LParenLoc, EndLoc);
19763 }
19764
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19765 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
19766 SourceLocation StartLoc,
19767 SourceLocation LParenLoc,
19768 SourceLocation EndLoc) {
19769 Expr *ValExpr = NumTasks;
19770 Stmt *HelperValStmt = nullptr;
19771 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19772
19773 // OpenMP [2.9.2, taskloop Constrcut]
19774 // The parameter of the num_tasks clause must be a positive integer
19775 // expression.
19776 if (!isNonNegativeIntegerValue(
19777 ValExpr, *this, OMPC_num_tasks,
19778 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
19779 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19780 return nullptr;
19781
19782 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
19783 StartLoc, LParenLoc, EndLoc);
19784 }
19785
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19786 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
19787 SourceLocation LParenLoc,
19788 SourceLocation EndLoc) {
19789 // OpenMP [2.13.2, critical construct, Description]
19790 // ... where hint-expression is an integer constant expression that evaluates
19791 // to a valid lock hint.
19792 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
19793 if (HintExpr.isInvalid())
19794 return nullptr;
19795 return new (Context)
19796 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
19797 }
19798
19799 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)19800 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
19801 DSAStackTy *Stack) {
19802 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
19803 if (!OMPEventHandleT.isNull())
19804 return true;
19805 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
19806 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
19807 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19808 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
19809 return false;
19810 }
19811 Stack->setOMPEventHandleT(PT.get());
19812 return true;
19813 }
19814
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19815 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
19816 SourceLocation LParenLoc,
19817 SourceLocation EndLoc) {
19818 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
19819 !Evt->isInstantiationDependent() &&
19820 !Evt->containsUnexpandedParameterPack()) {
19821 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
19822 return nullptr;
19823 // OpenMP 5.0, 2.10.1 task Construct.
19824 // event-handle is a variable of the omp_event_handle_t type.
19825 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
19826 if (!Ref) {
19827 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19828 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
19829 return nullptr;
19830 }
19831 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
19832 if (!VD) {
19833 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19834 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
19835 return nullptr;
19836 }
19837 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
19838 VD->getType()) ||
19839 VD->getType().isConstant(Context)) {
19840 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19841 << "omp_event_handle_t" << 1 << VD->getType()
19842 << Evt->getSourceRange();
19843 return nullptr;
19844 }
19845 // OpenMP 5.0, 2.10.1 task Construct
19846 // [detach clause]... The event-handle will be considered as if it was
19847 // specified on a firstprivate clause.
19848 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
19849 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
19850 DVar.RefExpr) {
19851 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
19852 << getOpenMPClauseName(DVar.CKind)
19853 << getOpenMPClauseName(OMPC_firstprivate);
19854 reportOriginalDsa(*this, DSAStack, VD, DVar);
19855 return nullptr;
19856 }
19857 }
19858
19859 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
19860 }
19861
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)19862 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
19863 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
19864 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
19865 SourceLocation EndLoc) {
19866 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
19867 std::string Values;
19868 Values += "'";
19869 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
19870 Values += "'";
19871 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19872 << Values << getOpenMPClauseName(OMPC_dist_schedule);
19873 return nullptr;
19874 }
19875 Expr *ValExpr = ChunkSize;
19876 Stmt *HelperValStmt = nullptr;
19877 if (ChunkSize) {
19878 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
19879 !ChunkSize->isInstantiationDependent() &&
19880 !ChunkSize->containsUnexpandedParameterPack()) {
19881 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
19882 ExprResult Val =
19883 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
19884 if (Val.isInvalid())
19885 return nullptr;
19886
19887 ValExpr = Val.get();
19888
19889 // OpenMP [2.7.1, Restrictions]
19890 // chunk_size must be a loop invariant integer expression with a positive
19891 // value.
19892 if (Optional<llvm::APSInt> Result =
19893 ValExpr->getIntegerConstantExpr(Context)) {
19894 if (Result->isSigned() && !Result->isStrictlyPositive()) {
19895 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
19896 << "dist_schedule" << ChunkSize->getSourceRange();
19897 return nullptr;
19898 }
19899 } else if (getOpenMPCaptureRegionForClause(
19900 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
19901 LangOpts.OpenMP) != OMPD_unknown &&
19902 !CurContext->isDependentContext()) {
19903 ValExpr = MakeFullExpr(ValExpr).get();
19904 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19905 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19906 HelperValStmt = buildPreInits(Context, Captures);
19907 }
19908 }
19909 }
19910
19911 return new (Context)
19912 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
19913 Kind, ValExpr, HelperValStmt);
19914 }
19915
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)19916 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
19917 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
19918 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
19919 SourceLocation KindLoc, SourceLocation EndLoc) {
19920 if (getLangOpts().OpenMP < 50) {
19921 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
19922 Kind != OMPC_DEFAULTMAP_scalar) {
19923 std::string Value;
19924 SourceLocation Loc;
19925 Value += "'";
19926 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
19927 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19928 OMPC_DEFAULTMAP_MODIFIER_tofrom);
19929 Loc = MLoc;
19930 } else {
19931 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19932 OMPC_DEFAULTMAP_scalar);
19933 Loc = KindLoc;
19934 }
19935 Value += "'";
19936 Diag(Loc, diag::err_omp_unexpected_clause_value)
19937 << Value << getOpenMPClauseName(OMPC_defaultmap);
19938 return nullptr;
19939 }
19940 } else {
19941 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
19942 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
19943 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
19944 if (!isDefaultmapKind || !isDefaultmapModifier) {
19945 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
19946 if (LangOpts.OpenMP == 50) {
19947 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
19948 "'firstprivate', 'none', 'default'";
19949 if (!isDefaultmapKind && isDefaultmapModifier) {
19950 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19951 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19952 } else if (isDefaultmapKind && !isDefaultmapModifier) {
19953 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19954 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19955 } else {
19956 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19957 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19958 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19959 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19960 }
19961 } else {
19962 StringRef ModifierValue =
19963 "'alloc', 'from', 'to', 'tofrom', "
19964 "'firstprivate', 'none', 'default', 'present'";
19965 if (!isDefaultmapKind && isDefaultmapModifier) {
19966 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19967 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19968 } else if (isDefaultmapKind && !isDefaultmapModifier) {
19969 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19970 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19971 } else {
19972 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19973 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19974 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19975 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19976 }
19977 }
19978 return nullptr;
19979 }
19980
19981 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
19982 // At most one defaultmap clause for each category can appear on the
19983 // directive.
19984 if (DSAStack->checkDefaultmapCategory(Kind)) {
19985 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
19986 return nullptr;
19987 }
19988 }
19989 if (Kind == OMPC_DEFAULTMAP_unknown) {
19990 // Variable category is not specified - mark all categories.
19991 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
19992 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
19993 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
19994 } else {
19995 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
19996 }
19997
19998 return new (Context)
19999 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
20000 }
20001
ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20002 bool Sema::ActOnStartOpenMPDeclareTargetContext(
20003 DeclareTargetContextInfo &DTCI) {
20004 DeclContext *CurLexicalContext = getCurLexicalContext();
20005 if (!CurLexicalContext->isFileContext() &&
20006 !CurLexicalContext->isExternCContext() &&
20007 !CurLexicalContext->isExternCXXContext() &&
20008 !isa<CXXRecordDecl>(CurLexicalContext) &&
20009 !isa<ClassTemplateDecl>(CurLexicalContext) &&
20010 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
20011 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
20012 Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
20013 return false;
20014 }
20015 DeclareTargetNesting.push_back(DTCI);
20016 return true;
20017 }
20018
20019 const Sema::DeclareTargetContextInfo
ActOnOpenMPEndDeclareTargetDirective()20020 Sema::ActOnOpenMPEndDeclareTargetDirective() {
20021 assert(!DeclareTargetNesting.empty() &&
20022 "check isInOpenMPDeclareTargetContext() first!");
20023 return DeclareTargetNesting.pop_back_val();
20024 }
20025
ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20026 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
20027 DeclareTargetContextInfo &DTCI) {
20028 for (auto &It : DTCI.ExplicitlyMapped)
20029 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT,
20030 DTCI.DT);
20031 }
20032
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)20033 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
20034 CXXScopeSpec &ScopeSpec,
20035 const DeclarationNameInfo &Id) {
20036 LookupResult Lookup(*this, Id, LookupOrdinaryName);
20037 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
20038
20039 if (Lookup.isAmbiguous())
20040 return nullptr;
20041 Lookup.suppressDiagnostics();
20042
20043 if (!Lookup.isSingleResult()) {
20044 VarOrFuncDeclFilterCCC CCC(*this);
20045 if (TypoCorrection Corrected =
20046 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
20047 CTK_ErrorRecovery)) {
20048 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
20049 << Id.getName());
20050 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
20051 return nullptr;
20052 }
20053
20054 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
20055 return nullptr;
20056 }
20057
20058 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
20059 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
20060 !isa<FunctionTemplateDecl>(ND)) {
20061 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
20062 return nullptr;
20063 }
20064 return ND;
20065 }
20066
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,OMPDeclareTargetDeclAttr::DevTypeTy DT)20067 void Sema::ActOnOpenMPDeclareTargetName(
20068 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
20069 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
20070 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
20071 isa<FunctionTemplateDecl>(ND)) &&
20072 "Expected variable, function or function template.");
20073
20074 // Diagnose marking after use as it may lead to incorrect diagnosis and
20075 // codegen.
20076 if (LangOpts.OpenMP >= 50 &&
20077 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
20078 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
20079
20080 // Explicit declare target lists have precedence.
20081 const unsigned Level = -1;
20082
20083 auto *VD = cast<ValueDecl>(ND);
20084 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20085 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20086 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DT &&
20087 ActiveAttr.getValue()->getLevel() == Level) {
20088 Diag(Loc, diag::err_omp_device_type_mismatch)
20089 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
20090 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
20091 ActiveAttr.getValue()->getDevType());
20092 return;
20093 }
20094 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
20095 ActiveAttr.getValue()->getLevel() == Level) {
20096 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
20097 return;
20098 }
20099
20100 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
20101 return;
20102
20103 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, Level,
20104 SourceRange(Loc, Loc));
20105 ND->addAttr(A);
20106 if (ASTMutationListener *ML = Context.getASTMutationListener())
20107 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
20108 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
20109 }
20110
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)20111 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
20112 Sema &SemaRef, Decl *D) {
20113 if (!D || !isa<VarDecl>(D))
20114 return;
20115 auto *VD = cast<VarDecl>(D);
20116 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
20117 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
20118 if (SemaRef.LangOpts.OpenMP >= 50 &&
20119 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
20120 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
20121 VD->hasGlobalStorage()) {
20122 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
20123 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
20124 // If a lambda declaration and definition appears between a
20125 // declare target directive and the matching end declare target
20126 // directive, all variables that are captured by the lambda
20127 // expression must also appear in a to clause.
20128 SemaRef.Diag(VD->getLocation(),
20129 diag::err_omp_lambda_capture_in_declare_target_not_to);
20130 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
20131 << VD << 0 << SR;
20132 return;
20133 }
20134 }
20135 if (MapTy.hasValue())
20136 return;
20137 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
20138 SemaRef.Diag(SL, diag::note_used_here) << SR;
20139 }
20140
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)20141 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
20142 Sema &SemaRef, DSAStackTy *Stack,
20143 ValueDecl *VD) {
20144 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
20145 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
20146 /*FullCheck=*/false);
20147 }
20148
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)20149 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
20150 SourceLocation IdLoc) {
20151 if (!D || D->isInvalidDecl())
20152 return;
20153 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
20154 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
20155 if (auto *VD = dyn_cast<VarDecl>(D)) {
20156 // Only global variables can be marked as declare target.
20157 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
20158 !VD->isStaticDataMember())
20159 return;
20160 // 2.10.6: threadprivate variable cannot appear in a declare target
20161 // directive.
20162 if (DSAStack->isThreadPrivate(VD)) {
20163 Diag(SL, diag::err_omp_threadprivate_in_target);
20164 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
20165 return;
20166 }
20167 }
20168 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
20169 D = FTD->getTemplatedDecl();
20170 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
20171 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
20172 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
20173 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
20174 Diag(IdLoc, diag::err_omp_function_in_link_clause);
20175 Diag(FD->getLocation(), diag::note_defined_here) << FD;
20176 return;
20177 }
20178 }
20179 if (auto *VD = dyn_cast<ValueDecl>(D)) {
20180 // Problem if any with var declared with incomplete type will be reported
20181 // as normal, so no need to check it here.
20182 if ((E || !VD->getType()->isIncompleteType()) &&
20183 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
20184 return;
20185 if (!E && isInOpenMPDeclareTargetContext()) {
20186 // Checking declaration inside declare target region.
20187 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
20188 isa<FunctionTemplateDecl>(D)) {
20189 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20190 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20191 unsigned Level = DeclareTargetNesting.size();
20192 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
20193 return;
20194 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
20195 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
20196 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, Level,
20197 SourceRange(DTCI.Loc, DTCI.Loc));
20198 D->addAttr(A);
20199 if (ASTMutationListener *ML = Context.getASTMutationListener())
20200 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
20201 }
20202 return;
20203 }
20204 }
20205 if (!E)
20206 return;
20207 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
20208 }
20209
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20210 OMPClause *Sema::ActOnOpenMPToClause(
20211 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20212 ArrayRef<SourceLocation> MotionModifiersLoc,
20213 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20214 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20215 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20216 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20217 OMPC_MOTION_MODIFIER_unknown};
20218 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20219
20220 // Process motion-modifiers, flag errors for duplicate modifiers.
20221 unsigned Count = 0;
20222 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20223 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20224 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20225 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20226 continue;
20227 }
20228 assert(Count < NumberOfOMPMotionModifiers &&
20229 "Modifiers exceed the allowed number of motion modifiers");
20230 Modifiers[Count] = MotionModifiers[I];
20231 ModifiersLoc[Count] = MotionModifiersLoc[I];
20232 ++Count;
20233 }
20234
20235 MappableVarListInfo MVLI(VarList);
20236 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
20237 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20238 if (MVLI.ProcessedVarList.empty())
20239 return nullptr;
20240
20241 return OMPToClause::Create(
20242 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20243 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20244 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20245 }
20246
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20247 OMPClause *Sema::ActOnOpenMPFromClause(
20248 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20249 ArrayRef<SourceLocation> MotionModifiersLoc,
20250 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20251 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20252 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20253 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20254 OMPC_MOTION_MODIFIER_unknown};
20255 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20256
20257 // Process motion-modifiers, flag errors for duplicate modifiers.
20258 unsigned Count = 0;
20259 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20260 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20261 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20262 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20263 continue;
20264 }
20265 assert(Count < NumberOfOMPMotionModifiers &&
20266 "Modifiers exceed the allowed number of motion modifiers");
20267 Modifiers[Count] = MotionModifiers[I];
20268 ModifiersLoc[Count] = MotionModifiersLoc[I];
20269 ++Count;
20270 }
20271
20272 MappableVarListInfo MVLI(VarList);
20273 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
20274 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20275 if (MVLI.ProcessedVarList.empty())
20276 return nullptr;
20277
20278 return OMPFromClause::Create(
20279 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20280 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20281 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20282 }
20283
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20284 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
20285 const OMPVarListLocTy &Locs) {
20286 MappableVarListInfo MVLI(VarList);
20287 SmallVector<Expr *, 8> PrivateCopies;
20288 SmallVector<Expr *, 8> Inits;
20289
20290 for (Expr *RefExpr : VarList) {
20291 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
20292 SourceLocation ELoc;
20293 SourceRange ERange;
20294 Expr *SimpleRefExpr = RefExpr;
20295 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20296 if (Res.second) {
20297 // It will be analyzed later.
20298 MVLI.ProcessedVarList.push_back(RefExpr);
20299 PrivateCopies.push_back(nullptr);
20300 Inits.push_back(nullptr);
20301 }
20302 ValueDecl *D = Res.first;
20303 if (!D)
20304 continue;
20305
20306 QualType Type = D->getType();
20307 Type = Type.getNonReferenceType().getUnqualifiedType();
20308
20309 auto *VD = dyn_cast<VarDecl>(D);
20310
20311 // Item should be a pointer or reference to pointer.
20312 if (!Type->isPointerType()) {
20313 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
20314 << 0 << RefExpr->getSourceRange();
20315 continue;
20316 }
20317
20318 // Build the private variable and the expression that refers to it.
20319 auto VDPrivate =
20320 buildVarDecl(*this, ELoc, Type, D->getName(),
20321 D->hasAttrs() ? &D->getAttrs() : nullptr,
20322 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20323 if (VDPrivate->isInvalidDecl())
20324 continue;
20325
20326 CurContext->addDecl(VDPrivate);
20327 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
20328 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
20329
20330 // Add temporary variable to initialize the private copy of the pointer.
20331 VarDecl *VDInit =
20332 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
20333 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
20334 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
20335 AddInitializerToDecl(VDPrivate,
20336 DefaultLvalueConversion(VDInitRefExpr).get(),
20337 /*DirectInit=*/false);
20338
20339 // If required, build a capture to implement the privatization initialized
20340 // with the current list item value.
20341 DeclRefExpr *Ref = nullptr;
20342 if (!VD)
20343 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20344 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20345 PrivateCopies.push_back(VDPrivateRefExpr);
20346 Inits.push_back(VDInitRefExpr);
20347
20348 // We need to add a data sharing attribute for this variable to make sure it
20349 // is correctly captured. A variable that shows up in a use_device_ptr has
20350 // similar properties of a first private variable.
20351 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20352
20353 // Create a mappable component for the list item. List items in this clause
20354 // only need a component.
20355 MVLI.VarBaseDeclarations.push_back(D);
20356 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20357 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
20358 /*IsNonContiguous=*/false);
20359 }
20360
20361 if (MVLI.ProcessedVarList.empty())
20362 return nullptr;
20363
20364 return OMPUseDevicePtrClause::Create(
20365 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
20366 MVLI.VarBaseDeclarations, MVLI.VarComponents);
20367 }
20368
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20369 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
20370 const OMPVarListLocTy &Locs) {
20371 MappableVarListInfo MVLI(VarList);
20372
20373 for (Expr *RefExpr : VarList) {
20374 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
20375 SourceLocation ELoc;
20376 SourceRange ERange;
20377 Expr *SimpleRefExpr = RefExpr;
20378 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20379 /*AllowArraySection=*/true);
20380 if (Res.second) {
20381 // It will be analyzed later.
20382 MVLI.ProcessedVarList.push_back(RefExpr);
20383 }
20384 ValueDecl *D = Res.first;
20385 if (!D)
20386 continue;
20387 auto *VD = dyn_cast<VarDecl>(D);
20388
20389 // If required, build a capture to implement the privatization initialized
20390 // with the current list item value.
20391 DeclRefExpr *Ref = nullptr;
20392 if (!VD)
20393 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20394 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20395
20396 // We need to add a data sharing attribute for this variable to make sure it
20397 // is correctly captured. A variable that shows up in a use_device_addr has
20398 // similar properties of a first private variable.
20399 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20400
20401 // Create a mappable component for the list item. List items in this clause
20402 // only need a component.
20403 MVLI.VarBaseDeclarations.push_back(D);
20404 MVLI.VarComponents.emplace_back();
20405 Expr *Component = SimpleRefExpr;
20406 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
20407 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
20408 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
20409 MVLI.VarComponents.back().emplace_back(Component, D,
20410 /*IsNonContiguous=*/false);
20411 }
20412
20413 if (MVLI.ProcessedVarList.empty())
20414 return nullptr;
20415
20416 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20417 MVLI.VarBaseDeclarations,
20418 MVLI.VarComponents);
20419 }
20420
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20421 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
20422 const OMPVarListLocTy &Locs) {
20423 MappableVarListInfo MVLI(VarList);
20424 for (Expr *RefExpr : VarList) {
20425 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
20426 SourceLocation ELoc;
20427 SourceRange ERange;
20428 Expr *SimpleRefExpr = RefExpr;
20429 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20430 if (Res.second) {
20431 // It will be analyzed later.
20432 MVLI.ProcessedVarList.push_back(RefExpr);
20433 }
20434 ValueDecl *D = Res.first;
20435 if (!D)
20436 continue;
20437
20438 QualType Type = D->getType();
20439 // item should be a pointer or array or reference to pointer or array
20440 if (!Type.getNonReferenceType()->isPointerType() &&
20441 !Type.getNonReferenceType()->isArrayType()) {
20442 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
20443 << 0 << RefExpr->getSourceRange();
20444 continue;
20445 }
20446
20447 // Check if the declaration in the clause does not show up in any data
20448 // sharing attribute.
20449 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20450 if (isOpenMPPrivate(DVar.CKind)) {
20451 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20452 << getOpenMPClauseName(DVar.CKind)
20453 << getOpenMPClauseName(OMPC_is_device_ptr)
20454 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20455 reportOriginalDsa(*this, DSAStack, D, DVar);
20456 continue;
20457 }
20458
20459 const Expr *ConflictExpr;
20460 if (DSAStack->checkMappableExprComponentListsForDecl(
20461 D, /*CurrentRegionOnly=*/true,
20462 [&ConflictExpr](
20463 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
20464 OpenMPClauseKind) -> bool {
20465 ConflictExpr = R.front().getAssociatedExpression();
20466 return true;
20467 })) {
20468 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
20469 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
20470 << ConflictExpr->getSourceRange();
20471 continue;
20472 }
20473
20474 // Store the components in the stack so that they can be used to check
20475 // against other clauses later on.
20476 OMPClauseMappableExprCommon::MappableComponent MC(
20477 SimpleRefExpr, D, /*IsNonContiguous=*/false);
20478 DSAStack->addMappableExpressionComponents(
20479 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
20480
20481 // Record the expression we've just processed.
20482 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
20483
20484 // Create a mappable component for the list item. List items in this clause
20485 // only need a component. We use a null declaration to signal fields in
20486 // 'this'.
20487 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
20488 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
20489 "Unexpected device pointer expression!");
20490 MVLI.VarBaseDeclarations.push_back(
20491 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
20492 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20493 MVLI.VarComponents.back().push_back(MC);
20494 }
20495
20496 if (MVLI.ProcessedVarList.empty())
20497 return nullptr;
20498
20499 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20500 MVLI.VarBaseDeclarations,
20501 MVLI.VarComponents);
20502 }
20503
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20504 OMPClause *Sema::ActOnOpenMPAllocateClause(
20505 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
20506 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
20507 if (Allocator) {
20508 // OpenMP [2.11.4 allocate Clause, Description]
20509 // allocator is an expression of omp_allocator_handle_t type.
20510 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
20511 return nullptr;
20512
20513 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
20514 if (AllocatorRes.isInvalid())
20515 return nullptr;
20516 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
20517 DSAStack->getOMPAllocatorHandleT(),
20518 Sema::AA_Initializing,
20519 /*AllowExplicit=*/true);
20520 if (AllocatorRes.isInvalid())
20521 return nullptr;
20522 Allocator = AllocatorRes.get();
20523 } else {
20524 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
20525 // allocate clauses that appear on a target construct or on constructs in a
20526 // target region must specify an allocator expression unless a requires
20527 // directive with the dynamic_allocators clause is present in the same
20528 // compilation unit.
20529 if (LangOpts.OpenMPIsDevice &&
20530 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
20531 targetDiag(StartLoc, diag::err_expected_allocator_expression);
20532 }
20533 // Analyze and build list of variables.
20534 SmallVector<Expr *, 8> Vars;
20535 for (Expr *RefExpr : VarList) {
20536 assert(RefExpr && "NULL expr in OpenMP private clause.");
20537 SourceLocation ELoc;
20538 SourceRange ERange;
20539 Expr *SimpleRefExpr = RefExpr;
20540 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20541 if (Res.second) {
20542 // It will be analyzed later.
20543 Vars.push_back(RefExpr);
20544 }
20545 ValueDecl *D = Res.first;
20546 if (!D)
20547 continue;
20548
20549 auto *VD = dyn_cast<VarDecl>(D);
20550 DeclRefExpr *Ref = nullptr;
20551 if (!VD && !CurContext->isDependentContext())
20552 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20553 Vars.push_back((VD || CurContext->isDependentContext())
20554 ? RefExpr->IgnoreParens()
20555 : Ref);
20556 }
20557
20558 if (Vars.empty())
20559 return nullptr;
20560
20561 if (Allocator)
20562 DSAStack->addInnerAllocatorExpr(Allocator);
20563 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
20564 ColonLoc, EndLoc, Vars);
20565 }
20566
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20567 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
20568 SourceLocation StartLoc,
20569 SourceLocation LParenLoc,
20570 SourceLocation EndLoc) {
20571 SmallVector<Expr *, 8> Vars;
20572 for (Expr *RefExpr : VarList) {
20573 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
20574 SourceLocation ELoc;
20575 SourceRange ERange;
20576 Expr *SimpleRefExpr = RefExpr;
20577 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20578 if (Res.second)
20579 // It will be analyzed later.
20580 Vars.push_back(RefExpr);
20581 ValueDecl *D = Res.first;
20582 if (!D)
20583 continue;
20584
20585 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
20586 // A list-item cannot appear in more than one nontemporal clause.
20587 if (const Expr *PrevRef =
20588 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
20589 Diag(ELoc, diag::err_omp_used_in_clause_twice)
20590 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
20591 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20592 << getOpenMPClauseName(OMPC_nontemporal);
20593 continue;
20594 }
20595
20596 Vars.push_back(RefExpr);
20597 }
20598
20599 if (Vars.empty())
20600 return nullptr;
20601
20602 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20603 Vars);
20604 }
20605
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20606 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
20607 SourceLocation StartLoc,
20608 SourceLocation LParenLoc,
20609 SourceLocation EndLoc) {
20610 SmallVector<Expr *, 8> Vars;
20611 for (Expr *RefExpr : VarList) {
20612 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
20613 SourceLocation ELoc;
20614 SourceRange ERange;
20615 Expr *SimpleRefExpr = RefExpr;
20616 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20617 /*AllowArraySection=*/true);
20618 if (Res.second)
20619 // It will be analyzed later.
20620 Vars.push_back(RefExpr);
20621 ValueDecl *D = Res.first;
20622 if (!D)
20623 continue;
20624
20625 const DSAStackTy::DSAVarData DVar =
20626 DSAStack->getTopDSA(D, /*FromParent=*/true);
20627 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
20628 // A list item that appears in the inclusive or exclusive clause must appear
20629 // in a reduction clause with the inscan modifier on the enclosing
20630 // worksharing-loop, worksharing-loop SIMD, or simd construct.
20631 if (DVar.CKind != OMPC_reduction ||
20632 DVar.Modifier != OMPC_REDUCTION_inscan)
20633 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
20634 << RefExpr->getSourceRange();
20635
20636 if (DSAStack->getParentDirective() != OMPD_unknown)
20637 DSAStack->markDeclAsUsedInScanDirective(D);
20638 Vars.push_back(RefExpr);
20639 }
20640
20641 if (Vars.empty())
20642 return nullptr;
20643
20644 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
20645 }
20646
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20647 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
20648 SourceLocation StartLoc,
20649 SourceLocation LParenLoc,
20650 SourceLocation EndLoc) {
20651 SmallVector<Expr *, 8> Vars;
20652 for (Expr *RefExpr : VarList) {
20653 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
20654 SourceLocation ELoc;
20655 SourceRange ERange;
20656 Expr *SimpleRefExpr = RefExpr;
20657 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20658 /*AllowArraySection=*/true);
20659 if (Res.second)
20660 // It will be analyzed later.
20661 Vars.push_back(RefExpr);
20662 ValueDecl *D = Res.first;
20663 if (!D)
20664 continue;
20665
20666 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
20667 DSAStackTy::DSAVarData DVar;
20668 if (ParentDirective != OMPD_unknown)
20669 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
20670 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
20671 // A list item that appears in the inclusive or exclusive clause must appear
20672 // in a reduction clause with the inscan modifier on the enclosing
20673 // worksharing-loop, worksharing-loop SIMD, or simd construct.
20674 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
20675 DVar.Modifier != OMPC_REDUCTION_inscan) {
20676 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
20677 << RefExpr->getSourceRange();
20678 } else {
20679 DSAStack->markDeclAsUsedInScanDirective(D);
20680 }
20681 Vars.push_back(RefExpr);
20682 }
20683
20684 if (Vars.empty())
20685 return nullptr;
20686
20687 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
20688 }
20689
20690 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)20691 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
20692 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
20693 if (!OMPAlloctraitT.isNull())
20694 return true;
20695 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
20696 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
20697 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20698 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
20699 return false;
20700 }
20701 Stack->setOMPAlloctraitT(PT.get());
20702 return true;
20703 }
20704
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)20705 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
20706 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
20707 ArrayRef<UsesAllocatorsData> Data) {
20708 // OpenMP [2.12.5, target Construct]
20709 // allocator is an identifier of omp_allocator_handle_t type.
20710 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
20711 return nullptr;
20712 // OpenMP [2.12.5, target Construct]
20713 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
20714 if (llvm::any_of(
20715 Data,
20716 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
20717 !findOMPAlloctraitT(*this, StartLoc, DSAStack))
20718 return nullptr;
20719 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
20720 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
20721 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
20722 StringRef Allocator =
20723 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
20724 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
20725 PredefinedAllocators.insert(LookupSingleName(
20726 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
20727 }
20728
20729 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
20730 for (const UsesAllocatorsData &D : Data) {
20731 Expr *AllocatorExpr = nullptr;
20732 // Check allocator expression.
20733 if (D.Allocator->isTypeDependent()) {
20734 AllocatorExpr = D.Allocator;
20735 } else {
20736 // Traits were specified - need to assign new allocator to the specified
20737 // allocator, so it must be an lvalue.
20738 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
20739 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
20740 bool IsPredefinedAllocator = false;
20741 if (DRE)
20742 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
20743 if (!DRE ||
20744 !(Context.hasSameUnqualifiedType(
20745 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
20746 Context.typesAreCompatible(AllocatorExpr->getType(),
20747 DSAStack->getOMPAllocatorHandleT(),
20748 /*CompareUnqualified=*/true)) ||
20749 (!IsPredefinedAllocator &&
20750 (AllocatorExpr->getType().isConstant(Context) ||
20751 !AllocatorExpr->isLValue()))) {
20752 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
20753 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
20754 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
20755 continue;
20756 }
20757 // OpenMP [2.12.5, target Construct]
20758 // Predefined allocators appearing in a uses_allocators clause cannot have
20759 // traits specified.
20760 if (IsPredefinedAllocator && D.AllocatorTraits) {
20761 Diag(D.AllocatorTraits->getExprLoc(),
20762 diag::err_omp_predefined_allocator_with_traits)
20763 << D.AllocatorTraits->getSourceRange();
20764 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
20765 << cast<NamedDecl>(DRE->getDecl())->getName()
20766 << D.Allocator->getSourceRange();
20767 continue;
20768 }
20769 // OpenMP [2.12.5, target Construct]
20770 // Non-predefined allocators appearing in a uses_allocators clause must
20771 // have traits specified.
20772 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
20773 Diag(D.Allocator->getExprLoc(),
20774 diag::err_omp_nonpredefined_allocator_without_traits);
20775 continue;
20776 }
20777 // No allocator traits - just convert it to rvalue.
20778 if (!D.AllocatorTraits)
20779 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
20780 DSAStack->addUsesAllocatorsDecl(
20781 DRE->getDecl(),
20782 IsPredefinedAllocator
20783 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
20784 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
20785 }
20786 Expr *AllocatorTraitsExpr = nullptr;
20787 if (D.AllocatorTraits) {
20788 if (D.AllocatorTraits->isTypeDependent()) {
20789 AllocatorTraitsExpr = D.AllocatorTraits;
20790 } else {
20791 // OpenMP [2.12.5, target Construct]
20792 // Arrays that contain allocator traits that appear in a uses_allocators
20793 // clause must be constant arrays, have constant values and be defined
20794 // in the same scope as the construct in which the clause appears.
20795 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
20796 // Check that traits expr is a constant array.
20797 QualType TraitTy;
20798 if (const ArrayType *Ty =
20799 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
20800 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
20801 TraitTy = ConstArrayTy->getElementType();
20802 if (TraitTy.isNull() ||
20803 !(Context.hasSameUnqualifiedType(TraitTy,
20804 DSAStack->getOMPAlloctraitT()) ||
20805 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
20806 /*CompareUnqualified=*/true))) {
20807 Diag(D.AllocatorTraits->getExprLoc(),
20808 diag::err_omp_expected_array_alloctraits)
20809 << AllocatorTraitsExpr->getType();
20810 continue;
20811 }
20812 // Do not map by default allocator traits if it is a standalone
20813 // variable.
20814 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
20815 DSAStack->addUsesAllocatorsDecl(
20816 DRE->getDecl(),
20817 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
20818 }
20819 }
20820 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
20821 NewD.Allocator = AllocatorExpr;
20822 NewD.AllocatorTraits = AllocatorTraitsExpr;
20823 NewD.LParenLoc = D.LParenLoc;
20824 NewD.RParenLoc = D.RParenLoc;
20825 }
20826 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20827 NewData);
20828 }
20829
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)20830 OMPClause *Sema::ActOnOpenMPAffinityClause(
20831 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
20832 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
20833 SmallVector<Expr *, 8> Vars;
20834 for (Expr *RefExpr : Locators) {
20835 assert(RefExpr && "NULL expr in OpenMP shared clause.");
20836 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
20837 // It will be analyzed later.
20838 Vars.push_back(RefExpr);
20839 continue;
20840 }
20841
20842 SourceLocation ELoc = RefExpr->getExprLoc();
20843 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
20844
20845 if (!SimpleExpr->isLValue()) {
20846 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20847 << 1 << 0 << RefExpr->getSourceRange();
20848 continue;
20849 }
20850
20851 ExprResult Res;
20852 {
20853 Sema::TentativeAnalysisScope Trap(*this);
20854 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
20855 }
20856 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20857 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20858 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20859 << 1 << 0 << RefExpr->getSourceRange();
20860 continue;
20861 }
20862 Vars.push_back(SimpleExpr);
20863 }
20864
20865 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20866 EndLoc, Modifier, Vars);
20867 }
20868