File: | clang/lib/Sema/SemaOpenMP.cpp |
Warning: | line 4273, column 5 Value stored to 'ErrorFound' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// \file |
9 | /// This file implements semantic analysis for OpenMP directives and |
10 | /// clauses. |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "TreeTransform.h" |
15 | #include "clang/AST/ASTContext.h" |
16 | #include "clang/AST/ASTMutationListener.h" |
17 | #include "clang/AST/CXXInheritance.h" |
18 | #include "clang/AST/Decl.h" |
19 | #include "clang/AST/DeclCXX.h" |
20 | #include "clang/AST/DeclOpenMP.h" |
21 | #include "clang/AST/OpenMPClause.h" |
22 | #include "clang/AST/StmtCXX.h" |
23 | #include "clang/AST/StmtOpenMP.h" |
24 | #include "clang/AST/StmtVisitor.h" |
25 | #include "clang/AST/TypeOrdering.h" |
26 | #include "clang/Basic/DiagnosticSema.h" |
27 | #include "clang/Basic/OpenMPKinds.h" |
28 | #include "clang/Basic/PartialDiagnostic.h" |
29 | #include "clang/Basic/TargetInfo.h" |
30 | #include "clang/Sema/Initialization.h" |
31 | #include "clang/Sema/Lookup.h" |
32 | #include "clang/Sema/Scope.h" |
33 | #include "clang/Sema/ScopeInfo.h" |
34 | #include "clang/Sema/SemaInternal.h" |
35 | #include "llvm/ADT/IndexedMap.h" |
36 | #include "llvm/ADT/PointerEmbeddedInt.h" |
37 | #include "llvm/ADT/STLExtras.h" |
38 | #include "llvm/Frontend/OpenMP/OMPConstants.h" |
39 | #include <set> |
40 | |
41 | using namespace clang; |
42 | using namespace llvm::omp; |
43 | |
44 | //===----------------------------------------------------------------------===// |
45 | // Stack of data-sharing attributes for variables |
46 | //===----------------------------------------------------------------------===// |
47 | |
48 | static const Expr *checkMapClauseExpressionBase( |
49 | Sema &SemaRef, Expr *E, |
50 | OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, |
51 | OpenMPClauseKind CKind, bool NoDiagnose); |
52 | |
53 | namespace { |
54 | /// Default data sharing attributes, which can be applied to directive. |
55 | enum DefaultDataSharingAttributes { |
56 | DSA_unspecified = 0, /// Data sharing attribute not specified. |
57 | DSA_none = 1 << 0, /// Default data sharing attribute 'none'. |
58 | DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. |
59 | DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. |
60 | }; |
61 | |
62 | /// Stack for tracking declarations used in OpenMP directives and |
63 | /// clauses and their data-sharing attributes. |
64 | class DSAStackTy { |
65 | public: |
66 | struct DSAVarData { |
67 | OpenMPDirectiveKind DKind = OMPD_unknown; |
68 | OpenMPClauseKind CKind = OMPC_unknown; |
69 | unsigned Modifier = 0; |
70 | const Expr *RefExpr = nullptr; |
71 | DeclRefExpr *PrivateCopy = nullptr; |
72 | SourceLocation ImplicitDSALoc; |
73 | DSAVarData() = default; |
74 | DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, |
75 | const Expr *RefExpr, DeclRefExpr *PrivateCopy, |
76 | SourceLocation ImplicitDSALoc, unsigned Modifier) |
77 | : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), |
78 | PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} |
79 | }; |
80 | using OperatorOffsetTy = |
81 | llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; |
82 | using DoacrossDependMapTy = |
83 | llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; |
84 | /// Kind of the declaration used in the uses_allocators clauses. |
85 | enum class UsesAllocatorsDeclKind { |
86 | /// Predefined allocator |
87 | PredefinedAllocator, |
88 | /// User-defined allocator |
89 | UserDefinedAllocator, |
90 | /// The declaration that represent allocator trait |
91 | AllocatorTrait, |
92 | }; |
93 | |
94 | private: |
95 | struct DSAInfo { |
96 | OpenMPClauseKind Attributes = OMPC_unknown; |
97 | unsigned Modifier = 0; |
98 | /// Pointer to a reference expression and a flag which shows that the |
99 | /// variable is marked as lastprivate(true) or not (false). |
100 | llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; |
101 | DeclRefExpr *PrivateCopy = nullptr; |
102 | }; |
103 | using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; |
104 | using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; |
105 | using LCDeclInfo = std::pair<unsigned, VarDecl *>; |
106 | using LoopControlVariablesMapTy = |
107 | llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; |
108 | /// Struct that associates a component with the clause kind where they are |
109 | /// found. |
110 | struct MappedExprComponentTy { |
111 | OMPClauseMappableExprCommon::MappableExprComponentLists Components; |
112 | OpenMPClauseKind Kind = OMPC_unknown; |
113 | }; |
114 | using MappedExprComponentsTy = |
115 | llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; |
116 | using CriticalsWithHintsTy = |
117 | llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; |
118 | struct ReductionData { |
119 | using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; |
120 | SourceRange ReductionRange; |
121 | llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; |
122 | ReductionData() = default; |
123 | void set(BinaryOperatorKind BO, SourceRange RR) { |
124 | ReductionRange = RR; |
125 | ReductionOp = BO; |
126 | } |
127 | void set(const Expr *RefExpr, SourceRange RR) { |
128 | ReductionRange = RR; |
129 | ReductionOp = RefExpr; |
130 | } |
131 | }; |
132 | using DeclReductionMapTy = |
133 | llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; |
134 | struct DefaultmapInfo { |
135 | OpenMPDefaultmapClauseModifier ImplicitBehavior = |
136 | OMPC_DEFAULTMAP_MODIFIER_unknown; |
137 | SourceLocation SLoc; |
138 | DefaultmapInfo() = default; |
139 | DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) |
140 | : ImplicitBehavior(M), SLoc(Loc) {} |
141 | }; |
142 | |
143 | struct SharingMapTy { |
144 | DeclSAMapTy SharingMap; |
145 | DeclReductionMapTy ReductionMap; |
146 | UsedRefMapTy AlignedMap; |
147 | UsedRefMapTy NontemporalMap; |
148 | MappedExprComponentsTy MappedExprComponents; |
149 | LoopControlVariablesMapTy LCVMap; |
150 | DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; |
151 | SourceLocation DefaultAttrLoc; |
152 | DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; |
153 | OpenMPDirectiveKind Directive = OMPD_unknown; |
154 | DeclarationNameInfo DirectiveName; |
155 | Scope *CurScope = nullptr; |
156 | SourceLocation ConstructLoc; |
157 | /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to |
158 | /// get the data (loop counters etc.) about enclosing loop-based construct. |
159 | /// This data is required during codegen. |
160 | DoacrossDependMapTy DoacrossDepends; |
161 | /// First argument (Expr *) contains optional argument of the |
162 | /// 'ordered' clause, the second one is true if the regions has 'ordered' |
163 | /// clause, false otherwise. |
164 | llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; |
165 | unsigned AssociatedLoops = 1; |
166 | bool HasMutipleLoops = false; |
167 | const Decl *PossiblyLoopCounter = nullptr; |
168 | bool NowaitRegion = false; |
169 | bool CancelRegion = false; |
170 | bool LoopStart = false; |
171 | bool BodyComplete = false; |
172 | SourceLocation PrevScanLocation; |
173 | SourceLocation PrevOrderedLocation; |
174 | SourceLocation InnerTeamsRegionLoc; |
175 | /// Reference to the taskgroup task_reduction reference expression. |
176 | Expr *TaskgroupReductionRef = nullptr; |
177 | llvm::DenseSet<QualType> MappedClassesQualTypes; |
178 | SmallVector<Expr *, 4> InnerUsedAllocators; |
179 | llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; |
180 | /// List of globals marked as declare target link in this target region |
181 | /// (isOpenMPTargetExecutionDirective(Directive) == true). |
182 | llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; |
183 | /// List of decls used in inclusive/exclusive clauses of the scan directive. |
184 | llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; |
185 | llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> |
186 | UsesAllocatorsDecls; |
187 | SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, |
188 | Scope *CurScope, SourceLocation Loc) |
189 | : Directive(DKind), DirectiveName(Name), CurScope(CurScope), |
190 | ConstructLoc(Loc) {} |
191 | SharingMapTy() = default; |
192 | }; |
193 | |
194 | using StackTy = SmallVector<SharingMapTy, 4>; |
195 | |
196 | /// Stack of used declaration and their data-sharing attributes. |
197 | DeclSAMapTy Threadprivates; |
198 | const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; |
199 | SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; |
200 | /// true, if check for DSA must be from parent directive, false, if |
201 | /// from current directive. |
202 | OpenMPClauseKind ClauseKindMode = OMPC_unknown; |
203 | Sema &SemaRef; |
204 | bool ForceCapturing = false; |
205 | /// true if all the variables in the target executable directives must be |
206 | /// captured by reference. |
207 | bool ForceCaptureByReferenceInTargetExecutable = false; |
208 | CriticalsWithHintsTy Criticals; |
209 | unsigned IgnoredStackElements = 0; |
210 | |
211 | /// Iterators over the stack iterate in order from innermost to outermost |
212 | /// directive. |
213 | using const_iterator = StackTy::const_reverse_iterator; |
214 | const_iterator begin() const { |
215 | return Stack.empty() ? const_iterator() |
216 | : Stack.back().first.rbegin() + IgnoredStackElements; |
217 | } |
218 | const_iterator end() const { |
219 | return Stack.empty() ? const_iterator() : Stack.back().first.rend(); |
220 | } |
221 | using iterator = StackTy::reverse_iterator; |
222 | iterator begin() { |
223 | return Stack.empty() ? iterator() |
224 | : Stack.back().first.rbegin() + IgnoredStackElements; |
225 | } |
226 | iterator end() { |
227 | return Stack.empty() ? iterator() : Stack.back().first.rend(); |
228 | } |
229 | |
230 | // Convenience operations to get at the elements of the stack. |
231 | |
232 | bool isStackEmpty() const { |
233 | return Stack.empty() || |
234 | Stack.back().second != CurrentNonCapturingFunctionScope || |
235 | Stack.back().first.size() <= IgnoredStackElements; |
236 | } |
237 | size_t getStackSize() const { |
238 | return isStackEmpty() ? 0 |
239 | : Stack.back().first.size() - IgnoredStackElements; |
240 | } |
241 | |
242 | SharingMapTy *getTopOfStackOrNull() { |
243 | size_t Size = getStackSize(); |
244 | if (Size == 0) |
245 | return nullptr; |
246 | return &Stack.back().first[Size - 1]; |
247 | } |
248 | const SharingMapTy *getTopOfStackOrNull() const { |
249 | return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); |
250 | } |
251 | SharingMapTy &getTopOfStack() { |
252 | assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast <void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 252, __PRETTY_FUNCTION__)); |
253 | return *getTopOfStackOrNull(); |
254 | } |
255 | const SharingMapTy &getTopOfStack() const { |
256 | return const_cast<DSAStackTy&>(*this).getTopOfStack(); |
257 | } |
258 | |
259 | SharingMapTy *getSecondOnStackOrNull() { |
260 | size_t Size = getStackSize(); |
261 | if (Size <= 1) |
262 | return nullptr; |
263 | return &Stack.back().first[Size - 2]; |
264 | } |
265 | const SharingMapTy *getSecondOnStackOrNull() const { |
266 | return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); |
267 | } |
268 | |
269 | /// Get the stack element at a certain level (previously returned by |
270 | /// \c getNestingLevel). |
271 | /// |
272 | /// Note that nesting levels count from outermost to innermost, and this is |
273 | /// the reverse of our iteration order where new inner levels are pushed at |
274 | /// the front of the stack. |
275 | SharingMapTy &getStackElemAtLevel(unsigned Level) { |
276 | assert(Level < getStackSize() && "no such stack element")((Level < getStackSize() && "no such stack element" ) ? static_cast<void> (0) : __assert_fail ("Level < getStackSize() && \"no such stack element\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 276, __PRETTY_FUNCTION__)); |
277 | return Stack.back().first[Level]; |
278 | } |
279 | const SharingMapTy &getStackElemAtLevel(unsigned Level) const { |
280 | return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); |
281 | } |
282 | |
283 | DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; |
284 | |
285 | /// Checks if the variable is a local for OpenMP region. |
286 | bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; |
287 | |
288 | /// Vector of previously declared requires directives |
289 | SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; |
290 | /// omp_allocator_handle_t type. |
291 | QualType OMPAllocatorHandleT; |
292 | /// omp_depend_t type. |
293 | QualType OMPDependT; |
294 | /// omp_event_handle_t type. |
295 | QualType OMPEventHandleT; |
296 | /// omp_alloctrait_t type. |
297 | QualType OMPAlloctraitT; |
298 | /// Expression for the predefined allocators. |
299 | Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { |
300 | nullptr}; |
301 | /// Vector of previously encountered target directives |
302 | SmallVector<SourceLocation, 2> TargetLocations; |
303 | SourceLocation AtomicLocation; |
304 | |
305 | public: |
306 | explicit DSAStackTy(Sema &S) : SemaRef(S) {} |
307 | |
308 | /// Sets omp_allocator_handle_t type. |
309 | void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } |
310 | /// Gets omp_allocator_handle_t type. |
311 | QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } |
312 | /// Sets omp_alloctrait_t type. |
313 | void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } |
314 | /// Gets omp_alloctrait_t type. |
315 | QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } |
316 | /// Sets the given default allocator. |
317 | void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, |
318 | Expr *Allocator) { |
319 | OMPPredefinedAllocators[AllocatorKind] = Allocator; |
320 | } |
321 | /// Returns the specified default allocator. |
322 | Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { |
323 | return OMPPredefinedAllocators[AllocatorKind]; |
324 | } |
325 | /// Sets omp_depend_t type. |
326 | void setOMPDependT(QualType Ty) { OMPDependT = Ty; } |
327 | /// Gets omp_depend_t type. |
328 | QualType getOMPDependT() const { return OMPDependT; } |
329 | |
330 | /// Sets omp_event_handle_t type. |
331 | void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } |
332 | /// Gets omp_event_handle_t type. |
333 | QualType getOMPEventHandleT() const { return OMPEventHandleT; } |
334 | |
335 | bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } |
336 | OpenMPClauseKind getClauseParsingMode() const { |
337 | assert(isClauseParsingMode() && "Must be in clause parsing mode.")((isClauseParsingMode() && "Must be in clause parsing mode." ) ? static_cast<void> (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 337, __PRETTY_FUNCTION__)); |
338 | return ClauseKindMode; |
339 | } |
340 | void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } |
341 | |
342 | bool isBodyComplete() const { |
343 | const SharingMapTy *Top = getTopOfStackOrNull(); |
344 | return Top && Top->BodyComplete; |
345 | } |
346 | void setBodyComplete() { |
347 | getTopOfStack().BodyComplete = true; |
348 | } |
349 | |
350 | bool isForceVarCapturing() const { return ForceCapturing; } |
351 | void setForceVarCapturing(bool V) { ForceCapturing = V; } |
352 | |
353 | void setForceCaptureByReferenceInTargetExecutable(bool V) { |
354 | ForceCaptureByReferenceInTargetExecutable = V; |
355 | } |
356 | bool isForceCaptureByReferenceInTargetExecutable() const { |
357 | return ForceCaptureByReferenceInTargetExecutable; |
358 | } |
359 | |
360 | void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, |
361 | Scope *CurScope, SourceLocation Loc) { |
362 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 363, __PRETTY_FUNCTION__)) |
363 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 363, __PRETTY_FUNCTION__)); |
364 | if (Stack.empty() || |
365 | Stack.back().second != CurrentNonCapturingFunctionScope) |
366 | Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); |
367 | Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); |
368 | Stack.back().first.back().DefaultAttrLoc = Loc; |
369 | } |
370 | |
371 | void pop() { |
372 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 373, __PRETTY_FUNCTION__)) |
373 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 373, __PRETTY_FUNCTION__)); |
374 | assert(!Stack.back().first.empty() &&((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!" ) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 375, __PRETTY_FUNCTION__)) |
375 | "Data-sharing attributes stack is empty!")((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!" ) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 375, __PRETTY_FUNCTION__)); |
376 | Stack.back().first.pop_back(); |
377 | } |
378 | |
379 | /// RAII object to temporarily leave the scope of a directive when we want to |
380 | /// logically operate in its parent. |
381 | class ParentDirectiveScope { |
382 | DSAStackTy &Self; |
383 | bool Active; |
384 | public: |
385 | ParentDirectiveScope(DSAStackTy &Self, bool Activate) |
386 | : Self(Self), Active(false) { |
387 | if (Activate) |
388 | enable(); |
389 | } |
390 | ~ParentDirectiveScope() { disable(); } |
391 | void disable() { |
392 | if (Active) { |
393 | --Self.IgnoredStackElements; |
394 | Active = false; |
395 | } |
396 | } |
397 | void enable() { |
398 | if (!Active) { |
399 | ++Self.IgnoredStackElements; |
400 | Active = true; |
401 | } |
402 | } |
403 | }; |
404 | |
405 | /// Marks that we're started loop parsing. |
406 | void loopInit() { |
407 | assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 408, __PRETTY_FUNCTION__)) |
408 | "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 408, __PRETTY_FUNCTION__)); |
409 | getTopOfStack().LoopStart = true; |
410 | } |
411 | /// Start capturing of the variables in the loop context. |
412 | void loopStart() { |
413 | assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 414, __PRETTY_FUNCTION__)) |
414 | "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 414, __PRETTY_FUNCTION__)); |
415 | getTopOfStack().LoopStart = false; |
416 | } |
417 | /// true, if variables are captured, false otherwise. |
418 | bool isLoopStarted() const { |
419 | assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 420, __PRETTY_FUNCTION__)) |
420 | "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive." ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 420, __PRETTY_FUNCTION__)); |
421 | return !getTopOfStack().LoopStart; |
422 | } |
423 | /// Marks (or clears) declaration as possibly loop counter. |
424 | void resetPossibleLoopCounter(const Decl *D = nullptr) { |
425 | getTopOfStack().PossiblyLoopCounter = |
426 | D ? D->getCanonicalDecl() : D; |
427 | } |
428 | /// Gets the possible loop counter decl. |
429 | const Decl *getPossiblyLoopCunter() const { |
430 | return getTopOfStack().PossiblyLoopCounter; |
431 | } |
432 | /// Start new OpenMP region stack in new non-capturing function. |
433 | void pushFunction() { |
434 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 435, __PRETTY_FUNCTION__)) |
435 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 435, __PRETTY_FUNCTION__)); |
436 | const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); |
437 | assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast< void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 437, __PRETTY_FUNCTION__)); |
438 | CurrentNonCapturingFunctionScope = CurFnScope; |
439 | } |
440 | /// Pop region stack for non-capturing function. |
441 | void popFunction(const FunctionScopeInfo *OldFSI) { |
442 | assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 443, __PRETTY_FUNCTION__)) |
443 | "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements" ) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 443, __PRETTY_FUNCTION__)); |
444 | if (!Stack.empty() && Stack.back().second == OldFSI) { |
445 | assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) : __assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 445, __PRETTY_FUNCTION__)); |
446 | Stack.pop_back(); |
447 | } |
448 | CurrentNonCapturingFunctionScope = nullptr; |
449 | for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { |
450 | if (!isa<CapturingScopeInfo>(FSI)) { |
451 | CurrentNonCapturingFunctionScope = FSI; |
452 | break; |
453 | } |
454 | } |
455 | } |
456 | |
457 | void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { |
458 | Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); |
459 | } |
460 | const std::pair<const OMPCriticalDirective *, llvm::APSInt> |
461 | getCriticalWithHint(const DeclarationNameInfo &Name) const { |
462 | auto I = Criticals.find(Name.getAsString()); |
463 | if (I != Criticals.end()) |
464 | return I->second; |
465 | return std::make_pair(nullptr, llvm::APSInt()); |
466 | } |
467 | /// If 'aligned' declaration for given variable \a D was not seen yet, |
468 | /// add it and return NULL; otherwise return previous occurrence's expression |
469 | /// for diagnostics. |
470 | const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); |
471 | /// If 'nontemporal' declaration for given variable \a D was not seen yet, |
472 | /// add it and return NULL; otherwise return previous occurrence's expression |
473 | /// for diagnostics. |
474 | const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); |
475 | |
476 | /// Register specified variable as loop control variable. |
477 | void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); |
478 | /// Check if the specified variable is a loop control variable for |
479 | /// current region. |
480 | /// \return The index of the loop control variable in the list of associated |
481 | /// for-loops (from outer to inner). |
482 | const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; |
483 | /// Check if the specified variable is a loop control variable for |
484 | /// parent region. |
485 | /// \return The index of the loop control variable in the list of associated |
486 | /// for-loops (from outer to inner). |
487 | const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; |
488 | /// Check if the specified variable is a loop control variable for |
489 | /// current region. |
490 | /// \return The index of the loop control variable in the list of associated |
491 | /// for-loops (from outer to inner). |
492 | const LCDeclInfo isLoopControlVariable(const ValueDecl *D, |
493 | unsigned Level) const; |
494 | /// Get the loop control variable for the I-th loop (or nullptr) in |
495 | /// parent directive. |
496 | const ValueDecl *getParentLoopControlVariable(unsigned I) const; |
497 | |
498 | /// Marks the specified decl \p D as used in scan directive. |
499 | void markDeclAsUsedInScanDirective(ValueDecl *D) { |
500 | if (SharingMapTy *Stack = getSecondOnStackOrNull()) |
501 | Stack->UsedInScanDirective.insert(D); |
502 | } |
503 | |
504 | /// Checks if the specified declaration was used in the inner scan directive. |
505 | bool isUsedInScanDirective(ValueDecl *D) const { |
506 | if (const SharingMapTy *Stack = getTopOfStackOrNull()) |
507 | return Stack->UsedInScanDirective.count(D) > 0; |
508 | return false; |
509 | } |
510 | |
511 | /// Adds explicit data sharing attribute to the specified declaration. |
512 | void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, |
513 | DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); |
514 | |
515 | /// Adds additional information for the reduction items with the reduction id |
516 | /// represented as an operator. |
517 | void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, |
518 | BinaryOperatorKind BOK); |
519 | /// Adds additional information for the reduction items with the reduction id |
520 | /// represented as reduction identifier. |
521 | void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, |
522 | const Expr *ReductionRef); |
523 | /// Returns the location and reduction operation from the innermost parent |
524 | /// region for the given \p D. |
525 | const DSAVarData |
526 | getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, |
527 | BinaryOperatorKind &BOK, |
528 | Expr *&TaskgroupDescriptor) const; |
529 | /// Returns the location and reduction operation from the innermost parent |
530 | /// region for the given \p D. |
531 | const DSAVarData |
532 | getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, |
533 | const Expr *&ReductionRef, |
534 | Expr *&TaskgroupDescriptor) const; |
535 | /// Return reduction reference expression for the current taskgroup or |
536 | /// parallel/worksharing directives with task reductions. |
537 | Expr *getTaskgroupReductionRef() const { |
538 | assert((getTopOfStack().Directive == OMPD_taskgroup ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) |
539 | ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) |
540 | isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) |
541 | !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) |
542 | "taskgroup reference expression requested for non taskgroup or "(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)) |
543 | "parallel/worksharing directive.")(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "taskgroup reference expression requested for non taskgroup or " "parallel/worksharing directive.") ? static_cast<void> (0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 543, __PRETTY_FUNCTION__)); |
544 | return getTopOfStack().TaskgroupReductionRef; |
545 | } |
546 | /// Checks if the given \p VD declaration is actually a taskgroup reduction |
547 | /// descriptor variable at the \p Level of OpenMP regions. |
548 | bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { |
549 | return getStackElemAtLevel(Level).TaskgroupReductionRef && |
550 | cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) |
551 | ->getDecl() == VD; |
552 | } |
553 | |
554 | /// Returns data sharing attributes from top of the stack for the |
555 | /// specified declaration. |
556 | const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); |
557 | /// Returns data-sharing attributes for the specified declaration. |
558 | const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; |
559 | /// Returns data-sharing attributes for the specified declaration. |
560 | const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; |
561 | /// Checks if the specified variables has data-sharing attributes which |
562 | /// match specified \a CPred predicate in any directive which matches \a DPred |
563 | /// predicate. |
564 | const DSAVarData |
565 | hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, |
566 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, |
567 | bool FromParent) const; |
568 | /// Checks if the specified variables has data-sharing attributes which |
569 | /// match specified \a CPred predicate in any innermost directive which |
570 | /// matches \a DPred predicate. |
571 | const DSAVarData |
572 | hasInnermostDSA(ValueDecl *D, |
573 | const llvm::function_ref<bool(OpenMPClauseKind)> CPred, |
574 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, |
575 | bool FromParent) const; |
576 | /// Checks if the specified variables has explicit data-sharing |
577 | /// attributes which match specified \a CPred predicate at the specified |
578 | /// OpenMP region. |
579 | bool hasExplicitDSA(const ValueDecl *D, |
580 | const llvm::function_ref<bool(OpenMPClauseKind)> CPred, |
581 | unsigned Level, bool NotLastprivate = false) const; |
582 | |
583 | /// Returns true if the directive at level \Level matches in the |
584 | /// specified \a DPred predicate. |
585 | bool hasExplicitDirective( |
586 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, |
587 | unsigned Level) const; |
588 | |
589 | /// Finds a directive which matches specified \a DPred predicate. |
590 | bool hasDirective( |
591 | const llvm::function_ref<bool( |
592 | OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> |
593 | DPred, |
594 | bool FromParent) const; |
595 | |
596 | /// Returns currently analyzed directive. |
597 | OpenMPDirectiveKind getCurrentDirective() const { |
598 | const SharingMapTy *Top = getTopOfStackOrNull(); |
599 | return Top ? Top->Directive : OMPD_unknown; |
600 | } |
601 | /// Returns directive kind at specified level. |
602 | OpenMPDirectiveKind getDirective(unsigned Level) const { |
603 | assert(!isStackEmpty() && "No directive at specified level.")((!isStackEmpty() && "No directive at specified level." ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 603, __PRETTY_FUNCTION__)); |
604 | return getStackElemAtLevel(Level).Directive; |
605 | } |
606 | /// Returns the capture region at the specified level. |
607 | OpenMPDirectiveKind getCaptureRegion(unsigned Level, |
608 | unsigned OpenMPCaptureLevel) const { |
609 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
610 | getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); |
611 | return CaptureRegions[OpenMPCaptureLevel]; |
612 | } |
613 | /// Returns parent directive. |
614 | OpenMPDirectiveKind getParentDirective() const { |
615 | const SharingMapTy *Parent = getSecondOnStackOrNull(); |
616 | return Parent ? Parent->Directive : OMPD_unknown; |
617 | } |
618 | |
619 | /// Add requires decl to internal vector |
620 | void addRequiresDecl(OMPRequiresDecl *RD) { |
621 | RequiresDecls.push_back(RD); |
622 | } |
623 | |
624 | /// Checks if the defined 'requires' directive has specified type of clause. |
625 | template <typename ClauseType> |
626 | bool hasRequiresDeclWithClause() const { |
627 | return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { |
628 | return llvm::any_of(D->clauselists(), [](const OMPClause *C) { |
629 | return isa<ClauseType>(C); |
630 | }); |
631 | }); |
632 | } |
633 | |
634 | /// Checks for a duplicate clause amongst previously declared requires |
635 | /// directives |
636 | bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { |
637 | bool IsDuplicate = false; |
638 | for (OMPClause *CNew : ClauseList) { |
639 | for (const OMPRequiresDecl *D : RequiresDecls) { |
640 | for (const OMPClause *CPrev : D->clauselists()) { |
641 | if (CNew->getClauseKind() == CPrev->getClauseKind()) { |
642 | SemaRef.Diag(CNew->getBeginLoc(), |
643 | diag::err_omp_requires_clause_redeclaration) |
644 | << getOpenMPClauseName(CNew->getClauseKind()); |
645 | SemaRef.Diag(CPrev->getBeginLoc(), |
646 | diag::note_omp_requires_previous_clause) |
647 | << getOpenMPClauseName(CPrev->getClauseKind()); |
648 | IsDuplicate = true; |
649 | } |
650 | } |
651 | } |
652 | } |
653 | return IsDuplicate; |
654 | } |
655 | |
656 | /// Add location of previously encountered target to internal vector |
657 | void addTargetDirLocation(SourceLocation LocStart) { |
658 | TargetLocations.push_back(LocStart); |
659 | } |
660 | |
661 | /// Add location for the first encountered atomicc directive. |
662 | void addAtomicDirectiveLoc(SourceLocation Loc) { |
663 | if (AtomicLocation.isInvalid()) |
664 | AtomicLocation = Loc; |
665 | } |
666 | |
667 | /// Returns the location of the first encountered atomic directive in the |
668 | /// module. |
669 | SourceLocation getAtomicDirectiveLoc() const { |
670 | return AtomicLocation; |
671 | } |
672 | |
673 | // Return previously encountered target region locations. |
674 | ArrayRef<SourceLocation> getEncounteredTargetLocs() const { |
675 | return TargetLocations; |
676 | } |
677 | |
678 | /// Set default data sharing attribute to none. |
679 | void setDefaultDSANone(SourceLocation Loc) { |
680 | getTopOfStack().DefaultAttr = DSA_none; |
681 | getTopOfStack().DefaultAttrLoc = Loc; |
682 | } |
683 | /// Set default data sharing attribute to shared. |
684 | void setDefaultDSAShared(SourceLocation Loc) { |
685 | getTopOfStack().DefaultAttr = DSA_shared; |
686 | getTopOfStack().DefaultAttrLoc = Loc; |
687 | } |
688 | /// Set default data sharing attribute to firstprivate. |
689 | void setDefaultDSAFirstPrivate(SourceLocation Loc) { |
690 | getTopOfStack().DefaultAttr = DSA_firstprivate; |
691 | getTopOfStack().DefaultAttrLoc = Loc; |
692 | } |
693 | /// Set default data mapping attribute to Modifier:Kind |
694 | void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, |
695 | OpenMPDefaultmapClauseKind Kind, |
696 | SourceLocation Loc) { |
697 | DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; |
698 | DMI.ImplicitBehavior = M; |
699 | DMI.SLoc = Loc; |
700 | } |
701 | /// Check whether the implicit-behavior has been set in defaultmap |
702 | bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { |
703 | if (VariableCategory == OMPC_DEFAULTMAP_unknown) |
704 | return getTopOfStack() |
705 | .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] |
706 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || |
707 | getTopOfStack() |
708 | .DefaultmapMap[OMPC_DEFAULTMAP_scalar] |
709 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || |
710 | getTopOfStack() |
711 | .DefaultmapMap[OMPC_DEFAULTMAP_pointer] |
712 | .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; |
713 | return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != |
714 | OMPC_DEFAULTMAP_MODIFIER_unknown; |
715 | } |
716 | |
717 | DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { |
718 | return getStackSize() <= Level ? DSA_unspecified |
719 | : getStackElemAtLevel(Level).DefaultAttr; |
720 | } |
721 | DefaultDataSharingAttributes getDefaultDSA() const { |
722 | return isStackEmpty() ? DSA_unspecified |
723 | : getTopOfStack().DefaultAttr; |
724 | } |
725 | SourceLocation getDefaultDSALocation() const { |
726 | return isStackEmpty() ? SourceLocation() |
727 | : getTopOfStack().DefaultAttrLoc; |
728 | } |
729 | OpenMPDefaultmapClauseModifier |
730 | getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { |
731 | return isStackEmpty() |
732 | ? OMPC_DEFAULTMAP_MODIFIER_unknown |
733 | : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; |
734 | } |
735 | OpenMPDefaultmapClauseModifier |
736 | getDefaultmapModifierAtLevel(unsigned Level, |
737 | OpenMPDefaultmapClauseKind Kind) const { |
738 | return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; |
739 | } |
740 | bool isDefaultmapCapturedByRef(unsigned Level, |
741 | OpenMPDefaultmapClauseKind Kind) const { |
742 | OpenMPDefaultmapClauseModifier M = |
743 | getDefaultmapModifierAtLevel(Level, Kind); |
744 | if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { |
745 | return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || |
746 | (M == OMPC_DEFAULTMAP_MODIFIER_to) || |
747 | (M == OMPC_DEFAULTMAP_MODIFIER_from) || |
748 | (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); |
749 | } |
750 | return true; |
751 | } |
752 | static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, |
753 | OpenMPDefaultmapClauseKind Kind) { |
754 | switch (Kind) { |
755 | case OMPC_DEFAULTMAP_scalar: |
756 | case OMPC_DEFAULTMAP_pointer: |
757 | return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || |
758 | (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || |
759 | (M == OMPC_DEFAULTMAP_MODIFIER_default); |
760 | case OMPC_DEFAULTMAP_aggregate: |
761 | return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; |
762 | default: |
763 | break; |
764 | } |
765 | llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 765); |
766 | } |
767 | bool mustBeFirstprivateAtLevel(unsigned Level, |
768 | OpenMPDefaultmapClauseKind Kind) const { |
769 | OpenMPDefaultmapClauseModifier M = |
770 | getDefaultmapModifierAtLevel(Level, Kind); |
771 | return mustBeFirstprivateBase(M, Kind); |
772 | } |
773 | bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { |
774 | OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); |
775 | return mustBeFirstprivateBase(M, Kind); |
776 | } |
777 | |
778 | /// Checks if the specified variable is a threadprivate. |
779 | bool isThreadPrivate(VarDecl *D) { |
780 | const DSAVarData DVar = getTopDSA(D, false); |
781 | return isOpenMPThreadPrivate(DVar.CKind); |
782 | } |
783 | |
784 | /// Marks current region as ordered (it has an 'ordered' clause). |
785 | void setOrderedRegion(bool IsOrdered, const Expr *Param, |
786 | OMPOrderedClause *Clause) { |
787 | if (IsOrdered) |
788 | getTopOfStack().OrderedRegion.emplace(Param, Clause); |
789 | else |
790 | getTopOfStack().OrderedRegion.reset(); |
791 | } |
792 | /// Returns true, if region is ordered (has associated 'ordered' clause), |
793 | /// false - otherwise. |
794 | bool isOrderedRegion() const { |
795 | if (const SharingMapTy *Top = getTopOfStackOrNull()) |
796 | return Top->OrderedRegion.hasValue(); |
797 | return false; |
798 | } |
799 | /// Returns optional parameter for the ordered region. |
800 | std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { |
801 | if (const SharingMapTy *Top = getTopOfStackOrNull()) |
802 | if (Top->OrderedRegion.hasValue()) |
803 | return Top->OrderedRegion.getValue(); |
804 | return std::make_pair(nullptr, nullptr); |
805 | } |
806 | /// Returns true, if parent region is ordered (has associated |
807 | /// 'ordered' clause), false - otherwise. |
808 | bool isParentOrderedRegion() const { |
809 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) |
810 | return Parent->OrderedRegion.hasValue(); |
811 | return false; |
812 | } |
813 | /// Returns optional parameter for the ordered region. |
814 | std::pair<const Expr *, OMPOrderedClause *> |
815 | getParentOrderedRegionParam() const { |
816 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) |
817 | if (Parent->OrderedRegion.hasValue()) |
818 | return Parent->OrderedRegion.getValue(); |
819 | return std::make_pair(nullptr, nullptr); |
820 | } |
821 | /// Marks current region as nowait (it has a 'nowait' clause). |
822 | void setNowaitRegion(bool IsNowait = true) { |
823 | getTopOfStack().NowaitRegion = IsNowait; |
824 | } |
825 | /// Returns true, if parent region is nowait (has associated |
826 | /// 'nowait' clause), false - otherwise. |
827 | bool isParentNowaitRegion() const { |
828 | if (const SharingMapTy *Parent = getSecondOnStackOrNull()) |
829 | return Parent->NowaitRegion; |
830 | return false; |
831 | } |
832 | /// Marks parent region as cancel region. |
833 | void setParentCancelRegion(bool Cancel = true) { |
834 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) |
835 | Parent->CancelRegion |= Cancel; |
836 | } |
837 | /// Return true if current region has inner cancel construct. |
838 | bool isCancelRegion() const { |
839 | const SharingMapTy *Top = getTopOfStackOrNull(); |
840 | return Top ? Top->CancelRegion : false; |
841 | } |
842 | |
843 | /// Mark that parent region already has scan directive. |
844 | void setParentHasScanDirective(SourceLocation Loc) { |
845 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) |
846 | Parent->PrevScanLocation = Loc; |
847 | } |
848 | /// Return true if current region has inner cancel construct. |
849 | bool doesParentHasScanDirective() const { |
850 | const SharingMapTy *Top = getSecondOnStackOrNull(); |
851 | return Top ? Top->PrevScanLocation.isValid() : false; |
852 | } |
853 | /// Return true if current region has inner cancel construct. |
854 | SourceLocation getParentScanDirectiveLoc() const { |
855 | const SharingMapTy *Top = getSecondOnStackOrNull(); |
856 | return Top ? Top->PrevScanLocation : SourceLocation(); |
857 | } |
858 | /// Mark that parent region already has ordered directive. |
859 | void setParentHasOrderedDirective(SourceLocation Loc) { |
860 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) |
861 | Parent->PrevOrderedLocation = Loc; |
862 | } |
863 | /// Return true if current region has inner ordered construct. |
864 | bool doesParentHasOrderedDirective() const { |
865 | const SharingMapTy *Top = getSecondOnStackOrNull(); |
866 | return Top ? Top->PrevOrderedLocation.isValid() : false; |
867 | } |
868 | /// Returns the location of the previously specified ordered directive. |
869 | SourceLocation getParentOrderedDirectiveLoc() const { |
870 | const SharingMapTy *Top = getSecondOnStackOrNull(); |
871 | return Top ? Top->PrevOrderedLocation : SourceLocation(); |
872 | } |
873 | |
874 | /// Set collapse value for the region. |
875 | void setAssociatedLoops(unsigned Val) { |
876 | getTopOfStack().AssociatedLoops = Val; |
877 | if (Val > 1) |
878 | getTopOfStack().HasMutipleLoops = true; |
879 | } |
880 | /// Return collapse value for region. |
881 | unsigned getAssociatedLoops() const { |
882 | const SharingMapTy *Top = getTopOfStackOrNull(); |
883 | return Top ? Top->AssociatedLoops : 0; |
884 | } |
885 | /// Returns true if the construct is associated with multiple loops. |
886 | bool hasMutipleLoops() const { |
887 | const SharingMapTy *Top = getTopOfStackOrNull(); |
888 | return Top ? Top->HasMutipleLoops : false; |
889 | } |
890 | |
891 | /// Marks current target region as one with closely nested teams |
892 | /// region. |
893 | void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { |
894 | if (SharingMapTy *Parent = getSecondOnStackOrNull()) |
895 | Parent->InnerTeamsRegionLoc = TeamsRegionLoc; |
896 | } |
897 | /// Returns true, if current region has closely nested teams region. |
898 | bool hasInnerTeamsRegion() const { |
899 | return getInnerTeamsRegionLoc().isValid(); |
900 | } |
901 | /// Returns location of the nested teams region (if any). |
902 | SourceLocation getInnerTeamsRegionLoc() const { |
903 | const SharingMapTy *Top = getTopOfStackOrNull(); |
904 | return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); |
905 | } |
906 | |
907 | Scope *getCurScope() const { |
908 | const SharingMapTy *Top = getTopOfStackOrNull(); |
909 | return Top ? Top->CurScope : nullptr; |
910 | } |
911 | SourceLocation getConstructLoc() const { |
912 | const SharingMapTy *Top = getTopOfStackOrNull(); |
913 | return Top ? Top->ConstructLoc : SourceLocation(); |
914 | } |
915 | |
916 | /// Do the check specified in \a Check to all component lists and return true |
917 | /// if any issue is found. |
918 | bool checkMappableExprComponentListsForDecl( |
919 | const ValueDecl *VD, bool CurrentRegionOnly, |
920 | const llvm::function_ref< |
921 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, |
922 | OpenMPClauseKind)> |
923 | Check) const { |
924 | if (isStackEmpty()) |
925 | return false; |
926 | auto SI = begin(); |
927 | auto SE = end(); |
928 | |
929 | if (SI == SE) |
930 | return false; |
931 | |
932 | if (CurrentRegionOnly) |
933 | SE = std::next(SI); |
934 | else |
935 | std::advance(SI, 1); |
936 | |
937 | for (; SI != SE; ++SI) { |
938 | auto MI = SI->MappedExprComponents.find(VD); |
939 | if (MI != SI->MappedExprComponents.end()) |
940 | for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : |
941 | MI->second.Components) |
942 | if (Check(L, MI->second.Kind)) |
943 | return true; |
944 | } |
945 | return false; |
946 | } |
947 | |
948 | /// Do the check specified in \a Check to all component lists at a given level |
949 | /// and return true if any issue is found. |
950 | bool checkMappableExprComponentListsForDeclAtLevel( |
951 | const ValueDecl *VD, unsigned Level, |
952 | const llvm::function_ref< |
953 | bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, |
954 | OpenMPClauseKind)> |
955 | Check) const { |
956 | if (getStackSize() <= Level) |
957 | return false; |
958 | |
959 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); |
960 | auto MI = StackElem.MappedExprComponents.find(VD); |
961 | if (MI != StackElem.MappedExprComponents.end()) |
962 | for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : |
963 | MI->second.Components) |
964 | if (Check(L, MI->second.Kind)) |
965 | return true; |
966 | return false; |
967 | } |
968 | |
969 | /// Create a new mappable expression component list associated with a given |
970 | /// declaration and initialize it with the provided list of components. |
971 | void addMappableExpressionComponents( |
972 | const ValueDecl *VD, |
973 | OMPClauseMappableExprCommon::MappableExprComponentListRef Components, |
974 | OpenMPClauseKind WhereFoundClauseKind) { |
975 | MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; |
976 | // Create new entry and append the new components there. |
977 | MEC.Components.resize(MEC.Components.size() + 1); |
978 | MEC.Components.back().append(Components.begin(), Components.end()); |
979 | MEC.Kind = WhereFoundClauseKind; |
980 | } |
981 | |
982 | unsigned getNestingLevel() const { |
983 | assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 983, __PRETTY_FUNCTION__)); |
984 | return getStackSize() - 1; |
985 | } |
986 | void addDoacrossDependClause(OMPDependClause *C, |
987 | const OperatorOffsetTy &OpsOffs) { |
988 | SharingMapTy *Parent = getSecondOnStackOrNull(); |
989 | assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive )) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 989, __PRETTY_FUNCTION__)); |
990 | Parent->DoacrossDepends.try_emplace(C, OpsOffs); |
991 | } |
992 | llvm::iterator_range<DoacrossDependMapTy::const_iterator> |
993 | getDoacrossDependClauses() const { |
994 | const SharingMapTy &StackElem = getTopOfStack(); |
995 | if (isOpenMPWorksharingDirective(StackElem.Directive)) { |
996 | const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; |
997 | return llvm::make_range(Ref.begin(), Ref.end()); |
998 | } |
999 | return llvm::make_range(StackElem.DoacrossDepends.end(), |
1000 | StackElem.DoacrossDepends.end()); |
1001 | } |
1002 | |
1003 | // Store types of classes which have been explicitly mapped |
1004 | void addMappedClassesQualTypes(QualType QT) { |
1005 | SharingMapTy &StackElem = getTopOfStack(); |
1006 | StackElem.MappedClassesQualTypes.insert(QT); |
1007 | } |
1008 | |
1009 | // Return set of mapped classes types |
1010 | bool isClassPreviouslyMapped(QualType QT) const { |
1011 | const SharingMapTy &StackElem = getTopOfStack(); |
1012 | return StackElem.MappedClassesQualTypes.count(QT) != 0; |
1013 | } |
1014 | |
1015 | /// Adds global declare target to the parent target region. |
1016 | void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { |
1017 | assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E-> getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global." ) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1019, __PRETTY_FUNCTION__)) |
1018 | E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E-> getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global." ) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1019, __PRETTY_FUNCTION__)) |
1019 | "Expected declare target link global.")((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E-> getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global." ) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1019, __PRETTY_FUNCTION__)); |
1020 | for (auto &Elem : *this) { |
1021 | if (isOpenMPTargetExecutionDirective(Elem.Directive)) { |
1022 | Elem.DeclareTargetLinkVarDecls.push_back(E); |
1023 | return; |
1024 | } |
1025 | } |
1026 | } |
1027 | |
1028 | /// Returns the list of globals with declare target link if current directive |
1029 | /// is target. |
1030 | ArrayRef<DeclRefExpr *> getLinkGlobals() const { |
1031 | assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&((isOpenMPTargetExecutionDirective(getCurrentDirective()) && "Expected target executable directive.") ? static_cast<void > (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1032, __PRETTY_FUNCTION__)) |
1032 | "Expected target executable directive.")((isOpenMPTargetExecutionDirective(getCurrentDirective()) && "Expected target executable directive.") ? static_cast<void > (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1032, __PRETTY_FUNCTION__)); |
1033 | return getTopOfStack().DeclareTargetLinkVarDecls; |
1034 | } |
1035 | |
1036 | /// Adds list of allocators expressions. |
1037 | void addInnerAllocatorExpr(Expr *E) { |
1038 | getTopOfStack().InnerUsedAllocators.push_back(E); |
1039 | } |
1040 | /// Return list of used allocators. |
1041 | ArrayRef<Expr *> getInnerAllocators() const { |
1042 | return getTopOfStack().InnerUsedAllocators; |
1043 | } |
1044 | /// Marks the declaration as implicitly firstprivate nin the task-based |
1045 | /// regions. |
1046 | void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { |
1047 | getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); |
1048 | } |
1049 | /// Checks if the decl is implicitly firstprivate in the task-based region. |
1050 | bool isImplicitTaskFirstprivate(Decl *D) const { |
1051 | return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; |
1052 | } |
1053 | |
1054 | /// Marks decl as used in uses_allocators clause as the allocator. |
1055 | void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { |
1056 | getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); |
1057 | } |
1058 | /// Checks if specified decl is used in uses allocator clause as the |
1059 | /// allocator. |
1060 | Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, |
1061 | const Decl *D) const { |
1062 | const SharingMapTy &StackElem = getTopOfStack(); |
1063 | auto I = StackElem.UsesAllocatorsDecls.find(D); |
1064 | if (I == StackElem.UsesAllocatorsDecls.end()) |
1065 | return None; |
1066 | return I->getSecond(); |
1067 | } |
1068 | Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { |
1069 | const SharingMapTy &StackElem = getTopOfStack(); |
1070 | auto I = StackElem.UsesAllocatorsDecls.find(D); |
1071 | if (I == StackElem.UsesAllocatorsDecls.end()) |
1072 | return None; |
1073 | return I->getSecond(); |
1074 | } |
1075 | }; |
1076 | |
1077 | bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { |
1078 | return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); |
1079 | } |
1080 | |
1081 | bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { |
1082 | return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || |
1083 | DKind == OMPD_unknown; |
1084 | } |
1085 | |
1086 | } // namespace |
1087 | |
1088 | static const Expr *getExprAsWritten(const Expr *E) { |
1089 | if (const auto *FE = dyn_cast<FullExpr>(E)) |
1090 | E = FE->getSubExpr(); |
1091 | |
1092 | if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) |
1093 | E = MTE->getSubExpr(); |
1094 | |
1095 | while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) |
1096 | E = Binder->getSubExpr(); |
1097 | |
1098 | if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) |
1099 | E = ICE->getSubExprAsWritten(); |
1100 | return E->IgnoreParens(); |
1101 | } |
1102 | |
1103 | static Expr *getExprAsWritten(Expr *E) { |
1104 | return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); |
1105 | } |
1106 | |
1107 | static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { |
1108 | if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) |
1109 | if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) |
1110 | D = ME->getMemberDecl(); |
1111 | const auto *VD = dyn_cast<VarDecl>(D); |
1112 | const auto *FD = dyn_cast<FieldDecl>(D); |
1113 | if (VD != nullptr) { |
1114 | VD = VD->getCanonicalDecl(); |
1115 | D = VD; |
1116 | } else { |
1117 | assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1117, __PRETTY_FUNCTION__)); |
1118 | FD = FD->getCanonicalDecl(); |
1119 | D = FD; |
1120 | } |
1121 | return D; |
1122 | } |
1123 | |
1124 | static ValueDecl *getCanonicalDecl(ValueDecl *D) { |
1125 | return const_cast<ValueDecl *>( |
1126 | getCanonicalDecl(const_cast<const ValueDecl *>(D))); |
1127 | } |
1128 | |
1129 | DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, |
1130 | ValueDecl *D) const { |
1131 | D = getCanonicalDecl(D); |
1132 | auto *VD = dyn_cast<VarDecl>(D); |
1133 | const auto *FD = dyn_cast<FieldDecl>(D); |
1134 | DSAVarData DVar; |
1135 | if (Iter == end()) { |
1136 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1137 | // in a region but not in construct] |
1138 | // File-scope or namespace-scope variables referenced in called routines |
1139 | // in the region are shared unless they appear in a threadprivate |
1140 | // directive. |
1141 | if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) |
1142 | DVar.CKind = OMPC_shared; |
1143 | |
1144 | // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced |
1145 | // in a region but not in construct] |
1146 | // Variables with static storage duration that are declared in called |
1147 | // routines in the region are shared. |
1148 | if (VD && VD->hasGlobalStorage()) |
1149 | DVar.CKind = OMPC_shared; |
1150 | |
1151 | // Non-static data members are shared by default. |
1152 | if (FD) |
1153 | DVar.CKind = OMPC_shared; |
1154 | |
1155 | return DVar; |
1156 | } |
1157 | |
1158 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1159 | // in a Construct, C/C++, predetermined, p.1] |
1160 | // Variables with automatic storage duration that are declared in a scope |
1161 | // inside the construct are private. |
1162 | if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && |
1163 | (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { |
1164 | DVar.CKind = OMPC_private; |
1165 | return DVar; |
1166 | } |
1167 | |
1168 | DVar.DKind = Iter->Directive; |
1169 | // Explicitly specified attributes and local variables with predetermined |
1170 | // attributes. |
1171 | if (Iter->SharingMap.count(D)) { |
1172 | const DSAInfo &Data = Iter->SharingMap.lookup(D); |
1173 | DVar.RefExpr = Data.RefExpr.getPointer(); |
1174 | DVar.PrivateCopy = Data.PrivateCopy; |
1175 | DVar.CKind = Data.Attributes; |
1176 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; |
1177 | DVar.Modifier = Data.Modifier; |
1178 | return DVar; |
1179 | } |
1180 | |
1181 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1182 | // in a Construct, C/C++, implicitly determined, p.1] |
1183 | // In a parallel or task construct, the data-sharing attributes of these |
1184 | // variables are determined by the default clause, if present. |
1185 | switch (Iter->DefaultAttr) { |
1186 | case DSA_shared: |
1187 | DVar.CKind = OMPC_shared; |
1188 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; |
1189 | return DVar; |
1190 | case DSA_none: |
1191 | return DVar; |
1192 | case DSA_firstprivate: |
1193 | if (VD->getStorageDuration() == SD_Static && |
1194 | VD->getDeclContext()->isFileContext()) { |
1195 | DVar.CKind = OMPC_unknown; |
1196 | } else { |
1197 | DVar.CKind = OMPC_firstprivate; |
1198 | } |
1199 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; |
1200 | return DVar; |
1201 | case DSA_unspecified: |
1202 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1203 | // in a Construct, implicitly determined, p.2] |
1204 | // In a parallel construct, if no default clause is present, these |
1205 | // variables are shared. |
1206 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; |
1207 | if ((isOpenMPParallelDirective(DVar.DKind) && |
1208 | !isOpenMPTaskLoopDirective(DVar.DKind)) || |
1209 | isOpenMPTeamsDirective(DVar.DKind)) { |
1210 | DVar.CKind = OMPC_shared; |
1211 | return DVar; |
1212 | } |
1213 | |
1214 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1215 | // in a Construct, implicitly determined, p.4] |
1216 | // In a task construct, if no default clause is present, a variable that in |
1217 | // the enclosing context is determined to be shared by all implicit tasks |
1218 | // bound to the current team is shared. |
1219 | if (isOpenMPTaskingDirective(DVar.DKind)) { |
1220 | DSAVarData DVarTemp; |
1221 | const_iterator I = Iter, E = end(); |
1222 | do { |
1223 | ++I; |
1224 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables |
1225 | // Referenced in a Construct, implicitly determined, p.6] |
1226 | // In a task construct, if no default clause is present, a variable |
1227 | // whose data-sharing attribute is not determined by the rules above is |
1228 | // firstprivate. |
1229 | DVarTemp = getDSA(I, D); |
1230 | if (DVarTemp.CKind != OMPC_shared) { |
1231 | DVar.RefExpr = nullptr; |
1232 | DVar.CKind = OMPC_firstprivate; |
1233 | return DVar; |
1234 | } |
1235 | } while (I != E && !isImplicitTaskingRegion(I->Directive)); |
1236 | DVar.CKind = |
1237 | (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; |
1238 | return DVar; |
1239 | } |
1240 | } |
1241 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1242 | // in a Construct, implicitly determined, p.3] |
1243 | // For constructs other than task, if no default clause is present, these |
1244 | // variables inherit their data-sharing attributes from the enclosing |
1245 | // context. |
1246 | return getDSA(++Iter, D); |
1247 | } |
1248 | |
1249 | const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, |
1250 | const Expr *NewDE) { |
1251 | assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1251, __PRETTY_FUNCTION__)); |
1252 | D = getCanonicalDecl(D); |
1253 | SharingMapTy &StackElem = getTopOfStack(); |
1254 | auto It = StackElem.AlignedMap.find(D); |
1255 | if (It == StackElem.AlignedMap.end()) { |
1256 | assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map" ) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1256, __PRETTY_FUNCTION__)); |
1257 | StackElem.AlignedMap[D] = NewDE; |
1258 | return nullptr; |
1259 | } |
1260 | assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map" ) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1260, __PRETTY_FUNCTION__)); |
1261 | return It->second; |
1262 | } |
1263 | |
1264 | const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, |
1265 | const Expr *NewDE) { |
1266 | assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1266, __PRETTY_FUNCTION__)); |
1267 | D = getCanonicalDecl(D); |
1268 | SharingMapTy &StackElem = getTopOfStack(); |
1269 | auto It = StackElem.NontemporalMap.find(D); |
1270 | if (It == StackElem.NontemporalMap.end()) { |
1271 | assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map" ) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1271, __PRETTY_FUNCTION__)); |
1272 | StackElem.NontemporalMap[D] = NewDE; |
1273 | return nullptr; |
1274 | } |
1275 | assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map" ) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1275, __PRETTY_FUNCTION__)); |
1276 | return It->second; |
1277 | } |
1278 | |
1279 | void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { |
1280 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1280, __PRETTY_FUNCTION__)); |
1281 | D = getCanonicalDecl(D); |
1282 | SharingMapTy &StackElem = getTopOfStack(); |
1283 | StackElem.LCVMap.try_emplace( |
1284 | D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); |
1285 | } |
1286 | |
1287 | const DSAStackTy::LCDeclInfo |
1288 | DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { |
1289 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1289, __PRETTY_FUNCTION__)); |
1290 | D = getCanonicalDecl(D); |
1291 | const SharingMapTy &StackElem = getTopOfStack(); |
1292 | auto It = StackElem.LCVMap.find(D); |
1293 | if (It != StackElem.LCVMap.end()) |
1294 | return It->second; |
1295 | return {0, nullptr}; |
1296 | } |
1297 | |
1298 | const DSAStackTy::LCDeclInfo |
1299 | DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { |
1300 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1300, __PRETTY_FUNCTION__)); |
1301 | D = getCanonicalDecl(D); |
1302 | for (unsigned I = Level + 1; I > 0; --I) { |
1303 | const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); |
1304 | auto It = StackElem.LCVMap.find(D); |
1305 | if (It != StackElem.LCVMap.end()) |
1306 | return It->second; |
1307 | } |
1308 | return {0, nullptr}; |
1309 | } |
1310 | |
1311 | const DSAStackTy::LCDeclInfo |
1312 | DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { |
1313 | const SharingMapTy *Parent = getSecondOnStackOrNull(); |
1314 | assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty") ? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1314, __PRETTY_FUNCTION__)); |
1315 | D = getCanonicalDecl(D); |
1316 | auto It = Parent->LCVMap.find(D); |
1317 | if (It != Parent->LCVMap.end()) |
1318 | return It->second; |
1319 | return {0, nullptr}; |
1320 | } |
1321 | |
1322 | const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { |
1323 | const SharingMapTy *Parent = getSecondOnStackOrNull(); |
1324 | assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty") ? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1324, __PRETTY_FUNCTION__)); |
1325 | if (Parent->LCVMap.size() < I) |
1326 | return nullptr; |
1327 | for (const auto &Pair : Parent->LCVMap) |
1328 | if (Pair.second.first == I) |
1329 | return Pair.first; |
1330 | return nullptr; |
1331 | } |
1332 | |
1333 | void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, |
1334 | DeclRefExpr *PrivateCopy, unsigned Modifier) { |
1335 | D = getCanonicalDecl(D); |
1336 | if (A == OMPC_threadprivate) { |
1337 | DSAInfo &Data = Threadprivates[D]; |
1338 | Data.Attributes = A; |
1339 | Data.RefExpr.setPointer(E); |
1340 | Data.PrivateCopy = nullptr; |
1341 | Data.Modifier = Modifier; |
1342 | } else { |
1343 | DSAInfo &Data = getTopOfStack().SharingMap[D]; |
1344 | assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)) |
1345 | (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)) |
1346 | (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)) |
1347 | (isLoopControlVariable(D).first && A == OMPC_private))((Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate ) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate ) || (isLoopControlVariable(D).first && A == OMPC_private )) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1347, __PRETTY_FUNCTION__)); |
1348 | Data.Modifier = Modifier; |
1349 | if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { |
1350 | Data.RefExpr.setInt(/*IntVal=*/true); |
1351 | return; |
1352 | } |
1353 | const bool IsLastprivate = |
1354 | A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; |
1355 | Data.Attributes = A; |
1356 | Data.RefExpr.setPointerAndInt(E, IsLastprivate); |
1357 | Data.PrivateCopy = PrivateCopy; |
1358 | if (PrivateCopy) { |
1359 | DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; |
1360 | Data.Modifier = Modifier; |
1361 | Data.Attributes = A; |
1362 | Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); |
1363 | Data.PrivateCopy = nullptr; |
1364 | } |
1365 | } |
1366 | } |
1367 | |
1368 | /// Build a variable declaration for OpenMP loop iteration variable. |
1369 | static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, |
1370 | StringRef Name, const AttrVec *Attrs = nullptr, |
1371 | DeclRefExpr *OrigRef = nullptr) { |
1372 | DeclContext *DC = SemaRef.CurContext; |
1373 | IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); |
1374 | TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); |
1375 | auto *Decl = |
1376 | VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); |
1377 | if (Attrs) { |
1378 | for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); |
1379 | I != E; ++I) |
1380 | Decl->addAttr(*I); |
1381 | } |
1382 | Decl->setImplicit(); |
1383 | if (OrigRef) { |
1384 | Decl->addAttr( |
1385 | OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); |
1386 | } |
1387 | return Decl; |
1388 | } |
1389 | |
1390 | static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, |
1391 | SourceLocation Loc, |
1392 | bool RefersToCapture = false) { |
1393 | D->setReferenced(); |
1394 | D->markUsed(S.Context); |
1395 | return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), |
1396 | SourceLocation(), D, RefersToCapture, Loc, Ty, |
1397 | VK_LValue); |
1398 | } |
1399 | |
1400 | void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, |
1401 | BinaryOperatorKind BOK) { |
1402 | D = getCanonicalDecl(D); |
1403 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1403, __PRETTY_FUNCTION__)); |
1404 | assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1406, __PRETTY_FUNCTION__)) |
1405 | getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1406, __PRETTY_FUNCTION__)) |
1406 | "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1406, __PRETTY_FUNCTION__)); |
1407 | ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; |
1408 | assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) |
1409 | (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) |
1410 | ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) |
1411 | isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) |
1412 | !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) |
1413 | "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)) |
1414 | "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1414, __PRETTY_FUNCTION__)); |
1415 | ReductionData.set(BOK, SR); |
1416 | Expr *&TaskgroupReductionRef = |
1417 | getTopOfStack().TaskgroupReductionRef; |
1418 | if (!TaskgroupReductionRef) { |
1419 | VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), |
1420 | SemaRef.Context.VoidPtrTy, ".task_red."); |
1421 | TaskgroupReductionRef = |
1422 | buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); |
1423 | } |
1424 | } |
1425 | |
1426 | void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, |
1427 | const Expr *ReductionRef) { |
1428 | D = getCanonicalDecl(D); |
1429 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1429, __PRETTY_FUNCTION__)); |
1430 | assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1432, __PRETTY_FUNCTION__)) |
1431 | getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1432, __PRETTY_FUNCTION__)) |
1432 | "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items." ) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1432, __PRETTY_FUNCTION__)); |
1433 | ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; |
1434 | assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) |
1435 | (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) |
1436 | ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) |
1437 | isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) |
1438 | !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) |
1439 | "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)) |
1440 | "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack ().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective (getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack ().Directive)) && !isOpenMPSimdDirective(getTopOfStack ().Directive))) && "Additional reduction info may be specified only once for reduction " "items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1440, __PRETTY_FUNCTION__)); |
1441 | ReductionData.set(ReductionRef, 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 | |
1452 | const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( |
1453 | const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, |
1454 | Expr *&TaskgroupDescriptor) const { |
1455 | D = getCanonicalDecl(D); |
1456 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty." ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1456, __PRETTY_FUNCTION__)); |
1457 | for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { |
1458 | const DSAInfo &Data = I->SharingMap.lookup(D); |
1459 | if (Data.Attributes != OMPC_reduction || |
1460 | Data.Modifier != OMPC_REDUCTION_task) |
1461 | continue; |
1462 | const ReductionData &ReductionData = I->ReductionMap.lookup(D); |
1463 | if (!ReductionData.ReductionOp || |
1464 | ReductionData.ReductionOp.is<const Expr *>()) |
1465 | return DSAVarData(); |
1466 | SR = ReductionData.ReductionRange; |
1467 | BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); |
1468 | assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1470, __PRETTY_FUNCTION__)) |
1469 | "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1470, __PRETTY_FUNCTION__)) |
1470 | "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1470, __PRETTY_FUNCTION__)); |
1471 | TaskgroupDescriptor = I->TaskgroupReductionRef; |
1472 | return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), |
1473 | Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); |
1474 | } |
1475 | return DSAVarData(); |
1476 | } |
1477 | |
1478 | const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( |
1479 | const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, |
1480 | Expr *&TaskgroupDescriptor) const { |
1481 | D = getCanonicalDecl(D); |
1482 | assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty." ) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1482, __PRETTY_FUNCTION__)); |
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 | ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); |
1494 | assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1496, __PRETTY_FUNCTION__)) |
1495 | "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1496, __PRETTY_FUNCTION__)) |
1496 | "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference " "expression for the descriptor is not " "set.") ? static_cast <void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1496, __PRETTY_FUNCTION__)); |
1497 | TaskgroupDescriptor = I->TaskgroupReductionRef; |
1498 | return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), |
1499 | Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); |
1500 | } |
1501 | return DSAVarData(); |
1502 | } |
1503 | |
1504 | bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { |
1505 | D = D->getCanonicalDecl(); |
1506 | for (const_iterator E = end(); I != E; ++I) { |
1507 | if (isImplicitOrExplicitTaskingRegion(I->Directive) || |
1508 | isOpenMPTargetExecutionDirective(I->Directive)) { |
1509 | Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; |
1510 | Scope *CurScope = getCurScope(); |
1511 | while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) |
1512 | CurScope = CurScope->getParent(); |
1513 | return CurScope != TopScope; |
1514 | } |
1515 | } |
1516 | return false; |
1517 | } |
1518 | |
1519 | static bool isConstNotMutableType(Sema &SemaRef, QualType Type, |
1520 | bool AcceptIfMutable = true, |
1521 | bool *IsClassType = nullptr) { |
1522 | ASTContext &Context = SemaRef.getASTContext(); |
1523 | Type = Type.getNonReferenceType().getCanonicalType(); |
1524 | bool IsConstant = Type.isConstant(Context); |
1525 | Type = Context.getBaseElementType(Type); |
1526 | const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus |
1527 | ? Type->getAsCXXRecordDecl() |
1528 | : nullptr; |
1529 | if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) |
1530 | if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) |
1531 | RD = CTD->getTemplatedDecl(); |
1532 | if (IsClassType) |
1533 | *IsClassType = RD; |
1534 | return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && |
1535 | RD->hasDefinition() && RD->hasMutableFields()); |
1536 | } |
1537 | |
1538 | static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, |
1539 | QualType Type, OpenMPClauseKind CKind, |
1540 | SourceLocation ELoc, |
1541 | bool AcceptIfMutable = true, |
1542 | bool ListItemNotVar = false) { |
1543 | ASTContext &Context = SemaRef.getASTContext(); |
1544 | bool IsClassType; |
1545 | if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { |
1546 | unsigned Diag = ListItemNotVar |
1547 | ? diag::err_omp_const_list_item |
1548 | : IsClassType ? diag::err_omp_const_not_mutable_variable |
1549 | : diag::err_omp_const_variable; |
1550 | SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); |
1551 | if (!ListItemNotVar && D) { |
1552 | const VarDecl *VD = dyn_cast<VarDecl>(D); |
1553 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
1554 | VarDecl::DeclarationOnly; |
1555 | SemaRef.Diag(D->getLocation(), |
1556 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
1557 | << D; |
1558 | } |
1559 | return true; |
1560 | } |
1561 | return false; |
1562 | } |
1563 | |
1564 | const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, |
1565 | bool FromParent) { |
1566 | D = getCanonicalDecl(D); |
1567 | DSAVarData DVar; |
1568 | |
1569 | auto *VD = dyn_cast<VarDecl>(D); |
1570 | auto TI = Threadprivates.find(D); |
1571 | if (TI != Threadprivates.end()) { |
1572 | DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); |
1573 | DVar.CKind = OMPC_threadprivate; |
1574 | DVar.Modifier = TI->getSecond().Modifier; |
1575 | return DVar; |
1576 | } |
1577 | if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { |
1578 | DVar.RefExpr = buildDeclRefExpr( |
1579 | SemaRef, VD, D->getType().getNonReferenceType(), |
1580 | VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); |
1581 | DVar.CKind = OMPC_threadprivate; |
1582 | addDSA(D, DVar.RefExpr, OMPC_threadprivate); |
1583 | return DVar; |
1584 | } |
1585 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1586 | // in a Construct, C/C++, predetermined, p.1] |
1587 | // Variables appearing in threadprivate directives are threadprivate. |
1588 | if ((VD && VD->getTLSKind() != VarDecl::TLS_None && |
1589 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && |
1590 | SemaRef.getLangOpts().OpenMPUseTLS && |
1591 | SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || |
1592 | (VD && VD->getStorageClass() == SC_Register && |
1593 | VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { |
1594 | DVar.RefExpr = buildDeclRefExpr( |
1595 | SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); |
1596 | DVar.CKind = OMPC_threadprivate; |
1597 | addDSA(D, DVar.RefExpr, OMPC_threadprivate); |
1598 | return DVar; |
1599 | } |
1600 | if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && |
1601 | VD->isLocalVarDeclOrParm() && !isStackEmpty() && |
1602 | !isLoopControlVariable(D).first) { |
1603 | const_iterator IterTarget = |
1604 | std::find_if(begin(), end(), [](const SharingMapTy &Data) { |
1605 | return isOpenMPTargetExecutionDirective(Data.Directive); |
1606 | }); |
1607 | if (IterTarget != end()) { |
1608 | const_iterator ParentIterTarget = IterTarget + 1; |
1609 | for (const_iterator Iter = begin(); |
1610 | Iter != ParentIterTarget; ++Iter) { |
1611 | if (isOpenMPLocal(VD, Iter)) { |
1612 | DVar.RefExpr = |
1613 | buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), |
1614 | D->getLocation()); |
1615 | DVar.CKind = OMPC_threadprivate; |
1616 | return DVar; |
1617 | } |
1618 | } |
1619 | if (!isClauseParsingMode() || IterTarget != begin()) { |
1620 | auto DSAIter = IterTarget->SharingMap.find(D); |
1621 | if (DSAIter != IterTarget->SharingMap.end() && |
1622 | isOpenMPPrivate(DSAIter->getSecond().Attributes)) { |
1623 | DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); |
1624 | DVar.CKind = OMPC_threadprivate; |
1625 | return DVar; |
1626 | } |
1627 | const_iterator End = end(); |
1628 | if (!SemaRef.isOpenMPCapturedByRef( |
1629 | D, std::distance(ParentIterTarget, End), |
1630 | /*OpenMPCaptureLevel=*/0)) { |
1631 | DVar.RefExpr = |
1632 | buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), |
1633 | IterTarget->ConstructLoc); |
1634 | DVar.CKind = OMPC_threadprivate; |
1635 | return DVar; |
1636 | } |
1637 | } |
1638 | } |
1639 | } |
1640 | |
1641 | if (isStackEmpty()) |
1642 | // Not in OpenMP execution region and top scope was already checked. |
1643 | return DVar; |
1644 | |
1645 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1646 | // in a Construct, C/C++, predetermined, p.4] |
1647 | // Static data members are shared. |
1648 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1649 | // in a Construct, C/C++, predetermined, p.7] |
1650 | // Variables with static storage duration that are declared in a scope |
1651 | // inside the construct are shared. |
1652 | if (VD && VD->isStaticDataMember()) { |
1653 | // Check for explicitly specified attributes. |
1654 | const_iterator I = begin(); |
1655 | const_iterator EndI = end(); |
1656 | if (FromParent && I != EndI) |
1657 | ++I; |
1658 | if (I != EndI) { |
1659 | auto It = I->SharingMap.find(D); |
1660 | if (It != I->SharingMap.end()) { |
1661 | const DSAInfo &Data = It->getSecond(); |
1662 | DVar.RefExpr = Data.RefExpr.getPointer(); |
1663 | DVar.PrivateCopy = Data.PrivateCopy; |
1664 | DVar.CKind = Data.Attributes; |
1665 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; |
1666 | DVar.DKind = I->Directive; |
1667 | DVar.Modifier = Data.Modifier; |
1668 | return DVar; |
1669 | } |
1670 | } |
1671 | |
1672 | DVar.CKind = OMPC_shared; |
1673 | return DVar; |
1674 | } |
1675 | |
1676 | auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; |
1677 | // The predetermined shared attribute for const-qualified types having no |
1678 | // mutable members was removed after OpenMP 3.1. |
1679 | if (SemaRef.LangOpts.OpenMP <= 31) { |
1680 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
1681 | // in a Construct, C/C++, predetermined, p.6] |
1682 | // Variables with const qualified type having no mutable member are |
1683 | // shared. |
1684 | if (isConstNotMutableType(SemaRef, D->getType())) { |
1685 | // Variables with const-qualified type having no mutable member may be |
1686 | // listed in a firstprivate clause, even if they are static data members. |
1687 | DSAVarData DVarTemp = hasInnermostDSA( |
1688 | D, |
1689 | [](OpenMPClauseKind C) { |
1690 | return C == OMPC_firstprivate || C == OMPC_shared; |
1691 | }, |
1692 | MatchesAlways, FromParent); |
1693 | if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) |
1694 | return DVarTemp; |
1695 | |
1696 | DVar.CKind = OMPC_shared; |
1697 | return DVar; |
1698 | } |
1699 | } |
1700 | |
1701 | // Explicitly specified attributes and local variables with predetermined |
1702 | // attributes. |
1703 | const_iterator I = begin(); |
1704 | const_iterator EndI = end(); |
1705 | if (FromParent && I != EndI) |
1706 | ++I; |
1707 | if (I == EndI) |
1708 | return DVar; |
1709 | auto It = I->SharingMap.find(D); |
1710 | if (It != I->SharingMap.end()) { |
1711 | const DSAInfo &Data = It->getSecond(); |
1712 | DVar.RefExpr = Data.RefExpr.getPointer(); |
1713 | DVar.PrivateCopy = Data.PrivateCopy; |
1714 | DVar.CKind = Data.Attributes; |
1715 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; |
1716 | DVar.DKind = I->Directive; |
1717 | DVar.Modifier = Data.Modifier; |
1718 | } |
1719 | |
1720 | return DVar; |
1721 | } |
1722 | |
1723 | const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, |
1724 | bool FromParent) const { |
1725 | if (isStackEmpty()) { |
1726 | const_iterator I; |
1727 | return getDSA(I, D); |
1728 | } |
1729 | D = getCanonicalDecl(D); |
1730 | const_iterator StartI = begin(); |
1731 | const_iterator EndI = end(); |
1732 | if (FromParent && StartI != EndI) |
1733 | ++StartI; |
1734 | return getDSA(StartI, D); |
1735 | } |
1736 | |
1737 | const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, |
1738 | unsigned Level) const { |
1739 | if (getStackSize() <= Level) |
1740 | return DSAVarData(); |
1741 | D = getCanonicalDecl(D); |
1742 | const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); |
1743 | return getDSA(StartI, D); |
1744 | } |
1745 | |
1746 | const DSAStackTy::DSAVarData |
1747 | DSAStackTy::hasDSA(ValueDecl *D, |
1748 | const llvm::function_ref<bool(OpenMPClauseKind)> CPred, |
1749 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, |
1750 | bool FromParent) const { |
1751 | if (isStackEmpty()) |
1752 | return {}; |
1753 | D = getCanonicalDecl(D); |
1754 | const_iterator I = begin(); |
1755 | const_iterator EndI = end(); |
1756 | if (FromParent && I != EndI) |
1757 | ++I; |
1758 | for (; I != EndI; ++I) { |
1759 | if (!DPred(I->Directive) && |
1760 | !isImplicitOrExplicitTaskingRegion(I->Directive)) |
1761 | continue; |
1762 | const_iterator NewI = I; |
1763 | DSAVarData DVar = getDSA(NewI, D); |
1764 | if (I == NewI && CPred(DVar.CKind)) |
1765 | return DVar; |
1766 | } |
1767 | return {}; |
1768 | } |
1769 | |
1770 | const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( |
1771 | ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, |
1772 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, |
1773 | bool FromParent) const { |
1774 | if (isStackEmpty()) |
1775 | return {}; |
1776 | D = getCanonicalDecl(D); |
1777 | const_iterator StartI = begin(); |
1778 | const_iterator EndI = end(); |
1779 | if (FromParent && StartI != EndI) |
1780 | ++StartI; |
1781 | if (StartI == EndI || !DPred(StartI->Directive)) |
1782 | return {}; |
1783 | const_iterator NewI = StartI; |
1784 | DSAVarData DVar = getDSA(NewI, D); |
1785 | return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); |
1786 | } |
1787 | |
1788 | bool DSAStackTy::hasExplicitDSA( |
1789 | const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, |
1790 | unsigned Level, bool NotLastprivate) const { |
1791 | if (getStackSize() <= Level) |
1792 | return false; |
1793 | D = getCanonicalDecl(D); |
1794 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); |
1795 | auto I = StackElem.SharingMap.find(D); |
1796 | if (I != StackElem.SharingMap.end() && |
1797 | I->getSecond().RefExpr.getPointer() && |
1798 | CPred(I->getSecond().Attributes) && |
1799 | (!NotLastprivate || !I->getSecond().RefExpr.getInt())) |
1800 | return true; |
1801 | // Check predetermined rules for the loop control variables. |
1802 | auto LI = StackElem.LCVMap.find(D); |
1803 | if (LI != StackElem.LCVMap.end()) |
1804 | return CPred(OMPC_private); |
1805 | return false; |
1806 | } |
1807 | |
1808 | bool DSAStackTy::hasExplicitDirective( |
1809 | const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, |
1810 | unsigned Level) const { |
1811 | if (getStackSize() <= Level) |
1812 | return false; |
1813 | const SharingMapTy &StackElem = getStackElemAtLevel(Level); |
1814 | return DPred(StackElem.Directive); |
1815 | } |
1816 | |
1817 | bool DSAStackTy::hasDirective( |
1818 | const llvm::function_ref<bool(OpenMPDirectiveKind, |
1819 | const DeclarationNameInfo &, SourceLocation)> |
1820 | DPred, |
1821 | bool FromParent) const { |
1822 | // We look only in the enclosing region. |
1823 | size_t Skip = FromParent ? 2 : 1; |
1824 | for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); |
1825 | I != E; ++I) { |
1826 | if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) |
1827 | return true; |
1828 | } |
1829 | return false; |
1830 | } |
1831 | |
1832 | void Sema::InitDataSharingAttributesStack() { |
1833 | VarDataSharingAttributesStack = new DSAStackTy(*this); |
1834 | } |
1835 | |
1836 | #define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ) static_cast<DSAStackTy *>(VarDataSharingAttributesStack) |
1837 | |
1838 | void Sema::pushOpenMPFunctionRegion() { |
1839 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->pushFunction(); |
1840 | } |
1841 | |
1842 | void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { |
1843 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->popFunction(OldFSI); |
1844 | } |
1845 | |
1846 | static bool isOpenMPDeviceDelayedContext(Sema &S) { |
1847 | assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1848, __PRETTY_FUNCTION__)) |
1848 | "Expected OpenMP device compilation.")((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1848, __PRETTY_FUNCTION__)); |
1849 | return !S.isInOpenMPTargetExecutionDirective() && |
1850 | !S.isInOpenMPDeclareTargetContext(); |
1851 | } |
1852 | |
1853 | namespace { |
1854 | /// Status of the function emission on the host/device. |
1855 | enum class FunctionEmissionStatus { |
1856 | Emitted, |
1857 | Discarded, |
1858 | Unknown, |
1859 | }; |
1860 | } // anonymous namespace |
1861 | |
1862 | Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, |
1863 | unsigned DiagID) { |
1864 | assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1865, __PRETTY_FUNCTION__)) |
1865 | "Expected OpenMP device compilation.")((LangOpts.OpenMP && LangOpts.OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast<void > (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1865, __PRETTY_FUNCTION__)); |
1866 | |
1867 | FunctionDecl *FD = getCurFunctionDecl(); |
1868 | DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; |
1869 | if (FD) { |
1870 | FunctionEmissionStatus FES = getEmissionStatus(FD); |
1871 | switch (FES) { |
1872 | case FunctionEmissionStatus::Emitted: |
1873 | Kind = DeviceDiagBuilder::K_Immediate; |
1874 | break; |
1875 | case FunctionEmissionStatus::Unknown: |
1876 | Kind = isOpenMPDeviceDelayedContext(*this) |
1877 | ? DeviceDiagBuilder::K_Deferred |
1878 | : DeviceDiagBuilder::K_Immediate; |
1879 | break; |
1880 | case FunctionEmissionStatus::TemplateDiscarded: |
1881 | case FunctionEmissionStatus::OMPDiscarded: |
1882 | Kind = DeviceDiagBuilder::K_Nop; |
1883 | break; |
1884 | case FunctionEmissionStatus::CUDADiscarded: |
1885 | llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1885); |
1886 | break; |
1887 | } |
1888 | } |
1889 | |
1890 | return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); |
1891 | } |
1892 | |
1893 | Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, |
1894 | unsigned DiagID) { |
1895 | assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && "Expected OpenMP host compilation.") ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1896, __PRETTY_FUNCTION__)) |
1896 | "Expected OpenMP host compilation.")((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && "Expected OpenMP host compilation.") ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1896, __PRETTY_FUNCTION__)); |
1897 | FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); |
1898 | DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; |
1899 | switch (FES) { |
1900 | case FunctionEmissionStatus::Emitted: |
1901 | Kind = DeviceDiagBuilder::K_Immediate; |
1902 | break; |
1903 | case FunctionEmissionStatus::Unknown: |
1904 | Kind = DeviceDiagBuilder::K_Deferred; |
1905 | break; |
1906 | case FunctionEmissionStatus::TemplateDiscarded: |
1907 | case FunctionEmissionStatus::OMPDiscarded: |
1908 | case FunctionEmissionStatus::CUDADiscarded: |
1909 | Kind = DeviceDiagBuilder::K_Nop; |
1910 | break; |
1911 | } |
1912 | |
1913 | return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); |
1914 | } |
1915 | |
1916 | static OpenMPDefaultmapClauseKind |
1917 | getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { |
1918 | if (LO.OpenMP <= 45) { |
1919 | if (VD->getType().getNonReferenceType()->isScalarType()) |
1920 | return OMPC_DEFAULTMAP_scalar; |
1921 | return OMPC_DEFAULTMAP_aggregate; |
1922 | } |
1923 | if (VD->getType().getNonReferenceType()->isAnyPointerType()) |
1924 | return OMPC_DEFAULTMAP_pointer; |
1925 | if (VD->getType().getNonReferenceType()->isScalarType()) |
1926 | return OMPC_DEFAULTMAP_scalar; |
1927 | return OMPC_DEFAULTMAP_aggregate; |
1928 | } |
1929 | |
1930 | bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, |
1931 | unsigned OpenMPCaptureLevel) const { |
1932 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 1932, __PRETTY_FUNCTION__)); |
1933 | |
1934 | ASTContext &Ctx = getASTContext(); |
1935 | bool IsByRef = true; |
1936 | |
1937 | // Find the directive that is associated with the provided scope. |
1938 | D = cast<ValueDecl>(D->getCanonicalDecl()); |
1939 | QualType Ty = D->getType(); |
1940 | |
1941 | bool IsVariableUsedInMapClause = false; |
1942 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { |
1943 | // This table summarizes how a given variable should be passed to the device |
1944 | // given its type and the clauses where it appears. This table is based on |
1945 | // the description in OpenMP 4.5 [2.10.4, target Construct] and |
1946 | // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. |
1947 | // |
1948 | // ========================================================================= |
1949 | // | type | defaultmap | pvt | first | is_device_ptr | map | res. | |
1950 | // | |(tofrom:scalar)| | pvt | | | | |
1951 | // ========================================================================= |
1952 | // | scl | | | | - | | bycopy| |
1953 | // | scl | | - | x | - | - | bycopy| |
1954 | // | scl | | x | - | - | - | null | |
1955 | // | scl | x | | | - | | byref | |
1956 | // | scl | x | - | x | - | - | bycopy| |
1957 | // | scl | x | x | - | - | - | null | |
1958 | // | scl | | - | - | - | x | byref | |
1959 | // | scl | x | - | - | - | x | byref | |
1960 | // |
1961 | // | agg | n.a. | | | - | | byref | |
1962 | // | agg | n.a. | - | x | - | - | byref | |
1963 | // | agg | n.a. | x | - | - | - | null | |
1964 | // | agg | n.a. | - | - | - | x | byref | |
1965 | // | agg | n.a. | - | - | - | x[] | byref | |
1966 | // |
1967 | // | ptr | n.a. | | | - | | bycopy| |
1968 | // | ptr | n.a. | - | x | - | - | bycopy| |
1969 | // | ptr | n.a. | x | - | - | - | null | |
1970 | // | ptr | n.a. | - | - | - | x | byref | |
1971 | // | ptr | n.a. | - | - | - | x[] | bycopy| |
1972 | // | ptr | n.a. | - | - | x | | bycopy| |
1973 | // | ptr | n.a. | - | - | x | x | bycopy| |
1974 | // | ptr | n.a. | - | - | x | x[] | bycopy| |
1975 | // ========================================================================= |
1976 | // Legend: |
1977 | // scl - scalar |
1978 | // ptr - pointer |
1979 | // agg - aggregate |
1980 | // x - applies |
1981 | // - - invalid in this combination |
1982 | // [] - mapped with an array section |
1983 | // byref - should be mapped by reference |
1984 | // byval - should be mapped by value |
1985 | // null - initialize a local variable to null on the device |
1986 | // |
1987 | // Observations: |
1988 | // - All scalar declarations that show up in a map clause have to be passed |
1989 | // by reference, because they may have been mapped in the enclosing data |
1990 | // environment. |
1991 | // - If the scalar value does not fit the size of uintptr, it has to be |
1992 | // passed by reference, regardless the result in the table above. |
1993 | // - For pointers mapped by value that have either an implicit map or an |
1994 | // array section, the runtime library may pass the NULL value to the |
1995 | // device instead of the value passed to it by the compiler. |
1996 | |
1997 | if (Ty->isReferenceType()) |
1998 | Ty = Ty->castAs<ReferenceType>()->getPointeeType(); |
1999 | |
2000 | // Locate map clauses and see if the variable being captured is referred to |
2001 | // in any of those clauses. Here we only care about variables, not fields, |
2002 | // because fields are part of aggregates. |
2003 | bool IsVariableAssociatedWithSection = false; |
2004 | |
2005 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDeclAtLevel( |
2006 | D, Level, |
2007 | [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( |
2008 | OMPClauseMappableExprCommon::MappableExprComponentListRef |
2009 | MapExprComponents, |
2010 | OpenMPClauseKind WhereFoundClauseKind) { |
2011 | // Only the map clause information influences how a variable is |
2012 | // captured. E.g. is_device_ptr does not require changing the default |
2013 | // behavior. |
2014 | if (WhereFoundClauseKind != OMPC_map) |
2015 | return false; |
2016 | |
2017 | auto EI = MapExprComponents.rbegin(); |
2018 | auto EE = MapExprComponents.rend(); |
2019 | |
2020 | assert(EI != EE && "Invalid map expression!")((EI != EE && "Invalid map expression!") ? static_cast <void> (0) : __assert_fail ("EI != EE && \"Invalid map expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2020, __PRETTY_FUNCTION__)); |
2021 | |
2022 | if (isa<DeclRefExpr>(EI->getAssociatedExpression())) |
2023 | IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; |
2024 | |
2025 | ++EI; |
2026 | if (EI == EE) |
2027 | return false; |
2028 | |
2029 | if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || |
2030 | isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || |
2031 | isa<MemberExpr>(EI->getAssociatedExpression()) || |
2032 | isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { |
2033 | IsVariableAssociatedWithSection = true; |
2034 | // There is nothing more we need to know about this variable. |
2035 | return true; |
2036 | } |
2037 | |
2038 | // Keep looking for more map info. |
2039 | return false; |
2040 | }); |
2041 | |
2042 | if (IsVariableUsedInMapClause) { |
2043 | // If variable is identified in a map clause it is always captured by |
2044 | // reference except if it is a pointer that is dereferenced somehow. |
2045 | IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); |
2046 | } else { |
2047 | // By default, all the data that has a scalar type is mapped by copy |
2048 | // (except for reduction variables). |
2049 | // Defaultmap scalar is mutual exclusive to defaultmap pointer |
2050 | IsByRef = |
2051 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceCaptureByReferenceInTargetExecutable() && |
2052 | !Ty->isAnyPointerType()) || |
2053 | !Ty->isScalarType() || |
2054 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isDefaultmapCapturedByRef( |
2055 | Level, getVariableCategoryFromDecl(LangOpts, D)) || |
2056 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( |
2057 | D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); |
2058 | } |
2059 | } |
2060 | |
2061 | if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { |
2062 | IsByRef = |
2063 | ((IsVariableUsedInMapClause && |
2064 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCaptureRegion(Level, OpenMPCaptureLevel) == |
2065 | OMPD_target) || |
2066 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( |
2067 | D, |
2068 | [](OpenMPClauseKind K) -> bool { |
2069 | return K == OMPC_firstprivate; |
2070 | }, |
2071 | Level, /*NotLastprivate=*/true) || |
2072 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isUsesAllocatorsDecl(Level, D))) && |
2073 | // If the variable is artificial and must be captured by value - try to |
2074 | // capture by value. |
2075 | !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && |
2076 | !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && |
2077 | // If the variable is implicitly firstprivate and scalar - capture by |
2078 | // copy |
2079 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate && |
2080 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( |
2081 | D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) && |
2082 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D, Level).first); |
2083 | } |
2084 | |
2085 | // When passing data by copy, we need to make sure it fits the uintptr size |
2086 | // and alignment, because the runtime library only deals with uintptr types. |
2087 | // If it does not fit the uintptr size, we need to pass the data by reference |
2088 | // instead. |
2089 | if (!IsByRef && |
2090 | (Ctx.getTypeSizeInChars(Ty) > |
2091 | Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || |
2092 | Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { |
2093 | IsByRef = true; |
2094 | } |
2095 | |
2096 | return IsByRef; |
2097 | } |
2098 | |
2099 | unsigned Sema::getOpenMPNestingLevel() const { |
2100 | assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail ("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2100, __PRETTY_FUNCTION__)); |
2101 | return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getNestingLevel(); |
2102 | } |
2103 | |
2104 | bool Sema::isInOpenMPTargetExecutionDirective() const { |
2105 | return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && |
2106 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()) || |
2107 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDirective( |
2108 | [](OpenMPDirectiveKind K, const DeclarationNameInfo &, |
2109 | SourceLocation) -> bool { |
2110 | return isOpenMPTargetExecutionDirective(K); |
2111 | }, |
2112 | false); |
2113 | } |
2114 | |
2115 | VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, |
2116 | unsigned StopAt) { |
2117 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2117, __PRETTY_FUNCTION__)); |
2118 | D = getCanonicalDecl(D); |
2119 | |
2120 | auto *VD = dyn_cast<VarDecl>(D); |
2121 | // Do not capture constexpr variables. |
2122 | if (VD && VD->isConstexpr()) |
2123 | return nullptr; |
2124 | |
2125 | // If we want to determine whether the variable should be captured from the |
2126 | // perspective of the current capturing scope, and we've already left all the |
2127 | // capturing scopes of the top directive on the stack, check from the |
2128 | // perspective of its parent directive (if any) instead. |
2129 | DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( |
2130 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isBodyComplete()); |
2131 | |
2132 | // If we are attempting to capture a global variable in a directive with |
2133 | // 'target' we return true so that this global is also mapped to the device. |
2134 | // |
2135 | if (VD && !VD->hasLocalStorage() && |
2136 | (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { |
2137 | if (isInOpenMPDeclareTargetContext()) { |
2138 | // Try to mark variable as declare target if it is used in capturing |
2139 | // regions. |
2140 | if (LangOpts.OpenMP <= 45 && |
2141 | !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) |
2142 | checkDeclIsAllowedInOpenMPTarget(nullptr, VD); |
2143 | return nullptr; |
2144 | } else if (isInOpenMPTargetExecutionDirective()) { |
2145 | // If the declaration is enclosed in a 'declare target' directive, |
2146 | // then it should not be captured. |
2147 | // |
2148 | if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) |
2149 | return nullptr; |
2150 | CapturedRegionScopeInfo *CSI = nullptr; |
2151 | for (FunctionScopeInfo *FSI : llvm::drop_begin( |
2152 | llvm::reverse(FunctionScopes), |
2153 | CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { |
2154 | if (!isa<CapturingScopeInfo>(FSI)) |
2155 | return nullptr; |
2156 | if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) |
2157 | if (RSI->CapRegionKind == CR_OpenMP) { |
2158 | CSI = RSI; |
2159 | break; |
2160 | } |
2161 | } |
2162 | SmallVector<OpenMPDirectiveKind, 4> Regions; |
2163 | getOpenMPCaptureRegions(Regions, |
2164 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(CSI->OpenMPLevel)); |
2165 | if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) |
2166 | return VD; |
2167 | } |
2168 | } |
2169 | |
2170 | if (CheckScopeInfo) { |
2171 | bool OpenMPFound = false; |
2172 | for (unsigned I = StopAt + 1; I > 0; --I) { |
2173 | FunctionScopeInfo *FSI = FunctionScopes[I - 1]; |
2174 | if(!isa<CapturingScopeInfo>(FSI)) |
2175 | return nullptr; |
2176 | if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) |
2177 | if (RSI->CapRegionKind == CR_OpenMP) { |
2178 | OpenMPFound = true; |
2179 | break; |
2180 | } |
2181 | } |
2182 | if (!OpenMPFound) |
2183 | return nullptr; |
2184 | } |
2185 | |
2186 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_unknown && |
2187 | (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode() || |
2188 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective() != OMPD_unknown)) { |
2189 | auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D); |
2190 | if (Info.first || |
2191 | (VD && VD->hasLocalStorage() && |
2192 | isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) || |
2193 | (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceVarCapturing())) |
2194 | return VD ? VD : Info.second; |
2195 | DSAStackTy::DSAVarData DVarTop = |
2196 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); |
2197 | if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind)) |
2198 | return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); |
2199 | // Threadprivate variables must not be captured. |
2200 | if (isOpenMPThreadPrivate(DVarTop.CKind)) |
2201 | return nullptr; |
2202 | // The variable is not private or it is the variable in the directive with |
2203 | // default(none) clause and not used in any clause. |
2204 | DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDSA( |
2205 | D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, |
2206 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); |
2207 | // Global shared must not be captured. |
2208 | if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && |
2209 | ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() != DSA_none && |
2210 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() != DSA_firstprivate) || |
2211 | DVarTop.CKind == OMPC_shared)) |
2212 | return nullptr; |
2213 | if (DVarPrivate.CKind != OMPC_unknown || |
2214 | (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || |
2215 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate))) |
2216 | return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); |
2217 | } |
2218 | return nullptr; |
2219 | } |
2220 | |
2221 | void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, |
2222 | unsigned Level) const { |
2223 | FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); |
2224 | } |
2225 | |
2226 | void Sema::startOpenMPLoop() { |
2227 | assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2227, __PRETTY_FUNCTION__)); |
2228 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) |
2229 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopInit(); |
2230 | } |
2231 | |
2232 | void Sema::startOpenMPCXXRangeFor() { |
2233 | assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2233, __PRETTY_FUNCTION__)); |
2234 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { |
2235 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(); |
2236 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); |
2237 | } |
2238 | } |
2239 | |
2240 | OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, |
2241 | unsigned CapLevel) const { |
2242 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2242, __PRETTY_FUNCTION__)); |
2243 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective( |
2244 | [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, |
2245 | Level)) { |
2246 | bool IsTriviallyCopyable = |
2247 | D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && |
2248 | !D->getType() |
2249 | .getNonReferenceType() |
2250 | .getCanonicalType() |
2251 | ->getAsCXXRecordDecl(); |
2252 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level); |
2253 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
2254 | getOpenMPCaptureRegions(CaptureRegions, DKind); |
2255 | if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && |
2256 | (IsTriviallyCopyable || |
2257 | !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { |
2258 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( |
2259 | D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, |
2260 | Level, /*NotLastprivate=*/true)) |
2261 | return OMPC_firstprivate; |
2262 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, Level); |
2263 | if (DVar.CKind != OMPC_shared && |
2264 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { |
2265 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addImplicitTaskFirstprivate(Level, D); |
2266 | return OMPC_firstprivate; |
2267 | } |
2268 | } |
2269 | } |
2270 | if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { |
2271 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() > 0 && |
2272 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopStarted()) { |
2273 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(D); |
2274 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); |
2275 | return OMPC_private; |
2276 | } |
2277 | if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getPossiblyLoopCunter() == D->getCanonicalDecl() || |
2278 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(D).first) && |
2279 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( |
2280 | D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && |
2281 | !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) |
2282 | return OMPC_private; |
2283 | } |
2284 | if (const auto *VD = dyn_cast<VarDecl>(D)) { |
2285 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(const_cast<VarDecl *>(VD)) && |
2286 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceVarCapturing() && |
2287 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( |
2288 | D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) |
2289 | return OMPC_private; |
2290 | } |
2291 | // User-defined allocators are private since they must be defined in the |
2292 | // context of target region. |
2293 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && |
2294 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isUsesAllocatorsDecl(Level, D).getValueOr( |
2295 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == |
2296 | DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) |
2297 | return OMPC_private; |
2298 | return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( |
2299 | D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || |
2300 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode() && |
2301 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getClauseParsingMode() == OMPC_private) || |
2302 | // Consider taskgroup reduction descriptor variable a private |
2303 | // to avoid possible capture in the region. |
2304 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective( |
2305 | [](OpenMPDirectiveKind K) { |
2306 | return K == OMPD_taskgroup || |
2307 | ((isOpenMPParallelDirective(K) || |
2308 | isOpenMPWorksharingDirective(K)) && |
2309 | !isOpenMPSimdDirective(K)); |
2310 | }, |
2311 | Level) && |
2312 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isTaskgroupReductionRef(D, Level))) |
2313 | ? OMPC_private |
2314 | : OMPC_unknown; |
2315 | } |
2316 | |
2317 | void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, |
2318 | unsigned Level) { |
2319 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2319, __PRETTY_FUNCTION__)); |
2320 | D = getCanonicalDecl(D); |
2321 | OpenMPClauseKind OMPC = OMPC_unknown; |
2322 | for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getNestingLevel() + 1; I > Level; --I) { |
2323 | const unsigned NewLevel = I - 1; |
2324 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA(D, |
2325 | [&OMPC](const OpenMPClauseKind K) { |
2326 | if (isOpenMPPrivate(K)) { |
2327 | OMPC = K; |
2328 | return true; |
2329 | } |
2330 | return false; |
2331 | }, |
2332 | NewLevel)) |
2333 | break; |
2334 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDeclAtLevel( |
2335 | D, NewLevel, |
2336 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef, |
2337 | OpenMPClauseKind) { return true; })) { |
2338 | OMPC = OMPC_map; |
2339 | break; |
2340 | } |
2341 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, |
2342 | NewLevel)) { |
2343 | OMPC = OMPC_map; |
2344 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->mustBeFirstprivateAtLevel( |
2345 | NewLevel, getVariableCategoryFromDecl(LangOpts, D))) |
2346 | OMPC = OMPC_firstprivate; |
2347 | break; |
2348 | } |
2349 | } |
2350 | if (OMPC != OMPC_unknown) |
2351 | FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); |
2352 | } |
2353 | |
2354 | bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, |
2355 | unsigned CaptureLevel) const { |
2356 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2356, __PRETTY_FUNCTION__)); |
2357 | // Return true if the current level is no longer enclosed in a target region. |
2358 | |
2359 | SmallVector<OpenMPDirectiveKind, 4> Regions; |
2360 | getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); |
2361 | const auto *VD = dyn_cast<VarDecl>(D); |
2362 | return VD && !VD->hasLocalStorage() && |
2363 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDirective(isOpenMPTargetExecutionDirective, |
2364 | Level) && |
2365 | Regions[CaptureLevel] != OMPD_task; |
2366 | } |
2367 | |
2368 | bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, |
2369 | unsigned CaptureLevel) const { |
2370 | assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast <void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2370, __PRETTY_FUNCTION__)); |
2371 | // Return true if the current level is no longer enclosed in a target region. |
2372 | |
2373 | if (const auto *VD = dyn_cast<VarDecl>(D)) { |
2374 | if (!VD->hasLocalStorage()) { |
2375 | DSAStackTy::DSAVarData TopDVar = |
2376 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
2377 | unsigned NumLevels = |
2378 | getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); |
2379 | if (Level == 0) |
2380 | return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; |
2381 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, Level - 1); |
2382 | return DVar.CKind != OMPC_shared || |
2383 | isOpenMPGlobalCapturedDecl( |
2384 | D, Level - 1, |
2385 | getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level - 1)) - 1); |
2386 | } |
2387 | } |
2388 | return true; |
2389 | } |
2390 | |
2391 | void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ); } |
2392 | |
2393 | void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, |
2394 | OMPTraitInfo &TI) { |
2395 | if (!OMPDeclareVariantScopes.empty()) { |
2396 | Diag(Loc, diag::warn_nested_declare_variant); |
2397 | return; |
2398 | } |
2399 | OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); |
2400 | } |
2401 | |
2402 | void Sema::ActOnOpenMPEndDeclareVariant() { |
2403 | assert(isInOpenMPDeclareVariantScope() &&((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!" ) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2404, __PRETTY_FUNCTION__)) |
2404 | "Not in OpenMP declare variant scope!")((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!" ) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2404, __PRETTY_FUNCTION__)); |
2405 | |
2406 | OMPDeclareVariantScopes.pop_back(); |
2407 | } |
2408 | |
2409 | void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, |
2410 | const FunctionDecl *Callee, |
2411 | SourceLocation Loc) { |
2412 | assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.")((LangOpts.OpenMP && "Expected OpenMP compilation mode." ) ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP compilation mode.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2412, __PRETTY_FUNCTION__)); |
2413 | Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = |
2414 | OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); |
2415 | // Ignore host functions during device analyzis. |
2416 | if (LangOpts.OpenMPIsDevice && DevTy && |
2417 | *DevTy == OMPDeclareTargetDeclAttr::DT_Host) |
2418 | return; |
2419 | // Ignore nohost functions during host analyzis. |
2420 | if (!LangOpts.OpenMPIsDevice && DevTy && |
2421 | *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) |
2422 | return; |
2423 | const FunctionDecl *FD = Callee->getMostRecentDecl(); |
2424 | DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); |
2425 | if (LangOpts.OpenMPIsDevice && DevTy && |
2426 | *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { |
2427 | // Diagnose host function called during device codegen. |
2428 | StringRef HostDevTy = |
2429 | getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); |
2430 | Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; |
2431 | Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), |
2432 | diag::note_omp_marked_device_type_here) |
2433 | << HostDevTy; |
2434 | return; |
2435 | } |
2436 | if (!LangOpts.OpenMPIsDevice && DevTy && |
2437 | *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { |
2438 | // Diagnose nohost function called during host codegen. |
2439 | StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( |
2440 | OMPC_device_type, OMPC_DEVICE_TYPE_nohost); |
2441 | Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; |
2442 | Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), |
2443 | diag::note_omp_marked_device_type_here) |
2444 | << NoHostDevTy; |
2445 | } |
2446 | } |
2447 | |
2448 | void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, |
2449 | const DeclarationNameInfo &DirName, |
2450 | Scope *CurScope, SourceLocation Loc) { |
2451 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->push(DKind, DirName, CurScope, Loc); |
2452 | PushExpressionEvaluationContext( |
2453 | ExpressionEvaluationContext::PotentiallyEvaluated); |
2454 | } |
2455 | |
2456 | void Sema::StartOpenMPClause(OpenMPClauseKind K) { |
2457 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(K); |
2458 | } |
2459 | |
2460 | void Sema::EndOpenMPClause() { |
2461 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(/*K=*/OMPC_unknown); |
2462 | } |
2463 | |
2464 | static std::pair<ValueDecl *, bool> |
2465 | getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, |
2466 | SourceRange &ERange, bool AllowArraySection = false); |
2467 | |
2468 | /// Check consistency of the reduction clauses. |
2469 | static void checkReductionClauses(Sema &S, DSAStackTy *Stack, |
2470 | ArrayRef<OMPClause *> Clauses) { |
2471 | bool InscanFound = false; |
2472 | SourceLocation InscanLoc; |
2473 | // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. |
2474 | // A reduction clause without the inscan reduction-modifier may not appear on |
2475 | // a construct on which a reduction clause with the inscan reduction-modifier |
2476 | // appears. |
2477 | for (OMPClause *C : Clauses) { |
2478 | if (C->getClauseKind() != OMPC_reduction) |
2479 | continue; |
2480 | auto *RC = cast<OMPReductionClause>(C); |
2481 | if (RC->getModifier() == OMPC_REDUCTION_inscan) { |
2482 | InscanFound = true; |
2483 | InscanLoc = RC->getModifierLoc(); |
2484 | continue; |
2485 | } |
2486 | if (RC->getModifier() == OMPC_REDUCTION_task) { |
2487 | // OpenMP 5.0, 2.19.5.4 reduction Clause. |
2488 | // A reduction clause with the task reduction-modifier may only appear on |
2489 | // a parallel construct, a worksharing construct or a combined or |
2490 | // composite construct for which any of the aforementioned constructs is a |
2491 | // constituent construct and simd or loop are not constituent constructs. |
2492 | OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); |
2493 | if (!(isOpenMPParallelDirective(CurDir) || |
2494 | isOpenMPWorksharingDirective(CurDir)) || |
2495 | isOpenMPSimdDirective(CurDir)) |
2496 | S.Diag(RC->getModifierLoc(), |
2497 | diag::err_omp_reduction_task_not_parallel_or_worksharing); |
2498 | continue; |
2499 | } |
2500 | } |
2501 | if (InscanFound) { |
2502 | for (OMPClause *C : Clauses) { |
2503 | if (C->getClauseKind() != OMPC_reduction) |
2504 | continue; |
2505 | auto *RC = cast<OMPReductionClause>(C); |
2506 | if (RC->getModifier() != OMPC_REDUCTION_inscan) { |
2507 | S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown |
2508 | ? RC->getBeginLoc() |
2509 | : RC->getModifierLoc(), |
2510 | diag::err_omp_inscan_reduction_expected); |
2511 | S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); |
2512 | continue; |
2513 | } |
2514 | for (Expr *Ref : RC->varlists()) { |
2515 | assert(Ref && "NULL expr in OpenMP nontemporal clause.")((Ref && "NULL expr in OpenMP nontemporal clause.") ? static_cast<void> (0) : __assert_fail ("Ref && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2515, __PRETTY_FUNCTION__)); |
2516 | SourceLocation ELoc; |
2517 | SourceRange ERange; |
2518 | Expr *SimpleRefExpr = Ref; |
2519 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, |
2520 | /*AllowArraySection=*/true); |
2521 | ValueDecl *D = Res.first; |
2522 | if (!D) |
2523 | continue; |
2524 | if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { |
2525 | S.Diag(Ref->getExprLoc(), |
2526 | diag::err_omp_reduction_not_inclusive_exclusive) |
2527 | << Ref->getSourceRange(); |
2528 | } |
2529 | } |
2530 | } |
2531 | } |
2532 | } |
2533 | |
2534 | static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, |
2535 | ArrayRef<OMPClause *> Clauses); |
2536 | static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, |
2537 | bool WithInit); |
2538 | |
2539 | static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, |
2540 | const ValueDecl *D, |
2541 | const DSAStackTy::DSAVarData &DVar, |
2542 | bool IsLoopIterVar = false); |
2543 | |
2544 | void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { |
2545 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] |
2546 | // A variable of class type (or array thereof) that appears in a lastprivate |
2547 | // clause requires an accessible, unambiguous default constructor for the |
2548 | // class type, unless the list item is also specified in a firstprivate |
2549 | // clause. |
2550 | if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { |
2551 | for (OMPClause *C : D->clauses()) { |
2552 | if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { |
2553 | SmallVector<Expr *, 8> PrivateCopies; |
2554 | for (Expr *DE : Clause->varlists()) { |
2555 | if (DE->isValueDependent() || DE->isTypeDependent()) { |
2556 | PrivateCopies.push_back(nullptr); |
2557 | continue; |
2558 | } |
2559 | auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); |
2560 | auto *VD = cast<VarDecl>(DRE->getDecl()); |
2561 | QualType Type = VD->getType().getNonReferenceType(); |
2562 | const DSAStackTy::DSAVarData DVar = |
2563 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); |
2564 | if (DVar.CKind == OMPC_lastprivate) { |
2565 | // Generate helper private variable and initialize it with the |
2566 | // default value. The address of the original variable is replaced |
2567 | // by the address of the new private variable in CodeGen. This new |
2568 | // variable is not added to IdResolver, so the code in the OpenMP |
2569 | // region uses original variable for proper diagnostics. |
2570 | VarDecl *VDPrivate = buildVarDecl( |
2571 | *this, DE->getExprLoc(), Type.getUnqualifiedType(), |
2572 | VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); |
2573 | ActOnUninitializedDecl(VDPrivate); |
2574 | if (VDPrivate->isInvalidDecl()) { |
2575 | PrivateCopies.push_back(nullptr); |
2576 | continue; |
2577 | } |
2578 | PrivateCopies.push_back(buildDeclRefExpr( |
2579 | *this, VDPrivate, DE->getType(), DE->getExprLoc())); |
2580 | } else { |
2581 | // The variable is also a firstprivate, so initialization sequence |
2582 | // for private copy is generated already. |
2583 | PrivateCopies.push_back(nullptr); |
2584 | } |
2585 | } |
2586 | Clause->setPrivateCopies(PrivateCopies); |
2587 | continue; |
2588 | } |
2589 | // Finalize nontemporal clause by handling private copies, if any. |
2590 | if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { |
2591 | SmallVector<Expr *, 8> PrivateRefs; |
2592 | for (Expr *RefExpr : Clause->varlists()) { |
2593 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 2593, __PRETTY_FUNCTION__)); |
2594 | SourceLocation ELoc; |
2595 | SourceRange ERange; |
2596 | Expr *SimpleRefExpr = RefExpr; |
2597 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
2598 | if (Res.second) |
2599 | // It will be analyzed later. |
2600 | PrivateRefs.push_back(RefExpr); |
2601 | ValueDecl *D = Res.first; |
2602 | if (!D) |
2603 | continue; |
2604 | |
2605 | const DSAStackTy::DSAVarData DVar = |
2606 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
2607 | PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy |
2608 | : SimpleRefExpr); |
2609 | } |
2610 | Clause->setPrivateRefs(PrivateRefs); |
2611 | continue; |
2612 | } |
2613 | if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { |
2614 | for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { |
2615 | OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); |
2616 | auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); |
2617 | if (!DRE) |
2618 | continue; |
2619 | ValueDecl *VD = DRE->getDecl(); |
2620 | if (!VD || !isa<VarDecl>(VD)) |
2621 | continue; |
2622 | DSAStackTy::DSAVarData DVar = |
2623 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); |
2624 | // OpenMP [2.12.5, target Construct] |
2625 | // Memory allocators that appear in a uses_allocators clause cannot |
2626 | // appear in other data-sharing attribute clauses or data-mapping |
2627 | // attribute clauses in the same construct. |
2628 | Expr *MapExpr = nullptr; |
2629 | if (DVar.RefExpr || |
2630 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( |
2631 | VD, /*CurrentRegionOnly=*/true, |
2632 | [VD, &MapExpr]( |
2633 | OMPClauseMappableExprCommon::MappableExprComponentListRef |
2634 | MapExprComponents, |
2635 | OpenMPClauseKind C) { |
2636 | auto MI = MapExprComponents.rbegin(); |
2637 | auto ME = MapExprComponents.rend(); |
2638 | if (MI != ME && |
2639 | MI->getAssociatedDeclaration()->getCanonicalDecl() == |
2640 | VD->getCanonicalDecl()) { |
2641 | MapExpr = MI->getAssociatedExpression(); |
2642 | return true; |
2643 | } |
2644 | return false; |
2645 | })) { |
2646 | Diag(D.Allocator->getExprLoc(), |
2647 | diag::err_omp_allocator_used_in_clauses) |
2648 | << D.Allocator->getSourceRange(); |
2649 | if (DVar.RefExpr) |
2650 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); |
2651 | else |
2652 | Diag(MapExpr->getExprLoc(), diag::note_used_here) |
2653 | << MapExpr->getSourceRange(); |
2654 | } |
2655 | } |
2656 | continue; |
2657 | } |
2658 | } |
2659 | // Check allocate clauses. |
2660 | if (!CurContext->isDependentContext()) |
2661 | checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D->clauses()); |
2662 | checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D->clauses()); |
2663 | } |
2664 | |
2665 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->pop(); |
2666 | DiscardCleanupsInEvaluationContext(); |
2667 | PopExpressionEvaluationContext(); |
2668 | } |
2669 | |
2670 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, |
2671 | Expr *NumIterations, Sema &SemaRef, |
2672 | Scope *S, DSAStackTy *Stack); |
2673 | |
2674 | namespace { |
2675 | |
2676 | class VarDeclFilterCCC final : public CorrectionCandidateCallback { |
2677 | private: |
2678 | Sema &SemaRef; |
2679 | |
2680 | public: |
2681 | explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} |
2682 | bool ValidateCandidate(const TypoCorrection &Candidate) override { |
2683 | NamedDecl *ND = Candidate.getCorrectionDecl(); |
2684 | if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { |
2685 | return VD->hasGlobalStorage() && |
2686 | SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), |
2687 | SemaRef.getCurScope()); |
2688 | } |
2689 | return false; |
2690 | } |
2691 | |
2692 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
2693 | return std::make_unique<VarDeclFilterCCC>(*this); |
2694 | } |
2695 | |
2696 | }; |
2697 | |
2698 | class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { |
2699 | private: |
2700 | Sema &SemaRef; |
2701 | |
2702 | public: |
2703 | explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} |
2704 | bool ValidateCandidate(const TypoCorrection &Candidate) override { |
2705 | NamedDecl *ND = Candidate.getCorrectionDecl(); |
2706 | if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || |
2707 | isa<FunctionDecl>(ND))) { |
2708 | return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), |
2709 | SemaRef.getCurScope()); |
2710 | } |
2711 | return false; |
2712 | } |
2713 | |
2714 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
2715 | return std::make_unique<VarOrFuncDeclFilterCCC>(*this); |
2716 | } |
2717 | }; |
2718 | |
2719 | } // namespace |
2720 | |
2721 | ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, |
2722 | CXXScopeSpec &ScopeSpec, |
2723 | const DeclarationNameInfo &Id, |
2724 | OpenMPDirectiveKind Kind) { |
2725 | LookupResult Lookup(*this, Id, LookupOrdinaryName); |
2726 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); |
2727 | |
2728 | if (Lookup.isAmbiguous()) |
2729 | return ExprError(); |
2730 | |
2731 | VarDecl *VD; |
2732 | if (!Lookup.isSingleResult()) { |
2733 | VarDeclFilterCCC CCC(*this); |
2734 | if (TypoCorrection Corrected = |
2735 | CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, |
2736 | CTK_ErrorRecovery)) { |
2737 | diagnoseTypo(Corrected, |
2738 | PDiag(Lookup.empty() |
2739 | ? diag::err_undeclared_var_use_suggest |
2740 | : diag::err_omp_expected_var_arg_suggest) |
2741 | << Id.getName()); |
2742 | VD = Corrected.getCorrectionDeclAs<VarDecl>(); |
2743 | } else { |
2744 | Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use |
2745 | : diag::err_omp_expected_var_arg) |
2746 | << Id.getName(); |
2747 | return ExprError(); |
2748 | } |
2749 | } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { |
2750 | Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); |
2751 | Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); |
2752 | return ExprError(); |
2753 | } |
2754 | Lookup.suppressDiagnostics(); |
2755 | |
2756 | // OpenMP [2.9.2, Syntax, C/C++] |
2757 | // Variables must be file-scope, namespace-scope, or static block-scope. |
2758 | if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { |
2759 | Diag(Id.getLoc(), diag::err_omp_global_var_arg) |
2760 | << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); |
2761 | bool IsDecl = |
2762 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
2763 | Diag(VD->getLocation(), |
2764 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
2765 | << VD; |
2766 | return ExprError(); |
2767 | } |
2768 | |
2769 | VarDecl *CanonicalVD = VD->getCanonicalDecl(); |
2770 | NamedDecl *ND = CanonicalVD; |
2771 | // OpenMP [2.9.2, Restrictions, C/C++, p.2] |
2772 | // A threadprivate directive for file-scope variables must appear outside |
2773 | // any definition or declaration. |
2774 | if (CanonicalVD->getDeclContext()->isTranslationUnit() && |
2775 | !getCurLexicalContext()->isTranslationUnit()) { |
2776 | Diag(Id.getLoc(), diag::err_omp_var_scope) |
2777 | << getOpenMPDirectiveName(Kind) << VD; |
2778 | bool IsDecl = |
2779 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
2780 | Diag(VD->getLocation(), |
2781 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
2782 | << VD; |
2783 | return ExprError(); |
2784 | } |
2785 | // OpenMP [2.9.2, Restrictions, C/C++, p.3] |
2786 | // A threadprivate directive for static class member variables must appear |
2787 | // in the class definition, in the same scope in which the member |
2788 | // variables are declared. |
2789 | if (CanonicalVD->isStaticDataMember() && |
2790 | !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { |
2791 | Diag(Id.getLoc(), diag::err_omp_var_scope) |
2792 | << getOpenMPDirectiveName(Kind) << VD; |
2793 | bool IsDecl = |
2794 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
2795 | Diag(VD->getLocation(), |
2796 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
2797 | << VD; |
2798 | return ExprError(); |
2799 | } |
2800 | // OpenMP [2.9.2, Restrictions, C/C++, p.4] |
2801 | // A threadprivate directive for namespace-scope variables must appear |
2802 | // outside any definition or declaration other than the namespace |
2803 | // definition itself. |
2804 | if (CanonicalVD->getDeclContext()->isNamespace() && |
2805 | (!getCurLexicalContext()->isFileContext() || |
2806 | !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { |
2807 | Diag(Id.getLoc(), diag::err_omp_var_scope) |
2808 | << getOpenMPDirectiveName(Kind) << VD; |
2809 | bool IsDecl = |
2810 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
2811 | Diag(VD->getLocation(), |
2812 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
2813 | << VD; |
2814 | return ExprError(); |
2815 | } |
2816 | // OpenMP [2.9.2, Restrictions, C/C++, p.6] |
2817 | // A threadprivate directive for static block-scope variables must appear |
2818 | // in the scope of the variable and not in a nested scope. |
2819 | if (CanonicalVD->isLocalVarDecl() && CurScope && |
2820 | !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { |
2821 | Diag(Id.getLoc(), diag::err_omp_var_scope) |
2822 | << getOpenMPDirectiveName(Kind) << VD; |
2823 | bool IsDecl = |
2824 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
2825 | Diag(VD->getLocation(), |
2826 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
2827 | << VD; |
2828 | return ExprError(); |
2829 | } |
2830 | |
2831 | // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] |
2832 | // A threadprivate directive must lexically precede all references to any |
2833 | // of the variables in its list. |
2834 | if (Kind == OMPD_threadprivate && VD->isUsed() && |
2835 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { |
2836 | Diag(Id.getLoc(), diag::err_omp_var_used) |
2837 | << getOpenMPDirectiveName(Kind) << VD; |
2838 | return ExprError(); |
2839 | } |
2840 | |
2841 | QualType ExprType = VD->getType().getNonReferenceType(); |
2842 | return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), |
2843 | SourceLocation(), VD, |
2844 | /*RefersToEnclosingVariableOrCapture=*/false, |
2845 | Id.getLoc(), ExprType, VK_LValue); |
2846 | } |
2847 | |
2848 | Sema::DeclGroupPtrTy |
2849 | Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, |
2850 | ArrayRef<Expr *> VarList) { |
2851 | if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { |
2852 | CurContext->addDecl(D); |
2853 | return DeclGroupPtrTy::make(DeclGroupRef(D)); |
2854 | } |
2855 | return nullptr; |
2856 | } |
2857 | |
2858 | namespace { |
2859 | class LocalVarRefChecker final |
2860 | : public ConstStmtVisitor<LocalVarRefChecker, bool> { |
2861 | Sema &SemaRef; |
2862 | |
2863 | public: |
2864 | bool VisitDeclRefExpr(const DeclRefExpr *E) { |
2865 | if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { |
2866 | if (VD->hasLocalStorage()) { |
2867 | SemaRef.Diag(E->getBeginLoc(), |
2868 | diag::err_omp_local_var_in_threadprivate_init) |
2869 | << E->getSourceRange(); |
2870 | SemaRef.Diag(VD->getLocation(), diag::note_defined_here) |
2871 | << VD << VD->getSourceRange(); |
2872 | return true; |
2873 | } |
2874 | } |
2875 | return false; |
2876 | } |
2877 | bool VisitStmt(const Stmt *S) { |
2878 | for (const Stmt *Child : S->children()) { |
2879 | if (Child && Visit(Child)) |
2880 | return true; |
2881 | } |
2882 | return false; |
2883 | } |
2884 | explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} |
2885 | }; |
2886 | } // namespace |
2887 | |
2888 | OMPThreadPrivateDecl * |
2889 | Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { |
2890 | SmallVector<Expr *, 8> Vars; |
2891 | for (Expr *RefExpr : VarList) { |
2892 | auto *DE = cast<DeclRefExpr>(RefExpr); |
2893 | auto *VD = cast<VarDecl>(DE->getDecl()); |
2894 | SourceLocation ILoc = DE->getExprLoc(); |
2895 | |
2896 | // Mark variable as used. |
2897 | VD->setReferenced(); |
2898 | VD->markUsed(Context); |
2899 | |
2900 | QualType QType = VD->getType(); |
2901 | if (QType->isDependentType() || QType->isInstantiationDependentType()) { |
2902 | // It will be analyzed later. |
2903 | Vars.push_back(DE); |
2904 | continue; |
2905 | } |
2906 | |
2907 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] |
2908 | // A threadprivate variable must not have an incomplete type. |
2909 | if (RequireCompleteType(ILoc, VD->getType(), |
2910 | diag::err_omp_threadprivate_incomplete_type)) { |
2911 | continue; |
2912 | } |
2913 | |
2914 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] |
2915 | // A threadprivate variable must not have a reference type. |
2916 | if (VD->getType()->isReferenceType()) { |
2917 | Diag(ILoc, diag::err_omp_ref_type_arg) |
2918 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); |
2919 | bool IsDecl = |
2920 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
2921 | Diag(VD->getLocation(), |
2922 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
2923 | << VD; |
2924 | continue; |
2925 | } |
2926 | |
2927 | // Check if this is a TLS variable. If TLS is not being supported, produce |
2928 | // the corresponding diagnostic. |
2929 | if ((VD->getTLSKind() != VarDecl::TLS_None && |
2930 | !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && |
2931 | getLangOpts().OpenMPUseTLS && |
2932 | getASTContext().getTargetInfo().isTLSSupported())) || |
2933 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && |
2934 | !VD->isLocalVarDecl())) { |
2935 | Diag(ILoc, diag::err_omp_var_thread_local) |
2936 | << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); |
2937 | bool IsDecl = |
2938 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
2939 | Diag(VD->getLocation(), |
2940 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
2941 | << VD; |
2942 | continue; |
2943 | } |
2944 | |
2945 | // Check if initial value of threadprivate variable reference variable with |
2946 | // local storage (it is not supported by runtime). |
2947 | if (const Expr *Init = VD->getAnyInitializer()) { |
2948 | LocalVarRefChecker Checker(*this); |
2949 | if (Checker.Visit(Init)) |
2950 | continue; |
2951 | } |
2952 | |
2953 | Vars.push_back(RefExpr); |
2954 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_threadprivate); |
2955 | VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( |
2956 | Context, SourceRange(Loc, Loc))); |
2957 | if (ASTMutationListener *ML = Context.getASTMutationListener()) |
2958 | ML->DeclarationMarkedOpenMPThreadPrivate(VD); |
2959 | } |
2960 | OMPThreadPrivateDecl *D = nullptr; |
2961 | if (!Vars.empty()) { |
2962 | D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, |
2963 | Vars); |
2964 | D->setAccess(AS_public); |
2965 | } |
2966 | return D; |
2967 | } |
2968 | |
2969 | static OMPAllocateDeclAttr::AllocatorTypeTy |
2970 | getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { |
2971 | if (!Allocator) |
2972 | return OMPAllocateDeclAttr::OMPNullMemAlloc; |
2973 | if (Allocator->isTypeDependent() || Allocator->isValueDependent() || |
2974 | Allocator->isInstantiationDependent() || |
2975 | Allocator->containsUnexpandedParameterPack()) |
2976 | return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; |
2977 | auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; |
2978 | const Expr *AE = Allocator->IgnoreParenImpCasts(); |
2979 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { |
2980 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); |
2981 | const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); |
2982 | llvm::FoldingSetNodeID AEId, DAEId; |
2983 | AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); |
2984 | DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); |
2985 | if (AEId == DAEId) { |
2986 | AllocatorKindRes = AllocatorKind; |
2987 | break; |
2988 | } |
2989 | } |
2990 | return AllocatorKindRes; |
2991 | } |
2992 | |
2993 | static bool checkPreviousOMPAllocateAttribute( |
2994 | Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, |
2995 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { |
2996 | if (!VD->hasAttr<OMPAllocateDeclAttr>()) |
2997 | return false; |
2998 | const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); |
2999 | Expr *PrevAllocator = A->getAllocator(); |
3000 | OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = |
3001 | getAllocatorKind(S, Stack, PrevAllocator); |
3002 | bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; |
3003 | if (AllocatorsMatch && |
3004 | AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && |
3005 | Allocator && PrevAllocator) { |
3006 | const Expr *AE = Allocator->IgnoreParenImpCasts(); |
3007 | const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); |
3008 | llvm::FoldingSetNodeID AEId, PAEId; |
3009 | AE->Profile(AEId, S.Context, /*Canonical=*/true); |
3010 | PAE->Profile(PAEId, S.Context, /*Canonical=*/true); |
3011 | AllocatorsMatch = AEId == PAEId; |
3012 | } |
3013 | if (!AllocatorsMatch) { |
3014 | SmallString<256> AllocatorBuffer; |
3015 | llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); |
3016 | if (Allocator) |
3017 | Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); |
3018 | SmallString<256> PrevAllocatorBuffer; |
3019 | llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); |
3020 | if (PrevAllocator) |
3021 | PrevAllocator->printPretty(PrevAllocatorStream, nullptr, |
3022 | S.getPrintingPolicy()); |
3023 | |
3024 | SourceLocation AllocatorLoc = |
3025 | Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); |
3026 | SourceRange AllocatorRange = |
3027 | Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); |
3028 | SourceLocation PrevAllocatorLoc = |
3029 | PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); |
3030 | SourceRange PrevAllocatorRange = |
3031 | PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); |
3032 | S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) |
3033 | << (Allocator ? 1 : 0) << AllocatorStream.str() |
3034 | << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() |
3035 | << AllocatorRange; |
3036 | S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) |
3037 | << PrevAllocatorRange; |
3038 | return true; |
3039 | } |
3040 | return false; |
3041 | } |
3042 | |
3043 | static void |
3044 | applyOMPAllocateAttribute(Sema &S, VarDecl *VD, |
3045 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, |
3046 | Expr *Allocator, SourceRange SR) { |
3047 | if (VD->hasAttr<OMPAllocateDeclAttr>()) |
3048 | return; |
3049 | if (Allocator && |
3050 | (Allocator->isTypeDependent() || Allocator->isValueDependent() || |
3051 | Allocator->isInstantiationDependent() || |
3052 | Allocator->containsUnexpandedParameterPack())) |
3053 | return; |
3054 | auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, |
3055 | Allocator, SR); |
3056 | VD->addAttr(A); |
3057 | if (ASTMutationListener *ML = S.Context.getASTMutationListener()) |
3058 | ML->DeclarationMarkedOpenMPAllocate(VD, A); |
3059 | } |
3060 | |
3061 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( |
3062 | SourceLocation Loc, ArrayRef<Expr *> VarList, |
3063 | ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { |
3064 | assert(Clauses.size() <= 1 && "Expected at most one clause.")((Clauses.size() <= 1 && "Expected at most one clause." ) ? static_cast<void> (0) : __assert_fail ("Clauses.size() <= 1 && \"Expected at most one clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3064, __PRETTY_FUNCTION__)); |
3065 | Expr *Allocator = nullptr; |
3066 | if (Clauses.empty()) { |
3067 | // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. |
3068 | // allocate directives that appear in a target region must specify an |
3069 | // allocator clause unless a requires directive with the dynamic_allocators |
3070 | // clause is present in the same compilation unit. |
3071 | if (LangOpts.OpenMPIsDevice && |
3072 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) |
3073 | targetDiag(Loc, diag::err_expected_allocator_clause); |
3074 | } else { |
3075 | Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); |
3076 | } |
3077 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = |
3078 | getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), Allocator); |
3079 | SmallVector<Expr *, 8> Vars; |
3080 | for (Expr *RefExpr : VarList) { |
3081 | auto *DE = cast<DeclRefExpr>(RefExpr); |
3082 | auto *VD = cast<VarDecl>(DE->getDecl()); |
3083 | |
3084 | // Check if this is a TLS variable or global register. |
3085 | if (VD->getTLSKind() != VarDecl::TLS_None || |
3086 | VD->hasAttr<OMPThreadPrivateDeclAttr>() || |
3087 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && |
3088 | !VD->isLocalVarDecl())) |
3089 | continue; |
3090 | |
3091 | // If the used several times in the allocate directive, the same allocator |
3092 | // must be used. |
3093 | if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), RefExpr, VD, |
3094 | AllocatorKind, Allocator)) |
3095 | continue; |
3096 | |
3097 | // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ |
3098 | // If a list item has a static storage type, the allocator expression in the |
3099 | // allocator clause must be a constant expression that evaluates to one of |
3100 | // the predefined memory allocator values. |
3101 | if (Allocator && VD->hasGlobalStorage()) { |
3102 | if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { |
3103 | Diag(Allocator->getExprLoc(), |
3104 | diag::err_omp_expected_predefined_allocator) |
3105 | << Allocator->getSourceRange(); |
3106 | bool IsDecl = VD->isThisDeclarationADefinition(Context) == |
3107 | VarDecl::DeclarationOnly; |
3108 | Diag(VD->getLocation(), |
3109 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
3110 | << VD; |
3111 | continue; |
3112 | } |
3113 | } |
3114 | |
3115 | Vars.push_back(RefExpr); |
3116 | applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, |
3117 | DE->getSourceRange()); |
3118 | } |
3119 | if (Vars.empty()) |
3120 | return nullptr; |
3121 | if (!Owner) |
3122 | Owner = getCurLexicalContext(); |
3123 | auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); |
3124 | D->setAccess(AS_public); |
3125 | Owner->addDecl(D); |
3126 | return DeclGroupPtrTy::make(DeclGroupRef(D)); |
3127 | } |
3128 | |
3129 | Sema::DeclGroupPtrTy |
3130 | Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, |
3131 | ArrayRef<OMPClause *> ClauseList) { |
3132 | OMPRequiresDecl *D = nullptr; |
3133 | if (!CurContext->isFileContext()) { |
3134 | Diag(Loc, diag::err_omp_invalid_scope) << "requires"; |
3135 | } else { |
3136 | D = CheckOMPRequiresDecl(Loc, ClauseList); |
3137 | if (D) { |
3138 | CurContext->addDecl(D); |
3139 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addRequiresDecl(D); |
3140 | } |
3141 | } |
3142 | return DeclGroupPtrTy::make(DeclGroupRef(D)); |
3143 | } |
3144 | |
3145 | OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, |
3146 | ArrayRef<OMPClause *> ClauseList) { |
3147 | /// For target specific clauses, the requires directive cannot be |
3148 | /// specified after the handling of any of the target regions in the |
3149 | /// current compilation unit. |
3150 | ArrayRef<SourceLocation> TargetLocations = |
3151 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getEncounteredTargetLocs(); |
3152 | SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAtomicDirectiveLoc(); |
3153 | if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { |
3154 | for (const OMPClause *CNew : ClauseList) { |
3155 | // Check if any of the requires clauses affect target regions. |
3156 | if (isa<OMPUnifiedSharedMemoryClause>(CNew) || |
3157 | isa<OMPUnifiedAddressClause>(CNew) || |
3158 | isa<OMPReverseOffloadClause>(CNew) || |
3159 | isa<OMPDynamicAllocatorsClause>(CNew)) { |
3160 | Diag(Loc, diag::err_omp_directive_before_requires) |
3161 | << "target" << getOpenMPClauseName(CNew->getClauseKind()); |
3162 | for (SourceLocation TargetLoc : TargetLocations) { |
3163 | Diag(TargetLoc, diag::note_omp_requires_encountered_directive) |
3164 | << "target"; |
3165 | } |
3166 | } else if (!AtomicLoc.isInvalid() && |
3167 | isa<OMPAtomicDefaultMemOrderClause>(CNew)) { |
3168 | Diag(Loc, diag::err_omp_directive_before_requires) |
3169 | << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); |
3170 | Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) |
3171 | << "atomic"; |
3172 | } |
3173 | } |
3174 | } |
3175 | |
3176 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDuplicateRequiresClause(ClauseList)) |
3177 | return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, |
3178 | ClauseList); |
3179 | return nullptr; |
3180 | } |
3181 | |
3182 | static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, |
3183 | const ValueDecl *D, |
3184 | const DSAStackTy::DSAVarData &DVar, |
3185 | bool IsLoopIterVar) { |
3186 | if (DVar.RefExpr) { |
3187 | SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) |
3188 | << getOpenMPClauseName(DVar.CKind); |
3189 | return; |
3190 | } |
3191 | enum { |
3192 | PDSA_StaticMemberShared, |
3193 | PDSA_StaticLocalVarShared, |
3194 | PDSA_LoopIterVarPrivate, |
3195 | PDSA_LoopIterVarLinear, |
3196 | PDSA_LoopIterVarLastprivate, |
3197 | PDSA_ConstVarShared, |
3198 | PDSA_GlobalVarShared, |
3199 | PDSA_TaskVarFirstprivate, |
3200 | PDSA_LocalVarPrivate, |
3201 | PDSA_Implicit |
3202 | } Reason = PDSA_Implicit; |
3203 | bool ReportHint = false; |
3204 | auto ReportLoc = D->getLocation(); |
3205 | auto *VD = dyn_cast<VarDecl>(D); |
3206 | if (IsLoopIterVar) { |
3207 | if (DVar.CKind == OMPC_private) |
3208 | Reason = PDSA_LoopIterVarPrivate; |
3209 | else if (DVar.CKind == OMPC_lastprivate) |
3210 | Reason = PDSA_LoopIterVarLastprivate; |
3211 | else |
3212 | Reason = PDSA_LoopIterVarLinear; |
3213 | } else if (isOpenMPTaskingDirective(DVar.DKind) && |
3214 | DVar.CKind == OMPC_firstprivate) { |
3215 | Reason = PDSA_TaskVarFirstprivate; |
3216 | ReportLoc = DVar.ImplicitDSALoc; |
3217 | } else if (VD && VD->isStaticLocal()) |
3218 | Reason = PDSA_StaticLocalVarShared; |
3219 | else if (VD && VD->isStaticDataMember()) |
3220 | Reason = PDSA_StaticMemberShared; |
3221 | else if (VD && VD->isFileVarDecl()) |
3222 | Reason = PDSA_GlobalVarShared; |
3223 | else if (D->getType().isConstant(SemaRef.getASTContext())) |
3224 | Reason = PDSA_ConstVarShared; |
3225 | else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { |
3226 | ReportHint = true; |
3227 | Reason = PDSA_LocalVarPrivate; |
3228 | } |
3229 | if (Reason != PDSA_Implicit) { |
3230 | SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) |
3231 | << Reason << ReportHint |
3232 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); |
3233 | } else if (DVar.ImplicitDSALoc.isValid()) { |
3234 | SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) |
3235 | << getOpenMPClauseName(DVar.CKind); |
3236 | } |
3237 | } |
3238 | |
3239 | static OpenMPMapClauseKind |
3240 | getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, |
3241 | bool IsAggregateOrDeclareTarget) { |
3242 | OpenMPMapClauseKind Kind = OMPC_MAP_unknown; |
3243 | switch (M) { |
3244 | case OMPC_DEFAULTMAP_MODIFIER_alloc: |
3245 | Kind = OMPC_MAP_alloc; |
3246 | break; |
3247 | case OMPC_DEFAULTMAP_MODIFIER_to: |
3248 | Kind = OMPC_MAP_to; |
3249 | break; |
3250 | case OMPC_DEFAULTMAP_MODIFIER_from: |
3251 | Kind = OMPC_MAP_from; |
3252 | break; |
3253 | case OMPC_DEFAULTMAP_MODIFIER_tofrom: |
3254 | Kind = OMPC_MAP_tofrom; |
3255 | break; |
3256 | case OMPC_DEFAULTMAP_MODIFIER_firstprivate: |
3257 | case OMPC_DEFAULTMAP_MODIFIER_last: |
3258 | llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3258); |
3259 | case OMPC_DEFAULTMAP_MODIFIER_none: |
3260 | case OMPC_DEFAULTMAP_MODIFIER_default: |
3261 | case OMPC_DEFAULTMAP_MODIFIER_unknown: |
3262 | // IsAggregateOrDeclareTarget could be true if: |
3263 | // 1. the implicit behavior for aggregate is tofrom |
3264 | // 2. it's a declare target link |
3265 | if (IsAggregateOrDeclareTarget) { |
3266 | Kind = OMPC_MAP_tofrom; |
3267 | break; |
3268 | } |
3269 | llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3269); |
3270 | } |
3271 | assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known")((Kind != OMPC_MAP_unknown && "Expect map kind to be known" ) ? static_cast<void> (0) : __assert_fail ("Kind != OMPC_MAP_unknown && \"Expect map kind to be known\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 3271, __PRETTY_FUNCTION__)); |
3272 | return Kind; |
3273 | } |
3274 | |
3275 | namespace { |
3276 | class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { |
3277 | DSAStackTy *Stack; |
3278 | Sema &SemaRef; |
3279 | bool ErrorFound = false; |
3280 | bool TryCaptureCXXThisMembers = false; |
3281 | CapturedStmt *CS = nullptr; |
3282 | llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; |
3283 | llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; |
3284 | Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; |
3285 | llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; |
3286 | |
3287 | void VisitSubCaptures(OMPExecutableDirective *S) { |
3288 | // Check implicitly captured variables. |
3289 | if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) |
3290 | return; |
3291 | visitSubCaptures(S->getInnermostCapturedStmt()); |
3292 | // Try to capture inner this->member references to generate correct mappings |
3293 | // and diagnostics. |
3294 | if (TryCaptureCXXThisMembers || |
3295 | (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && |
3296 | llvm::any_of(S->getInnermostCapturedStmt()->captures(), |
3297 | [](const CapturedStmt::Capture &C) { |
3298 | return C.capturesThis(); |
3299 | }))) { |
3300 | bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; |
3301 | TryCaptureCXXThisMembers = true; |
3302 | Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); |
3303 | TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; |
3304 | } |
3305 | // In tasks firstprivates are not captured anymore, need to analyze them |
3306 | // explicitly. |
3307 | if (isOpenMPTaskingDirective(S->getDirectiveKind()) && |
3308 | !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { |
3309 | for (OMPClause *C : S->clauses()) |
3310 | if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { |
3311 | for (Expr *Ref : FC->varlists()) |
3312 | Visit(Ref); |
3313 | } |
3314 | } |
3315 | } |
3316 | |
3317 | public: |
3318 | void VisitDeclRefExpr(DeclRefExpr *E) { |
3319 | if (TryCaptureCXXThisMembers || E->isTypeDependent() || |
3320 | E->isValueDependent() || E->containsUnexpandedParameterPack() || |
3321 | E->isInstantiationDependent()) |
3322 | return; |
3323 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { |
3324 | // Check the datasharing rules for the expressions in the clauses. |
3325 | if (!CS) { |
3326 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) |
3327 | if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { |
3328 | Visit(CED->getInit()); |
3329 | return; |
3330 | } |
3331 | } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) |
3332 | // Do not analyze internal variables and do not enclose them into |
3333 | // implicit clauses. |
3334 | return; |
3335 | VD = VD->getCanonicalDecl(); |
3336 | // Skip internally declared variables. |
3337 | if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && |
3338 | !Stack->isImplicitTaskFirstprivate(VD)) |
3339 | return; |
3340 | // Skip allocators in uses_allocators clauses. |
3341 | if (Stack->isUsesAllocatorsDecl(VD).hasValue()) |
3342 | return; |
3343 | |
3344 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); |
3345 | // Check if the variable has explicit DSA set and stop analysis if it so. |
3346 | if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) |
3347 | return; |
3348 | |
3349 | // Skip internally declared static variables. |
3350 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = |
3351 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); |
3352 | if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && |
3353 | (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || |
3354 | !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && |
3355 | !Stack->isImplicitTaskFirstprivate(VD)) |
3356 | return; |
3357 | |
3358 | SourceLocation ELoc = E->getExprLoc(); |
3359 | OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); |
3360 | // The default(none) clause requires that each variable that is referenced |
3361 | // in the construct, and does not have a predetermined data-sharing |
3362 | // attribute, must have its data-sharing attribute explicitly determined |
3363 | // by being listed in a data-sharing attribute clause. |
3364 | if (DVar.CKind == OMPC_unknown && |
3365 | (Stack->getDefaultDSA() == DSA_none || |
3366 | Stack->getDefaultDSA() == DSA_firstprivate) && |
3367 | isImplicitOrExplicitTaskingRegion(DKind) && |
3368 | VarsWithInheritedDSA.count(VD) == 0) { |
3369 | bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; |
3370 | if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { |
3371 | DSAStackTy::DSAVarData DVar = |
3372 | Stack->getImplicitDSA(VD, /*FromParent=*/false); |
3373 | InheritedDSA = DVar.CKind == OMPC_unknown; |
3374 | } |
3375 | if (InheritedDSA) |
3376 | VarsWithInheritedDSA[VD] = E; |
3377 | return; |
3378 | } |
3379 | |
3380 | // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] |
3381 | // If implicit-behavior is none, each variable referenced in the |
3382 | // construct that does not have a predetermined data-sharing attribute |
3383 | // and does not appear in a to or link clause on a declare target |
3384 | // directive must be listed in a data-mapping attribute clause, a |
3385 | // data-haring attribute clause (including a data-sharing attribute |
3386 | // clause on a combined construct where target. is one of the |
3387 | // constituent constructs), or an is_device_ptr clause. |
3388 | OpenMPDefaultmapClauseKind ClauseKind = |
3389 | getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); |
3390 | if (SemaRef.getLangOpts().OpenMP >= 50) { |
3391 | bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == |
3392 | OMPC_DEFAULTMAP_MODIFIER_none; |
3393 | if (DVar.CKind == OMPC_unknown && IsModifierNone && |
3394 | VarsWithInheritedDSA.count(VD) == 0 && !Res) { |
3395 | // Only check for data-mapping attribute and is_device_ptr here |
3396 | // since we have already make sure that the declaration does not |
3397 | // have a data-sharing attribute above |
3398 | if (!Stack->checkMappableExprComponentListsForDecl( |
3399 | VD, /*CurrentRegionOnly=*/true, |
3400 | [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef |
3401 | MapExprComponents, |
3402 | OpenMPClauseKind) { |
3403 | auto MI = MapExprComponents.rbegin(); |
3404 | auto ME = MapExprComponents.rend(); |
3405 | return MI != ME && MI->getAssociatedDeclaration() == VD; |
3406 | })) { |
3407 | VarsWithInheritedDSA[VD] = E; |
3408 | return; |
3409 | } |
3410 | } |
3411 | } |
3412 | |
3413 | if (isOpenMPTargetExecutionDirective(DKind) && |
3414 | !Stack->isLoopControlVariable(VD).first) { |
3415 | if (!Stack->checkMappableExprComponentListsForDecl( |
3416 | VD, /*CurrentRegionOnly=*/true, |
3417 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef |
3418 | StackComponents, |
3419 | OpenMPClauseKind) { |
3420 | // Variable is used if it has been marked as an array, array |
3421 | // section, array shaping or the variable iself. |
3422 | return StackComponents.size() == 1 || |
3423 | std::all_of( |
3424 | std::next(StackComponents.rbegin()), |
3425 | StackComponents.rend(), |
3426 | [](const OMPClauseMappableExprCommon:: |
3427 | MappableComponent &MC) { |
3428 | return MC.getAssociatedDeclaration() == |
3429 | nullptr && |
3430 | (isa<OMPArraySectionExpr>( |
3431 | MC.getAssociatedExpression()) || |
3432 | isa<OMPArrayShapingExpr>( |
3433 | MC.getAssociatedExpression()) || |
3434 | isa<ArraySubscriptExpr>( |
3435 | MC.getAssociatedExpression())); |
3436 | }); |
3437 | })) { |
3438 | bool IsFirstprivate = false; |
3439 | // By default lambdas are captured as firstprivates. |
3440 | if (const auto *RD = |
3441 | VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) |
3442 | IsFirstprivate = RD->isLambda(); |
3443 | IsFirstprivate = |
3444 | IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); |
3445 | if (IsFirstprivate) { |
3446 | ImplicitFirstprivate.emplace_back(E); |
3447 | } else { |
3448 | OpenMPDefaultmapClauseModifier M = |
3449 | Stack->getDefaultmapModifier(ClauseKind); |
3450 | OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( |
3451 | M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); |
3452 | ImplicitMap[Kind].emplace_back(E); |
3453 | } |
3454 | return; |
3455 | } |
3456 | } |
3457 | |
3458 | // OpenMP [2.9.3.6, Restrictions, p.2] |
3459 | // A list item that appears in a reduction clause of the innermost |
3460 | // enclosing worksharing or parallel construct may not be accessed in an |
3461 | // explicit task. |
3462 | DVar = Stack->hasInnermostDSA( |
3463 | VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, |
3464 | [](OpenMPDirectiveKind K) { |
3465 | return isOpenMPParallelDirective(K) || |
3466 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); |
3467 | }, |
3468 | /*FromParent=*/true); |
3469 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { |
3470 | ErrorFound = true; |
3471 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); |
3472 | reportOriginalDsa(SemaRef, Stack, VD, DVar); |
3473 | return; |
3474 | } |
3475 | |
3476 | // Define implicit data-sharing attributes for task. |
3477 | DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); |
3478 | if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || |
3479 | (Stack->getDefaultDSA() == DSA_firstprivate && |
3480 | DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && |
3481 | !Stack->isLoopControlVariable(VD).first) { |
3482 | ImplicitFirstprivate.push_back(E); |
3483 | return; |
3484 | } |
3485 | |
3486 | // Store implicitly used globals with declare target link for parent |
3487 | // target. |
3488 | if (!isOpenMPTargetExecutionDirective(DKind) && Res && |
3489 | *Res == OMPDeclareTargetDeclAttr::MT_Link) { |
3490 | Stack->addToParentTargetRegionLinkGlobals(E); |
3491 | return; |
3492 | } |
3493 | } |
3494 | } |
3495 | void VisitMemberExpr(MemberExpr *E) { |
3496 | if (E->isTypeDependent() || E->isValueDependent() || |
3497 | E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) |
3498 | return; |
3499 | auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); |
3500 | OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); |
3501 | if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { |
3502 | if (!FD) |
3503 | return; |
3504 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); |
3505 | // Check if the variable has explicit DSA set and stop analysis if it |
3506 | // so. |
3507 | if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) |
3508 | return; |
3509 | |
3510 | if (isOpenMPTargetExecutionDirective(DKind) && |
3511 | !Stack->isLoopControlVariable(FD).first && |
3512 | !Stack->checkMappableExprComponentListsForDecl( |
3513 | FD, /*CurrentRegionOnly=*/true, |
3514 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef |
3515 | StackComponents, |
3516 | OpenMPClauseKind) { |
3517 | return isa<CXXThisExpr>( |
3518 | cast<MemberExpr>( |
3519 | StackComponents.back().getAssociatedExpression()) |
3520 | ->getBase() |
3521 | ->IgnoreParens()); |
3522 | })) { |
3523 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] |
3524 | // A bit-field cannot appear in a map clause. |
3525 | // |
3526 | if (FD->isBitField()) |
3527 | return; |
3528 | |
3529 | // Check to see if the member expression is referencing a class that |
3530 | // has already been explicitly mapped |
3531 | if (Stack->isClassPreviouslyMapped(TE->getType())) |
3532 | return; |
3533 | |
3534 | OpenMPDefaultmapClauseModifier Modifier = |
3535 | Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); |
3536 | OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( |
3537 | Modifier, /*IsAggregateOrDeclareTarget*/ true); |
3538 | ImplicitMap[Kind].emplace_back(E); |
3539 | return; |
3540 | } |
3541 | |
3542 | SourceLocation ELoc = E->getExprLoc(); |
3543 | // OpenMP [2.9.3.6, Restrictions, p.2] |
3544 | // A list item that appears in a reduction clause of the innermost |
3545 | // enclosing worksharing or parallel construct may not be accessed in |
3546 | // an explicit task. |
3547 | DVar = Stack->hasInnermostDSA( |
3548 | FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, |
3549 | [](OpenMPDirectiveKind K) { |
3550 | return isOpenMPParallelDirective(K) || |
3551 | isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); |
3552 | }, |
3553 | /*FromParent=*/true); |
3554 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { |
3555 | ErrorFound = true; |
3556 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); |
3557 | reportOriginalDsa(SemaRef, Stack, FD, DVar); |
3558 | return; |
3559 | } |
3560 | |
3561 | // Define implicit data-sharing attributes for task. |
3562 | DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); |
3563 | if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && |
3564 | !Stack->isLoopControlVariable(FD).first) { |
3565 | // Check if there is a captured expression for the current field in the |
3566 | // region. Do not mark it as firstprivate unless there is no captured |
3567 | // expression. |
3568 | // TODO: try to make it firstprivate. |
3569 | if (DVar.CKind != OMPC_unknown) |
3570 | ImplicitFirstprivate.push_back(E); |
3571 | } |
3572 | return; |
3573 | } |
3574 | if (isOpenMPTargetExecutionDirective(DKind)) { |
3575 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; |
3576 | if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, |
3577 | /*NoDiagnose=*/true)) |
3578 | return; |
3579 | const auto *VD = cast<ValueDecl>( |
3580 | CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); |
3581 | if (!Stack->checkMappableExprComponentListsForDecl( |
3582 | VD, /*CurrentRegionOnly=*/true, |
3583 | [&CurComponents]( |
3584 | OMPClauseMappableExprCommon::MappableExprComponentListRef |
3585 | StackComponents, |
3586 | OpenMPClauseKind) { |
3587 | auto CCI = CurComponents.rbegin(); |
3588 | auto CCE = CurComponents.rend(); |
3589 | for (const auto &SC : llvm::reverse(StackComponents)) { |
3590 | // Do both expressions have the same kind? |
3591 | if (CCI->getAssociatedExpression()->getStmtClass() != |
3592 | SC.getAssociatedExpression()->getStmtClass()) |
3593 | if (!((isa<OMPArraySectionExpr>( |
3594 | SC.getAssociatedExpression()) || |
3595 | isa<OMPArrayShapingExpr>( |
3596 | SC.getAssociatedExpression())) && |
3597 | isa<ArraySubscriptExpr>( |
3598 | CCI->getAssociatedExpression()))) |
3599 | return false; |
3600 | |
3601 | const Decl *CCD = CCI->getAssociatedDeclaration(); |
3602 | const Decl *SCD = SC.getAssociatedDeclaration(); |
3603 | CCD = CCD ? CCD->getCanonicalDecl() : nullptr; |
3604 | SCD = SCD ? SCD->getCanonicalDecl() : nullptr; |
3605 | if (SCD != CCD) |
3606 | return false; |
3607 | std::advance(CCI, 1); |
3608 | if (CCI == CCE) |
3609 | break; |
3610 | } |
3611 | return true; |
3612 | })) { |
3613 | Visit(E->getBase()); |
3614 | } |
3615 | } else if (!TryCaptureCXXThisMembers) { |
3616 | Visit(E->getBase()); |
3617 | } |
3618 | } |
3619 | void VisitOMPExecutableDirective(OMPExecutableDirective *S) { |
3620 | for (OMPClause *C : S->clauses()) { |
3621 | // Skip analysis of arguments of implicitly defined firstprivate clause |
3622 | // for task|target directives. |
3623 | // Skip analysis of arguments of implicitly defined map clause for target |
3624 | // directives. |
3625 | if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && |
3626 | C->isImplicit())) { |
3627 | for (Stmt *CC : C->children()) { |
3628 | if (CC) |
3629 | Visit(CC); |
3630 | } |
3631 | } |
3632 | } |
3633 | // Check implicitly captured variables. |
3634 | VisitSubCaptures(S); |
3635 | } |
3636 | void VisitStmt(Stmt *S) { |
3637 | for (Stmt *C : S->children()) { |
3638 | if (C) { |
3639 | // Check implicitly captured variables in the task-based directives to |
3640 | // check if they must be firstprivatized. |
3641 | Visit(C); |
3642 | } |
3643 | } |
3644 | } |
3645 | |
3646 | void visitSubCaptures(CapturedStmt *S) { |
3647 | for (const CapturedStmt::Capture &Cap : S->captures()) { |
3648 | if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) |
3649 | continue; |
3650 | VarDecl *VD = Cap.getCapturedVar(); |
3651 | // Do not try to map the variable if it or its sub-component was mapped |
3652 | // already. |
3653 | if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && |
3654 | Stack->checkMappableExprComponentListsForDecl( |
3655 | VD, /*CurrentRegionOnly=*/true, |
3656 | [](OMPClauseMappableExprCommon::MappableExprComponentListRef, |
3657 | OpenMPClauseKind) { return true; })) |
3658 | continue; |
3659 | DeclRefExpr *DRE = buildDeclRefExpr( |
3660 | SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), |
3661 | Cap.getLocation(), /*RefersToCapture=*/true); |
3662 | Visit(DRE); |
3663 | } |
3664 | } |
3665 | bool isErrorFound() const { return ErrorFound; } |
3666 | ArrayRef<Expr *> getImplicitFirstprivate() const { |
3667 | return ImplicitFirstprivate; |
3668 | } |
3669 | ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { |
3670 | return ImplicitMap[Kind]; |
3671 | } |
3672 | const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { |
3673 | return VarsWithInheritedDSA; |
3674 | } |
3675 | |
3676 | DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) |
3677 | : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { |
3678 | // Process declare target link variables for the target directives. |
3679 | if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { |
3680 | for (DeclRefExpr *E : Stack->getLinkGlobals()) |
3681 | Visit(E); |
3682 | } |
3683 | } |
3684 | }; |
3685 | } // namespace |
3686 | |
3687 | void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { |
3688 | switch (DKind) { |
3689 | case OMPD_parallel: |
3690 | case OMPD_parallel_for: |
3691 | case OMPD_parallel_for_simd: |
3692 | case OMPD_parallel_sections: |
3693 | case OMPD_parallel_master: |
3694 | case OMPD_teams: |
3695 | case OMPD_teams_distribute: |
3696 | case OMPD_teams_distribute_simd: { |
3697 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
3698 | QualType KmpInt32PtrTy = |
3699 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3700 | Sema::CapturedParamNameType Params[] = { |
3701 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
3702 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
3703 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3704 | }; |
3705 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3706 | Params); |
3707 | break; |
3708 | } |
3709 | case OMPD_target_teams: |
3710 | case OMPD_target_parallel: |
3711 | case OMPD_target_parallel_for: |
3712 | case OMPD_target_parallel_for_simd: |
3713 | case OMPD_target_teams_distribute: |
3714 | case OMPD_target_teams_distribute_simd: { |
3715 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
3716 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); |
3717 | QualType KmpInt32PtrTy = |
3718 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3719 | QualType Args[] = {VoidPtrTy}; |
3720 | FunctionProtoType::ExtProtoInfo EPI; |
3721 | EPI.Variadic = true; |
3722 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); |
3723 | Sema::CapturedParamNameType Params[] = { |
3724 | std::make_pair(".global_tid.", KmpInt32Ty), |
3725 | std::make_pair(".part_id.", KmpInt32PtrTy), |
3726 | std::make_pair(".privates.", VoidPtrTy), |
3727 | std::make_pair( |
3728 | ".copy_fn.", |
3729 | Context.getPointerType(CopyFnType).withConst().withRestrict()), |
3730 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), |
3731 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3732 | }; |
3733 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3734 | Params, /*OpenMPCaptureLevel=*/0); |
3735 | // Mark this captured region as inlined, because we don't use outlined |
3736 | // function directly. |
3737 | getCurCapturedRegion()->TheCapturedDecl->addAttr( |
3738 | AlwaysInlineAttr::CreateImplicit( |
3739 | Context, {}, AttributeCommonInfo::AS_Keyword, |
3740 | AlwaysInlineAttr::Keyword_forceinline)); |
3741 | Sema::CapturedParamNameType ParamsTarget[] = { |
3742 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3743 | }; |
3744 | // Start a captured region for 'target' with no implicit parameters. |
3745 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3746 | ParamsTarget, /*OpenMPCaptureLevel=*/1); |
3747 | Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { |
3748 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
3749 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
3750 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3751 | }; |
3752 | // Start a captured region for 'teams' or 'parallel'. Both regions have |
3753 | // the same implicit parameters. |
3754 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3755 | ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); |
3756 | break; |
3757 | } |
3758 | case OMPD_target: |
3759 | case OMPD_target_simd: { |
3760 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
3761 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); |
3762 | QualType KmpInt32PtrTy = |
3763 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3764 | QualType Args[] = {VoidPtrTy}; |
3765 | FunctionProtoType::ExtProtoInfo EPI; |
3766 | EPI.Variadic = true; |
3767 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); |
3768 | Sema::CapturedParamNameType Params[] = { |
3769 | std::make_pair(".global_tid.", KmpInt32Ty), |
3770 | std::make_pair(".part_id.", KmpInt32PtrTy), |
3771 | std::make_pair(".privates.", VoidPtrTy), |
3772 | std::make_pair( |
3773 | ".copy_fn.", |
3774 | Context.getPointerType(CopyFnType).withConst().withRestrict()), |
3775 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), |
3776 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3777 | }; |
3778 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3779 | Params, /*OpenMPCaptureLevel=*/0); |
3780 | // Mark this captured region as inlined, because we don't use outlined |
3781 | // function directly. |
3782 | getCurCapturedRegion()->TheCapturedDecl->addAttr( |
3783 | AlwaysInlineAttr::CreateImplicit( |
3784 | Context, {}, AttributeCommonInfo::AS_Keyword, |
3785 | AlwaysInlineAttr::Keyword_forceinline)); |
3786 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3787 | std::make_pair(StringRef(), QualType()), |
3788 | /*OpenMPCaptureLevel=*/1); |
3789 | break; |
3790 | } |
3791 | case OMPD_simd: |
3792 | case OMPD_for: |
3793 | case OMPD_for_simd: |
3794 | case OMPD_sections: |
3795 | case OMPD_section: |
3796 | case OMPD_single: |
3797 | case OMPD_master: |
3798 | case OMPD_critical: |
3799 | case OMPD_taskgroup: |
3800 | case OMPD_distribute: |
3801 | case OMPD_distribute_simd: |
3802 | case OMPD_ordered: |
3803 | case OMPD_atomic: |
3804 | case OMPD_target_data: { |
3805 | Sema::CapturedParamNameType Params[] = { |
3806 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3807 | }; |
3808 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3809 | Params); |
3810 | break; |
3811 | } |
3812 | case OMPD_task: { |
3813 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
3814 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); |
3815 | QualType KmpInt32PtrTy = |
3816 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3817 | QualType Args[] = {VoidPtrTy}; |
3818 | FunctionProtoType::ExtProtoInfo EPI; |
3819 | EPI.Variadic = true; |
3820 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); |
3821 | Sema::CapturedParamNameType Params[] = { |
3822 | std::make_pair(".global_tid.", KmpInt32Ty), |
3823 | std::make_pair(".part_id.", KmpInt32PtrTy), |
3824 | std::make_pair(".privates.", VoidPtrTy), |
3825 | std::make_pair( |
3826 | ".copy_fn.", |
3827 | Context.getPointerType(CopyFnType).withConst().withRestrict()), |
3828 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), |
3829 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3830 | }; |
3831 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3832 | Params); |
3833 | // Mark this captured region as inlined, because we don't use outlined |
3834 | // function directly. |
3835 | getCurCapturedRegion()->TheCapturedDecl->addAttr( |
3836 | AlwaysInlineAttr::CreateImplicit( |
3837 | Context, {}, AttributeCommonInfo::AS_Keyword, |
3838 | AlwaysInlineAttr::Keyword_forceinline)); |
3839 | break; |
3840 | } |
3841 | case OMPD_taskloop: |
3842 | case OMPD_taskloop_simd: |
3843 | case OMPD_master_taskloop: |
3844 | case OMPD_master_taskloop_simd: { |
3845 | QualType KmpInt32Ty = |
3846 | Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) |
3847 | .withConst(); |
3848 | QualType KmpUInt64Ty = |
3849 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) |
3850 | .withConst(); |
3851 | QualType KmpInt64Ty = |
3852 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) |
3853 | .withConst(); |
3854 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); |
3855 | QualType KmpInt32PtrTy = |
3856 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3857 | QualType Args[] = {VoidPtrTy}; |
3858 | FunctionProtoType::ExtProtoInfo EPI; |
3859 | EPI.Variadic = true; |
3860 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); |
3861 | Sema::CapturedParamNameType Params[] = { |
3862 | std::make_pair(".global_tid.", KmpInt32Ty), |
3863 | std::make_pair(".part_id.", KmpInt32PtrTy), |
3864 | std::make_pair(".privates.", VoidPtrTy), |
3865 | std::make_pair( |
3866 | ".copy_fn.", |
3867 | Context.getPointerType(CopyFnType).withConst().withRestrict()), |
3868 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), |
3869 | std::make_pair(".lb.", KmpUInt64Ty), |
3870 | std::make_pair(".ub.", KmpUInt64Ty), |
3871 | std::make_pair(".st.", KmpInt64Ty), |
3872 | std::make_pair(".liter.", KmpInt32Ty), |
3873 | std::make_pair(".reductions.", VoidPtrTy), |
3874 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3875 | }; |
3876 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3877 | Params); |
3878 | // Mark this captured region as inlined, because we don't use outlined |
3879 | // function directly. |
3880 | getCurCapturedRegion()->TheCapturedDecl->addAttr( |
3881 | AlwaysInlineAttr::CreateImplicit( |
3882 | Context, {}, AttributeCommonInfo::AS_Keyword, |
3883 | AlwaysInlineAttr::Keyword_forceinline)); |
3884 | break; |
3885 | } |
3886 | case OMPD_parallel_master_taskloop: |
3887 | case OMPD_parallel_master_taskloop_simd: { |
3888 | QualType KmpInt32Ty = |
3889 | Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) |
3890 | .withConst(); |
3891 | QualType KmpUInt64Ty = |
3892 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) |
3893 | .withConst(); |
3894 | QualType KmpInt64Ty = |
3895 | Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) |
3896 | .withConst(); |
3897 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); |
3898 | QualType KmpInt32PtrTy = |
3899 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3900 | Sema::CapturedParamNameType ParamsParallel[] = { |
3901 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
3902 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
3903 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3904 | }; |
3905 | // Start a captured region for 'parallel'. |
3906 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3907 | ParamsParallel, /*OpenMPCaptureLevel=*/0); |
3908 | QualType Args[] = {VoidPtrTy}; |
3909 | FunctionProtoType::ExtProtoInfo EPI; |
3910 | EPI.Variadic = true; |
3911 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); |
3912 | Sema::CapturedParamNameType Params[] = { |
3913 | std::make_pair(".global_tid.", KmpInt32Ty), |
3914 | std::make_pair(".part_id.", KmpInt32PtrTy), |
3915 | std::make_pair(".privates.", VoidPtrTy), |
3916 | std::make_pair( |
3917 | ".copy_fn.", |
3918 | Context.getPointerType(CopyFnType).withConst().withRestrict()), |
3919 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), |
3920 | std::make_pair(".lb.", KmpUInt64Ty), |
3921 | std::make_pair(".ub.", KmpUInt64Ty), |
3922 | std::make_pair(".st.", KmpInt64Ty), |
3923 | std::make_pair(".liter.", KmpInt32Ty), |
3924 | std::make_pair(".reductions.", VoidPtrTy), |
3925 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3926 | }; |
3927 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3928 | Params, /*OpenMPCaptureLevel=*/1); |
3929 | // Mark this captured region as inlined, because we don't use outlined |
3930 | // function directly. |
3931 | getCurCapturedRegion()->TheCapturedDecl->addAttr( |
3932 | AlwaysInlineAttr::CreateImplicit( |
3933 | Context, {}, AttributeCommonInfo::AS_Keyword, |
3934 | AlwaysInlineAttr::Keyword_forceinline)); |
3935 | break; |
3936 | } |
3937 | case OMPD_distribute_parallel_for_simd: |
3938 | case OMPD_distribute_parallel_for: { |
3939 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
3940 | QualType KmpInt32PtrTy = |
3941 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3942 | Sema::CapturedParamNameType Params[] = { |
3943 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
3944 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
3945 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), |
3946 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), |
3947 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3948 | }; |
3949 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3950 | Params); |
3951 | break; |
3952 | } |
3953 | case OMPD_target_teams_distribute_parallel_for: |
3954 | case OMPD_target_teams_distribute_parallel_for_simd: { |
3955 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
3956 | QualType KmpInt32PtrTy = |
3957 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
3958 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); |
3959 | |
3960 | QualType Args[] = {VoidPtrTy}; |
3961 | FunctionProtoType::ExtProtoInfo EPI; |
3962 | EPI.Variadic = true; |
3963 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); |
3964 | Sema::CapturedParamNameType Params[] = { |
3965 | std::make_pair(".global_tid.", KmpInt32Ty), |
3966 | std::make_pair(".part_id.", KmpInt32PtrTy), |
3967 | std::make_pair(".privates.", VoidPtrTy), |
3968 | std::make_pair( |
3969 | ".copy_fn.", |
3970 | Context.getPointerType(CopyFnType).withConst().withRestrict()), |
3971 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), |
3972 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3973 | }; |
3974 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3975 | Params, /*OpenMPCaptureLevel=*/0); |
3976 | // Mark this captured region as inlined, because we don't use outlined |
3977 | // function directly. |
3978 | getCurCapturedRegion()->TheCapturedDecl->addAttr( |
3979 | AlwaysInlineAttr::CreateImplicit( |
3980 | Context, {}, AttributeCommonInfo::AS_Keyword, |
3981 | AlwaysInlineAttr::Keyword_forceinline)); |
3982 | Sema::CapturedParamNameType ParamsTarget[] = { |
3983 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3984 | }; |
3985 | // Start a captured region for 'target' with no implicit parameters. |
3986 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3987 | ParamsTarget, /*OpenMPCaptureLevel=*/1); |
3988 | |
3989 | Sema::CapturedParamNameType ParamsTeams[] = { |
3990 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
3991 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
3992 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
3993 | }; |
3994 | // Start a captured region for 'target' with no implicit parameters. |
3995 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
3996 | ParamsTeams, /*OpenMPCaptureLevel=*/2); |
3997 | |
3998 | Sema::CapturedParamNameType ParamsParallel[] = { |
3999 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
4000 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
4001 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), |
4002 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), |
4003 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
4004 | }; |
4005 | // Start a captured region for 'teams' or 'parallel'. Both regions have |
4006 | // the same implicit parameters. |
4007 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
4008 | ParamsParallel, /*OpenMPCaptureLevel=*/3); |
4009 | break; |
4010 | } |
4011 | |
4012 | case OMPD_teams_distribute_parallel_for: |
4013 | case OMPD_teams_distribute_parallel_for_simd: { |
4014 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
4015 | QualType KmpInt32PtrTy = |
4016 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
4017 | |
4018 | Sema::CapturedParamNameType ParamsTeams[] = { |
4019 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
4020 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
4021 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
4022 | }; |
4023 | // Start a captured region for 'target' with no implicit parameters. |
4024 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
4025 | ParamsTeams, /*OpenMPCaptureLevel=*/0); |
4026 | |
4027 | Sema::CapturedParamNameType ParamsParallel[] = { |
4028 | std::make_pair(".global_tid.", KmpInt32PtrTy), |
4029 | std::make_pair(".bound_tid.", KmpInt32PtrTy), |
4030 | std::make_pair(".previous.lb.", Context.getSizeType().withConst()), |
4031 | std::make_pair(".previous.ub.", Context.getSizeType().withConst()), |
4032 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
4033 | }; |
4034 | // Start a captured region for 'teams' or 'parallel'. Both regions have |
4035 | // the same implicit parameters. |
4036 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
4037 | ParamsParallel, /*OpenMPCaptureLevel=*/1); |
4038 | break; |
4039 | } |
4040 | case OMPD_target_update: |
4041 | case OMPD_target_enter_data: |
4042 | case OMPD_target_exit_data: { |
4043 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); |
4044 | QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); |
4045 | QualType KmpInt32PtrTy = |
4046 | Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); |
4047 | QualType Args[] = {VoidPtrTy}; |
4048 | FunctionProtoType::ExtProtoInfo EPI; |
4049 | EPI.Variadic = true; |
4050 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); |
4051 | Sema::CapturedParamNameType Params[] = { |
4052 | std::make_pair(".global_tid.", KmpInt32Ty), |
4053 | std::make_pair(".part_id.", KmpInt32PtrTy), |
4054 | std::make_pair(".privates.", VoidPtrTy), |
4055 | std::make_pair( |
4056 | ".copy_fn.", |
4057 | Context.getPointerType(CopyFnType).withConst().withRestrict()), |
4058 | std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), |
4059 | std::make_pair(StringRef(), QualType()) // __context with shared vars |
4060 | }; |
4061 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, |
4062 | Params); |
4063 | // Mark this captured region as inlined, because we don't use outlined |
4064 | // function directly. |
4065 | getCurCapturedRegion()->TheCapturedDecl->addAttr( |
4066 | AlwaysInlineAttr::CreateImplicit( |
4067 | Context, {}, AttributeCommonInfo::AS_Keyword, |
4068 | AlwaysInlineAttr::Keyword_forceinline)); |
4069 | break; |
4070 | } |
4071 | case OMPD_threadprivate: |
4072 | case OMPD_allocate: |
4073 | case OMPD_taskyield: |
4074 | case OMPD_barrier: |
4075 | case OMPD_taskwait: |
4076 | case OMPD_cancellation_point: |
4077 | case OMPD_cancel: |
4078 | case OMPD_flush: |
4079 | case OMPD_depobj: |
4080 | case OMPD_scan: |
4081 | case OMPD_declare_reduction: |
4082 | case OMPD_declare_mapper: |
4083 | case OMPD_declare_simd: |
4084 | case OMPD_declare_target: |
4085 | case OMPD_end_declare_target: |
4086 | case OMPD_requires: |
4087 | case OMPD_declare_variant: |
4088 | case OMPD_begin_declare_variant: |
4089 | case OMPD_end_declare_variant: |
4090 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4090); |
4091 | case OMPD_unknown: |
4092 | default: |
4093 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4093); |
4094 | } |
4095 | } |
4096 | |
4097 | int Sema::getNumberOfConstructScopes(unsigned Level) const { |
4098 | return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDirective(Level)); |
4099 | } |
4100 | |
4101 | int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { |
4102 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
4103 | getOpenMPCaptureRegions(CaptureRegions, DKind); |
4104 | return CaptureRegions.size(); |
4105 | } |
4106 | |
4107 | static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, |
4108 | Expr *CaptureExpr, bool WithInit, |
4109 | bool AsExpression) { |
4110 | assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail ( "CaptureExpr", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4110, __PRETTY_FUNCTION__)); |
4111 | ASTContext &C = S.getASTContext(); |
4112 | Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); |
4113 | QualType Ty = Init->getType(); |
4114 | if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { |
4115 | if (S.getLangOpts().CPlusPlus) { |
4116 | Ty = C.getLValueReferenceType(Ty); |
4117 | } else { |
4118 | Ty = C.getPointerType(Ty); |
4119 | ExprResult Res = |
4120 | S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); |
4121 | if (!Res.isUsable()) |
4122 | return nullptr; |
4123 | Init = Res.get(); |
4124 | } |
4125 | WithInit = true; |
4126 | } |
4127 | auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, |
4128 | CaptureExpr->getBeginLoc()); |
4129 | if (!WithInit) |
4130 | CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); |
4131 | S.CurContext->addHiddenDecl(CED); |
4132 | S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); |
4133 | return CED; |
4134 | } |
4135 | |
4136 | static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, |
4137 | bool WithInit) { |
4138 | OMPCapturedExprDecl *CD; |
4139 | if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) |
4140 | CD = cast<OMPCapturedExprDecl>(VD); |
4141 | else |
4142 | CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, |
4143 | /*AsExpression=*/false); |
4144 | return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), |
4145 | CaptureExpr->getExprLoc()); |
4146 | } |
4147 | |
4148 | static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { |
4149 | CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); |
4150 | if (!Ref) { |
4151 | OMPCapturedExprDecl *CD = buildCaptureDecl( |
4152 | S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, |
4153 | /*WithInit=*/true, /*AsExpression=*/true); |
4154 | Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), |
4155 | CaptureExpr->getExprLoc()); |
4156 | } |
4157 | ExprResult Res = Ref; |
4158 | if (!S.getLangOpts().CPlusPlus && |
4159 | CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && |
4160 | Ref->getType()->isPointerType()) { |
4161 | Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); |
4162 | if (!Res.isUsable()) |
4163 | return ExprError(); |
4164 | } |
4165 | return S.DefaultLvalueConversion(Res.get()); |
4166 | } |
4167 | |
4168 | namespace { |
4169 | // OpenMP directives parsed in this section are represented as a |
4170 | // CapturedStatement with an associated statement. If a syntax error |
4171 | // is detected during the parsing of the associated statement, the |
4172 | // compiler must abort processing and close the CapturedStatement. |
4173 | // |
4174 | // Combined directives such as 'target parallel' have more than one |
4175 | // nested CapturedStatements. This RAII ensures that we unwind out |
4176 | // of all the nested CapturedStatements when an error is found. |
4177 | class CaptureRegionUnwinderRAII { |
4178 | private: |
4179 | Sema &S; |
4180 | bool &ErrorFound; |
4181 | OpenMPDirectiveKind DKind = OMPD_unknown; |
4182 | |
4183 | public: |
4184 | CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, |
4185 | OpenMPDirectiveKind DKind) |
4186 | : S(S), ErrorFound(ErrorFound), DKind(DKind) {} |
4187 | ~CaptureRegionUnwinderRAII() { |
4188 | if (ErrorFound) { |
4189 | int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); |
4190 | while (--ThisCaptureLevel >= 0) |
4191 | S.ActOnCapturedRegionError(); |
4192 | } |
4193 | } |
4194 | }; |
4195 | } // namespace |
4196 | |
4197 | void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { |
4198 | // Capture variables captured by reference in lambdas for target-based |
4199 | // directives. |
4200 | if (!CurContext->isDependentContext() && |
4201 | (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) || |
4202 | isOpenMPTargetDataManagementDirective( |
4203 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()))) { |
4204 | QualType Type = V->getType(); |
4205 | if (const auto *RD = Type.getCanonicalType() |
4206 | .getNonReferenceType() |
4207 | ->getAsCXXRecordDecl()) { |
4208 | bool SavedForceCaptureByReferenceInTargetExecutable = |
4209 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isForceCaptureByReferenceInTargetExecutable(); |
4210 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceCaptureByReferenceInTargetExecutable( |
4211 | /*V=*/true); |
4212 | if (RD->isLambda()) { |
4213 | llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; |
4214 | FieldDecl *ThisCapture; |
4215 | RD->getCaptureFields(Captures, ThisCapture); |
4216 | for (const LambdaCapture &LC : RD->captures()) { |
4217 | if (LC.getCaptureKind() == LCK_ByRef) { |
4218 | VarDecl *VD = LC.getCapturedVar(); |
4219 | DeclContext *VDC = VD->getDeclContext(); |
4220 | if (!VDC->Encloses(CurContext)) |
4221 | continue; |
4222 | MarkVariableReferenced(LC.getLocation(), VD); |
4223 | } else if (LC.getCaptureKind() == LCK_This) { |
4224 | QualType ThisTy = getCurrentThisType(); |
4225 | if (!ThisTy.isNull() && |
4226 | Context.typesAreCompatible(ThisTy, ThisCapture->getType())) |
4227 | CheckCXXThisCapture(LC.getLocation()); |
4228 | } |
4229 | } |
4230 | } |
4231 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceCaptureByReferenceInTargetExecutable( |
4232 | SavedForceCaptureByReferenceInTargetExecutable); |
4233 | } |
4234 | } |
4235 | } |
4236 | |
4237 | static bool checkOrderedOrderSpecified(Sema &S, |
4238 | const ArrayRef<OMPClause *> Clauses) { |
4239 | const OMPOrderedClause *Ordered = nullptr; |
4240 | const OMPOrderClause *Order = nullptr; |
4241 | |
4242 | for (const OMPClause *Clause : Clauses) { |
4243 | if (Clause->getClauseKind() == OMPC_ordered) |
4244 | Ordered = cast<OMPOrderedClause>(Clause); |
4245 | else if (Clause->getClauseKind() == OMPC_order) { |
4246 | Order = cast<OMPOrderClause>(Clause); |
4247 | if (Order->getKind() != OMPC_ORDER_concurrent) |
4248 | Order = nullptr; |
4249 | } |
4250 | if (Ordered && Order) |
4251 | break; |
4252 | } |
4253 | |
4254 | if (Ordered && Order) { |
4255 | S.Diag(Order->getKindKwLoc(), |
4256 | diag::err_omp_simple_clause_incompatible_with_ordered) |
4257 | << getOpenMPClauseName(OMPC_order) |
4258 | << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) |
4259 | << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); |
4260 | S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) |
4261 | << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); |
4262 | return true; |
4263 | } |
4264 | return false; |
4265 | } |
4266 | |
4267 | StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, |
4268 | ArrayRef<OMPClause *> Clauses) { |
4269 | bool ErrorFound = false; |
4270 | CaptureRegionUnwinderRAII CaptureRegionUnwinder( |
4271 | *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); |
4272 | if (!S.isUsable()) { |
4273 | ErrorFound = true; |
Value stored to 'ErrorFound' is never read | |
4274 | return StmtError(); |
4275 | } |
4276 | |
4277 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
4278 | getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); |
4279 | OMPOrderedClause *OC = nullptr; |
4280 | OMPScheduleClause *SC = nullptr; |
4281 | SmallVector<const OMPLinearClause *, 4> LCs; |
4282 | SmallVector<const OMPClauseWithPreInit *, 4> PICs; |
4283 | // This is required for proper codegen. |
4284 | for (OMPClause *Clause : Clauses) { |
4285 | if (!LangOpts.OpenMPSimd && |
4286 | isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && |
4287 | Clause->getClauseKind() == OMPC_in_reduction) { |
4288 | // Capture taskgroup task_reduction descriptors inside the tasking regions |
4289 | // with the corresponding in_reduction items. |
4290 | auto *IRC = cast<OMPInReductionClause>(Clause); |
4291 | for (Expr *E : IRC->taskgroup_descriptors()) |
4292 | if (E) |
4293 | MarkDeclarationsReferencedInExpr(E); |
4294 | } |
4295 | if (isOpenMPPrivate(Clause->getClauseKind()) || |
4296 | Clause->getClauseKind() == OMPC_copyprivate || |
4297 | (getLangOpts().OpenMPUseTLS && |
4298 | getASTContext().getTargetInfo().isTLSSupported() && |
4299 | Clause->getClauseKind() == OMPC_copyin)) { |
4300 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); |
4301 | // Mark all variables in private list clauses as used in inner region. |
4302 | for (Stmt *VarRef : Clause->children()) { |
4303 | if (auto *E = cast_or_null<Expr>(VarRef)) { |
4304 | MarkDeclarationsReferencedInExpr(E); |
4305 | } |
4306 | } |
4307 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setForceVarCapturing(/*V=*/false); |
4308 | } else if (CaptureRegions.size() > 1 || |
4309 | CaptureRegions.back() != OMPD_unknown) { |
4310 | if (auto *C = OMPClauseWithPreInit::get(Clause)) |
4311 | PICs.push_back(C); |
4312 | if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { |
4313 | if (Expr *E = C->getPostUpdateExpr()) |
4314 | MarkDeclarationsReferencedInExpr(E); |
4315 | } |
4316 | } |
4317 | if (Clause->getClauseKind() == OMPC_schedule) |
4318 | SC = cast<OMPScheduleClause>(Clause); |
4319 | else if (Clause->getClauseKind() == OMPC_ordered) |
4320 | OC = cast<OMPOrderedClause>(Clause); |
4321 | else if (Clause->getClauseKind() == OMPC_linear) |
4322 | LCs.push_back(cast<OMPLinearClause>(Clause)); |
4323 | } |
4324 | // Capture allocator expressions if used. |
4325 | for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getInnerAllocators()) |
4326 | MarkDeclarationsReferencedInExpr(E); |
4327 | // OpenMP, 2.7.1 Loop Construct, Restrictions |
4328 | // The nonmonotonic modifier cannot be specified if an ordered clause is |
4329 | // specified. |
4330 | if (SC && |
4331 | (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || |
4332 | SC->getSecondScheduleModifier() == |
4333 | OMPC_SCHEDULE_MODIFIER_nonmonotonic) && |
4334 | OC) { |
4335 | Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic |
4336 | ? SC->getFirstScheduleModifierLoc() |
4337 | : SC->getSecondScheduleModifierLoc(), |
4338 | diag::err_omp_simple_clause_incompatible_with_ordered) |
4339 | << getOpenMPClauseName(OMPC_schedule) |
4340 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, |
4341 | OMPC_SCHEDULE_MODIFIER_nonmonotonic) |
4342 | << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); |
4343 | ErrorFound = true; |
4344 | } |
4345 | // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. |
4346 | // If an order(concurrent) clause is present, an ordered clause may not appear |
4347 | // on the same directive. |
4348 | if (checkOrderedOrderSpecified(*this, Clauses)) |
4349 | ErrorFound = true; |
4350 | if (!LCs.empty() && OC && OC->getNumForLoops()) { |
4351 | for (const OMPLinearClause *C : LCs) { |
4352 | Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) |
4353 | << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); |
4354 | } |
4355 | ErrorFound = true; |
4356 | } |
4357 | if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && |
4358 | isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && OC && |
4359 | OC->getNumForLoops()) { |
4360 | Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) |
4361 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); |
4362 | ErrorFound = true; |
4363 | } |
4364 | if (ErrorFound) { |
4365 | return StmtError(); |
4366 | } |
4367 | StmtResult SR = S; |
4368 | unsigned CompletedRegions = 0; |
4369 | for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { |
4370 | // Mark all variables in private list clauses as used in inner region. |
4371 | // Required for proper codegen of combined directives. |
4372 | // TODO: add processing for other clauses. |
4373 | if (ThisCaptureRegion != OMPD_unknown) { |
4374 | for (const clang::OMPClauseWithPreInit *C : PICs) { |
4375 | OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); |
4376 | // Find the particular capture region for the clause if the |
4377 | // directive is a combined one with multiple capture regions. |
4378 | // If the directive is not a combined one, the capture region |
4379 | // associated with the clause is OMPD_unknown and is generated |
4380 | // only once. |
4381 | if (CaptureRegion == ThisCaptureRegion || |
4382 | CaptureRegion == OMPD_unknown) { |
4383 | if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { |
4384 | for (Decl *D : DS->decls()) |
4385 | MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); |
4386 | } |
4387 | } |
4388 | } |
4389 | } |
4390 | if (ThisCaptureRegion == OMPD_target) { |
4391 | // Capture allocator traits in the target region. They are used implicitly |
4392 | // and, thus, are not captured by default. |
4393 | for (OMPClause *C : Clauses) { |
4394 | if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { |
4395 | for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; |
4396 | ++I) { |
4397 | OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); |
4398 | if (Expr *E = D.AllocatorTraits) |
4399 | MarkDeclarationsReferencedInExpr(E); |
4400 | } |
4401 | continue; |
4402 | } |
4403 | } |
4404 | } |
4405 | if (++CompletedRegions == CaptureRegions.size()) |
4406 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setBodyComplete(); |
4407 | SR = ActOnCapturedRegionEnd(SR.get()); |
4408 | } |
4409 | return SR; |
4410 | } |
4411 | |
4412 | static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, |
4413 | OpenMPDirectiveKind CancelRegion, |
4414 | SourceLocation StartLoc) { |
4415 | // CancelRegion is only needed for cancel and cancellation_point. |
4416 | if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) |
4417 | return false; |
4418 | |
4419 | if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || |
4420 | CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) |
4421 | return false; |
4422 | |
4423 | SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) |
4424 | << getOpenMPDirectiveName(CancelRegion); |
4425 | return true; |
4426 | } |
4427 | |
4428 | static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, |
4429 | OpenMPDirectiveKind CurrentRegion, |
4430 | const DeclarationNameInfo &CurrentName, |
4431 | OpenMPDirectiveKind CancelRegion, |
4432 | SourceLocation StartLoc) { |
4433 | if (Stack->getCurScope()) { |
4434 | OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); |
4435 | OpenMPDirectiveKind OffendingRegion = ParentRegion; |
4436 | bool NestingProhibited = false; |
4437 | bool CloseNesting = true; |
4438 | bool OrphanSeen = false; |
4439 | enum { |
4440 | NoRecommend, |
4441 | ShouldBeInParallelRegion, |
4442 | ShouldBeInOrderedRegion, |
4443 | ShouldBeInTargetRegion, |
4444 | ShouldBeInTeamsRegion, |
4445 | ShouldBeInLoopSimdRegion, |
4446 | } Recommend = NoRecommend; |
4447 | if (isOpenMPSimdDirective(ParentRegion) && |
4448 | ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || |
4449 | (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && |
4450 | CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && |
4451 | CurrentRegion != OMPD_scan))) { |
4452 | // OpenMP [2.16, Nesting of Regions] |
4453 | // OpenMP constructs may not be nested inside a simd region. |
4454 | // OpenMP [2.8.1,simd Construct, Restrictions] |
4455 | // An ordered construct with the simd clause is the only OpenMP |
4456 | // construct that can appear in the simd region. |
4457 | // Allowing a SIMD construct nested in another SIMD construct is an |
4458 | // extension. The OpenMP 4.5 spec does not allow it. Issue a warning |
4459 | // message. |
4460 | // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] |
4461 | // The only OpenMP constructs that can be encountered during execution of |
4462 | // a simd region are the atomic construct, the loop construct, the simd |
4463 | // construct and the ordered construct with the simd clause. |
4464 | SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) |
4465 | ? diag::err_omp_prohibited_region_simd |
4466 | : diag::warn_omp_nesting_simd) |
4467 | << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); |
4468 | return CurrentRegion != OMPD_simd; |
4469 | } |
4470 | if (ParentRegion == OMPD_atomic) { |
4471 | // OpenMP [2.16, Nesting of Regions] |
4472 | // OpenMP constructs may not be nested inside an atomic region. |
4473 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); |
4474 | return true; |
4475 | } |
4476 | if (CurrentRegion == OMPD_section) { |
4477 | // OpenMP [2.7.2, sections Construct, Restrictions] |
4478 | // Orphaned section directives are prohibited. That is, the section |
4479 | // directives must appear within the sections construct and must not be |
4480 | // encountered elsewhere in the sections region. |
4481 | if (ParentRegion != OMPD_sections && |
4482 | ParentRegion != OMPD_parallel_sections) { |
4483 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) |
4484 | << (ParentRegion != OMPD_unknown) |
4485 | << getOpenMPDirectiveName(ParentRegion); |
4486 | return true; |
4487 | } |
4488 | return false; |
4489 | } |
4490 | // Allow some constructs (except teams and cancellation constructs) to be |
4491 | // orphaned (they could be used in functions, called from OpenMP regions |
4492 | // with the required preconditions). |
4493 | if (ParentRegion == OMPD_unknown && |
4494 | !isOpenMPNestingTeamsDirective(CurrentRegion) && |
4495 | CurrentRegion != OMPD_cancellation_point && |
4496 | CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) |
4497 | return false; |
4498 | if (CurrentRegion == OMPD_cancellation_point || |
4499 | CurrentRegion == OMPD_cancel) { |
4500 | // OpenMP [2.16, Nesting of Regions] |
4501 | // A cancellation point construct for which construct-type-clause is |
4502 | // taskgroup must be nested inside a task construct. A cancellation |
4503 | // point construct for which construct-type-clause is not taskgroup must |
4504 | // be closely nested inside an OpenMP construct that matches the type |
4505 | // specified in construct-type-clause. |
4506 | // A cancel construct for which construct-type-clause is taskgroup must be |
4507 | // nested inside a task construct. A cancel construct for which |
4508 | // construct-type-clause is not taskgroup must be closely nested inside an |
4509 | // OpenMP construct that matches the type specified in |
4510 | // construct-type-clause. |
4511 | NestingProhibited = |
4512 | !((CancelRegion == OMPD_parallel && |
4513 | (ParentRegion == OMPD_parallel || |
4514 | ParentRegion == OMPD_target_parallel)) || |
4515 | (CancelRegion == OMPD_for && |
4516 | (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || |
4517 | ParentRegion == OMPD_target_parallel_for || |
4518 | ParentRegion == OMPD_distribute_parallel_for || |
4519 | ParentRegion == OMPD_teams_distribute_parallel_for || |
4520 | ParentRegion == OMPD_target_teams_distribute_parallel_for)) || |
4521 | (CancelRegion == OMPD_taskgroup && |
4522 | (ParentRegion == OMPD_task || |
4523 | (SemaRef.getLangOpts().OpenMP >= 50 && |
4524 | (ParentRegion == OMPD_taskloop || |
4525 | ParentRegion == OMPD_master_taskloop || |
4526 | ParentRegion == OMPD_parallel_master_taskloop)))) || |
4527 | (CancelRegion == OMPD_sections && |
4528 | (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || |
4529 | ParentRegion == OMPD_parallel_sections))); |
4530 | OrphanSeen = ParentRegion == OMPD_unknown; |
4531 | } else if (CurrentRegion == OMPD_master) { |
4532 | // OpenMP [2.16, Nesting of Regions] |
4533 | // A master region may not be closely nested inside a worksharing, |
4534 | // atomic, or explicit task region. |
4535 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || |
4536 | isOpenMPTaskingDirective(ParentRegion); |
4537 | } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { |
4538 | // OpenMP [2.16, Nesting of Regions] |
4539 | // A critical region may not be nested (closely or otherwise) inside a |
4540 | // critical region with the same name. Note that this restriction is not |
4541 | // sufficient to prevent deadlock. |
4542 | SourceLocation PreviousCriticalLoc; |
4543 | bool DeadLock = Stack->hasDirective( |
4544 | [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, |
4545 | const DeclarationNameInfo &DNI, |
4546 | SourceLocation Loc) { |
4547 | if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { |
4548 | PreviousCriticalLoc = Loc; |
4549 | return true; |
4550 | } |
4551 | return false; |
4552 | }, |
4553 | false /* skip top directive */); |
4554 | if (DeadLock) { |
4555 | SemaRef.Diag(StartLoc, |
4556 | diag::err_omp_prohibited_region_critical_same_name) |
4557 | << CurrentName.getName(); |
4558 | if (PreviousCriticalLoc.isValid()) |
4559 | SemaRef.Diag(PreviousCriticalLoc, |
4560 | diag::note_omp_previous_critical_region); |
4561 | return true; |
4562 | } |
4563 | } else if (CurrentRegion == OMPD_barrier) { |
4564 | // OpenMP [2.16, Nesting of Regions] |
4565 | // A barrier region may not be closely nested inside a worksharing, |
4566 | // explicit task, critical, ordered, atomic, or master region. |
4567 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || |
4568 | isOpenMPTaskingDirective(ParentRegion) || |
4569 | ParentRegion == OMPD_master || |
4570 | ParentRegion == OMPD_parallel_master || |
4571 | ParentRegion == OMPD_critical || |
4572 | ParentRegion == OMPD_ordered; |
4573 | } else if (isOpenMPWorksharingDirective(CurrentRegion) && |
4574 | !isOpenMPParallelDirective(CurrentRegion) && |
4575 | !isOpenMPTeamsDirective(CurrentRegion)) { |
4576 | // OpenMP [2.16, Nesting of Regions] |
4577 | // A worksharing region may not be closely nested inside a worksharing, |
4578 | // explicit task, critical, ordered, atomic, or master region. |
4579 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || |
4580 | isOpenMPTaskingDirective(ParentRegion) || |
4581 | ParentRegion == OMPD_master || |
4582 | ParentRegion == OMPD_parallel_master || |
4583 | ParentRegion == OMPD_critical || |
4584 | ParentRegion == OMPD_ordered; |
4585 | Recommend = ShouldBeInParallelRegion; |
4586 | } else if (CurrentRegion == OMPD_ordered) { |
4587 | // OpenMP [2.16, Nesting of Regions] |
4588 | // An ordered region may not be closely nested inside a critical, |
4589 | // atomic, or explicit task region. |
4590 | // An ordered region must be closely nested inside a loop region (or |
4591 | // parallel loop region) with an ordered clause. |
4592 | // OpenMP [2.8.1,simd Construct, Restrictions] |
4593 | // An ordered construct with the simd clause is the only OpenMP construct |
4594 | // that can appear in the simd region. |
4595 | NestingProhibited = ParentRegion == OMPD_critical || |
4596 | isOpenMPTaskingDirective(ParentRegion) || |
4597 | !(isOpenMPSimdDirective(ParentRegion) || |
4598 | Stack->isParentOrderedRegion()); |
4599 | Recommend = ShouldBeInOrderedRegion; |
4600 | } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { |
4601 | // OpenMP [2.16, Nesting of Regions] |
4602 | // If specified, a teams construct must be contained within a target |
4603 | // construct. |
4604 | NestingProhibited = |
4605 | (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || |
4606 | (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && |
4607 | ParentRegion != OMPD_target); |
4608 | OrphanSeen = ParentRegion == OMPD_unknown; |
4609 | Recommend = ShouldBeInTargetRegion; |
4610 | } else if (CurrentRegion == OMPD_scan) { |
4611 | // OpenMP [2.16, Nesting of Regions] |
4612 | // If specified, a teams construct must be contained within a target |
4613 | // construct. |
4614 | NestingProhibited = |
4615 | SemaRef.LangOpts.OpenMP < 50 || |
4616 | (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && |
4617 | ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && |
4618 | ParentRegion != OMPD_parallel_for_simd); |
4619 | OrphanSeen = ParentRegion == OMPD_unknown; |
4620 | Recommend = ShouldBeInLoopSimdRegion; |
4621 | } |
4622 | if (!NestingProhibited && |
4623 | !isOpenMPTargetExecutionDirective(CurrentRegion) && |
4624 | !isOpenMPTargetDataManagementDirective(CurrentRegion) && |
4625 | (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { |
4626 | // OpenMP [2.16, Nesting of Regions] |
4627 | // distribute, parallel, parallel sections, parallel workshare, and the |
4628 | // parallel loop and parallel loop SIMD constructs are the only OpenMP |
4629 | // constructs that can be closely nested in the teams region. |
4630 | NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && |
4631 | !isOpenMPDistributeDirective(CurrentRegion); |
4632 | Recommend = ShouldBeInParallelRegion; |
4633 | } |
4634 | if (!NestingProhibited && |
4635 | isOpenMPNestingDistributeDirective(CurrentRegion)) { |
4636 | // OpenMP 4.5 [2.17 Nesting of Regions] |
4637 | // The region associated with the distribute construct must be strictly |
4638 | // nested inside a teams region |
4639 | NestingProhibited = |
4640 | (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); |
4641 | Recommend = ShouldBeInTeamsRegion; |
4642 | } |
4643 | if (!NestingProhibited && |
4644 | (isOpenMPTargetExecutionDirective(CurrentRegion) || |
4645 | isOpenMPTargetDataManagementDirective(CurrentRegion))) { |
4646 | // OpenMP 4.5 [2.17 Nesting of Regions] |
4647 | // If a target, target update, target data, target enter data, or |
4648 | // target exit data construct is encountered during execution of a |
4649 | // target region, the behavior is unspecified. |
4650 | NestingProhibited = Stack->hasDirective( |
4651 | [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, |
4652 | SourceLocation) { |
4653 | if (isOpenMPTargetExecutionDirective(K)) { |
4654 | OffendingRegion = K; |
4655 | return true; |
4656 | } |
4657 | return false; |
4658 | }, |
4659 | false /* don't skip top directive */); |
4660 | CloseNesting = false; |
4661 | } |
4662 | if (NestingProhibited) { |
4663 | if (OrphanSeen) { |
4664 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) |
4665 | << getOpenMPDirectiveName(CurrentRegion) << Recommend; |
4666 | } else { |
4667 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) |
4668 | << CloseNesting << getOpenMPDirectiveName(OffendingRegion) |
4669 | << Recommend << getOpenMPDirectiveName(CurrentRegion); |
4670 | } |
4671 | return true; |
4672 | } |
4673 | } |
4674 | return false; |
4675 | } |
4676 | |
4677 | struct Kind2Unsigned { |
4678 | using argument_type = OpenMPDirectiveKind; |
4679 | unsigned operator()(argument_type DK) { return unsigned(DK); } |
4680 | }; |
4681 | static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, |
4682 | ArrayRef<OMPClause *> Clauses, |
4683 | ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { |
4684 | bool ErrorFound = false; |
4685 | unsigned NamedModifiersNumber = 0; |
4686 | llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; |
4687 | FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); |
4688 | SmallVector<SourceLocation, 4> NameModifierLoc; |
4689 | for (const OMPClause *C : Clauses) { |
4690 | if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { |
4691 | // At most one if clause without a directive-name-modifier can appear on |
4692 | // the directive. |
4693 | OpenMPDirectiveKind CurNM = IC->getNameModifier(); |
4694 | if (FoundNameModifiers[CurNM]) { |
4695 | S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) |
4696 | << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) |
4697 | << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); |
4698 | ErrorFound = true; |
4699 | } else if (CurNM != OMPD_unknown) { |
4700 | NameModifierLoc.push_back(IC->getNameModifierLoc()); |
4701 | ++NamedModifiersNumber; |
4702 | } |
4703 | FoundNameModifiers[CurNM] = IC; |
4704 | if (CurNM == OMPD_unknown) |
4705 | continue; |
4706 | // Check if the specified name modifier is allowed for the current |
4707 | // directive. |
4708 | // At most one if clause with the particular directive-name-modifier can |
4709 | // appear on the directive. |
4710 | bool MatchFound = false; |
4711 | for (auto NM : AllowedNameModifiers) { |
4712 | if (CurNM == NM) { |
4713 | MatchFound = true; |
4714 | break; |
4715 | } |
4716 | } |
4717 | if (!MatchFound) { |
4718 | S.Diag(IC->getNameModifierLoc(), |
4719 | diag::err_omp_wrong_if_directive_name_modifier) |
4720 | << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); |
4721 | ErrorFound = true; |
4722 | } |
4723 | } |
4724 | } |
4725 | // If any if clause on the directive includes a directive-name-modifier then |
4726 | // all if clauses on the directive must include a directive-name-modifier. |
4727 | if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { |
4728 | if (NamedModifiersNumber == AllowedNameModifiers.size()) { |
4729 | S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), |
4730 | diag::err_omp_no_more_if_clause); |
4731 | } else { |
4732 | std::string Values; |
4733 | std::string Sep(", "); |
4734 | unsigned AllowedCnt = 0; |
4735 | unsigned TotalAllowedNum = |
4736 | AllowedNameModifiers.size() - NamedModifiersNumber; |
4737 | for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; |
4738 | ++Cnt) { |
4739 | OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; |
4740 | if (!FoundNameModifiers[NM]) { |
4741 | Values += "'"; |
4742 | Values += getOpenMPDirectiveName(NM); |
4743 | Values += "'"; |
4744 | if (AllowedCnt + 2 == TotalAllowedNum) |
4745 | Values += " or "; |
4746 | else if (AllowedCnt + 1 != TotalAllowedNum) |
4747 | Values += Sep; |
4748 | ++AllowedCnt; |
4749 | } |
4750 | } |
4751 | S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), |
4752 | diag::err_omp_unnamed_if_clause) |
4753 | << (TotalAllowedNum > 1) << Values; |
4754 | } |
4755 | for (SourceLocation Loc : NameModifierLoc) { |
4756 | S.Diag(Loc, diag::note_omp_previous_named_if_clause); |
4757 | } |
4758 | ErrorFound = true; |
4759 | } |
4760 | return ErrorFound; |
4761 | } |
4762 | |
4763 | static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, |
4764 | SourceLocation &ELoc, |
4765 | SourceRange &ERange, |
4766 | bool AllowArraySection) { |
4767 | if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || |
4768 | RefExpr->containsUnexpandedParameterPack()) |
4769 | return std::make_pair(nullptr, true); |
4770 | |
4771 | // OpenMP [3.1, C/C++] |
4772 | // A list item is a variable name. |
4773 | // OpenMP [2.9.3.3, Restrictions, p.1] |
4774 | // A variable that is part of another variable (as an array or |
4775 | // structure element) cannot appear in a private clause. |
4776 | RefExpr = RefExpr->IgnoreParens(); |
4777 | enum { |
4778 | NoArrayExpr = -1, |
4779 | ArraySubscript = 0, |
4780 | OMPArraySection = 1 |
4781 | } IsArrayExpr = NoArrayExpr; |
4782 | if (AllowArraySection) { |
4783 | if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { |
4784 | Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); |
4785 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) |
4786 | Base = TempASE->getBase()->IgnoreParenImpCasts(); |
4787 | RefExpr = Base; |
4788 | IsArrayExpr = ArraySubscript; |
4789 | } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { |
4790 | Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); |
4791 | while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) |
4792 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); |
4793 | while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) |
4794 | Base = TempASE->getBase()->IgnoreParenImpCasts(); |
4795 | RefExpr = Base; |
4796 | IsArrayExpr = OMPArraySection; |
4797 | } |
4798 | } |
4799 | ELoc = RefExpr->getExprLoc(); |
4800 | ERange = RefExpr->getSourceRange(); |
4801 | RefExpr = RefExpr->IgnoreParenImpCasts(); |
4802 | auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); |
4803 | auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); |
4804 | if ((!DE || !isa<VarDecl>(DE->getDecl())) && |
4805 | (S.getCurrentThisType().isNull() || !ME || |
4806 | !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || |
4807 | !isa<FieldDecl>(ME->getMemberDecl()))) { |
4808 | if (IsArrayExpr != NoArrayExpr) { |
4809 | S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr |
4810 | << ERange; |
4811 | } else { |
4812 | S.Diag(ELoc, |
4813 | AllowArraySection |
4814 | ? diag::err_omp_expected_var_name_member_expr_or_array_item |
4815 | : diag::err_omp_expected_var_name_member_expr) |
4816 | << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; |
4817 | } |
4818 | return std::make_pair(nullptr, false); |
4819 | } |
4820 | return std::make_pair( |
4821 | getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); |
4822 | } |
4823 | |
4824 | namespace { |
4825 | /// Checks if the allocator is used in uses_allocators clause to be allowed in |
4826 | /// target regions. |
4827 | class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { |
4828 | DSAStackTy *S = nullptr; |
4829 | |
4830 | public: |
4831 | bool VisitDeclRefExpr(const DeclRefExpr *E) { |
4832 | return S->isUsesAllocatorsDecl(E->getDecl()) |
4833 | .getValueOr( |
4834 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == |
4835 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; |
4836 | } |
4837 | bool VisitStmt(const Stmt *S) { |
4838 | for (const Stmt *Child : S->children()) { |
4839 | if (Child && Visit(Child)) |
4840 | return true; |
4841 | } |
4842 | return false; |
4843 | } |
4844 | explicit AllocatorChecker(DSAStackTy *S) : S(S) {} |
4845 | }; |
4846 | } // namespace |
4847 | |
4848 | static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, |
4849 | ArrayRef<OMPClause *> Clauses) { |
4850 | assert(!S.CurContext->isDependentContext() &&((!S.CurContext->isDependentContext() && "Expected non-dependent context." ) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4851, __PRETTY_FUNCTION__)) |
4851 | "Expected non-dependent context.")((!S.CurContext->isDependentContext() && "Expected non-dependent context." ) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4851, __PRETTY_FUNCTION__)); |
4852 | auto AllocateRange = |
4853 | llvm::make_filter_range(Clauses, OMPAllocateClause::classof); |
4854 | llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> |
4855 | DeclToCopy; |
4856 | auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { |
4857 | return isOpenMPPrivate(C->getClauseKind()); |
4858 | }); |
4859 | for (OMPClause *Cl : PrivateRange) { |
4860 | MutableArrayRef<Expr *>::iterator I, It, Et; |
4861 | if (Cl->getClauseKind() == OMPC_private) { |
4862 | auto *PC = cast<OMPPrivateClause>(Cl); |
4863 | I = PC->private_copies().begin(); |
4864 | It = PC->varlist_begin(); |
4865 | Et = PC->varlist_end(); |
4866 | } else if (Cl->getClauseKind() == OMPC_firstprivate) { |
4867 | auto *PC = cast<OMPFirstprivateClause>(Cl); |
4868 | I = PC->private_copies().begin(); |
4869 | It = PC->varlist_begin(); |
4870 | Et = PC->varlist_end(); |
4871 | } else if (Cl->getClauseKind() == OMPC_lastprivate) { |
4872 | auto *PC = cast<OMPLastprivateClause>(Cl); |
4873 | I = PC->private_copies().begin(); |
4874 | It = PC->varlist_begin(); |
4875 | Et = PC->varlist_end(); |
4876 | } else if (Cl->getClauseKind() == OMPC_linear) { |
4877 | auto *PC = cast<OMPLinearClause>(Cl); |
4878 | I = PC->privates().begin(); |
4879 | It = PC->varlist_begin(); |
4880 | Et = PC->varlist_end(); |
4881 | } else if (Cl->getClauseKind() == OMPC_reduction) { |
4882 | auto *PC = cast<OMPReductionClause>(Cl); |
4883 | I = PC->privates().begin(); |
4884 | It = PC->varlist_begin(); |
4885 | Et = PC->varlist_end(); |
4886 | } else if (Cl->getClauseKind() == OMPC_task_reduction) { |
4887 | auto *PC = cast<OMPTaskReductionClause>(Cl); |
4888 | I = PC->privates().begin(); |
4889 | It = PC->varlist_begin(); |
4890 | Et = PC->varlist_end(); |
4891 | } else if (Cl->getClauseKind() == OMPC_in_reduction) { |
4892 | auto *PC = cast<OMPInReductionClause>(Cl); |
4893 | I = PC->privates().begin(); |
4894 | It = PC->varlist_begin(); |
4895 | Et = PC->varlist_end(); |
4896 | } else { |
4897 | llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4897); |
4898 | } |
4899 | for (Expr *E : llvm::make_range(It, Et)) { |
4900 | if (!*I) { |
4901 | ++I; |
4902 | continue; |
4903 | } |
4904 | SourceLocation ELoc; |
4905 | SourceRange ERange; |
4906 | Expr *SimpleRefExpr = E; |
4907 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, |
4908 | /*AllowArraySection=*/true); |
4909 | DeclToCopy.try_emplace(Res.first, |
4910 | cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); |
4911 | ++I; |
4912 | } |
4913 | } |
4914 | for (OMPClause *C : AllocateRange) { |
4915 | auto *AC = cast<OMPAllocateClause>(C); |
4916 | if (S.getLangOpts().OpenMP >= 50 && |
4917 | !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && |
4918 | isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && |
4919 | AC->getAllocator()) { |
4920 | Expr *Allocator = AC->getAllocator(); |
4921 | // OpenMP, 2.12.5 target Construct |
4922 | // Memory allocators that do not appear in a uses_allocators clause cannot |
4923 | // appear as an allocator in an allocate clause or be used in the target |
4924 | // region unless a requires directive with the dynamic_allocators clause |
4925 | // is present in the same compilation unit. |
4926 | AllocatorChecker Checker(Stack); |
4927 | if (Checker.Visit(Allocator)) |
4928 | S.Diag(Allocator->getExprLoc(), |
4929 | diag::err_omp_allocator_not_in_uses_allocators) |
4930 | << Allocator->getSourceRange(); |
4931 | } |
4932 | OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = |
4933 | getAllocatorKind(S, Stack, AC->getAllocator()); |
4934 | // OpenMP, 2.11.4 allocate Clause, Restrictions. |
4935 | // For task, taskloop or target directives, allocation requests to memory |
4936 | // allocators with the trait access set to thread result in unspecified |
4937 | // behavior. |
4938 | if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && |
4939 | (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || |
4940 | isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { |
4941 | S.Diag(AC->getAllocator()->getExprLoc(), |
4942 | diag::warn_omp_allocate_thread_on_task_target_directive) |
4943 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); |
4944 | } |
4945 | for (Expr *E : AC->varlists()) { |
4946 | SourceLocation ELoc; |
4947 | SourceRange ERange; |
4948 | Expr *SimpleRefExpr = E; |
4949 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); |
4950 | ValueDecl *VD = Res.first; |
4951 | DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); |
4952 | if (!isOpenMPPrivate(Data.CKind)) { |
4953 | S.Diag(E->getExprLoc(), |
4954 | diag::err_omp_expected_private_copy_for_allocate); |
4955 | continue; |
4956 | } |
4957 | VarDecl *PrivateVD = DeclToCopy[VD]; |
4958 | if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, |
4959 | AllocatorKind, AC->getAllocator())) |
4960 | continue; |
4961 | applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), |
4962 | E->getSourceRange()); |
4963 | } |
4964 | } |
4965 | } |
4966 | |
4967 | StmtResult Sema::ActOnOpenMPExecutableDirective( |
4968 | OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, |
4969 | OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, |
4970 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { |
4971 | StmtResult Res = StmtError(); |
4972 | // First check CancelRegion which is then used in checkNestingOfRegions. |
4973 | if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || |
4974 | checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), Kind, DirName, CancelRegion, |
4975 | StartLoc)) |
4976 | return StmtError(); |
4977 | |
4978 | llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; |
4979 | VarsWithInheritedDSAType VarsWithInheritedDSA; |
4980 | bool ErrorFound = false; |
4981 | ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); |
4982 | if (AStmt && !CurContext->isDependentContext()) { |
4983 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 4983, __PRETTY_FUNCTION__)); |
4984 | |
4985 | // Check default data sharing attributes for referenced variables. |
4986 | DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), *this, cast<CapturedStmt>(AStmt)); |
4987 | int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); |
4988 | Stmt *S = AStmt; |
4989 | while (--ThisCaptureLevel >= 0) |
4990 | S = cast<CapturedStmt>(S)->getCapturedStmt(); |
4991 | DSAChecker.Visit(S); |
4992 | if (!isOpenMPTargetDataManagementDirective(Kind) && |
4993 | !isOpenMPTaskingDirective(Kind)) { |
4994 | // Visit subcaptures to generate implicit clauses for captured vars. |
4995 | auto *CS = cast<CapturedStmt>(AStmt); |
4996 | SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
4997 | getOpenMPCaptureRegions(CaptureRegions, Kind); |
4998 | // Ignore outer tasking regions for target directives. |
4999 | if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) |
5000 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
5001 | DSAChecker.visitSubCaptures(CS); |
5002 | } |
5003 | if (DSAChecker.isErrorFound()) |
5004 | return StmtError(); |
5005 | // Generate list of implicitly defined firstprivate variables. |
5006 | VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); |
5007 | |
5008 | SmallVector<Expr *, 4> ImplicitFirstprivates( |
5009 | DSAChecker.getImplicitFirstprivate().begin(), |
5010 | DSAChecker.getImplicitFirstprivate().end()); |
5011 | SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; |
5012 | for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { |
5013 | ArrayRef<Expr *> ImplicitMap = |
5014 | DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); |
5015 | ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); |
5016 | } |
5017 | // Mark taskgroup task_reduction descriptors as implicitly firstprivate. |
5018 | for (OMPClause *C : Clauses) { |
5019 | if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { |
5020 | for (Expr *E : IRC->taskgroup_descriptors()) |
5021 | if (E) |
5022 | ImplicitFirstprivates.emplace_back(E); |
5023 | } |
5024 | // OpenMP 5.0, 2.10.1 task Construct |
5025 | // [detach clause]... The event-handle will be considered as if it was |
5026 | // specified on a firstprivate clause. |
5027 | if (auto *DC = dyn_cast<OMPDetachClause>(C)) |
5028 | ImplicitFirstprivates.push_back(DC->getEventHandler()); |
5029 | } |
5030 | if (!ImplicitFirstprivates.empty()) { |
5031 | if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( |
5032 | ImplicitFirstprivates, SourceLocation(), SourceLocation(), |
5033 | SourceLocation())) { |
5034 | ClausesWithImplicit.push_back(Implicit); |
5035 | ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != |
5036 | ImplicitFirstprivates.size(); |
5037 | } else { |
5038 | ErrorFound = true; |
5039 | } |
5040 | } |
5041 | int ClauseKindCnt = -1; |
5042 | for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { |
5043 | ++ClauseKindCnt; |
5044 | if (ImplicitMap.empty()) |
5045 | continue; |
5046 | CXXScopeSpec MapperIdScopeSpec; |
5047 | DeclarationNameInfo MapperId; |
5048 | auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); |
5049 | if (OMPClause *Implicit = ActOnOpenMPMapClause( |
5050 | llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, |
5051 | /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), |
5052 | ImplicitMap, OMPVarListLocTy())) { |
5053 | ClausesWithImplicit.emplace_back(Implicit); |
5054 | ErrorFound |= |
5055 | cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); |
5056 | } else { |
5057 | ErrorFound = true; |
5058 | } |
5059 | } |
5060 | } |
5061 | |
5062 | llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; |
5063 | switch (Kind) { |
5064 | case OMPD_parallel: |
5065 | Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, |
5066 | EndLoc); |
5067 | AllowedNameModifiers.push_back(OMPD_parallel); |
5068 | break; |
5069 | case OMPD_simd: |
5070 | Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, |
5071 | VarsWithInheritedDSA); |
5072 | if (LangOpts.OpenMP >= 50) |
5073 | AllowedNameModifiers.push_back(OMPD_simd); |
5074 | break; |
5075 | case OMPD_for: |
5076 | Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, |
5077 | VarsWithInheritedDSA); |
5078 | break; |
5079 | case OMPD_for_simd: |
5080 | Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, |
5081 | EndLoc, VarsWithInheritedDSA); |
5082 | if (LangOpts.OpenMP >= 50) |
5083 | AllowedNameModifiers.push_back(OMPD_simd); |
5084 | break; |
5085 | case OMPD_sections: |
5086 | Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, |
5087 | EndLoc); |
5088 | break; |
5089 | case OMPD_section: |
5090 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5091, __PRETTY_FUNCTION__)) |
5091 | "No clauses are allowed for 'omp section' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5091, __PRETTY_FUNCTION__)); |
5092 | Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); |
5093 | break; |
5094 | case OMPD_single: |
5095 | Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, |
5096 | EndLoc); |
5097 | break; |
5098 | case OMPD_master: |
5099 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5100, __PRETTY_FUNCTION__)) |
5100 | "No clauses are allowed for 'omp master' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5100, __PRETTY_FUNCTION__)); |
5101 | Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); |
5102 | break; |
5103 | case OMPD_critical: |
5104 | Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, |
5105 | StartLoc, EndLoc); |
5106 | break; |
5107 | case OMPD_parallel_for: |
5108 | Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, |
5109 | EndLoc, VarsWithInheritedDSA); |
5110 | AllowedNameModifiers.push_back(OMPD_parallel); |
5111 | break; |
5112 | case OMPD_parallel_for_simd: |
5113 | Res = ActOnOpenMPParallelForSimdDirective( |
5114 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5115 | AllowedNameModifiers.push_back(OMPD_parallel); |
5116 | if (LangOpts.OpenMP >= 50) |
5117 | AllowedNameModifiers.push_back(OMPD_simd); |
5118 | break; |
5119 | case OMPD_parallel_master: |
5120 | Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, |
5121 | StartLoc, EndLoc); |
5122 | AllowedNameModifiers.push_back(OMPD_parallel); |
5123 | break; |
5124 | case OMPD_parallel_sections: |
5125 | Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, |
5126 | StartLoc, EndLoc); |
5127 | AllowedNameModifiers.push_back(OMPD_parallel); |
5128 | break; |
5129 | case OMPD_task: |
5130 | Res = |
5131 | ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); |
5132 | AllowedNameModifiers.push_back(OMPD_task); |
5133 | break; |
5134 | case OMPD_taskyield: |
5135 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5136, __PRETTY_FUNCTION__)) |
5136 | "No clauses are allowed for 'omp taskyield' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5136, __PRETTY_FUNCTION__)); |
5137 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5138, __PRETTY_FUNCTION__)) |
5138 | "No associated statement allowed for 'omp taskyield' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5138, __PRETTY_FUNCTION__)); |
5139 | Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); |
5140 | break; |
5141 | case OMPD_barrier: |
5142 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5143, __PRETTY_FUNCTION__)) |
5143 | "No clauses are allowed for 'omp barrier' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5143, __PRETTY_FUNCTION__)); |
5144 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5145, __PRETTY_FUNCTION__)) |
5145 | "No associated statement allowed for 'omp barrier' directive")((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5145, __PRETTY_FUNCTION__)); |
5146 | Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); |
5147 | break; |
5148 | case OMPD_taskwait: |
5149 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5150, __PRETTY_FUNCTION__)) |
5150 | "No clauses are allowed for 'omp taskwait' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5150, __PRETTY_FUNCTION__)); |
5151 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5152, __PRETTY_FUNCTION__)) |
5152 | "No associated statement allowed for 'omp taskwait' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5152, __PRETTY_FUNCTION__)); |
5153 | Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); |
5154 | break; |
5155 | case OMPD_taskgroup: |
5156 | Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, |
5157 | EndLoc); |
5158 | break; |
5159 | case OMPD_flush: |
5160 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5161, __PRETTY_FUNCTION__)) |
5161 | "No associated statement allowed for 'omp flush' directive")((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5161, __PRETTY_FUNCTION__)); |
5162 | Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); |
5163 | break; |
5164 | case OMPD_depobj: |
5165 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5166, __PRETTY_FUNCTION__)) |
5166 | "No associated statement allowed for 'omp depobj' directive")((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5166, __PRETTY_FUNCTION__)); |
5167 | Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); |
5168 | break; |
5169 | case OMPD_scan: |
5170 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5171, __PRETTY_FUNCTION__)) |
5171 | "No associated statement allowed for 'omp scan' directive")((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5171, __PRETTY_FUNCTION__)); |
5172 | Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); |
5173 | break; |
5174 | case OMPD_ordered: |
5175 | Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, |
5176 | EndLoc); |
5177 | break; |
5178 | case OMPD_atomic: |
5179 | Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, |
5180 | EndLoc); |
5181 | break; |
5182 | case OMPD_teams: |
5183 | Res = |
5184 | ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); |
5185 | break; |
5186 | case OMPD_target: |
5187 | Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, |
5188 | EndLoc); |
5189 | AllowedNameModifiers.push_back(OMPD_target); |
5190 | break; |
5191 | case OMPD_target_parallel: |
5192 | Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, |
5193 | StartLoc, EndLoc); |
5194 | AllowedNameModifiers.push_back(OMPD_target); |
5195 | AllowedNameModifiers.push_back(OMPD_parallel); |
5196 | break; |
5197 | case OMPD_target_parallel_for: |
5198 | Res = ActOnOpenMPTargetParallelForDirective( |
5199 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5200 | AllowedNameModifiers.push_back(OMPD_target); |
5201 | AllowedNameModifiers.push_back(OMPD_parallel); |
5202 | break; |
5203 | case OMPD_cancellation_point: |
5204 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5205, __PRETTY_FUNCTION__)) |
5205 | "No clauses are allowed for 'omp cancellation point' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5205, __PRETTY_FUNCTION__)); |
5206 | assert(AStmt == nullptr && "No associated statement allowed for 'omp "((AStmt == nullptr && "No associated statement allowed for 'omp " "cancellation point' directive") ? static_cast<void> ( 0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5207, __PRETTY_FUNCTION__)) |
5207 | "cancellation point' directive")((AStmt == nullptr && "No associated statement allowed for 'omp " "cancellation point' directive") ? static_cast<void> ( 0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5207, __PRETTY_FUNCTION__)); |
5208 | Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); |
5209 | break; |
5210 | case OMPD_cancel: |
5211 | assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5212, __PRETTY_FUNCTION__)) |
5212 | "No associated statement allowed for 'omp cancel' directive")((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive" ) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5212, __PRETTY_FUNCTION__)); |
5213 | Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, |
5214 | CancelRegion); |
5215 | AllowedNameModifiers.push_back(OMPD_cancel); |
5216 | break; |
5217 | case OMPD_target_data: |
5218 | Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, |
5219 | EndLoc); |
5220 | AllowedNameModifiers.push_back(OMPD_target_data); |
5221 | break; |
5222 | case OMPD_target_enter_data: |
5223 | Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, |
5224 | EndLoc, AStmt); |
5225 | AllowedNameModifiers.push_back(OMPD_target_enter_data); |
5226 | break; |
5227 | case OMPD_target_exit_data: |
5228 | Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, |
5229 | EndLoc, AStmt); |
5230 | AllowedNameModifiers.push_back(OMPD_target_exit_data); |
5231 | break; |
5232 | case OMPD_taskloop: |
5233 | Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, |
5234 | EndLoc, VarsWithInheritedDSA); |
5235 | AllowedNameModifiers.push_back(OMPD_taskloop); |
5236 | break; |
5237 | case OMPD_taskloop_simd: |
5238 | Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, |
5239 | EndLoc, VarsWithInheritedDSA); |
5240 | AllowedNameModifiers.push_back(OMPD_taskloop); |
5241 | if (LangOpts.OpenMP >= 50) |
5242 | AllowedNameModifiers.push_back(OMPD_simd); |
5243 | break; |
5244 | case OMPD_master_taskloop: |
5245 | Res = ActOnOpenMPMasterTaskLoopDirective( |
5246 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5247 | AllowedNameModifiers.push_back(OMPD_taskloop); |
5248 | break; |
5249 | case OMPD_master_taskloop_simd: |
5250 | Res = ActOnOpenMPMasterTaskLoopSimdDirective( |
5251 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5252 | AllowedNameModifiers.push_back(OMPD_taskloop); |
5253 | if (LangOpts.OpenMP >= 50) |
5254 | AllowedNameModifiers.push_back(OMPD_simd); |
5255 | break; |
5256 | case OMPD_parallel_master_taskloop: |
5257 | Res = ActOnOpenMPParallelMasterTaskLoopDirective( |
5258 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5259 | AllowedNameModifiers.push_back(OMPD_taskloop); |
5260 | AllowedNameModifiers.push_back(OMPD_parallel); |
5261 | break; |
5262 | case OMPD_parallel_master_taskloop_simd: |
5263 | Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( |
5264 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5265 | AllowedNameModifiers.push_back(OMPD_taskloop); |
5266 | AllowedNameModifiers.push_back(OMPD_parallel); |
5267 | if (LangOpts.OpenMP >= 50) |
5268 | AllowedNameModifiers.push_back(OMPD_simd); |
5269 | break; |
5270 | case OMPD_distribute: |
5271 | Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, |
5272 | EndLoc, VarsWithInheritedDSA); |
5273 | break; |
5274 | case OMPD_target_update: |
5275 | Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, |
5276 | EndLoc, AStmt); |
5277 | AllowedNameModifiers.push_back(OMPD_target_update); |
5278 | break; |
5279 | case OMPD_distribute_parallel_for: |
5280 | Res = ActOnOpenMPDistributeParallelForDirective( |
5281 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5282 | AllowedNameModifiers.push_back(OMPD_parallel); |
5283 | break; |
5284 | case OMPD_distribute_parallel_for_simd: |
5285 | Res = ActOnOpenMPDistributeParallelForSimdDirective( |
5286 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5287 | AllowedNameModifiers.push_back(OMPD_parallel); |
5288 | if (LangOpts.OpenMP >= 50) |
5289 | AllowedNameModifiers.push_back(OMPD_simd); |
5290 | break; |
5291 | case OMPD_distribute_simd: |
5292 | Res = ActOnOpenMPDistributeSimdDirective( |
5293 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5294 | if (LangOpts.OpenMP >= 50) |
5295 | AllowedNameModifiers.push_back(OMPD_simd); |
5296 | break; |
5297 | case OMPD_target_parallel_for_simd: |
5298 | Res = ActOnOpenMPTargetParallelForSimdDirective( |
5299 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5300 | AllowedNameModifiers.push_back(OMPD_target); |
5301 | AllowedNameModifiers.push_back(OMPD_parallel); |
5302 | if (LangOpts.OpenMP >= 50) |
5303 | AllowedNameModifiers.push_back(OMPD_simd); |
5304 | break; |
5305 | case OMPD_target_simd: |
5306 | Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, |
5307 | EndLoc, VarsWithInheritedDSA); |
5308 | AllowedNameModifiers.push_back(OMPD_target); |
5309 | if (LangOpts.OpenMP >= 50) |
5310 | AllowedNameModifiers.push_back(OMPD_simd); |
5311 | break; |
5312 | case OMPD_teams_distribute: |
5313 | Res = ActOnOpenMPTeamsDistributeDirective( |
5314 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5315 | break; |
5316 | case OMPD_teams_distribute_simd: |
5317 | Res = ActOnOpenMPTeamsDistributeSimdDirective( |
5318 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5319 | if (LangOpts.OpenMP >= 50) |
5320 | AllowedNameModifiers.push_back(OMPD_simd); |
5321 | break; |
5322 | case OMPD_teams_distribute_parallel_for_simd: |
5323 | Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( |
5324 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5325 | AllowedNameModifiers.push_back(OMPD_parallel); |
5326 | if (LangOpts.OpenMP >= 50) |
5327 | AllowedNameModifiers.push_back(OMPD_simd); |
5328 | break; |
5329 | case OMPD_teams_distribute_parallel_for: |
5330 | Res = ActOnOpenMPTeamsDistributeParallelForDirective( |
5331 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5332 | AllowedNameModifiers.push_back(OMPD_parallel); |
5333 | break; |
5334 | case OMPD_target_teams: |
5335 | Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, |
5336 | EndLoc); |
5337 | AllowedNameModifiers.push_back(OMPD_target); |
5338 | break; |
5339 | case OMPD_target_teams_distribute: |
5340 | Res = ActOnOpenMPTargetTeamsDistributeDirective( |
5341 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5342 | AllowedNameModifiers.push_back(OMPD_target); |
5343 | break; |
5344 | case OMPD_target_teams_distribute_parallel_for: |
5345 | Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( |
5346 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5347 | AllowedNameModifiers.push_back(OMPD_target); |
5348 | AllowedNameModifiers.push_back(OMPD_parallel); |
5349 | break; |
5350 | case OMPD_target_teams_distribute_parallel_for_simd: |
5351 | Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( |
5352 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5353 | AllowedNameModifiers.push_back(OMPD_target); |
5354 | AllowedNameModifiers.push_back(OMPD_parallel); |
5355 | if (LangOpts.OpenMP >= 50) |
5356 | AllowedNameModifiers.push_back(OMPD_simd); |
5357 | break; |
5358 | case OMPD_target_teams_distribute_simd: |
5359 | Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( |
5360 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); |
5361 | AllowedNameModifiers.push_back(OMPD_target); |
5362 | if (LangOpts.OpenMP >= 50) |
5363 | AllowedNameModifiers.push_back(OMPD_simd); |
5364 | break; |
5365 | case OMPD_declare_target: |
5366 | case OMPD_end_declare_target: |
5367 | case OMPD_threadprivate: |
5368 | case OMPD_allocate: |
5369 | case OMPD_declare_reduction: |
5370 | case OMPD_declare_mapper: |
5371 | case OMPD_declare_simd: |
5372 | case OMPD_requires: |
5373 | case OMPD_declare_variant: |
5374 | case OMPD_begin_declare_variant: |
5375 | case OMPD_end_declare_variant: |
5376 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5376); |
5377 | case OMPD_unknown: |
5378 | default: |
5379 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5379); |
5380 | } |
5381 | |
5382 | ErrorFound = Res.isInvalid() || ErrorFound; |
5383 | |
5384 | // Check variables in the clauses if default(none) or |
5385 | // default(firstprivate) was specified. |
5386 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || |
5387 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate) { |
5388 | DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), *this, nullptr); |
5389 | for (OMPClause *C : Clauses) { |
5390 | switch (C->getClauseKind()) { |
5391 | case OMPC_num_threads: |
5392 | case OMPC_dist_schedule: |
5393 | // Do not analyse if no parent teams directive. |
5394 | if (isOpenMPTeamsDirective(Kind)) |
5395 | break; |
5396 | continue; |
5397 | case OMPC_if: |
5398 | if (isOpenMPTeamsDirective(Kind) && |
5399 | cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) |
5400 | break; |
5401 | if (isOpenMPParallelDirective(Kind) && |
5402 | isOpenMPTaskLoopDirective(Kind) && |
5403 | cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) |
5404 | break; |
5405 | continue; |
5406 | case OMPC_schedule: |
5407 | case OMPC_detach: |
5408 | break; |
5409 | case OMPC_grainsize: |
5410 | case OMPC_num_tasks: |
5411 | case OMPC_final: |
5412 | case OMPC_priority: |
5413 | // Do not analyze if no parent parallel directive. |
5414 | if (isOpenMPParallelDirective(Kind)) |
5415 | break; |
5416 | continue; |
5417 | case OMPC_ordered: |
5418 | case OMPC_device: |
5419 | case OMPC_num_teams: |
5420 | case OMPC_thread_limit: |
5421 | case OMPC_hint: |
5422 | case OMPC_collapse: |
5423 | case OMPC_safelen: |
5424 | case OMPC_simdlen: |
5425 | case OMPC_default: |
5426 | case OMPC_proc_bind: |
5427 | case OMPC_private: |
5428 | case OMPC_firstprivate: |
5429 | case OMPC_lastprivate: |
5430 | case OMPC_shared: |
5431 | case OMPC_reduction: |
5432 | case OMPC_task_reduction: |
5433 | case OMPC_in_reduction: |
5434 | case OMPC_linear: |
5435 | case OMPC_aligned: |
5436 | case OMPC_copyin: |
5437 | case OMPC_copyprivate: |
5438 | case OMPC_nowait: |
5439 | case OMPC_untied: |
5440 | case OMPC_mergeable: |
5441 | case OMPC_allocate: |
5442 | case OMPC_read: |
5443 | case OMPC_write: |
5444 | case OMPC_update: |
5445 | case OMPC_capture: |
5446 | case OMPC_seq_cst: |
5447 | case OMPC_acq_rel: |
5448 | case OMPC_acquire: |
5449 | case OMPC_release: |
5450 | case OMPC_relaxed: |
5451 | case OMPC_depend: |
5452 | case OMPC_threads: |
5453 | case OMPC_simd: |
5454 | case OMPC_map: |
5455 | case OMPC_nogroup: |
5456 | case OMPC_defaultmap: |
5457 | case OMPC_to: |
5458 | case OMPC_from: |
5459 | case OMPC_use_device_ptr: |
5460 | case OMPC_use_device_addr: |
5461 | case OMPC_is_device_ptr: |
5462 | case OMPC_nontemporal: |
5463 | case OMPC_order: |
5464 | case OMPC_destroy: |
5465 | case OMPC_inclusive: |
5466 | case OMPC_exclusive: |
5467 | case OMPC_uses_allocators: |
5468 | case OMPC_affinity: |
5469 | continue; |
5470 | case OMPC_allocator: |
5471 | case OMPC_flush: |
5472 | case OMPC_depobj: |
5473 | case OMPC_threadprivate: |
5474 | case OMPC_uniform: |
5475 | case OMPC_unknown: |
5476 | case OMPC_unified_address: |
5477 | case OMPC_unified_shared_memory: |
5478 | case OMPC_reverse_offload: |
5479 | case OMPC_dynamic_allocators: |
5480 | case OMPC_atomic_default_mem_order: |
5481 | case OMPC_device_type: |
5482 | case OMPC_match: |
5483 | default: |
5484 | llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5484); |
5485 | } |
5486 | for (Stmt *CC : C->children()) { |
5487 | if (CC) |
5488 | DSAChecker.Visit(CC); |
5489 | } |
5490 | } |
5491 | for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) |
5492 | VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); |
5493 | } |
5494 | for (const auto &P : VarsWithInheritedDSA) { |
5495 | if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) |
5496 | continue; |
5497 | ErrorFound = true; |
5498 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_none || |
5499 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSA() == DSA_firstprivate) { |
5500 | Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) |
5501 | << P.first << P.second->getSourceRange(); |
5502 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSALocation(), diag::note_omp_default_dsa_none); |
5503 | } else if (getLangOpts().OpenMP >= 50) { |
5504 | Diag(P.second->getExprLoc(), |
5505 | diag::err_omp_defaultmap_no_attr_for_variable) |
5506 | << P.first << P.second->getSourceRange(); |
5507 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getDefaultDSALocation(), |
5508 | diag::note_omp_defaultmap_attr_none); |
5509 | } |
5510 | } |
5511 | |
5512 | if (!AllowedNameModifiers.empty()) |
5513 | ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || |
5514 | ErrorFound; |
5515 | |
5516 | if (ErrorFound) |
5517 | return StmtError(); |
5518 | |
5519 | if (!CurContext->isDependentContext() && |
5520 | isOpenMPTargetExecutionDirective(Kind) && |
5521 | !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || |
5522 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || |
5523 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || |
5524 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { |
5525 | // Register target to DSA Stack. |
5526 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addTargetDirLocation(StartLoc); |
5527 | } |
5528 | |
5529 | return Res; |
5530 | } |
5531 | |
5532 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( |
5533 | DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, |
5534 | ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, |
5535 | ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, |
5536 | ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { |
5537 | assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void > (0) : __assert_fail ("Aligneds.size() == Alignments.size()" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5537, __PRETTY_FUNCTION__)); |
5538 | assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void > (0) : __assert_fail ("Linears.size() == LinModifiers.size()" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5538, __PRETTY_FUNCTION__)); |
5539 | assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> ( 0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5539, __PRETTY_FUNCTION__)); |
5540 | if (!DG || DG.get().isNull()) |
5541 | return DeclGroupPtrTy(); |
5542 | |
5543 | const int SimdId = 0; |
5544 | if (!DG.get().isSingleDecl()) { |
5545 | Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) |
5546 | << SimdId; |
5547 | return DG; |
5548 | } |
5549 | Decl *ADecl = DG.get().getSingleDecl(); |
5550 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) |
5551 | ADecl = FTD->getTemplatedDecl(); |
5552 | |
5553 | auto *FD = dyn_cast<FunctionDecl>(ADecl); |
5554 | if (!FD) { |
5555 | Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; |
5556 | return DeclGroupPtrTy(); |
5557 | } |
5558 | |
5559 | // OpenMP [2.8.2, declare simd construct, Description] |
5560 | // The parameter of the simdlen clause must be a constant positive integer |
5561 | // expression. |
5562 | ExprResult SL; |
5563 | if (Simdlen) |
5564 | SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); |
5565 | // OpenMP [2.8.2, declare simd construct, Description] |
5566 | // The special this pointer can be used as if was one of the arguments to the |
5567 | // function in any of the linear, aligned, or uniform clauses. |
5568 | // The uniform clause declares one or more arguments to have an invariant |
5569 | // value for all concurrent invocations of the function in the execution of a |
5570 | // single SIMD loop. |
5571 | llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; |
5572 | const Expr *UniformedLinearThis = nullptr; |
5573 | for (const Expr *E : Uniforms) { |
5574 | E = E->IgnoreParenImpCasts(); |
5575 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) |
5576 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) |
5577 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && |
5578 | FD->getParamDecl(PVD->getFunctionScopeIndex()) |
5579 | ->getCanonicalDecl() == PVD->getCanonicalDecl()) { |
5580 | UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); |
5581 | continue; |
5582 | } |
5583 | if (isa<CXXThisExpr>(E)) { |
5584 | UniformedLinearThis = E; |
5585 | continue; |
5586 | } |
5587 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) |
5588 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); |
5589 | } |
5590 | // OpenMP [2.8.2, declare simd construct, Description] |
5591 | // The aligned clause declares that the object to which each list item points |
5592 | // is aligned to the number of bytes expressed in the optional parameter of |
5593 | // the aligned clause. |
5594 | // The special this pointer can be used as if was one of the arguments to the |
5595 | // function in any of the linear, aligned, or uniform clauses. |
5596 | // The type of list items appearing in the aligned clause must be array, |
5597 | // pointer, reference to array, or reference to pointer. |
5598 | llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; |
5599 | const Expr *AlignedThis = nullptr; |
5600 | for (const Expr *E : Aligneds) { |
5601 | E = E->IgnoreParenImpCasts(); |
5602 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) |
5603 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { |
5604 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); |
5605 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && |
5606 | FD->getParamDecl(PVD->getFunctionScopeIndex()) |
5607 | ->getCanonicalDecl() == CanonPVD) { |
5608 | // OpenMP [2.8.1, simd construct, Restrictions] |
5609 | // A list-item cannot appear in more than one aligned clause. |
5610 | if (AlignedArgs.count(CanonPVD) > 0) { |
5611 | Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) |
5612 | << 1 << getOpenMPClauseName(OMPC_aligned) |
5613 | << E->getSourceRange(); |
5614 | Diag(AlignedArgs[CanonPVD]->getExprLoc(), |
5615 | diag::note_omp_explicit_dsa) |
5616 | << getOpenMPClauseName(OMPC_aligned); |
5617 | continue; |
5618 | } |
5619 | AlignedArgs[CanonPVD] = E; |
5620 | QualType QTy = PVD->getType() |
5621 | .getNonReferenceType() |
5622 | .getUnqualifiedType() |
5623 | .getCanonicalType(); |
5624 | const Type *Ty = QTy.getTypePtrOrNull(); |
5625 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { |
5626 | Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) |
5627 | << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); |
5628 | Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; |
5629 | } |
5630 | continue; |
5631 | } |
5632 | } |
5633 | if (isa<CXXThisExpr>(E)) { |
5634 | if (AlignedThis) { |
5635 | Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) |
5636 | << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); |
5637 | Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) |
5638 | << getOpenMPClauseName(OMPC_aligned); |
5639 | } |
5640 | AlignedThis = E; |
5641 | continue; |
5642 | } |
5643 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) |
5644 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); |
5645 | } |
5646 | // The optional parameter of the aligned clause, alignment, must be a constant |
5647 | // positive integer expression. If no optional parameter is specified, |
5648 | // implementation-defined default alignments for SIMD instructions on the |
5649 | // target platforms are assumed. |
5650 | SmallVector<const Expr *, 4> NewAligns; |
5651 | for (Expr *E : Alignments) { |
5652 | ExprResult Align; |
5653 | if (E) |
5654 | Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); |
5655 | NewAligns.push_back(Align.get()); |
5656 | } |
5657 | // OpenMP [2.8.2, declare simd construct, Description] |
5658 | // The linear clause declares one or more list items to be private to a SIMD |
5659 | // lane and to have a linear relationship with respect to the iteration space |
5660 | // of a loop. |
5661 | // The special this pointer can be used as if was one of the arguments to the |
5662 | // function in any of the linear, aligned, or uniform clauses. |
5663 | // When a linear-step expression is specified in a linear clause it must be |
5664 | // either a constant integer expression or an integer-typed parameter that is |
5665 | // specified in a uniform clause on the directive. |
5666 | llvm::DenseMap<const Decl *, const Expr *> LinearArgs; |
5667 | const bool IsUniformedThis = UniformedLinearThis != nullptr; |
5668 | auto MI = LinModifiers.begin(); |
5669 | for (const Expr *E : Linears) { |
5670 | auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); |
5671 | ++MI; |
5672 | E = E->IgnoreParenImpCasts(); |
5673 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) |
5674 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { |
5675 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); |
5676 | if (FD->getNumParams() > PVD->getFunctionScopeIndex() && |
5677 | FD->getParamDecl(PVD->getFunctionScopeIndex()) |
5678 | ->getCanonicalDecl() == CanonPVD) { |
5679 | // OpenMP [2.15.3.7, linear Clause, Restrictions] |
5680 | // A list-item cannot appear in more than one linear clause. |
5681 | if (LinearArgs.count(CanonPVD) > 0) { |
5682 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) |
5683 | << getOpenMPClauseName(OMPC_linear) |
5684 | << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); |
5685 | Diag(LinearArgs[CanonPVD]->getExprLoc(), |
5686 | diag::note_omp_explicit_dsa) |
5687 | << getOpenMPClauseName(OMPC_linear); |
5688 | continue; |
5689 | } |
5690 | // Each argument can appear in at most one uniform or linear clause. |
5691 | if (UniformedArgs.count(CanonPVD) > 0) { |
5692 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) |
5693 | << getOpenMPClauseName(OMPC_linear) |
5694 | << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); |
5695 | Diag(UniformedArgs[CanonPVD]->getExprLoc(), |
5696 | diag::note_omp_explicit_dsa) |
5697 | << getOpenMPClauseName(OMPC_uniform); |
5698 | continue; |
5699 | } |
5700 | LinearArgs[CanonPVD] = E; |
5701 | if (E->isValueDependent() || E->isTypeDependent() || |
5702 | E->isInstantiationDependent() || |
5703 | E->containsUnexpandedParameterPack()) |
5704 | continue; |
5705 | (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, |
5706 | PVD->getOriginalType(), |
5707 | /*IsDeclareSimd=*/true); |
5708 | continue; |
5709 | } |
5710 | } |
5711 | if (isa<CXXThisExpr>(E)) { |
5712 | if (UniformedLinearThis) { |
5713 | Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) |
5714 | << getOpenMPClauseName(OMPC_linear) |
5715 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) |
5716 | << E->getSourceRange(); |
5717 | Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) |
5718 | << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform |
5719 | : OMPC_linear); |
5720 | continue; |
5721 | } |
5722 | UniformedLinearThis = E; |
5723 | if (E->isValueDependent() || E->isTypeDependent() || |
5724 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) |
5725 | continue; |
5726 | (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, |
5727 | E->getType(), /*IsDeclareSimd=*/true); |
5728 | continue; |
5729 | } |
5730 | Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) |
5731 | << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); |
5732 | } |
5733 | Expr *Step = nullptr; |
5734 | Expr *NewStep = nullptr; |
5735 | SmallVector<Expr *, 4> NewSteps; |
5736 | for (Expr *E : Steps) { |
5737 | // Skip the same step expression, it was checked already. |
5738 | if (Step == E || !E) { |
5739 | NewSteps.push_back(E ? NewStep : nullptr); |
5740 | continue; |
5741 | } |
5742 | Step = E; |
5743 | if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) |
5744 | if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { |
5745 | const VarDecl *CanonPVD = PVD->getCanonicalDecl(); |
5746 | if (UniformedArgs.count(CanonPVD) == 0) { |
5747 | Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) |
5748 | << Step->getSourceRange(); |
5749 | } else if (E->isValueDependent() || E->isTypeDependent() || |
5750 | E->isInstantiationDependent() || |
5751 | E->containsUnexpandedParameterPack() || |
5752 | CanonPVD->getType()->hasIntegerRepresentation()) { |
5753 | NewSteps.push_back(Step); |
5754 | } else { |
5755 | Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) |
5756 | << Step->getSourceRange(); |
5757 | } |
5758 | continue; |
5759 | } |
5760 | NewStep = Step; |
5761 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && |
5762 | !Step->isInstantiationDependent() && |
5763 | !Step->containsUnexpandedParameterPack()) { |
5764 | NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) |
5765 | .get(); |
5766 | if (NewStep) |
5767 | NewStep = VerifyIntegerConstantExpression(NewStep).get(); |
5768 | } |
5769 | NewSteps.push_back(NewStep); |
5770 | } |
5771 | auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( |
5772 | Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), |
5773 | Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), |
5774 | const_cast<Expr **>(NewAligns.data()), NewAligns.size(), |
5775 | const_cast<Expr **>(Linears.data()), Linears.size(), |
5776 | const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), |
5777 | NewSteps.data(), NewSteps.size(), SR); |
5778 | ADecl->addAttr(NewAttr); |
5779 | return DG; |
5780 | } |
5781 | |
5782 | static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, |
5783 | QualType NewType) { |
5784 | assert(NewType->isFunctionProtoType() &&((NewType->isFunctionProtoType() && "Expected function type with prototype." ) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5785, __PRETTY_FUNCTION__)) |
5785 | "Expected function type with prototype.")((NewType->isFunctionProtoType() && "Expected function type with prototype." ) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5785, __PRETTY_FUNCTION__)); |
5786 | assert(FD->getType()->isFunctionNoProtoType() &&((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype." ) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5787, __PRETTY_FUNCTION__)) |
5787 | "Expected function with type with no prototype.")((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype." ) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5787, __PRETTY_FUNCTION__)); |
5788 | assert(FDWithProto->getType()->isFunctionProtoType() &&((FDWithProto->getType()->isFunctionProtoType() && "Expected function with prototype.") ? static_cast<void> (0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5789, __PRETTY_FUNCTION__)) |
5789 | "Expected function with prototype.")((FDWithProto->getType()->isFunctionProtoType() && "Expected function with prototype.") ? static_cast<void> (0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 5789, __PRETTY_FUNCTION__)); |
5790 | // Synthesize parameters with the same types. |
5791 | FD->setType(NewType); |
5792 | SmallVector<ParmVarDecl *, 16> Params; |
5793 | for (const ParmVarDecl *P : FDWithProto->parameters()) { |
5794 | auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), |
5795 | SourceLocation(), nullptr, P->getType(), |
5796 | /*TInfo=*/nullptr, SC_None, nullptr); |
5797 | Param->setScopeInfo(0, Params.size()); |
5798 | Param->setImplicit(); |
5799 | Params.push_back(Param); |
5800 | } |
5801 | |
5802 | FD->setParams(Params); |
5803 | } |
5804 | |
5805 | Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) |
5806 | : TI(&TI), NameSuffix(TI.getMangledName()) {} |
5807 | |
5808 | FunctionDecl * |
5809 | Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, |
5810 | Declarator &D) { |
5811 | IdentifierInfo *BaseII = D.getIdentifier(); |
5812 | LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), |
5813 | LookupOrdinaryName); |
5814 | LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); |
5815 | |
5816 | TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); |
5817 | QualType FType = TInfo->getType(); |
5818 | |
5819 | bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; |
5820 | bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; |
5821 | |
5822 | FunctionDecl *BaseFD = nullptr; |
5823 | for (auto *Candidate : Lookup) { |
5824 | auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); |
5825 | if (!UDecl) |
5826 | continue; |
5827 | |
5828 | // Don't specialize constexpr/consteval functions with |
5829 | // non-constexpr/consteval functions. |
5830 | if (UDecl->isConstexpr() && !IsConstexpr) |
5831 | continue; |
5832 | if (UDecl->isConsteval() && !IsConsteval) |
5833 | continue; |
5834 | |
5835 | QualType NewType = Context.mergeFunctionTypes( |
5836 | FType, UDecl->getType(), /* OfBlockPointer */ false, |
5837 | /* Unqualified */ false, /* AllowCXX */ true); |
5838 | if (NewType.isNull()) |
5839 | continue; |
5840 | |
5841 | // Found a base! |
5842 | BaseFD = UDecl; |
5843 | break; |
5844 | } |
5845 | if (!BaseFD) { |
5846 | BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); |
5847 | BaseFD->setImplicit(true); |
5848 | } |
5849 | |
5850 | OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); |
5851 | std::string MangledName; |
5852 | MangledName += D.getIdentifier()->getName(); |
5853 | MangledName += getOpenMPVariantManglingSeparatorStr(); |
5854 | MangledName += DVScope.NameSuffix; |
5855 | IdentifierInfo &VariantII = Context.Idents.get(MangledName); |
5856 | |
5857 | VariantII.setMangledOpenMPVariantName(true); |
5858 | D.SetIdentifier(&VariantII, D.getBeginLoc()); |
5859 | return BaseFD; |
5860 | } |
5861 | |
5862 | void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( |
5863 | FunctionDecl *FD, FunctionDecl *BaseFD) { |
5864 | // Do not mark function as is used to prevent its emission if this is the |
5865 | // only place where it is used. |
5866 | EnterExpressionEvaluationContext Unevaluated( |
5867 | *this, Sema::ExpressionEvaluationContext::Unevaluated); |
5868 | |
5869 | Expr *VariantFuncRef = DeclRefExpr::Create( |
5870 | Context, NestedNameSpecifierLoc(), SourceLocation(), FD, |
5871 | /* RefersToEnclosingVariableOrCapture */ false, |
5872 | /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); |
5873 | |
5874 | OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); |
5875 | auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( |
5876 | Context, VariantFuncRef, DVScope.TI); |
5877 | BaseFD->addAttr(OMPDeclareVariantA); |
5878 | } |
5879 | |
5880 | ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, |
5881 | SourceLocation LParenLoc, |
5882 | MultiExprArg ArgExprs, |
5883 | SourceLocation RParenLoc, Expr *ExecConfig) { |
5884 | // The common case is a regular call we do not want to specialize at all. Try |
5885 | // to make that case fast by bailing early. |
5886 | CallExpr *CE = dyn_cast<CallExpr>(Call.get()); |
5887 | if (!CE) |
5888 | return Call; |
5889 | |
5890 | FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); |
5891 | if (!CalleeFnDecl) |
5892 | return Call; |
5893 | |
5894 | if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) |
5895 | return Call; |
5896 | |
5897 | ASTContext &Context = getASTContext(); |
5898 | std::function<void(StringRef)> DiagUnknownTrait = [this, |
5899 | CE](StringRef ISATrait) { |
5900 | // TODO Track the selector locations in a way that is accessible here to |
5901 | // improve the diagnostic location. |
5902 | Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) |
5903 | << ISATrait; |
5904 | }; |
5905 | TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), |
5906 | getCurFunctionDecl()); |
5907 | |
5908 | SmallVector<Expr *, 4> Exprs; |
5909 | SmallVector<VariantMatchInfo, 4> VMIs; |
5910 | while (CalleeFnDecl) { |
5911 | for (OMPDeclareVariantAttr *A : |
5912 | CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { |
5913 | Expr *VariantRef = A->getVariantFuncRef(); |
5914 | |
5915 | VariantMatchInfo VMI; |
5916 | OMPTraitInfo &TI = A->getTraitInfo(); |
5917 | TI.getAsVariantMatchInfo(Context, VMI); |
5918 | if (!isVariantApplicableInContext(VMI, OMPCtx, |
5919 | /* DeviceSetOnly */ false)) |
5920 | continue; |
5921 | |
5922 | VMIs.push_back(VMI); |
5923 | Exprs.push_back(VariantRef); |
5924 | } |
5925 | |
5926 | CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); |
5927 | } |
5928 | |
5929 | ExprResult NewCall; |
5930 | do { |
5931 | int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); |
5932 | if (BestIdx < 0) |
5933 | return Call; |
5934 | Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); |
5935 | Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); |
5936 | |
5937 | { |
5938 | // Try to build a (member) call expression for the current best applicable |
5939 | // variant expression. We allow this to fail in which case we continue |
5940 | // with the next best variant expression. The fail case is part of the |
5941 | // implementation defined behavior in the OpenMP standard when it talks |
5942 | // about what differences in the function prototypes: "Any differences |
5943 | // that the specific OpenMP context requires in the prototype of the |
5944 | // variant from the base function prototype are implementation defined." |
5945 | // This wording is there to allow the specialized variant to have a |
5946 | // different type than the base function. This is intended and OK but if |
5947 | // we cannot create a call the difference is not in the "implementation |
5948 | // defined range" we allow. |
5949 | Sema::TentativeAnalysisScope Trap(*this); |
5950 | |
5951 | if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { |
5952 | auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); |
5953 | BestExpr = MemberExpr::CreateImplicit( |
5954 | Context, MemberCall->getImplicitObjectArgument(), |
5955 | /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, |
5956 | MemberCall->getValueKind(), MemberCall->getObjectKind()); |
5957 | } |
5958 | NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, |
5959 | ExecConfig); |
5960 | if (NewCall.isUsable()) |
5961 | break; |
5962 | } |
5963 | |
5964 | VMIs.erase(VMIs.begin() + BestIdx); |
5965 | Exprs.erase(Exprs.begin() + BestIdx); |
5966 | } while (!VMIs.empty()); |
5967 | |
5968 | if (!NewCall.isUsable()) |
5969 | return Call; |
5970 | return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); |
5971 | } |
5972 | |
5973 | Optional<std::pair<FunctionDecl *, Expr *>> |
5974 | Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, |
5975 | Expr *VariantRef, OMPTraitInfo &TI, |
5976 | SourceRange SR) { |
5977 | if (!DG || DG.get().isNull()) |
5978 | return None; |
5979 | |
5980 | const int VariantId = 1; |
5981 | // Must be applied only to single decl. |
5982 | if (!DG.get().isSingleDecl()) { |
5983 | Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) |
5984 | << VariantId << SR; |
5985 | return None; |
5986 | } |
5987 | Decl *ADecl = DG.get().getSingleDecl(); |
5988 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) |
5989 | ADecl = FTD->getTemplatedDecl(); |
5990 | |
5991 | // Decl must be a function. |
5992 | auto *FD = dyn_cast<FunctionDecl>(ADecl); |
5993 | if (!FD) { |
5994 | Diag(ADecl->getLocation(), diag::err_omp_function_expected) |
5995 | << VariantId << SR; |
5996 | return None; |
5997 | } |
5998 | |
5999 | auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { |
6000 | return FD->hasAttrs() && |
6001 | (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || |
6002 | FD->hasAttr<TargetAttr>()); |
6003 | }; |
6004 | // OpenMP is not compatible with CPU-specific attributes. |
6005 | if (HasMultiVersionAttributes(FD)) { |
6006 | Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) |
6007 | << SR; |
6008 | return None; |
6009 | } |
6010 | |
6011 | // Allow #pragma omp declare variant only if the function is not used. |
6012 | if (FD->isUsed(false)) |
6013 | Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) |
6014 | << FD->getLocation(); |
6015 | |
6016 | // Check if the function was emitted already. |
6017 | const FunctionDecl *Definition; |
6018 | if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && |
6019 | (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) |
6020 | Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) |
6021 | << FD->getLocation(); |
6022 | |
6023 | // The VariantRef must point to function. |
6024 | if (!VariantRef) { |
6025 | Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; |
6026 | return None; |
6027 | } |
6028 | |
6029 | auto ShouldDelayChecks = [](Expr *&E, bool) { |
6030 | return E && (E->isTypeDependent() || E->isValueDependent() || |
6031 | E->containsUnexpandedParameterPack() || |
6032 | E->isInstantiationDependent()); |
6033 | }; |
6034 | // Do not check templates, wait until instantiation. |
6035 | if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || |
6036 | TI.anyScoreOrCondition(ShouldDelayChecks)) |
6037 | return std::make_pair(FD, VariantRef); |
6038 | |
6039 | // Deal with non-constant score and user condition expressions. |
6040 | auto HandleNonConstantScoresAndConditions = [this](Expr *&E, |
6041 | bool IsScore) -> bool { |
6042 | if (!E || E->isIntegerConstantExpr(Context)) |
6043 | return false; |
6044 | |
6045 | if (IsScore) { |
6046 | // We warn on non-constant scores and pretend they were not present. |
6047 | Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) |
6048 | << E; |
6049 | E = nullptr; |
6050 | } else { |
6051 | // We could replace a non-constant user condition with "false" but we |
6052 | // will soon need to handle these anyway for the dynamic version of |
6053 | // OpenMP context selectors. |
6054 | Diag(E->getExprLoc(), |
6055 | diag::err_omp_declare_variant_user_condition_not_constant) |
6056 | << E; |
6057 | } |
6058 | return true; |
6059 | }; |
6060 | if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) |
6061 | return None; |
6062 | |
6063 | // Convert VariantRef expression to the type of the original function to |
6064 | // resolve possible conflicts. |
6065 | ExprResult VariantRefCast; |
6066 | if (LangOpts.CPlusPlus) { |
6067 | QualType FnPtrType; |
6068 | auto *Method = dyn_cast<CXXMethodDecl>(FD); |
6069 | if (Method && !Method->isStatic()) { |
6070 | const Type *ClassType = |
6071 | Context.getTypeDeclType(Method->getParent()).getTypePtr(); |
6072 | FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); |
6073 | ExprResult ER; |
6074 | { |
6075 | // Build adrr_of unary op to correctly handle type checks for member |
6076 | // functions. |
6077 | Sema::TentativeAnalysisScope Trap(*this); |
6078 | ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, |
6079 | VariantRef); |
6080 | } |
6081 | if (!ER.isUsable()) { |
6082 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) |
6083 | << VariantId << VariantRef->getSourceRange(); |
6084 | return None; |
6085 | } |
6086 | VariantRef = ER.get(); |
6087 | } else { |
6088 | FnPtrType = Context.getPointerType(FD->getType()); |
6089 | } |
6090 | ImplicitConversionSequence ICS = |
6091 | TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), |
6092 | /*SuppressUserConversions=*/false, |
6093 | AllowedExplicit::None, |
6094 | /*InOverloadResolution=*/false, |
6095 | /*CStyle=*/false, |
6096 | /*AllowObjCWritebackConversion=*/false); |
6097 | if (ICS.isFailure()) { |
6098 | Diag(VariantRef->getExprLoc(), |
6099 | diag::err_omp_declare_variant_incompat_types) |
6100 | << VariantRef->getType() |
6101 | << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) |
6102 | << VariantRef->getSourceRange(); |
6103 | return None; |
6104 | } |
6105 | VariantRefCast = PerformImplicitConversion( |
6106 | VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); |
6107 | if (!VariantRefCast.isUsable()) |
6108 | return None; |
6109 | // Drop previously built artificial addr_of unary op for member functions. |
6110 | if (Method && !Method->isStatic()) { |
6111 | Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); |
6112 | if (auto *UO = dyn_cast<UnaryOperator>( |
6113 | PossibleAddrOfVariantRef->IgnoreImplicit())) |
6114 | VariantRefCast = UO->getSubExpr(); |
6115 | } |
6116 | } else { |
6117 | VariantRefCast = VariantRef; |
6118 | } |
6119 | |
6120 | ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); |
6121 | if (!ER.isUsable() || |
6122 | !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { |
6123 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) |
6124 | << VariantId << VariantRef->getSourceRange(); |
6125 | return None; |
6126 | } |
6127 | |
6128 | // The VariantRef must point to function. |
6129 | auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); |
6130 | if (!DRE) { |
6131 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) |
6132 | << VariantId << VariantRef->getSourceRange(); |
6133 | return None; |
6134 | } |
6135 | auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); |
6136 | if (!NewFD) { |
6137 | Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) |
6138 | << VariantId << VariantRef->getSourceRange(); |
6139 | return None; |
6140 | } |
6141 | |
6142 | // Check if function types are compatible in C. |
6143 | if (!LangOpts.CPlusPlus) { |
6144 | QualType NewType = |
6145 | Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); |
6146 | if (NewType.isNull()) { |
6147 | Diag(VariantRef->getExprLoc(), |
6148 | diag::err_omp_declare_variant_incompat_types) |
6149 | << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); |
6150 | return None; |
6151 | } |
6152 | if (NewType->isFunctionProtoType()) { |
6153 | if (FD->getType()->isFunctionNoProtoType()) |
6154 | setPrototype(*this, FD, NewFD, NewType); |
6155 | else if (NewFD->getType()->isFunctionNoProtoType()) |
6156 | setPrototype(*this, NewFD, FD, NewType); |
6157 | } |
6158 | } |
6159 | |
6160 | // Check if variant function is not marked with declare variant directive. |
6161 | if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { |
6162 | Diag(VariantRef->getExprLoc(), |
6163 | diag::warn_omp_declare_variant_marked_as_declare_variant) |
6164 | << VariantRef->getSourceRange(); |
6165 | SourceRange SR = |
6166 | NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); |
6167 | Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; |
6168 | return None; |
6169 | } |
6170 | |
6171 | enum DoesntSupport { |
6172 | VirtFuncs = 1, |
6173 | Constructors = 3, |
6174 | Destructors = 4, |
6175 | DeletedFuncs = 5, |
6176 | DefaultedFuncs = 6, |
6177 | ConstexprFuncs = 7, |
6178 | ConstevalFuncs = 8, |
6179 | }; |
6180 | if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { |
6181 | if (CXXFD->isVirtual()) { |
6182 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) |
6183 | << VirtFuncs; |
6184 | return None; |
6185 | } |
6186 | |
6187 | if (isa<CXXConstructorDecl>(FD)) { |
6188 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) |
6189 | << Constructors; |
6190 | return None; |
6191 | } |
6192 | |
6193 | if (isa<CXXDestructorDecl>(FD)) { |
6194 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) |
6195 | << Destructors; |
6196 | return None; |
6197 | } |
6198 | } |
6199 | |
6200 | if (FD->isDeleted()) { |
6201 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) |
6202 | << DeletedFuncs; |
6203 | return None; |
6204 | } |
6205 | |
6206 | if (FD->isDefaulted()) { |
6207 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) |
6208 | << DefaultedFuncs; |
6209 | return None; |
6210 | } |
6211 | |
6212 | if (FD->isConstexpr()) { |
6213 | Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) |
6214 | << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); |
6215 | return None; |
6216 | } |
6217 | |
6218 | // Check general compatibility. |
6219 | if (areMultiversionVariantFunctionsCompatible( |
6220 | FD, NewFD, PartialDiagnostic::NullDiagnostic(), |
6221 | PartialDiagnosticAt(SourceLocation(), |
6222 | PartialDiagnostic::NullDiagnostic()), |
6223 | PartialDiagnosticAt( |
6224 | VariantRef->getExprLoc(), |
6225 | PDiag(diag::err_omp_declare_variant_doesnt_support)), |
6226 | PartialDiagnosticAt(VariantRef->getExprLoc(), |
6227 | PDiag(diag::err_omp_declare_variant_diff) |
6228 | << FD->getLocation()), |
6229 | /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, |
6230 | /*CLinkageMayDiffer=*/true)) |
6231 | return None; |
6232 | return std::make_pair(FD, cast<Expr>(DRE)); |
6233 | } |
6234 | |
6235 | void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, |
6236 | Expr *VariantRef, |
6237 | OMPTraitInfo &TI, |
6238 | SourceRange SR) { |
6239 | auto *NewAttr = |
6240 | OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); |
6241 | FD->addAttr(NewAttr); |
6242 | } |
6243 | |
6244 | StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, |
6245 | Stmt *AStmt, |
6246 | SourceLocation StartLoc, |
6247 | SourceLocation EndLoc) { |
6248 | if (!AStmt) |
6249 | return StmtError(); |
6250 | |
6251 | auto *CS = cast<CapturedStmt>(AStmt); |
6252 | // 1.2.2 OpenMP Language Terminology |
6253 | // Structured block - An executable statement with a single entry at the |
6254 | // top and a single exit at the bottom. |
6255 | // The point of exit cannot be a branch out of the structured block. |
6256 | // longjmp() and throw() must not violate the entry/exit criteria. |
6257 | CS->getCapturedDecl()->setNothrow(); |
6258 | |
6259 | setFunctionHasBranchProtectedScope(); |
6260 | |
6261 | return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
6262 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), |
6263 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
6264 | } |
6265 | |
6266 | namespace { |
6267 | /// Iteration space of a single for loop. |
6268 | struct LoopIterationSpace final { |
6269 | /// True if the condition operator is the strict compare operator (<, > or |
6270 | /// !=). |
6271 | bool IsStrictCompare = false; |
6272 | /// Condition of the loop. |
6273 | Expr *PreCond = nullptr; |
6274 | /// This expression calculates the number of iterations in the loop. |
6275 | /// It is always possible to calculate it before starting the loop. |
6276 | Expr *NumIterations = nullptr; |
6277 | /// The loop counter variable. |
6278 | Expr *CounterVar = nullptr; |
6279 | /// Private loop counter variable. |
6280 | Expr *PrivateCounterVar = nullptr; |
6281 | /// This is initializer for the initial value of #CounterVar. |
6282 | Expr *CounterInit = nullptr; |
6283 | /// This is step for the #CounterVar used to generate its update: |
6284 | /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. |
6285 | Expr *CounterStep = nullptr; |
6286 | /// Should step be subtracted? |
6287 | bool Subtract = false; |
6288 | /// Source range of the loop init. |
6289 | SourceRange InitSrcRange; |
6290 | /// Source range of the loop condition. |
6291 | SourceRange CondSrcRange; |
6292 | /// Source range of the loop increment. |
6293 | SourceRange IncSrcRange; |
6294 | /// Minimum value that can have the loop control variable. Used to support |
6295 | /// non-rectangular loops. Applied only for LCV with the non-iterator types, |
6296 | /// since only such variables can be used in non-loop invariant expressions. |
6297 | Expr *MinValue = nullptr; |
6298 | /// Maximum value that can have the loop control variable. Used to support |
6299 | /// non-rectangular loops. Applied only for LCV with the non-iterator type, |
6300 | /// since only such variables can be used in non-loop invariant expressions. |
6301 | Expr *MaxValue = nullptr; |
6302 | /// true, if the lower bound depends on the outer loop control var. |
6303 | bool IsNonRectangularLB = false; |
6304 | /// true, if the upper bound depends on the outer loop control var. |
6305 | bool IsNonRectangularUB = false; |
6306 | /// Index of the loop this loop depends on and forms non-rectangular loop |
6307 | /// nest. |
6308 | unsigned LoopDependentIdx = 0; |
6309 | /// Final condition for the non-rectangular loop nest support. It is used to |
6310 | /// check that the number of iterations for this particular counter must be |
6311 | /// finished. |
6312 | Expr *FinalCondition = nullptr; |
6313 | }; |
6314 | |
6315 | /// Helper class for checking canonical form of the OpenMP loops and |
6316 | /// extracting iteration space of each loop in the loop nest, that will be used |
6317 | /// for IR generation. |
6318 | class OpenMPIterationSpaceChecker { |
6319 | /// Reference to Sema. |
6320 | Sema &SemaRef; |
6321 | /// Data-sharing stack. |
6322 | DSAStackTy &Stack; |
6323 | /// A location for diagnostics (when there is no some better location). |
6324 | SourceLocation DefaultLoc; |
6325 | /// A location for diagnostics (when increment is not compatible). |
6326 | SourceLocation ConditionLoc; |
6327 | /// A source location for referring to loop init later. |
6328 | SourceRange InitSrcRange; |
6329 | /// A source location for referring to condition later. |
6330 | SourceRange ConditionSrcRange; |
6331 | /// A source location for referring to increment later. |
6332 | SourceRange IncrementSrcRange; |
6333 | /// Loop variable. |
6334 | ValueDecl *LCDecl = nullptr; |
6335 | /// Reference to loop variable. |
6336 | Expr *LCRef = nullptr; |
6337 | /// Lower bound (initializer for the var). |
6338 | Expr *LB = nullptr; |
6339 | /// Upper bound. |
6340 | Expr *UB = nullptr; |
6341 | /// Loop step (increment). |
6342 | Expr *Step = nullptr; |
6343 | /// This flag is true when condition is one of: |
6344 | /// Var < UB |
6345 | /// Var <= UB |
6346 | /// UB > Var |
6347 | /// UB >= Var |
6348 | /// This will have no value when the condition is != |
6349 | llvm::Optional<bool> TestIsLessOp; |
6350 | /// This flag is true when condition is strict ( < or > ). |
6351 | bool TestIsStrictOp = false; |
6352 | /// This flag is true when step is subtracted on each iteration. |
6353 | bool SubtractStep = false; |
6354 | /// The outer loop counter this loop depends on (if any). |
6355 | const ValueDecl *DepDecl = nullptr; |
6356 | /// Contains number of loop (starts from 1) on which loop counter init |
6357 | /// expression of this loop depends on. |
6358 | Optional<unsigned> InitDependOnLC; |
6359 | /// Contains number of loop (starts from 1) on which loop counter condition |
6360 | /// expression of this loop depends on. |
6361 | Optional<unsigned> CondDependOnLC; |
6362 | /// Checks if the provide statement depends on the loop counter. |
6363 | Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); |
6364 | /// Original condition required for checking of the exit condition for |
6365 | /// non-rectangular loop. |
6366 | Expr *Condition = nullptr; |
6367 | |
6368 | public: |
6369 | OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, |
6370 | SourceLocation DefaultLoc) |
6371 | : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), |
6372 | ConditionLoc(DefaultLoc) {} |
6373 | /// Check init-expr for canonical loop form and save loop counter |
6374 | /// variable - #Var and its initialization value - #LB. |
6375 | bool checkAndSetInit(Stmt *S, bool EmitDiags = true); |
6376 | /// Check test-expr for canonical form, save upper-bound (#UB), flags |
6377 | /// for less/greater and for strict/non-strict comparison. |
6378 | bool checkAndSetCond(Expr *S); |
6379 | /// Check incr-expr for canonical loop form and return true if it |
6380 | /// does not conform, otherwise save loop step (#Step). |
6381 | bool checkAndSetInc(Expr *S); |
6382 | /// Return the loop counter variable. |
6383 | ValueDecl *getLoopDecl() const { return LCDecl; } |
6384 | /// Return the reference expression to loop counter variable. |
6385 | Expr *getLoopDeclRefExpr() const { return LCRef; } |
6386 | /// Source range of the loop init. |
6387 | SourceRange getInitSrcRange() const { return InitSrcRange; } |
6388 | /// Source range of the loop condition. |
6389 | SourceRange getConditionSrcRange() const { return ConditionSrcRange; } |
6390 | /// Source range of the loop increment. |
6391 | SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } |
6392 | /// True if the step should be subtracted. |
6393 | bool shouldSubtractStep() const { return SubtractStep; } |
6394 | /// True, if the compare operator is strict (<, > or !=). |
6395 | bool isStrictTestOp() const { return TestIsStrictOp; } |
6396 | /// Build the expression to calculate the number of iterations. |
6397 | Expr *buildNumIterations( |
6398 | Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, |
6399 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; |
6400 | /// Build the precondition expression for the loops. |
6401 | Expr * |
6402 | buildPreCond(Scope *S, Expr *Cond, |
6403 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; |
6404 | /// Build reference expression to the counter be used for codegen. |
6405 | DeclRefExpr * |
6406 | buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, |
6407 | DSAStackTy &DSA) const; |
6408 | /// Build reference expression to the private counter be used for |
6409 | /// codegen. |
6410 | Expr *buildPrivateCounterVar() const; |
6411 | /// Build initialization of the counter be used for codegen. |
6412 | Expr *buildCounterInit() const; |
6413 | /// Build step of the counter be used for codegen. |
6414 | Expr *buildCounterStep() const; |
6415 | /// Build loop data with counter value for depend clauses in ordered |
6416 | /// directives. |
6417 | Expr * |
6418 | buildOrderedLoopData(Scope *S, Expr *Counter, |
6419 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, |
6420 | SourceLocation Loc, Expr *Inc = nullptr, |
6421 | OverloadedOperatorKind OOK = OO_Amp); |
6422 | /// Builds the minimum value for the loop counter. |
6423 | std::pair<Expr *, Expr *> buildMinMaxValues( |
6424 | Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; |
6425 | /// Builds final condition for the non-rectangular loops. |
6426 | Expr *buildFinalCondition(Scope *S) const; |
6427 | /// Return true if any expression is dependent. |
6428 | bool dependent() const; |
6429 | /// Returns true if the initializer forms non-rectangular loop. |
6430 | bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } |
6431 | /// Returns true if the condition forms non-rectangular loop. |
6432 | bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } |
6433 | /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. |
6434 | unsigned getLoopDependentIdx() const { |
6435 | return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); |
6436 | } |
6437 | |
6438 | private: |
6439 | /// Check the right-hand side of an assignment in the increment |
6440 | /// expression. |
6441 | bool checkAndSetIncRHS(Expr *RHS); |
6442 | /// Helper to set loop counter variable and its initializer. |
6443 | bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, |
6444 | bool EmitDiags); |
6445 | /// Helper to set upper bound. |
6446 | bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, |
6447 | SourceRange SR, SourceLocation SL); |
6448 | /// Helper to set loop increment. |
6449 | bool setStep(Expr *NewStep, bool Subtract); |
6450 | }; |
6451 | |
6452 | bool OpenMPIterationSpaceChecker::dependent() const { |
6453 | if (!LCDecl) { |
6454 | assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void> (0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6454, __PRETTY_FUNCTION__)); |
6455 | return false; |
6456 | } |
6457 | return LCDecl->getType()->isDependentType() || |
6458 | (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || |
6459 | (Step && Step->isValueDependent()); |
6460 | } |
6461 | |
6462 | bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, |
6463 | Expr *NewLCRefExpr, |
6464 | Expr *NewLB, bool EmitDiags) { |
6465 | // State consistency checking to ensure correct usage. |
6466 | assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&((LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast <void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6467, __PRETTY_FUNCTION__)) |
6467 | UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast <void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6467, __PRETTY_FUNCTION__)); |
6468 | if (!NewLCDecl || !NewLB) |
6469 | return true; |
6470 | LCDecl = getCanonicalDecl(NewLCDecl); |
6471 | LCRef = NewLCRefExpr; |
6472 | if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) |
6473 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) |
6474 | if ((Ctor->isCopyOrMoveConstructor() || |
6475 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && |
6476 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) |
6477 | NewLB = CE->getArg(0)->IgnoreParenImpCasts(); |
6478 | LB = NewLB; |
6479 | if (EmitDiags) |
6480 | InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); |
6481 | return false; |
6482 | } |
6483 | |
6484 | bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, |
6485 | llvm::Optional<bool> LessOp, |
6486 | bool StrictOp, SourceRange SR, |
6487 | SourceLocation SL) { |
6488 | // State consistency checking to ensure correct usage. |
6489 | assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&((LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6490, __PRETTY_FUNCTION__)) |
6490 | Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6490, __PRETTY_FUNCTION__)); |
6491 | if (!NewUB) |
6492 | return true; |
6493 | UB = NewUB; |
6494 | if (LessOp) |
6495 | TestIsLessOp = LessOp; |
6496 | TestIsStrictOp = StrictOp; |
6497 | ConditionSrcRange = SR; |
6498 | ConditionLoc = SL; |
6499 | CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); |
6500 | return false; |
6501 | } |
6502 | |
6503 | bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { |
6504 | // State consistency checking to ensure correct usage. |
6505 | assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)((LCDecl != nullptr && LB != nullptr && Step == nullptr) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && Step == nullptr" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6505, __PRETTY_FUNCTION__)); |
6506 | if (!NewStep) |
6507 | return true; |
6508 | if (!NewStep->isValueDependent()) { |
6509 | // Check that the step is integer expression. |
6510 | SourceLocation StepLoc = NewStep->getBeginLoc(); |
6511 | ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( |
6512 | StepLoc, getExprAsWritten(NewStep)); |
6513 | if (Val.isInvalid()) |
6514 | return true; |
6515 | NewStep = Val.get(); |
6516 | |
6517 | // OpenMP [2.6, Canonical Loop Form, Restrictions] |
6518 | // If test-expr is of form var relational-op b and relational-op is < or |
6519 | // <= then incr-expr must cause var to increase on each iteration of the |
6520 | // loop. If test-expr is of form var relational-op b and relational-op is |
6521 | // > or >= then incr-expr must cause var to decrease on each iteration of |
6522 | // the loop. |
6523 | // If test-expr is of form b relational-op var and relational-op is < or |
6524 | // <= then incr-expr must cause var to decrease on each iteration of the |
6525 | // loop. If test-expr is of form b relational-op var and relational-op is |
6526 | // > or >= then incr-expr must cause var to increase on each iteration of |
6527 | // the loop. |
6528 | Optional<llvm::APSInt> Result = |
6529 | NewStep->getIntegerConstantExpr(SemaRef.Context); |
6530 | bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); |
6531 | bool IsConstNeg = |
6532 | Result && Result->isSigned() && (Subtract != Result->isNegative()); |
6533 | bool IsConstPos = |
6534 | Result && Result->isSigned() && (Subtract == Result->isNegative()); |
6535 | bool IsConstZero = Result && !Result->getBoolValue(); |
6536 | |
6537 | // != with increment is treated as <; != with decrement is treated as > |
6538 | if (!TestIsLessOp.hasValue()) |
6539 | TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); |
6540 | if (UB && (IsConstZero || |
6541 | (TestIsLessOp.getValue() ? |
6542 | (IsConstNeg || (IsUnsigned && Subtract)) : |
6543 | (IsConstPos || (IsUnsigned && !Subtract))))) { |
6544 | SemaRef.Diag(NewStep->getExprLoc(), |
6545 | diag::err_omp_loop_incr_not_compatible) |
6546 | << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); |
6547 | SemaRef.Diag(ConditionLoc, |
6548 | diag::note_omp_loop_cond_requres_compatible_incr) |
6549 | << TestIsLessOp.getValue() << ConditionSrcRange; |
6550 | return true; |
6551 | } |
6552 | if (TestIsLessOp.getValue() == Subtract) { |
6553 | NewStep = |
6554 | SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) |
6555 | .get(); |
6556 | Subtract = !Subtract; |
6557 | } |
6558 | } |
6559 | |
6560 | Step = NewStep; |
6561 | SubtractStep = Subtract; |
6562 | return false; |
6563 | } |
6564 | |
6565 | namespace { |
6566 | /// Checker for the non-rectangular loops. Checks if the initializer or |
6567 | /// condition expression references loop counter variable. |
6568 | class LoopCounterRefChecker final |
6569 | : public ConstStmtVisitor<LoopCounterRefChecker, bool> { |
6570 | Sema &SemaRef; |
6571 | DSAStackTy &Stack; |
6572 | const ValueDecl *CurLCDecl = nullptr; |
6573 | const ValueDecl *DepDecl = nullptr; |
6574 | const ValueDecl *PrevDepDecl = nullptr; |
6575 | bool IsInitializer = true; |
6576 | unsigned BaseLoopId = 0; |
6577 | bool checkDecl(const Expr *E, const ValueDecl *VD) { |
6578 | if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { |
6579 | SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) |
6580 | << (IsInitializer ? 0 : 1); |
6581 | return false; |
6582 | } |
6583 | const auto &&Data = Stack.isLoopControlVariable(VD); |
6584 | // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. |
6585 | // The type of the loop iterator on which we depend may not have a random |
6586 | // access iterator type. |
6587 | if (Data.first && VD->getType()->isRecordType()) { |
6588 | SmallString<128> Name; |
6589 | llvm::raw_svector_ostream OS(Name); |
6590 | VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), |
6591 | /*Qualified=*/true); |
6592 | SemaRef.Diag(E->getExprLoc(), |
6593 | diag::err_omp_wrong_dependency_iterator_type) |
6594 | << OS.str(); |
6595 | SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; |
6596 | return false; |
6597 | } |
6598 | if (Data.first && |
6599 | (DepDecl || (PrevDepDecl && |
6600 | getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { |
6601 | if (!DepDecl && PrevDepDecl) |
6602 | DepDecl = PrevDepDecl; |
6603 | SmallString<128> Name; |
6604 | llvm::raw_svector_ostream OS(Name); |
6605 | DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), |
6606 | /*Qualified=*/true); |
6607 | SemaRef.Diag(E->getExprLoc(), |
6608 | diag::err_omp_invariant_or_linear_dependency) |
6609 | << OS.str(); |
6610 | return false; |
6611 | } |
6612 | if (Data.first) { |
6613 | DepDecl = VD; |
6614 | BaseLoopId = Data.first; |
6615 | } |
6616 | return Data.first; |
6617 | } |
6618 | |
6619 | public: |
6620 | bool VisitDeclRefExpr(const DeclRefExpr *E) { |
6621 | const ValueDecl *VD = E->getDecl(); |
6622 | if (isa<VarDecl>(VD)) |
6623 | return checkDecl(E, VD); |
6624 | return false; |
6625 | } |
6626 | bool VisitMemberExpr(const MemberExpr *E) { |
6627 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { |
6628 | const ValueDecl *VD = E->getMemberDecl(); |
6629 | if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) |
6630 | return checkDecl(E, VD); |
6631 | } |
6632 | return false; |
6633 | } |
6634 | bool VisitStmt(const Stmt *S) { |
6635 | bool Res = false; |
6636 | for (const Stmt *Child : S->children()) |
6637 | Res = (Child && Visit(Child)) || Res; |
6638 | return Res; |
6639 | } |
6640 | explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, |
6641 | const ValueDecl *CurLCDecl, bool IsInitializer, |
6642 | const ValueDecl *PrevDepDecl = nullptr) |
6643 | : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), |
6644 | PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} |
6645 | unsigned getBaseLoopId() const { |
6646 | assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast <void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6646, __PRETTY_FUNCTION__)); |
6647 | return BaseLoopId; |
6648 | } |
6649 | const ValueDecl *getDepDecl() const { |
6650 | assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast <void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 6650, __PRETTY_FUNCTION__)); |
6651 | return DepDecl; |
6652 | } |
6653 | }; |
6654 | } // namespace |
6655 | |
6656 | Optional<unsigned> |
6657 | OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, |
6658 | bool IsInitializer) { |
6659 | // Check for the non-rectangular loops. |
6660 | LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, |
6661 | DepDecl); |
6662 | if (LoopStmtChecker.Visit(S)) { |
6663 | DepDecl = LoopStmtChecker.getDepDecl(); |
6664 | return LoopStmtChecker.getBaseLoopId(); |
6665 | } |
6666 | return llvm::None; |
6667 | } |
6668 | |
6669 | bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { |
6670 | // Check init-expr for canonical loop form and save loop counter |
6671 | // variable - #Var and its initialization value - #LB. |
6672 | // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: |
6673 | // var = lb |
6674 | // integer-type var = lb |
6675 | // random-access-iterator-type var = lb |
6676 | // pointer-type var = lb |
6677 | // |
6678 | if (!S) { |
6679 | if (EmitDiags) { |
6680 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); |
6681 | } |
6682 | return true; |
6683 | } |
6684 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) |
6685 | if (!ExprTemp->cleanupsHaveSideEffects()) |
6686 | S = ExprTemp->getSubExpr(); |
6687 | |
6688 | InitSrcRange = S->getSourceRange(); |
6689 | if (Expr *E = dyn_cast<Expr>(S)) |
6690 | S = E->IgnoreParens(); |
6691 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { |
6692 | if (BO->getOpcode() == BO_Assign) { |
6693 | Expr *LHS = BO->getLHS()->IgnoreParens(); |
6694 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { |
6695 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) |
6696 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) |
6697 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), |
6698 | EmitDiags); |
6699 | return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); |
6700 | } |
6701 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { |
6702 | if (ME->isArrow() && |
6703 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) |
6704 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), |
6705 | EmitDiags); |
6706 | } |
6707 | } |
6708 | } else if (auto *DS = dyn_cast<DeclStmt>(S)) { |
6709 | if (DS->isSingleDecl()) { |
6710 | if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { |
6711 | if (Var->hasInit() && !Var->getType()->isReferenceType()) { |
6712 | // Accept non-canonical init form here but emit ext. warning. |
6713 | if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) |
6714 | SemaRef.Diag(S->getBeginLoc(), |
6715 | diag::ext_omp_loop_not_canonical_init) |
6716 | << S->getSourceRange(); |
6717 | return setLCDeclAndLB( |
6718 | Var, |
6719 | buildDeclRefExpr(SemaRef, Var, |
6720 | Var->getType().getNonReferenceType(), |
6721 | DS->getBeginLoc()), |
6722 | Var->getInit(), EmitDiags); |
6723 | } |
6724 | } |
6725 | } |
6726 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { |
6727 | if (CE->getOperator() == OO_Equal) { |
6728 | Expr *LHS = CE->getArg(0); |
6729 | if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { |
6730 | if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) |
6731 | if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) |
6732 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), |
6733 | EmitDiags); |
6734 | return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); |
6735 | } |
6736 | if (auto *ME = dyn_cast<MemberExpr>(LHS)) { |
6737 | if (ME->isArrow() && |
6738 | isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) |
6739 | return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), |
6740 | EmitDiags); |
6741 | } |
6742 | } |
6743 | } |
6744 | |
6745 | if (dependent() || SemaRef.CurContext->isDependentContext()) |
6746 | return false; |
6747 | if (EmitDiags) { |
6748 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) |
6749 | << S->getSourceRange(); |
6750 | } |
6751 | return true; |
6752 | } |
6753 | |
6754 | /// Ignore parenthesizes, implicit casts, copy constructor and return the |
6755 | /// variable (which may be the loop variable) if possible. |
6756 | static const ValueDecl *getInitLCDecl(const Expr *E) { |
6757 | if (!E) |
6758 | return nullptr; |
6759 | E = getExprAsWritten(E); |
6760 | if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) |
6761 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) |
6762 | if ((Ctor->isCopyOrMoveConstructor() || |
6763 | Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && |
6764 | CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) |
6765 | E = CE->getArg(0)->IgnoreParenImpCasts(); |
6766 | if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { |
6767 | if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) |
6768 | return getCanonicalDecl(VD); |
6769 | } |
6770 | if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) |
6771 | if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) |
6772 | return getCanonicalDecl(ME->getMemberDecl()); |
6773 | return nullptr; |
6774 | } |
6775 | |
6776 | bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { |
6777 | // Check test-expr for canonical form, save upper-bound UB, flags for |
6778 | // less/greater and for strict/non-strict comparison. |
6779 | // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: |
6780 | // var relational-op b |
6781 | // b relational-op var |
6782 | // |
6783 | bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; |
6784 | if (!S) { |
6785 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) |
6786 | << (IneqCondIsCanonical ? 1 : 0) << LCDecl; |
6787 | return true; |
6788 | } |
6789 | Condition = S; |
6790 | S = getExprAsWritten(S); |
6791 | SourceLocation CondLoc = S->getBeginLoc(); |
6792 | if (auto *BO = dyn_cast<BinaryOperator>(S)) { |
6793 | if (BO->isRelationalOp()) { |
6794 | if (getInitLCDecl(BO->getLHS()) == LCDecl) |
6795 | return setUB(BO->getRHS(), |
6796 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), |
6797 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), |
6798 | BO->getSourceRange(), BO->getOperatorLoc()); |
6799 | if (getInitLCDecl(BO->getRHS()) == LCDecl) |
6800 | return setUB(BO->getLHS(), |
6801 | (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), |
6802 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), |
6803 | BO->getSourceRange(), BO->getOperatorLoc()); |
6804 | } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) |
6805 | return setUB( |
6806 | getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), |
6807 | /*LessOp=*/llvm::None, |
6808 | /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); |
6809 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { |
6810 | if (CE->getNumArgs() == 2) { |
6811 | auto Op = CE->getOperator(); |
6812 | switch (Op) { |
6813 | case OO_Greater: |
6814 | case OO_GreaterEqual: |
6815 | case OO_Less: |
6816 | case OO_LessEqual: |
6817 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) |
6818 | return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, |
6819 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), |
6820 | CE->getOperatorLoc()); |
6821 | if (getInitLCDecl(CE->getArg(1)) == LCDecl) |
6822 | return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, |
6823 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), |
6824 | CE->getOperatorLoc()); |
6825 | break; |
6826 | case OO_ExclaimEqual: |
6827 | if (IneqCondIsCanonical) |
6828 | return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) |
6829 | : CE->getArg(0), |
6830 | /*LessOp=*/llvm::None, |
6831 | /*StrictOp=*/true, CE->getSourceRange(), |
6832 | CE->getOperatorLoc()); |
6833 | break; |
6834 | default: |
6835 | break; |
6836 | } |
6837 | } |
6838 | } |
6839 | if (dependent() || SemaRef.CurContext->isDependentContext()) |
6840 | return false; |
6841 | SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) |
6842 | << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; |
6843 | return true; |
6844 | } |
6845 | |
6846 | bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { |
6847 | // RHS of canonical loop form increment can be: |
6848 | // var + incr |
6849 | // incr + var |
6850 | // var - incr |
6851 | // |
6852 | RHS = RHS->IgnoreParenImpCasts(); |
6853 | if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { |
6854 | if (BO->isAdditiveOp()) { |
6855 | bool IsAdd = BO->getOpcode() == BO_Add; |
6856 | if (getInitLCDecl(BO->getLHS()) == LCDecl) |
6857 | return setStep(BO->getRHS(), !IsAdd); |
6858 | if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) |
6859 | return setStep(BO->getLHS(), /*Subtract=*/false); |
6860 | } |
6861 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { |
6862 | bool IsAdd = CE->getOperator() == OO_Plus; |
6863 | if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { |
6864 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) |
6865 | return setStep(CE->getArg(1), !IsAdd); |
6866 | if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) |
6867 | return setStep(CE->getArg(0), /*Subtract=*/false); |
6868 | } |
6869 | } |
6870 | if (dependent() || SemaRef.CurContext->isDependentContext()) |
6871 | return false; |
6872 | SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) |
6873 | << RHS->getSourceRange() << LCDecl; |
6874 | return true; |
6875 | } |
6876 | |
6877 | bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { |
6878 | // Check incr-expr for canonical loop form and return true if it |
6879 | // does not conform. |
6880 | // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: |
6881 | // ++var |
6882 | // var++ |
6883 | // --var |
6884 | // var-- |
6885 | // var += incr |
6886 | // var -= incr |
6887 | // var = var + incr |
6888 | // var = incr + var |
6889 | // var = var - incr |
6890 | // |
6891 | if (!S) { |
6892 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; |
6893 | return true; |
6894 | } |
6895 | if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) |
6896 | if (!ExprTemp->cleanupsHaveSideEffects()) |
6897 | S = ExprTemp->getSubExpr(); |
6898 | |
6899 | IncrementSrcRange = S->getSourceRange(); |
6900 | S = S->IgnoreParens(); |
6901 | if (auto *UO = dyn_cast<UnaryOperator>(S)) { |
6902 | if (UO->isIncrementDecrementOp() && |
6903 | getInitLCDecl(UO->getSubExpr()) == LCDecl) |
6904 | return setStep(SemaRef |
6905 | .ActOnIntegerConstant(UO->getBeginLoc(), |
6906 | (UO->isDecrementOp() ? -1 : 1)) |
6907 | .get(), |
6908 | /*Subtract=*/false); |
6909 | } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { |
6910 | switch (BO->getOpcode()) { |
6911 | case BO_AddAssign: |
6912 | case BO_SubAssign: |
6913 | if (getInitLCDecl(BO->getLHS()) == LCDecl) |
6914 | return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); |
6915 | break; |
6916 | case BO_Assign: |
6917 | if (getInitLCDecl(BO->getLHS()) == LCDecl) |
6918 | return checkAndSetIncRHS(BO->getRHS()); |
6919 | break; |
6920 | default: |
6921 | break; |
6922 | } |
6923 | } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { |
6924 | switch (CE->getOperator()) { |
6925 | case OO_PlusPlus: |
6926 | case OO_MinusMinus: |
6927 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) |
6928 | return setStep(SemaRef |
6929 | .ActOnIntegerConstant( |
6930 | CE->getBeginLoc(), |
6931 | ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) |
6932 | .get(), |
6933 | /*Subtract=*/false); |
6934 | break; |
6935 | case OO_PlusEqual: |
6936 | case OO_MinusEqual: |
6937 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) |
6938 | return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); |
6939 | break; |
6940 | case OO_Equal: |
6941 | if (getInitLCDecl(CE->getArg(0)) == LCDecl) |
6942 | return checkAndSetIncRHS(CE->getArg(1)); |
6943 | break; |
6944 | default: |
6945 | break; |
6946 | } |
6947 | } |
6948 | if (dependent() || SemaRef.CurContext->isDependentContext()) |
6949 | return false; |
6950 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) |
6951 | << S->getSourceRange() << LCDecl; |
6952 | return true; |
6953 | } |
6954 | |
6955 | static ExprResult |
6956 | tryBuildCapture(Sema &SemaRef, Expr *Capture, |
6957 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { |
6958 | if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) |
6959 | return Capture; |
6960 | if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) |
6961 | return SemaRef.PerformImplicitConversion( |
6962 | Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, |
6963 | /*AllowExplicit=*/true); |
6964 | auto I = Captures.find(Capture); |
6965 | if (I != Captures.end()) |
6966 | return buildCapture(SemaRef, Capture, I->second); |
6967 | DeclRefExpr *Ref = nullptr; |
6968 | ExprResult Res = buildCapture(SemaRef, Capture, Ref); |
6969 | Captures[Capture] = Ref; |
6970 | return Res; |
6971 | } |
6972 | |
6973 | /// Calculate number of iterations, transforming to unsigned, if number of |
6974 | /// iterations may be larger than the original type. |
6975 | static Expr * |
6976 | calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, |
6977 | Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, |
6978 | bool TestIsStrictOp, bool RoundToStep, |
6979 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { |
6980 | ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); |
6981 | if (!NewStep.isUsable()) |
6982 | return nullptr; |
6983 | llvm::APSInt LRes, SRes; |
6984 | bool IsLowerConst = false, IsStepConst = false; |
6985 | if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) { |
6986 | LRes = *Res; |
6987 | IsLowerConst = true; |
6988 | } |
6989 | if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) { |
6990 | SRes = *Res; |
6991 | IsStepConst = true; |
6992 | } |
6993 | bool NoNeedToConvert = IsLowerConst && !RoundToStep && |
6994 | ((!TestIsStrictOp && LRes.isNonNegative()) || |
6995 | (TestIsStrictOp && LRes.isStrictlyPositive())); |
6996 | bool NeedToReorganize = false; |
6997 | // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. |
6998 | if (!NoNeedToConvert && IsLowerConst && |
6999 | (TestIsStrictOp || (RoundToStep && IsStepConst))) { |
7000 | NoNeedToConvert = true; |
7001 | if (RoundToStep) { |
7002 | unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() |
7003 | ? LRes.getBitWidth() |
7004 | : SRes.getBitWidth(); |
7005 | LRes = LRes.extend(BW + 1); |
7006 | LRes.setIsSigned(true); |
7007 | SRes = SRes.extend(BW + 1); |
7008 | SRes.setIsSigned(true); |
7009 | LRes -= SRes; |
7010 | NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; |
7011 | LRes = LRes.trunc(BW); |
7012 | } |
7013 | if (TestIsStrictOp) { |
7014 | unsigned BW = LRes.getBitWidth(); |
7015 | LRes = LRes.extend(BW + 1); |
7016 | LRes.setIsSigned(true); |
7017 | ++LRes; |
7018 | NoNeedToConvert = |
7019 | NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; |
7020 | // truncate to the original bitwidth. |
7021 | LRes = LRes.trunc(BW); |
7022 | } |
7023 | NeedToReorganize = NoNeedToConvert; |
7024 | } |
7025 | llvm::APSInt URes; |
7026 | bool IsUpperConst = false; |
7027 | if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) { |
7028 | URes = *Res; |
7029 | IsUpperConst = true; |
7030 | } |
7031 | if (NoNeedToConvert && IsLowerConst && IsUpperConst && |
7032 | (!RoundToStep || IsStepConst)) { |
7033 | unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() |
7034 | : URes.getBitWidth(); |
7035 | LRes = LRes.extend(BW + 1); |
7036 | LRes.setIsSigned(true); |
7037 | URes = URes.extend(BW + 1); |
7038 | URes.setIsSigned(true); |
7039 | URes -= LRes; |
7040 | NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; |
7041 | NeedToReorganize = NoNeedToConvert; |
7042 | } |
7043 | // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant |
7044 | // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to |
7045 | // unsigned. |
7046 | if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && |
7047 | !LCTy->isDependentType() && LCTy->isIntegerType()) { |
7048 | QualType LowerTy = Lower->getType(); |
7049 | QualType UpperTy = Upper->getType(); |
7050 | uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); |
7051 | uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); |
7052 | if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || |
7053 | (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { |
7054 | QualType CastType = SemaRef.Context.getIntTypeForBitwidth( |
7055 | LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); |
7056 | Upper = |
7057 | SemaRef |
7058 | .PerformImplicitConversion( |
7059 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), |
7060 | CastType, Sema::AA_Converting) |
7061 | .get(); |
7062 | Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); |
7063 | NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); |
7064 | } |
7065 | } |
7066 | if (!Lower || !Upper || NewStep.isInvalid()) |
7067 | return nullptr; |
7068 | |
7069 | ExprResult Diff; |
7070 | // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ |
7071 | // 1]). |
7072 | if (NeedToReorganize) { |
7073 | Diff = Lower; |
7074 | |
7075 | if (RoundToStep) { |
7076 | // Lower - Step |
7077 | Diff = |
7078 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); |
7079 | if (!Diff.isUsable()) |
7080 | return nullptr; |
7081 | } |
7082 | |
7083 | // Lower - Step [+ 1] |
7084 | if (TestIsStrictOp) |
7085 | Diff = SemaRef.BuildBinOp( |
7086 | S, DefaultLoc, BO_Add, Diff.get(), |
7087 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); |
7088 | if (!Diff.isUsable()) |
7089 | return nullptr; |
7090 | |
7091 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); |
7092 | if (!Diff.isUsable()) |
7093 | return nullptr; |
7094 | |
7095 | // Upper - (Lower - Step [+ 1]). |
7096 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); |
7097 | if (!Diff.isUsable()) |
7098 | return nullptr; |
7099 | } else { |
7100 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); |
7101 | |
7102 | if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { |
7103 | // BuildBinOp already emitted error, this one is to point user to upper |
7104 | // and lower bound, and to tell what is passed to 'operator-'. |
7105 | SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) |
7106 | << Upper->getSourceRange() << Lower->getSourceRange(); |
7107 | return nullptr; |
7108 | } |
7109 | |
7110 | if (!Diff.isUsable()) |
7111 | return nullptr; |
7112 | |
7113 | // Upper - Lower [- 1] |
7114 | if (TestIsStrictOp) |
7115 | Diff = SemaRef.BuildBinOp( |
7116 | S, DefaultLoc, BO_Sub, Diff.get(), |
7117 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); |
7118 | if (!Diff.isUsable()) |
7119 | return nullptr; |
7120 | |
7121 | if (RoundToStep) { |
7122 | // Upper - Lower [- 1] + Step |
7123 | Diff = |
7124 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); |
7125 | if (!Diff.isUsable()) |
7126 | return nullptr; |
7127 | } |
7128 | } |
7129 | |
7130 | // Parentheses (for dumping/debugging purposes only). |
7131 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); |
7132 | if (!Diff.isUsable()) |
7133 | return nullptr; |
7134 | |
7135 | // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step |
7136 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); |
7137 | if (!Diff.isUsable()) |
7138 | return nullptr; |
7139 | |
7140 | return Diff.get(); |
7141 | } |
7142 | |
7143 | /// Build the expression to calculate the number of iterations. |
7144 | Expr *OpenMPIterationSpaceChecker::buildNumIterations( |
7145 | Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, |
7146 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { |
7147 | QualType VarType = LCDecl->getType().getNonReferenceType(); |
7148 | if (!VarType->isIntegerType() && !VarType->isPointerType() && |
7149 | !SemaRef.getLangOpts().CPlusPlus) |
7150 | return nullptr; |
7151 | Expr *LBVal = LB; |
7152 | Expr *UBVal = UB; |
7153 | // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : |
7154 | // max(LB(MinVal), LB(MaxVal)) |
7155 | if (InitDependOnLC) { |
7156 | const LoopIterationSpace &IS = |
7157 | ResultIterSpaces[ResultIterSpaces.size() - 1 - |
7158 | InitDependOnLC.getValueOr( |
7159 | CondDependOnLC.getValueOr(0))]; |
7160 | if (!IS.MinValue || !IS.MaxValue) |
7161 | return nullptr; |
7162 | // OuterVar = Min |
7163 | ExprResult MinValue = |
7164 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); |
7165 | if (!MinValue.isUsable()) |
7166 | return nullptr; |
7167 | |
7168 | ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, |
7169 | IS.CounterVar, MinValue.get()); |
7170 | if (!LBMinVal.isUsable()) |
7171 | return nullptr; |
7172 | // OuterVar = Min, LBVal |
7173 | LBMinVal = |
7174 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); |
7175 | if (!LBMinVal.isUsable()) |
7176 | return nullptr; |
7177 | // (OuterVar = Min, LBVal) |
7178 | LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); |
7179 | if (!LBMinVal.isUsable()) |
7180 | return nullptr; |
7181 | |
7182 | // OuterVar = Max |
7183 | ExprResult MaxValue = |
7184 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); |
7185 | if (!MaxValue.isUsable()) |
7186 | return nullptr; |
7187 | |
7188 | ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, |
7189 | IS.CounterVar, MaxValue.get()); |
7190 | if (!LBMaxVal.isUsable()) |
7191 | return nullptr; |
7192 | // OuterVar = Max, LBVal |
7193 | LBMaxVal = |
7194 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); |
7195 | if (!LBMaxVal.isUsable()) |
7196 | return nullptr; |
7197 | // (OuterVar = Max, LBVal) |
7198 | LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); |
7199 | if (!LBMaxVal.isUsable()) |
7200 | return nullptr; |
7201 | |
7202 | Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); |
7203 | Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); |
7204 | if (!LBMin || !LBMax) |
7205 | return nullptr; |
7206 | // LB(MinVal) < LB(MaxVal) |
7207 | ExprResult MinLessMaxRes = |
7208 | SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); |
7209 | if (!MinLessMaxRes.isUsable()) |
7210 | return nullptr; |
7211 | Expr *MinLessMax = |
7212 | tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); |
7213 | if (!MinLessMax) |
7214 | return nullptr; |
7215 | if (TestIsLessOp.getValue()) { |
7216 | // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), |
7217 | // LB(MaxVal)) |
7218 | ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, |
7219 | MinLessMax, LBMin, LBMax); |
7220 | if (!MinLB.isUsable()) |
7221 | return nullptr; |
7222 | LBVal = MinLB.get(); |
7223 | } else { |
7224 | // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), |
7225 | // LB(MaxVal)) |
7226 | ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, |
7227 | MinLessMax, LBMax, LBMin); |
7228 | if (!MaxLB.isUsable()) |
7229 | return nullptr; |
7230 | LBVal = MaxLB.get(); |
7231 | } |
7232 | } |
7233 | // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : |
7234 | // min(UB(MinVal), UB(MaxVal)) |
7235 | if (CondDependOnLC) { |
7236 | const LoopIterationSpace &IS = |
7237 | ResultIterSpaces[ResultIterSpaces.size() - 1 - |
7238 | InitDependOnLC.getValueOr( |
7239 | CondDependOnLC.getValueOr(0))]; |
7240 | if (!IS.MinValue || !IS.MaxValue) |
7241 | return nullptr; |
7242 | // OuterVar = Min |
7243 | ExprResult MinValue = |
7244 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); |
7245 | if (!MinValue.isUsable()) |
7246 | return nullptr; |
7247 | |
7248 | ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, |
7249 | IS.CounterVar, MinValue.get()); |
7250 | if (!UBMinVal.isUsable()) |
7251 | return nullptr; |
7252 | // OuterVar = Min, UBVal |
7253 | UBMinVal = |
7254 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); |
7255 | if (!UBMinVal.isUsable()) |
7256 | return nullptr; |
7257 | // (OuterVar = Min, UBVal) |
7258 | UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); |
7259 | if (!UBMinVal.isUsable()) |
7260 | return nullptr; |
7261 | |
7262 | // OuterVar = Max |
7263 | ExprResult MaxValue = |
7264 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); |
7265 | if (!MaxValue.isUsable()) |
7266 | return nullptr; |
7267 | |
7268 | ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, |
7269 | IS.CounterVar, MaxValue.get()); |
7270 | if (!UBMaxVal.isUsable()) |
7271 | return nullptr; |
7272 | // OuterVar = Max, UBVal |
7273 | UBMaxVal = |
7274 | SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); |
7275 | if (!UBMaxVal.isUsable()) |
7276 | return nullptr; |
7277 | // (OuterVar = Max, UBVal) |
7278 | UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); |
7279 | if (!UBMaxVal.isUsable()) |
7280 | return nullptr; |
7281 | |
7282 | Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); |
7283 | Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); |
7284 | if (!UBMin || !UBMax) |
7285 | return nullptr; |
7286 | // UB(MinVal) > UB(MaxVal) |
7287 | ExprResult MinGreaterMaxRes = |
7288 | SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); |
7289 | if (!MinGreaterMaxRes.isUsable()) |
7290 | return nullptr; |
7291 | Expr *MinGreaterMax = |
7292 | tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); |
7293 | if (!MinGreaterMax) |
7294 | return nullptr; |
7295 | if (TestIsLessOp.getValue()) { |
7296 | // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), |
7297 | // UB(MaxVal)) |
7298 | ExprResult MaxUB = SemaRef.ActOnConditionalOp( |
7299 | DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); |
7300 | if (!MaxUB.isUsable()) |
7301 | return nullptr; |
7302 | UBVal = MaxUB.get(); |
7303 | } else { |
7304 | // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), |
7305 | // UB(MaxVal)) |
7306 | ExprResult MinUB = SemaRef.ActOnConditionalOp( |
7307 | DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); |
7308 | if (!MinUB.isUsable()) |
7309 | return nullptr; |
7310 | UBVal = MinUB.get(); |
7311 | } |
7312 | } |
7313 | Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; |
7314 | Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; |
7315 | Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); |
7316 | Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); |
7317 | if (!Upper || !Lower) |
7318 | return nullptr; |
7319 | |
7320 | ExprResult Diff = |
7321 | calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, |
7322 | TestIsStrictOp, /*RoundToStep=*/true, Captures); |
7323 | if (!Diff.isUsable()) |
7324 | return nullptr; |
7325 | |
7326 | // OpenMP runtime requires 32-bit or 64-bit loop variables. |
7327 | QualType Type = Diff.get()->getType(); |
7328 | ASTContext &C = SemaRef.Context; |
7329 | bool UseVarType = VarType->hasIntegerRepresentation() && |
7330 | C.getTypeSize(Type) > C.getTypeSize(VarType); |
7331 | if (!Type->isIntegerType() || UseVarType) { |
7332 | unsigned NewSize = |
7333 | UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); |
7334 | bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() |
7335 | : Type->hasSignedIntegerRepresentation(); |
7336 | Type = C.getIntTypeForBitwidth(NewSize, IsSigned); |
7337 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { |
7338 | Diff = SemaRef.PerformImplicitConversion( |
7339 | Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); |
7340 | if (!Diff.isUsable()) |
7341 | return nullptr; |
7342 | } |
7343 | } |
7344 | if (LimitedType) { |
7345 | unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; |
7346 | if (NewSize != C.getTypeSize(Type)) { |
7347 | if (NewSize < C.getTypeSize(Type)) { |
7348 | assert(NewSize == 64 && "incorrect loop var size")((NewSize == 64 && "incorrect loop var size") ? static_cast <void> (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7348, __PRETTY_FUNCTION__)); |
7349 | SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) |
7350 | << InitSrcRange << ConditionSrcRange; |
7351 | } |
7352 | QualType NewType = C.getIntTypeForBitwidth( |
7353 | NewSize, Type->hasSignedIntegerRepresentation() || |
7354 | C.getTypeSize(Type) < NewSize); |
7355 | if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { |
7356 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, |
7357 | Sema::AA_Converting, true); |
7358 | if (!Diff.isUsable()) |
7359 | return nullptr; |
7360 | } |
7361 | } |
7362 | } |
7363 | |
7364 | return Diff.get(); |
7365 | } |
7366 | |
7367 | std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( |
7368 | Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { |
7369 | // Do not build for iterators, they cannot be used in non-rectangular loop |
7370 | // nests. |
7371 | if (LCDecl->getType()->isRecordType()) |
7372 | return std::make_pair(nullptr, nullptr); |
7373 | // If we subtract, the min is in the condition, otherwise the min is in the |
7374 | // init value. |
7375 | Expr *MinExpr = nullptr; |
7376 | Expr *MaxExpr = nullptr; |
7377 | Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; |
7378 | Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; |
7379 | bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() |
7380 | : CondDependOnLC.hasValue(); |
7381 | bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() |
7382 | : InitDependOnLC.hasValue(); |
7383 | Expr *Lower = |
7384 | LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); |
7385 | Expr *Upper = |
7386 | UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); |
7387 | if (!Upper || !Lower) |
7388 | return std::make_pair(nullptr, nullptr); |
7389 | |
7390 | if (TestIsLessOp.getValue()) |
7391 | MinExpr = Lower; |
7392 | else |
7393 | MaxExpr = Upper; |
7394 | |
7395 | // Build minimum/maximum value based on number of iterations. |
7396 | QualType VarType = LCDecl->getType().getNonReferenceType(); |
7397 | |
7398 | ExprResult Diff = |
7399 | calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, |
7400 | TestIsStrictOp, /*RoundToStep=*/false, Captures); |
7401 | if (!Diff.isUsable()) |
7402 | return std::make_pair(nullptr, nullptr); |
7403 | |
7404 | // ((Upper - Lower [- 1]) / Step) * Step |
7405 | // Parentheses (for dumping/debugging purposes only). |
7406 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); |
7407 | if (!Diff.isUsable()) |
7408 | return std::make_pair(nullptr, nullptr); |
7409 | |
7410 | ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); |
7411 | if (!NewStep.isUsable()) |
7412 | return std::make_pair(nullptr, nullptr); |
7413 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); |
7414 | if (!Diff.isUsable()) |
7415 | return std::make_pair(nullptr, nullptr); |
7416 | |
7417 | // Parentheses (for dumping/debugging purposes only). |
7418 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); |
7419 | if (!Diff.isUsable()) |
7420 | return std::make_pair(nullptr, nullptr); |
7421 | |
7422 | // Convert to the ptrdiff_t, if original type is pointer. |
7423 | if (VarType->isAnyPointerType() && |
7424 | !SemaRef.Context.hasSameType( |
7425 | Diff.get()->getType(), |
7426 | SemaRef.Context.getUnsignedPointerDiffType())) { |
7427 | Diff = SemaRef.PerformImplicitConversion( |
7428 | Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), |
7429 | Sema::AA_Converting, /*AllowExplicit=*/true); |
7430 | } |
7431 | if (!Diff.isUsable()) |
7432 | return std::make_pair(nullptr, nullptr); |
7433 | |
7434 | if (TestIsLessOp.getValue()) { |
7435 | // MinExpr = Lower; |
7436 | // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) |
7437 | Diff = SemaRef.BuildBinOp( |
7438 | S, DefaultLoc, BO_Add, |
7439 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), |
7440 | Diff.get()); |
7441 | if (!Diff.isUsable()) |
7442 | return std::make_pair(nullptr, nullptr); |
7443 | } else { |
7444 | // MaxExpr = Upper; |
7445 | // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) |
7446 | Diff = SemaRef.BuildBinOp( |
7447 | S, DefaultLoc, BO_Sub, |
7448 | SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), |
7449 | Diff.get()); |
7450 | if (!Diff.isUsable()) |
7451 | return std::make_pair(nullptr, nullptr); |
7452 | } |
7453 | |
7454 | // Convert to the original type. |
7455 | if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) |
7456 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, |
7457 | Sema::AA_Converting, |
7458 | /*AllowExplicit=*/true); |
7459 | if (!Diff.isUsable()) |
7460 | return std::make_pair(nullptr, nullptr); |
7461 | |
7462 | Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); |
7463 | if (!Diff.isUsable()) |
7464 | return std::make_pair(nullptr, nullptr); |
7465 | |
7466 | if (TestIsLessOp.getValue()) |
7467 | MaxExpr = Diff.get(); |
7468 | else |
7469 | MinExpr = Diff.get(); |
7470 | |
7471 | return std::make_pair(MinExpr, MaxExpr); |
7472 | } |
7473 | |
7474 | Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { |
7475 | if (InitDependOnLC || CondDependOnLC) |
7476 | return Condition; |
7477 | return nullptr; |
7478 | } |
7479 | |
7480 | Expr *OpenMPIterationSpaceChecker::buildPreCond( |
7481 | Scope *S, Expr *Cond, |
7482 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { |
7483 | // Do not build a precondition when the condition/initialization is dependent |
7484 | // to prevent pessimistic early loop exit. |
7485 | // TODO: this can be improved by calculating min/max values but not sure that |
7486 | // it will be very effective. |
7487 | if (CondDependOnLC || InitDependOnLC) |
7488 | return SemaRef.PerformImplicitConversion( |
7489 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), |
7490 | SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, |
7491 | /*AllowExplicit=*/true).get(); |
7492 | |
7493 | // Try to build LB <op> UB, where <op> is <, >, <=, or >=. |
7494 | Sema::TentativeAnalysisScope Trap(SemaRef); |
7495 | |
7496 | ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); |
7497 | ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); |
7498 | if (!NewLB.isUsable() || !NewUB.isUsable()) |
7499 | return nullptr; |
7500 | |
7501 | ExprResult CondExpr = |
7502 | SemaRef.BuildBinOp(S, DefaultLoc, |
7503 | TestIsLessOp.getValue() ? |
7504 | (TestIsStrictOp ? BO_LT : BO_LE) : |
7505 | (TestIsStrictOp ? BO_GT : BO_GE), |
7506 | NewLB.get(), NewUB.get()); |
7507 | if (CondExpr.isUsable()) { |
7508 | if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), |
7509 | SemaRef.Context.BoolTy)) |
7510 | CondExpr = SemaRef.PerformImplicitConversion( |
7511 | CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, |
7512 | /*AllowExplicit=*/true); |
7513 | } |
7514 | |
7515 | // Otherwise use original loop condition and evaluate it in runtime. |
7516 | return CondExpr.isUsable() ? CondExpr.get() : Cond; |
7517 | } |
7518 | |
7519 | /// Build reference expression to the counter be used for codegen. |
7520 | DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( |
7521 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, |
7522 | DSAStackTy &DSA) const { |
7523 | auto *VD = dyn_cast<VarDecl>(LCDecl); |
7524 | if (!VD) { |
7525 | VD = SemaRef.isOpenMPCapturedDecl(LCDecl); |
7526 | DeclRefExpr *Ref = buildDeclRefExpr( |
7527 | SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); |
7528 | const DSAStackTy::DSAVarData Data = |
7529 | DSA.getTopDSA(LCDecl, /*FromParent=*/false); |
7530 | // If the loop control decl is explicitly marked as private, do not mark it |
7531 | // as captured again. |
7532 | if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) |
7533 | Captures.insert(std::make_pair(LCRef, Ref)); |
7534 | return Ref; |
7535 | } |
7536 | return cast<DeclRefExpr>(LCRef); |
7537 | } |
7538 | |
7539 | Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { |
7540 | if (LCDecl && !LCDecl->isInvalidDecl()) { |
7541 | QualType Type = LCDecl->getType().getNonReferenceType(); |
7542 | VarDecl *PrivateVar = buildVarDecl( |
7543 | SemaRef, DefaultLoc, Type, LCDecl->getName(), |
7544 | LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, |
7545 | isa<VarDecl>(LCDecl) |
7546 | ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) |
7547 | : nullptr); |
7548 | if (PrivateVar->isInvalidDecl()) |
7549 | return nullptr; |
7550 | return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); |
7551 | } |
7552 | return nullptr; |
7553 | } |
7554 | |
7555 | /// Build initialization of the counter to be used for codegen. |
7556 | Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } |
7557 | |
7558 | /// Build step of the counter be used for codegen. |
7559 | Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } |
7560 | |
7561 | Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( |
7562 | Scope *S, Expr *Counter, |
7563 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, |
7564 | Expr *Inc, OverloadedOperatorKind OOK) { |
7565 | Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); |
7566 | if (!Cnt) |
7567 | return nullptr; |
7568 | if (Inc) { |
7569 | assert((OOK == OO_Plus || OOK == OO_Minus) &&(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses." ) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7570, __PRETTY_FUNCTION__)) |
7570 | "Expected only + or - operations for depend clauses.")(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses." ) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7570, __PRETTY_FUNCTION__)); |
7571 | BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; |
7572 | Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); |
7573 | if (!Cnt) |
7574 | return nullptr; |
7575 | } |
7576 | QualType VarType = LCDecl->getType().getNonReferenceType(); |
7577 | if (!VarType->isIntegerType() && !VarType->isPointerType() && |
7578 | !SemaRef.getLangOpts().CPlusPlus) |
7579 | return nullptr; |
7580 | // Upper - Lower |
7581 | Expr *Upper = TestIsLessOp.getValue() |
7582 | ? Cnt |
7583 | : tryBuildCapture(SemaRef, LB, Captures).get(); |
7584 | Expr *Lower = TestIsLessOp.getValue() |
7585 | ? tryBuildCapture(SemaRef, LB, Captures).get() |
7586 | : Cnt; |
7587 | if (!Upper || !Lower) |
7588 | return nullptr; |
7589 | |
7590 | ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, |
7591 | Step, VarType, /*TestIsStrictOp=*/false, |
7592 | /*RoundToStep=*/false, Captures); |
7593 | if (!Diff.isUsable()) |
7594 | return nullptr; |
7595 | |
7596 | return Diff.get(); |
7597 | } |
7598 | } // namespace |
7599 | |
7600 | void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { |
7601 | assert(getLangOpts().OpenMP && "OpenMP is not active.")((getLangOpts().OpenMP && "OpenMP is not active.") ? static_cast <void> (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7601, __PRETTY_FUNCTION__)); |
7602 | assert(Init && "Expected loop in canonical form.")((Init && "Expected loop in canonical form.") ? static_cast <void> (0) : __assert_fail ("Init && \"Expected loop in canonical form.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7602, __PRETTY_FUNCTION__)); |
7603 | unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops(); |
7604 | if (AssociatedLoops > 0 && |
7605 | isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { |
7606 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->loopStart(); |
7607 | OpenMPIterationSpaceChecker ISC(*this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), ForLoc); |
7608 | if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { |
7609 | if (ValueDecl *D = ISC.getLoopDecl()) { |
7610 | auto *VD = dyn_cast<VarDecl>(D); |
7611 | DeclRefExpr *PrivateRef = nullptr; |
7612 | if (!VD) { |
7613 | if (VarDecl *Private = isOpenMPCapturedDecl(D)) { |
7614 | VD = Private; |
7615 | } else { |
7616 | PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), |
7617 | /*WithInit=*/false); |
7618 | VD = cast<VarDecl>(PrivateRef->getDecl()); |
7619 | } |
7620 | } |
7621 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addLoopControlVariable(D, VD); |
7622 | const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getPossiblyLoopCunter(); |
7623 | if (LD != D->getCanonicalDecl()) { |
7624 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->resetPossibleLoopCounter(); |
7625 | if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) |
7626 | MarkDeclarationsReferencedInExpr( |
7627 | buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), |
7628 | Var->getType().getNonLValueExprType(Context), |
7629 | ForLoc, /*RefersToCapture=*/true)); |
7630 | } |
7631 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
7632 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables |
7633 | // Referenced in a Construct, C/C++]. The loop iteration variable in the |
7634 | // associated for-loop of a simd construct with just one associated |
7635 | // for-loop may be listed in a linear clause with a constant-linear-step |
7636 | // that is the increment of the associated for-loop. The loop iteration |
7637 | // variable(s) in the associated for-loop(s) of a for or parallel for |
7638 | // construct may be listed in a private or lastprivate clause. |
7639 | DSAStackTy::DSAVarData DVar = |
7640 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
7641 | // If LoopVarRefExpr is nullptr it means the corresponding loop variable |
7642 | // is declared in the loop and it is predetermined as a private. |
7643 | Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); |
7644 | OpenMPClauseKind PredeterminedCKind = |
7645 | isOpenMPSimdDirective(DKind) |
7646 | ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) |
7647 | : OMPC_private; |
7648 | if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && |
7649 | DVar.CKind != PredeterminedCKind && DVar.RefExpr && |
7650 | (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && |
7651 | DVar.CKind != OMPC_private))) || |
7652 | ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || |
7653 | DKind == OMPD_master_taskloop || |
7654 | DKind == OMPD_parallel_master_taskloop || |
7655 | isOpenMPDistributeDirective(DKind)) && |
7656 | !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && |
7657 | DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && |
7658 | (DVar.CKind != OMPC_private || DVar.RefExpr)) { |
7659 | Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) |
7660 | << getOpenMPClauseName(DVar.CKind) |
7661 | << getOpenMPDirectiveName(DKind) |
7662 | << getOpenMPClauseName(PredeterminedCKind); |
7663 | if (DVar.RefExpr == nullptr) |
7664 | DVar.CKind = PredeterminedCKind; |
7665 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar, |
7666 | /*IsLoopIterVar=*/true); |
7667 | } else if (LoopDeclRefExpr) { |
7668 | // Make the loop iteration variable private (for worksharing |
7669 | // constructs), linear (for simd directives with the only one |
7670 | // associated loop) or lastprivate (for simd directives with several |
7671 | // collapsed or ordered loops). |
7672 | if (DVar.CKind == OMPC_unknown) |
7673 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, |
7674 | PrivateRef); |
7675 | } |
7676 | } |
7677 | } |
7678 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(AssociatedLoops - 1); |
7679 | } |
7680 | } |
7681 | |
7682 | /// Called on a for stmt to check and extract its iteration space |
7683 | /// for further processing (such as collapsing). |
7684 | static bool checkOpenMPIterationSpace( |
7685 | OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, |
7686 | unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, |
7687 | unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, |
7688 | Expr *OrderedLoopCountExpr, |
7689 | Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, |
7690 | llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, |
7691 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { |
7692 | // OpenMP [2.9.1, Canonical Loop Form] |
7693 | // for (init-expr; test-expr; incr-expr) structured-block |
7694 | // for (range-decl: range-expr) structured-block |
7695 | auto *For = dyn_cast_or_null<ForStmt>(S); |
7696 | auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); |
7697 | // Ranged for is supported only in OpenMP 5.0. |
7698 | if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { |
7699 | SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) |
7700 | << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) |
7701 | << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount |
7702 | << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; |
7703 | if (TotalNestedLoopCount > 1) { |
7704 | if (CollapseLoopCountExpr && OrderedLoopCountExpr) |
7705 | SemaRef.Diag(DSA.getConstructLoc(), |
7706 | diag::note_omp_collapse_ordered_expr) |
7707 | << 2 << CollapseLoopCountExpr->getSourceRange() |
7708 | << OrderedLoopCountExpr->getSourceRange(); |
7709 | else if (CollapseLoopCountExpr) |
7710 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), |
7711 | diag::note_omp_collapse_ordered_expr) |
7712 | << 0 << CollapseLoopCountExpr->getSourceRange(); |
7713 | else |
7714 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), |
7715 | diag::note_omp_collapse_ordered_expr) |
7716 | << 1 << OrderedLoopCountExpr->getSourceRange(); |
7717 | } |
7718 | return true; |
7719 | } |
7720 | assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&((((For && For->getBody()) || (CXXFor && CXXFor ->getBody())) && "No loop body.") ? static_cast< void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7721, __PRETTY_FUNCTION__)) |
7721 | "No loop body.")((((For && For->getBody()) || (CXXFor && CXXFor ->getBody())) && "No loop body.") ? static_cast< void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7721, __PRETTY_FUNCTION__)); |
7722 | |
7723 | OpenMPIterationSpaceChecker ISC(SemaRef, DSA, |
7724 | For ? For->getForLoc() : CXXFor->getForLoc()); |
7725 | |
7726 | // Check init. |
7727 | Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); |
7728 | if (ISC.checkAndSetInit(Init)) |
7729 | return true; |
7730 | |
7731 | bool HasErrors = false; |
7732 | |
7733 | // Check loop variable's type. |
7734 | if (ValueDecl *LCDecl = ISC.getLoopDecl()) { |
7735 | // OpenMP [2.6, Canonical Loop Form] |
7736 | // Var is one of the following: |
7737 | // A variable of signed or unsigned integer type. |
7738 | // For C++, a variable of a random access iterator type. |
7739 | // For C, a variable of a pointer type. |
7740 | QualType VarType = LCDecl->getType().getNonReferenceType(); |
7741 | if (!VarType->isDependentType() && !VarType->isIntegerType() && |
7742 | !VarType->isPointerType() && |
7743 | !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { |
7744 | SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) |
7745 | << SemaRef.getLangOpts().CPlusPlus; |
7746 | HasErrors = true; |
7747 | } |
7748 | |
7749 | // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in |
7750 | // a Construct |
7751 | // The loop iteration variable(s) in the associated for-loop(s) of a for or |
7752 | // parallel for construct is (are) private. |
7753 | // The loop iteration variable in the associated for-loop of a simd |
7754 | // construct with just one associated for-loop is linear with a |
7755 | // constant-linear-step that is the increment of the associated for-loop. |
7756 | // Exclude loop var from the list of variables with implicitly defined data |
7757 | // sharing attributes. |
7758 | VarsWithImplicitDSA.erase(LCDecl); |
7759 | |
7760 | assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")((isOpenMPLoopDirective(DKind) && "DSA for non-loop vars" ) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 7760, __PRETTY_FUNCTION__)); |
7761 | |
7762 | // Check test-expr. |
7763 | HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); |
7764 | |
7765 | // Check incr-expr. |
7766 | HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); |
7767 | } |
7768 | |
7769 | if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) |
7770 | return HasErrors; |
7771 | |
7772 | // Build the loop's iteration space representation. |
7773 | ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( |
7774 | DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); |
7775 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations = |
7776 | ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, |
7777 | (isOpenMPWorksharingDirective(DKind) || |
7778 | isOpenMPTaskLoopDirective(DKind) || |
7779 | isOpenMPDistributeDirective(DKind)), |
7780 | Captures); |
7781 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar = |
7782 | ISC.buildCounterVar(Captures, DSA); |
7783 | ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = |
7784 | ISC.buildPrivateCounterVar(); |
7785 | ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); |
7786 | ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); |
7787 | ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); |
7788 | ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = |
7789 | ISC.getConditionSrcRange(); |
7790 | ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = |
7791 | ISC.getIncrementSrcRange(); |
7792 | ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); |
7793 | ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = |
7794 | ISC.isStrictTestOp(); |
7795 | std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, |
7796 | ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = |
7797 | ISC.buildMinMaxValues(DSA.getCurScope(), Captures); |
7798 | ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = |
7799 | ISC.buildFinalCondition(DSA.getCurScope()); |
7800 | ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = |
7801 | ISC.doesInitDependOnLC(); |
7802 | ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = |
7803 | ISC.doesCondDependOnLC(); |
7804 | ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = |
7805 | ISC.getLoopDependentIdx(); |
7806 | |
7807 | HasErrors |= |
7808 | (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || |
7809 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || |
7810 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || |
7811 | ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || |
7812 | ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || |
7813 | ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); |
7814 | if (!HasErrors && DSA.isOrderedRegion()) { |
7815 | if (DSA.getOrderedRegionParam().second->getNumForLoops()) { |
7816 | if (CurrentNestedLoopCount < |
7817 | DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { |
7818 | DSA.getOrderedRegionParam().second->setLoopNumIterations( |
7819 | CurrentNestedLoopCount, |
7820 | ResultIterSpaces[CurrentNestedLoopCount].NumIterations); |
7821 | DSA.getOrderedRegionParam().second->setLoopCounter( |
7822 | CurrentNestedLoopCount, |
7823 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar); |
7824 | } |
7825 | } |
7826 | for (auto &Pair : DSA.getDoacrossDependClauses()) { |
7827 | if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { |
7828 | // Erroneous case - clause has some problems. |
7829 | continue; |
7830 | } |
7831 | if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && |
7832 | Pair.second.size() <= CurrentNestedLoopCount) { |
7833 | // Erroneous case - clause has some problems. |
7834 | Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); |
7835 | continue; |
7836 | } |
7837 | Expr *CntValue; |
7838 | if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) |
7839 | CntValue = ISC.buildOrderedLoopData( |
7840 | DSA.getCurScope(), |
7841 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, |
7842 | Pair.first->getDependencyLoc()); |
7843 | else |
7844 | CntValue = ISC.buildOrderedLoopData( |
7845 | DSA.getCurScope(), |
7846 | ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, |
7847 | Pair.first->getDependencyLoc(), |
7848 | Pair.second[CurrentNestedLoopCount].first, |
7849 | Pair.second[CurrentNestedLoopCount].second); |
7850 | Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); |
7851 | } |
7852 | } |
7853 | |
7854 | return HasErrors; |
7855 | } |
7856 | |
7857 | /// Build 'VarRef = Start. |
7858 | static ExprResult |
7859 | buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, |
7860 | ExprResult Start, bool IsNonRectangularLB, |
7861 | llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { |
7862 | // Build 'VarRef = Start. |
7863 | ExprResult NewStart = IsNonRectangularLB |
7864 | ? Start.get() |
7865 | : tryBuildCapture(SemaRef, Start.get(), Captures); |
7866 | if (!NewStart.isUsable()) |
7867 | return ExprError(); |
7868 | if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), |
7869 | VarRef.get()->getType())) { |
7870 | NewStart = SemaRef.PerformImplicitConversion( |
7871 | NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, |
7872 | /*AllowExplicit=*/true); |
7873 | if (!NewStart.isUsable()) |
7874 | return ExprError(); |
7875 | } |
7876 | |
7877 | ExprResult Init = |
7878 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); |
7879 | return Init; |
7880 | } |
7881 | |
7882 | /// Build 'VarRef = Start + Iter * Step'. |
7883 | static ExprResult buildCounterUpdate( |
7884 | Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, |
7885 | ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, |
7886 | bool IsNonRectangularLB, |
7887 | llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { |
7888 | // Add parentheses (for debugging purposes only). |
7889 | Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); |
7890 | if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || |
7891 | !Step.isUsable()) |
7892 | return ExprError(); |
7893 | |
7894 | ExprResult NewStep = Step; |
7895 | if (Captures) |
7896 | NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); |
7897 | if (NewStep.isInvalid()) |
7898 | return ExprError(); |
7899 | ExprResult Update = |
7900 | SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); |
7901 | if (!Update.isUsable()) |
7902 | return ExprError(); |
7903 | |
7904 | // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or |
7905 | // 'VarRef = Start (+|-) Iter * Step'. |
7906 | if (!Start.isUsable()) |
7907 | return ExprError(); |
7908 | ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); |
7909 | if (!NewStart.isUsable()) |
7910 | return ExprError(); |
7911 | if (Captures && !IsNonRectangularLB) |
7912 | NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); |
7913 | if (NewStart.isInvalid()) |
7914 | return ExprError(); |
7915 | |
7916 | // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. |
7917 | ExprResult SavedUpdate = Update; |
7918 | ExprResult UpdateVal; |
7919 | if (VarRef.get()->getType()->isOverloadableType() || |
7920 | NewStart.get()->getType()->isOverloadableType() || |
7921 | Update.get()->getType()->isOverloadableType()) { |
7922 | Sema::TentativeAnalysisScope Trap(SemaRef); |
7923 | |
7924 | Update = |
7925 | SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); |
7926 | if (Update.isUsable()) { |
7927 | UpdateVal = |
7928 | SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, |
7929 | VarRef.get(), SavedUpdate.get()); |
7930 | if (UpdateVal.isUsable()) { |
7931 | Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), |
7932 | UpdateVal.get()); |
7933 | } |
7934 | } |
7935 | } |
7936 | |
7937 | // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. |
7938 | if (!Update.isUsable() || !UpdateVal.isUsable()) { |
7939 | Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, |
7940 | NewStart.get(), SavedUpdate.get()); |
7941 | if (!Update.isUsable()) |
7942 | return ExprError(); |
7943 | |
7944 | if (!SemaRef.Context.hasSameType(Update.get()->getType(), |
7945 | VarRef.get()->getType())) { |
7946 | Update = SemaRef.PerformImplicitConversion( |
7947 | Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); |
7948 | if (!Update.isUsable()) |
7949 | return ExprError(); |
7950 | } |
7951 | |
7952 | Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); |
7953 | } |
7954 | return Update; |
7955 | } |
7956 | |
7957 | /// Convert integer expression \a E to make it have at least \a Bits |
7958 | /// bits. |
7959 | static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { |
7960 | if (E == nullptr) |
7961 | return ExprError(); |
7962 | ASTContext &C = SemaRef.Context; |
7963 | QualType OldType = E->getType(); |
7964 | unsigned HasBits = C.getTypeSize(OldType); |
7965 | if (HasBits >= Bits) |
7966 | return ExprResult(E); |
7967 | // OK to convert to signed, because new type has more bits than old. |
7968 | QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); |
7969 | return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, |
7970 | true); |
7971 | } |
7972 | |
7973 | /// Check if the given expression \a E is a constant integer that fits |
7974 | /// into \a Bits bits. |
7975 | static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { |
7976 | if (E == nullptr) |
7977 | return false; |
7978 | if (Optional<llvm::APSInt> Result = |
7979 | E->getIntegerConstantExpr(SemaRef.Context)) |
7980 | return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); |
7981 | return false; |
7982 | } |
7983 | |
7984 | /// Build preinits statement for the given declarations. |
7985 | static Stmt *buildPreInits(ASTContext &Context, |
7986 | MutableArrayRef<Decl *> PreInits) { |
7987 | if (!PreInits.empty()) { |
7988 | return new (Context) DeclStmt( |
7989 | DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), |
7990 | SourceLocation(), SourceLocation()); |
7991 | } |
7992 | return nullptr; |
7993 | } |
7994 | |
7995 | /// Build preinits statement for the given declarations. |
7996 | static Stmt * |
7997 | buildPreInits(ASTContext &Context, |
7998 | const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { |
7999 | if (!Captures.empty()) { |
8000 | SmallVector<Decl *, 16> PreInits; |
8001 | for (const auto &Pair : Captures) |
8002 | PreInits.push_back(Pair.second->getDecl()); |
8003 | return buildPreInits(Context, PreInits); |
8004 | } |
8005 | return nullptr; |
8006 | } |
8007 | |
8008 | /// Build postupdate expression for the given list of postupdates expressions. |
8009 | static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { |
8010 | Expr *PostUpdate = nullptr; |
8011 | if (!PostUpdates.empty()) { |
8012 | for (Expr *E : PostUpdates) { |
8013 | Expr *ConvE = S.BuildCStyleCastExpr( |
8014 | E->getExprLoc(), |
8015 | S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), |
8016 | E->getExprLoc(), E) |
8017 | .get(); |
8018 | PostUpdate = PostUpdate |
8019 | ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, |
8020 | PostUpdate, ConvE) |
8021 | .get() |
8022 | : ConvE; |
8023 | } |
8024 | } |
8025 | return PostUpdate; |
8026 | } |
8027 | |
8028 | /// Called on a for stmt to check itself and nested loops (if any). |
8029 | /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, |
8030 | /// number of collapsed loops otherwise. |
8031 | static unsigned |
8032 | checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, |
8033 | Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, |
8034 | DSAStackTy &DSA, |
8035 | Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, |
8036 | OMPLoopDirective::HelperExprs &Built) { |
8037 | unsigned NestedLoopCount = 1; |
8038 | if (CollapseLoopCountExpr) { |
8039 | // Found 'collapse' clause - calculate collapse number. |
8040 | Expr::EvalResult Result; |
8041 | if (!CollapseLoopCountExpr->isValueDependent() && |
8042 | CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { |
8043 | NestedLoopCount = Result.Val.getInt().getLimitedValue(); |
8044 | } else { |
8045 | Built.clear(/*Size=*/1); |
8046 | return 1; |
8047 | } |
8048 | } |
8049 | unsigned OrderedLoopCount = 1; |
8050 | if (OrderedLoopCountExpr) { |
8051 | // Found 'ordered' clause - calculate collapse number. |
8052 | Expr::EvalResult EVResult; |
8053 | if (!OrderedLoopCountExpr->isValueDependent() && |
8054 | OrderedLoopCountExpr->EvaluateAsInt(EVResult, |
8055 | SemaRef.getASTContext())) { |
8056 | llvm::APSInt Result = EVResult.Val.getInt(); |
8057 | if (Result.getLimitedValue() < NestedLoopCount) { |
8058 | SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), |
8059 | diag::err_omp_wrong_ordered_loop_count) |
8060 | << OrderedLoopCountExpr->getSourceRange(); |
8061 | SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), |
8062 | diag::note_collapse_loop_count) |
8063 | << CollapseLoopCountExpr->getSourceRange(); |
8064 | } |
8065 | OrderedLoopCount = Result.getLimitedValue(); |
8066 | } else { |
8067 | Built.clear(/*Size=*/1); |
8068 | return 1; |
8069 | } |
8070 | } |
8071 | // This is helper routine for loop directives (e.g., 'for', 'simd', |
8072 | // 'for simd', etc.). |
8073 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
8074 | SmallVector<LoopIterationSpace, 4> IterSpaces( |
8075 | std::max(OrderedLoopCount, NestedLoopCount)); |
8076 | Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); |
8077 | for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { |
8078 | if (checkOpenMPIterationSpace( |
8079 | DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, |
8080 | std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, |
8081 | OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) |
8082 | return 0; |
8083 | // Move on to the next nested for loop, or to the loop body. |
8084 | // OpenMP [2.8.1, simd construct, Restrictions] |
8085 | // All loops associated with the construct must be perfectly nested; that |
8086 | // is, there must be no intervening code nor any OpenMP directive between |
8087 | // any two loops. |
8088 | if (auto *For = dyn_cast<ForStmt>(CurStmt)) { |
8089 | CurStmt = For->getBody(); |
8090 | } else { |
8091 | assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8092, __PRETTY_FUNCTION__)) |
8092 | "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8092, __PRETTY_FUNCTION__)); |
8093 | CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); |
8094 | } |
8095 | CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( |
8096 | CurStmt, SemaRef.LangOpts.OpenMP >= 50); |
8097 | } |
8098 | for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { |
8099 | if (checkOpenMPIterationSpace( |
8100 | DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, |
8101 | std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, |
8102 | OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) |
8103 | return 0; |
8104 | if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { |
8105 | // Handle initialization of captured loop iterator variables. |
8106 | auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); |
8107 | if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { |
8108 | Captures[DRE] = DRE; |
8109 | } |
8110 | } |
8111 | // Move on to the next nested for loop, or to the loop body. |
8112 | // OpenMP [2.8.1, simd construct, Restrictions] |
8113 | // All loops associated with the construct must be perfectly nested; that |
8114 | // is, there must be no intervening code nor any OpenMP directive between |
8115 | // any two loops. |
8116 | if (auto *For = dyn_cast<ForStmt>(CurStmt)) { |
8117 | CurStmt = For->getBody(); |
8118 | } else { |
8119 | assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8120, __PRETTY_FUNCTION__)) |
8120 | "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops." ) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8120, __PRETTY_FUNCTION__)); |
8121 | CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); |
8122 | } |
8123 | CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( |
8124 | CurStmt, SemaRef.LangOpts.OpenMP >= 50); |
8125 | } |
8126 | |
8127 | Built.clear(/* size */ NestedLoopCount); |
8128 | |
8129 | if (SemaRef.CurContext->isDependentContext()) |
8130 | return NestedLoopCount; |
8131 | |
8132 | // An example of what is generated for the following code: |
8133 | // |
8134 | // #pragma omp simd collapse(2) ordered(2) |
8135 | // for (i = 0; i < NI; ++i) |
8136 | // for (k = 0; k < NK; ++k) |
8137 | // for (j = J0; j < NJ; j+=2) { |
8138 | // <loop body> |
8139 | // } |
8140 | // |
8141 | // We generate the code below. |
8142 | // Note: the loop body may be outlined in CodeGen. |
8143 | // Note: some counters may be C++ classes, operator- is used to find number of |
8144 | // iterations and operator+= to calculate counter value. |
8145 | // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 |
8146 | // or i64 is currently supported). |
8147 | // |
8148 | // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) |
8149 | // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { |
8150 | // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); |
8151 | // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; |
8152 | // // similar updates for vars in clauses (e.g. 'linear') |
8153 | // <loop body (using local i and j)> |
8154 | // } |
8155 | // i = NI; // assign final values of counters |
8156 | // j = NJ; |
8157 | // |
8158 | |
8159 | // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are |
8160 | // the iteration counts of the collapsed for loops. |
8161 | // Precondition tests if there is at least one iteration (all conditions are |
8162 | // true). |
8163 | auto PreCond = ExprResult(IterSpaces[0].PreCond); |
8164 | Expr *N0 = IterSpaces[0].NumIterations; |
8165 | ExprResult LastIteration32 = |
8166 | widenIterationCount(/*Bits=*/32, |
8167 | SemaRef |
8168 | .PerformImplicitConversion( |
8169 | N0->IgnoreImpCasts(), N0->getType(), |
8170 | Sema::AA_Converting, /*AllowExplicit=*/true) |
8171 | .get(), |
8172 | SemaRef); |
8173 | ExprResult LastIteration64 = widenIterationCount( |
8174 | /*Bits=*/64, |
8175 | SemaRef |
8176 | .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), |
8177 | Sema::AA_Converting, |
8178 | /*AllowExplicit=*/true) |
8179 | .get(), |
8180 | SemaRef); |
8181 | |
8182 | if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) |
8183 | return NestedLoopCount; |
8184 | |
8185 | ASTContext &C = SemaRef.Context; |
8186 | bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; |
8187 | |
8188 | Scope *CurScope = DSA.getCurScope(); |
8189 | for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { |
8190 | if (PreCond.isUsable()) { |
8191 | PreCond = |
8192 | SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, |
8193 | PreCond.get(), IterSpaces[Cnt].PreCond); |
8194 | } |
8195 | Expr *N = IterSpaces[Cnt].NumIterations; |
8196 | SourceLocation Loc = N->getExprLoc(); |
8197 | AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; |
8198 | if (LastIteration32.isUsable()) |
8199 | LastIteration32 = SemaRef.BuildBinOp( |
8200 | CurScope, Loc, BO_Mul, LastIteration32.get(), |
8201 | SemaRef |
8202 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), |
8203 | Sema::AA_Converting, |
8204 | /*AllowExplicit=*/true) |
8205 | .get()); |
8206 | if (LastIteration64.isUsable()) |
8207 | LastIteration64 = SemaRef.BuildBinOp( |
8208 | CurScope, Loc, BO_Mul, LastIteration64.get(), |
8209 | SemaRef |
8210 | .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), |
8211 | Sema::AA_Converting, |
8212 | /*AllowExplicit=*/true) |
8213 | .get()); |
8214 | } |
8215 | |
8216 | // Choose either the 32-bit or 64-bit version. |
8217 | ExprResult LastIteration = LastIteration64; |
8218 | if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || |
8219 | (LastIteration32.isUsable() && |
8220 | C.getTypeSize(LastIteration32.get()->getType()) == 32 && |
8221 | (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || |
8222 | fitsInto( |
8223 | /*Bits=*/32, |
8224 | LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), |
8225 | LastIteration64.get(), SemaRef)))) |
8226 | LastIteration = LastIteration32; |
8227 | QualType VType = LastIteration.get()->getType(); |
8228 | QualType RealVType = VType; |
8229 | QualType StrideVType = VType; |
8230 | if (isOpenMPTaskLoopDirective(DKind)) { |
8231 | VType = |
8232 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); |
8233 | StrideVType = |
8234 | SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); |
8235 | } |
8236 | |
8237 | if (!LastIteration.isUsable()) |
8238 | return 0; |
8239 | |
8240 | // Save the number of iterations. |
8241 | ExprResult NumIterations = LastIteration; |
8242 | { |
8243 | LastIteration = SemaRef.BuildBinOp( |
8244 | CurScope, LastIteration.get()->getExprLoc(), BO_Sub, |
8245 | LastIteration.get(), |
8246 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); |
8247 | if (!LastIteration.isUsable()) |
8248 | return 0; |
8249 | } |
8250 | |
8251 | // Calculate the last iteration number beforehand instead of doing this on |
8252 | // each iteration. Do not do this if the number of iterations may be kfold-ed. |
8253 | bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); |
8254 | ExprResult CalcLastIteration; |
8255 | if (!IsConstant) { |
8256 | ExprResult SaveRef = |
8257 | tryBuildCapture(SemaRef, LastIteration.get(), Captures); |
8258 | LastIteration = SaveRef; |
8259 | |
8260 | // Prepare SaveRef + 1. |
8261 | NumIterations = SemaRef.BuildBinOp( |
8262 | CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), |
8263 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); |
8264 | if (!NumIterations.isUsable()) |
8265 | return 0; |
8266 | } |
8267 | |
8268 | SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); |
8269 | |
8270 | // Build variables passed into runtime, necessary for worksharing directives. |
8271 | ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; |
8272 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || |
8273 | isOpenMPDistributeDirective(DKind)) { |
8274 | // Lower bound variable, initialized with zero. |
8275 | VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); |
8276 | LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); |
8277 | SemaRef.AddInitializerToDecl(LBDecl, |
8278 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), |
8279 | /*DirectInit*/ false); |
8280 | |
8281 | // Upper bound variable, initialized with last iteration number. |
8282 | VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); |
8283 | UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); |
8284 | SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), |
8285 | /*DirectInit*/ false); |
8286 | |
8287 | // A 32-bit variable-flag where runtime returns 1 for the last iteration. |
8288 | // This will be used to implement clause 'lastprivate'. |
8289 | QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); |
8290 | VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); |
8291 | IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); |
8292 | SemaRef.AddInitializerToDecl(ILDecl, |
8293 | SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), |
8294 | /*DirectInit*/ false); |
8295 | |
8296 | // Stride variable returned by runtime (we initialize it to 1 by default). |
8297 | VarDecl *STDecl = |
8298 | buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); |
8299 | ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); |
8300 | SemaRef.AddInitializerToDecl(STDecl, |
8301 | SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), |
8302 | /*DirectInit*/ false); |
8303 | |
8304 | // Build expression: UB = min(UB, LastIteration) |
8305 | // It is necessary for CodeGen of directives with static scheduling. |
8306 | ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, |
8307 | UB.get(), LastIteration.get()); |
8308 | ExprResult CondOp = SemaRef.ActOnConditionalOp( |
8309 | LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), |
8310 | LastIteration.get(), UB.get()); |
8311 | EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), |
8312 | CondOp.get()); |
8313 | EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); |
8314 | |
8315 | // If we have a combined directive that combines 'distribute', 'for' or |
8316 | // 'simd' we need to be able to access the bounds of the schedule of the |
8317 | // enclosing region. E.g. in 'distribute parallel for' the bounds obtained |
8318 | // by scheduling 'distribute' have to be passed to the schedule of 'for'. |
8319 | if (isOpenMPLoopBoundSharingDirective(DKind)) { |
8320 | // Lower bound variable, initialized with zero. |
8321 | VarDecl *CombLBDecl = |
8322 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); |
8323 | CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); |
8324 | SemaRef.AddInitializerToDecl( |
8325 | CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), |
8326 | /*DirectInit*/ false); |
8327 | |
8328 | // Upper bound variable, initialized with last iteration number. |
8329 | VarDecl *CombUBDecl = |
8330 | buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); |
8331 | CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); |
8332 | SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), |
8333 | /*DirectInit*/ false); |
8334 | |
8335 | ExprResult CombIsUBGreater = SemaRef.BuildBinOp( |
8336 | CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); |
8337 | ExprResult CombCondOp = |
8338 | SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), |
8339 | LastIteration.get(), CombUB.get()); |
8340 | CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), |
8341 | CombCondOp.get()); |
8342 | CombEUB = |
8343 | SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); |
8344 | |
8345 | const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); |
8346 | // We expect to have at least 2 more parameters than the 'parallel' |
8347 | // directive does - the lower and upper bounds of the previous schedule. |
8348 | assert(CD->getNumParams() >= 4 &&((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive" ) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8349, __PRETTY_FUNCTION__)) |
8349 | "Unexpected number of parameters in loop combined directive")((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive" ) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8349, __PRETTY_FUNCTION__)); |
8350 | |
8351 | // Set the proper type for the bounds given what we learned from the |
8352 | // enclosed loops. |
8353 | ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); |
8354 | ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); |
8355 | |
8356 | // Previous lower and upper bounds are obtained from the region |
8357 | // parameters. |
8358 | PrevLB = |
8359 | buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); |
8360 | PrevUB = |
8361 | buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); |
8362 | } |
8363 | } |
8364 | |
8365 | // Build the iteration variable and its initialization before loop. |
8366 | ExprResult IV; |
8367 | ExprResult Init, CombInit; |
8368 | { |
8369 | VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); |
8370 | IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); |
8371 | Expr *RHS = |
8372 | (isOpenMPWorksharingDirective(DKind) || |
8373 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) |
8374 | ? LB.get() |
8375 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); |
8376 | Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); |
8377 | Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); |
8378 | |
8379 | if (isOpenMPLoopBoundSharingDirective(DKind)) { |
8380 | Expr *CombRHS = |
8381 | (isOpenMPWorksharingDirective(DKind) || |
8382 | isOpenMPTaskLoopDirective(DKind) || |
8383 | isOpenMPDistributeDirective(DKind)) |
8384 | ? CombLB.get() |
8385 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); |
8386 | CombInit = |
8387 | SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); |
8388 | CombInit = |
8389 | SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); |
8390 | } |
8391 | } |
8392 | |
8393 | bool UseStrictCompare = |
8394 | RealVType->hasUnsignedIntegerRepresentation() && |
8395 | llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { |
8396 | return LIS.IsStrictCompare; |
8397 | }); |
8398 | // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for |
8399 | // unsigned IV)) for worksharing loops. |
8400 | SourceLocation CondLoc = AStmt->getBeginLoc(); |
8401 | Expr *BoundUB = UB.get(); |
8402 | if (UseStrictCompare) { |
8403 | BoundUB = |
8404 | SemaRef |
8405 | .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, |
8406 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) |
8407 | .get(); |
8408 | BoundUB = |
8409 | SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); |
8410 | } |
8411 | ExprResult Cond = |
8412 | (isOpenMPWorksharingDirective(DKind) || |
8413 | isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) |
8414 | ? SemaRef.BuildBinOp(CurScope, CondLoc, |
8415 | UseStrictCompare ? BO_LT : BO_LE, IV.get(), |
8416 | BoundUB) |
8417 | : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), |
8418 | NumIterations.get()); |
8419 | ExprResult CombDistCond; |
8420 | if (isOpenMPLoopBoundSharingDirective(DKind)) { |
8421 | CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), |
8422 | NumIterations.get()); |
8423 | } |
8424 | |
8425 | ExprResult CombCond; |
8426 | if (isOpenMPLoopBoundSharingDirective(DKind)) { |
8427 | Expr *BoundCombUB = CombUB.get(); |
8428 | if (UseStrictCompare) { |
8429 | BoundCombUB = |
8430 | SemaRef |
8431 | .BuildBinOp( |
8432 | CurScope, CondLoc, BO_Add, BoundCombUB, |
8433 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) |
8434 | .get(); |
8435 | BoundCombUB = |
8436 | SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) |
8437 | .get(); |
8438 | } |
8439 | CombCond = |
8440 | SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, |
8441 | IV.get(), BoundCombUB); |
8442 | } |
8443 | // Loop increment (IV = IV + 1) |
8444 | SourceLocation IncLoc = AStmt->getBeginLoc(); |
8445 | ExprResult Inc = |
8446 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), |
8447 | SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); |
8448 | if (!Inc.isUsable()) |
8449 | return 0; |
8450 | Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); |
8451 | Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); |
8452 | if (!Inc.isUsable()) |
8453 | return 0; |
8454 | |
8455 | // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). |
8456 | // Used for directives with static scheduling. |
8457 | // In combined construct, add combined version that use CombLB and CombUB |
8458 | // base variables for the update |
8459 | ExprResult NextLB, NextUB, CombNextLB, CombNextUB; |
8460 | if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || |
8461 | isOpenMPDistributeDirective(DKind)) { |
8462 | // LB + ST |
8463 | NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); |
8464 | if (!NextLB.isUsable()) |
8465 | return 0; |
8466 | // LB = LB + ST |
8467 | NextLB = |
8468 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); |
8469 | NextLB = |
8470 | SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); |
8471 | if (!NextLB.isUsable()) |
8472 | return 0; |
8473 | // UB + ST |
8474 | NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); |
8475 | if (!NextUB.isUsable()) |
8476 | return 0; |
8477 | // UB = UB + ST |
8478 | NextUB = |
8479 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); |
8480 | NextUB = |
8481 | SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); |
8482 | if (!NextUB.isUsable()) |
8483 | return 0; |
8484 | if (isOpenMPLoopBoundSharingDirective(DKind)) { |
8485 | CombNextLB = |
8486 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); |
8487 | if (!NextLB.isUsable()) |
8488 | return 0; |
8489 | // LB = LB + ST |
8490 | CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), |
8491 | CombNextLB.get()); |
8492 | CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), |
8493 | /*DiscardedValue*/ false); |
8494 | if (!CombNextLB.isUsable()) |
8495 | return 0; |
8496 | // UB + ST |
8497 | CombNextUB = |
8498 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); |
8499 | if (!CombNextUB.isUsable()) |
8500 | return 0; |
8501 | // UB = UB + ST |
8502 | CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), |
8503 | CombNextUB.get()); |
8504 | CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), |
8505 | /*DiscardedValue*/ false); |
8506 | if (!CombNextUB.isUsable()) |
8507 | return 0; |
8508 | } |
8509 | } |
8510 | |
8511 | // Create increment expression for distribute loop when combined in a same |
8512 | // directive with for as IV = IV + ST; ensure upper bound expression based |
8513 | // on PrevUB instead of NumIterations - used to implement 'for' when found |
8514 | // in combination with 'distribute', like in 'distribute parallel for' |
8515 | SourceLocation DistIncLoc = AStmt->getBeginLoc(); |
8516 | ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; |
8517 | if (isOpenMPLoopBoundSharingDirective(DKind)) { |
8518 | DistCond = SemaRef.BuildBinOp( |
8519 | CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); |
8520 | assert(DistCond.isUsable() && "distribute cond expr was not built")((DistCond.isUsable() && "distribute cond expr was not built" ) ? static_cast<void> (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8520, __PRETTY_FUNCTION__)); |
8521 | |
8522 | DistInc = |
8523 | SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); |
8524 | assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built" ) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8524, __PRETTY_FUNCTION__)); |
8525 | DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), |
8526 | DistInc.get()); |
8527 | DistInc = |
8528 | SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); |
8529 | assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built" ) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8529, __PRETTY_FUNCTION__)); |
8530 | |
8531 | // Build expression: UB = min(UB, prevUB) for #for in composite or combined |
8532 | // construct |
8533 | SourceLocation DistEUBLoc = AStmt->getBeginLoc(); |
8534 | ExprResult IsUBGreater = |
8535 | SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); |
8536 | ExprResult CondOp = SemaRef.ActOnConditionalOp( |
8537 | DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); |
8538 | PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), |
8539 | CondOp.get()); |
8540 | PrevEUB = |
8541 | SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); |
8542 | |
8543 | // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in |
8544 | // parallel for is in combination with a distribute directive with |
8545 | // schedule(static, 1) |
8546 | Expr *BoundPrevUB = PrevUB.get(); |
8547 | if (UseStrictCompare) { |
8548 | BoundPrevUB = |
8549 | SemaRef |
8550 | .BuildBinOp( |
8551 | CurScope, CondLoc, BO_Add, BoundPrevUB, |
8552 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) |
8553 | .get(); |
8554 | BoundPrevUB = |
8555 | SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) |
8556 | .get(); |
8557 | } |
8558 | ParForInDistCond = |
8559 | SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, |
8560 | IV.get(), BoundPrevUB); |
8561 | } |
8562 | |
8563 | // Build updates and final values of the loop counters. |
8564 | bool HasErrors = false; |
8565 | Built.Counters.resize(NestedLoopCount); |
8566 | Built.Inits.resize(NestedLoopCount); |
8567 | Built.Updates.resize(NestedLoopCount); |
8568 | Built.Finals.resize(NestedLoopCount); |
8569 | Built.DependentCounters.resize(NestedLoopCount); |
8570 | Built.DependentInits.resize(NestedLoopCount); |
8571 | Built.FinalsConditions.resize(NestedLoopCount); |
8572 | { |
8573 | // We implement the following algorithm for obtaining the |
8574 | // original loop iteration variable values based on the |
8575 | // value of the collapsed loop iteration variable IV. |
8576 | // |
8577 | // Let n+1 be the number of collapsed loops in the nest. |
8578 | // Iteration variables (I0, I1, .... In) |
8579 | // Iteration counts (N0, N1, ... Nn) |
8580 | // |
8581 | // Acc = IV; |
8582 | // |
8583 | // To compute Ik for loop k, 0 <= k <= n, generate: |
8584 | // Prod = N(k+1) * N(k+2) * ... * Nn; |
8585 | // Ik = Acc / Prod; |
8586 | // Acc -= Ik * Prod; |
8587 | // |
8588 | ExprResult Acc = IV; |
8589 | for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { |
8590 | LoopIterationSpace &IS = IterSpaces[Cnt]; |
8591 | SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); |
8592 | ExprResult Iter; |
8593 | |
8594 | // Compute prod |
8595 | ExprResult Prod = |
8596 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); |
8597 | for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) |
8598 | Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), |
8599 | IterSpaces[K].NumIterations); |
8600 | |
8601 | // Iter = Acc / Prod |
8602 | // If there is at least one more inner loop to avoid |
8603 | // multiplication by 1. |
8604 | if (Cnt + 1 < NestedLoopCount) |
8605 | Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, |
8606 | Acc.get(), Prod.get()); |
8607 | else |
8608 | Iter = Acc; |
8609 | if (!Iter.isUsable()) { |
8610 | HasErrors = true; |
8611 | break; |
8612 | } |
8613 | |
8614 | // Update Acc: |
8615 | // Acc -= Iter * Prod |
8616 | // Check if there is at least one more inner loop to avoid |
8617 | // multiplication by 1. |
8618 | if (Cnt + 1 < NestedLoopCount) |
8619 | Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, |
8620 | Iter.get(), Prod.get()); |
8621 | else |
8622 | Prod = Iter; |
8623 | Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, |
8624 | Acc.get(), Prod.get()); |
8625 | |
8626 | // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step |
8627 | auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); |
8628 | DeclRefExpr *CounterVar = buildDeclRefExpr( |
8629 | SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), |
8630 | /*RefersToCapture=*/true); |
8631 | ExprResult Init = |
8632 | buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, |
8633 | IS.CounterInit, IS.IsNonRectangularLB, Captures); |
8634 | if (!Init.isUsable()) { |
8635 | HasErrors = true; |
8636 | break; |
8637 | } |
8638 | ExprResult Update = buildCounterUpdate( |
8639 | SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, |
8640 | IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); |
8641 | if (!Update.isUsable()) { |
8642 | HasErrors = true; |
8643 | break; |
8644 | } |
8645 | |
8646 | // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step |
8647 | ExprResult Final = |
8648 | buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, |
8649 | IS.CounterInit, IS.NumIterations, IS.CounterStep, |
8650 | IS.Subtract, IS.IsNonRectangularLB, &Captures); |
8651 | if (!Final.isUsable()) { |
8652 | HasErrors = true; |
8653 | break; |
8654 | } |
8655 | |
8656 | if (!Update.isUsable() || !Final.isUsable()) { |
8657 | HasErrors = true; |
8658 | break; |
8659 | } |
8660 | // Save results |
8661 | Built.Counters[Cnt] = IS.CounterVar; |
8662 | Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; |
8663 | Built.Inits[Cnt] = Init.get(); |
8664 | Built.Updates[Cnt] = Update.get(); |
8665 | Built.Finals[Cnt] = Final.get(); |
8666 | Built.DependentCounters[Cnt] = nullptr; |
8667 | Built.DependentInits[Cnt] = nullptr; |
8668 | Built.FinalsConditions[Cnt] = nullptr; |
8669 | if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { |
8670 | Built.DependentCounters[Cnt] = |
8671 | Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; |
8672 | Built.DependentInits[Cnt] = |
8673 | Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; |
8674 | Built.FinalsConditions[Cnt] = IS.FinalCondition; |
8675 | } |
8676 | } |
8677 | } |
8678 | |
8679 | if (HasErrors) |
8680 | return 0; |
8681 | |
8682 | // Save results |
8683 | Built.IterationVarRef = IV.get(); |
8684 | Built.LastIteration = LastIteration.get(); |
8685 | Built.NumIterations = NumIterations.get(); |
8686 | Built.CalcLastIteration = SemaRef |
8687 | .ActOnFinishFullExpr(CalcLastIteration.get(), |
8688 | /*DiscardedValue=*/false) |
8689 | .get(); |
8690 | Built.PreCond = PreCond.get(); |
8691 | Built.PreInits = buildPreInits(C, Captures); |
8692 | Built.Cond = Cond.get(); |
8693 | Built.Init = Init.get(); |
8694 | Built.Inc = Inc.get(); |
8695 | Built.LB = LB.get(); |
8696 | Built.UB = UB.get(); |
8697 | Built.IL = IL.get(); |
8698 | Built.ST = ST.get(); |
8699 | Built.EUB = EUB.get(); |
8700 | Built.NLB = NextLB.get(); |
8701 | Built.NUB = NextUB.get(); |
8702 | Built.PrevLB = PrevLB.get(); |
8703 | Built.PrevUB = PrevUB.get(); |
8704 | Built.DistInc = DistInc.get(); |
8705 | Built.PrevEUB = PrevEUB.get(); |
8706 | Built.DistCombinedFields.LB = CombLB.get(); |
8707 | Built.DistCombinedFields.UB = CombUB.get(); |
8708 | Built.DistCombinedFields.EUB = CombEUB.get(); |
8709 | Built.DistCombinedFields.Init = CombInit.get(); |
8710 | Built.DistCombinedFields.Cond = CombCond.get(); |
8711 | Built.DistCombinedFields.NLB = CombNextLB.get(); |
8712 | Built.DistCombinedFields.NUB = CombNextUB.get(); |
8713 | Built.DistCombinedFields.DistCond = CombDistCond.get(); |
8714 | Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); |
8715 | |
8716 | return NestedLoopCount; |
8717 | } |
8718 | |
8719 | static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { |
8720 | auto CollapseClauses = |
8721 | OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); |
8722 | if (CollapseClauses.begin() != CollapseClauses.end()) |
8723 | return (*CollapseClauses.begin())->getNumForLoops(); |
8724 | return nullptr; |
8725 | } |
8726 | |
8727 | static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { |
8728 | auto OrderedClauses = |
8729 | OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); |
8730 | if (OrderedClauses.begin() != OrderedClauses.end()) |
8731 | return (*OrderedClauses.begin())->getNumForLoops(); |
8732 | return nullptr; |
8733 | } |
8734 | |
8735 | static bool checkSimdlenSafelenSpecified(Sema &S, |
8736 | const ArrayRef<OMPClause *> Clauses) { |
8737 | const OMPSafelenClause *Safelen = nullptr; |
8738 | const OMPSimdlenClause *Simdlen = nullptr; |
8739 | |
8740 | for (const OMPClause *Clause : Clauses) { |
8741 | if (Clause->getClauseKind() == OMPC_safelen) |
8742 | Safelen = cast<OMPSafelenClause>(Clause); |
8743 | else if (Clause->getClauseKind() == OMPC_simdlen) |
8744 | Simdlen = cast<OMPSimdlenClause>(Clause); |
8745 | if (Safelen && Simdlen) |
8746 | break; |
8747 | } |
8748 | |
8749 | if (Simdlen && Safelen) { |
8750 | const Expr *SimdlenLength = Simdlen->getSimdlen(); |
8751 | const Expr *SafelenLength = Safelen->getSafelen(); |
8752 | if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || |
8753 | SimdlenLength->isInstantiationDependent() || |
8754 | SimdlenLength->containsUnexpandedParameterPack()) |
8755 | return false; |
8756 | if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || |
8757 | SafelenLength->isInstantiationDependent() || |
8758 | SafelenLength->containsUnexpandedParameterPack()) |
8759 | return false; |
8760 | Expr::EvalResult SimdlenResult, SafelenResult; |
8761 | SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); |
8762 | SafelenLength->EvaluateAsInt(SafelenResult, S.Context); |
8763 | llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); |
8764 | llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); |
8765 | // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] |
8766 | // If both simdlen and safelen clauses are specified, the value of the |
8767 | // simdlen parameter must be less than or equal to the value of the safelen |
8768 | // parameter. |
8769 | if (SimdlenRes > SafelenRes) { |
8770 | S.Diag(SimdlenLength->getExprLoc(), |
8771 | diag::err_omp_wrong_simdlen_safelen_values) |
8772 | << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); |
8773 | return true; |
8774 | } |
8775 | } |
8776 | return false; |
8777 | } |
8778 | |
8779 | StmtResult |
8780 | Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
8781 | SourceLocation StartLoc, SourceLocation EndLoc, |
8782 | VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
8783 | if (!AStmt) |
8784 | return StmtError(); |
8785 | |
8786 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8786, __PRETTY_FUNCTION__)); |
8787 | OMPLoopDirective::HelperExprs B; |
8788 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
8789 | // define the nested loops number. |
8790 | unsigned NestedLoopCount = checkOpenMPLoop( |
8791 | OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), |
8792 | AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); |
8793 | if (NestedLoopCount == 0) |
8794 | return StmtError(); |
8795 | |
8796 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp simd loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8797, __PRETTY_FUNCTION__)) |
8797 | "omp simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp simd loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8797, __PRETTY_FUNCTION__)); |
8798 | |
8799 | if (!CurContext->isDependentContext()) { |
8800 | // Finalize the clauses that need pre-built expressions for CodeGen. |
8801 | for (OMPClause *C : Clauses) { |
8802 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
8803 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
8804 | B.NumIterations, *this, CurScope, |
8805 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
8806 | return StmtError(); |
8807 | } |
8808 | } |
8809 | |
8810 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
8811 | return StmtError(); |
8812 | |
8813 | setFunctionHasBranchProtectedScope(); |
8814 | return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, |
8815 | Clauses, AStmt, B); |
8816 | } |
8817 | |
8818 | StmtResult |
8819 | Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, |
8820 | SourceLocation StartLoc, SourceLocation EndLoc, |
8821 | VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
8822 | if (!AStmt) |
8823 | return StmtError(); |
8824 | |
8825 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8825, __PRETTY_FUNCTION__)); |
8826 | OMPLoopDirective::HelperExprs B; |
8827 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
8828 | // define the nested loops number. |
8829 | unsigned NestedLoopCount = checkOpenMPLoop( |
8830 | OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), |
8831 | AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); |
8832 | if (NestedLoopCount == 0) |
8833 | return StmtError(); |
8834 | |
8835 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8836, __PRETTY_FUNCTION__)) |
8836 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8836, __PRETTY_FUNCTION__)); |
8837 | |
8838 | if (!CurContext->isDependentContext()) { |
8839 | // Finalize the clauses that need pre-built expressions for CodeGen. |
8840 | for (OMPClause *C : Clauses) { |
8841 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
8842 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
8843 | B.NumIterations, *this, CurScope, |
8844 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
8845 | return StmtError(); |
8846 | } |
8847 | } |
8848 | |
8849 | setFunctionHasBranchProtectedScope(); |
8850 | return OMPForDirective::Create( |
8851 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
8852 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
8853 | } |
8854 | |
8855 | StmtResult Sema::ActOnOpenMPForSimdDirective( |
8856 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
8857 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
8858 | if (!AStmt) |
8859 | return StmtError(); |
8860 | |
8861 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8861, __PRETTY_FUNCTION__)); |
8862 | OMPLoopDirective::HelperExprs B; |
8863 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
8864 | // define the nested loops number. |
8865 | unsigned NestedLoopCount = |
8866 | checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), |
8867 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
8868 | VarsWithImplicitDSA, B); |
8869 | if (NestedLoopCount == 0) |
8870 | return StmtError(); |
8871 | |
8872 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for simd loop exprs were not built") ? static_cast<void > (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8873, __PRETTY_FUNCTION__)) |
8873 | "omp for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for simd loop exprs were not built") ? static_cast<void > (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8873, __PRETTY_FUNCTION__)); |
8874 | |
8875 | if (!CurContext->isDependentContext()) { |
8876 | // Finalize the clauses that need pre-built expressions for CodeGen. |
8877 | for (OMPClause *C : Clauses) { |
8878 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
8879 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
8880 | B.NumIterations, *this, CurScope, |
8881 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
8882 | return StmtError(); |
8883 | } |
8884 | } |
8885 | |
8886 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
8887 | return StmtError(); |
8888 | |
8889 | setFunctionHasBranchProtectedScope(); |
8890 | return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, |
8891 | Clauses, AStmt, B); |
8892 | } |
8893 | |
8894 | StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, |
8895 | Stmt *AStmt, |
8896 | SourceLocation StartLoc, |
8897 | SourceLocation EndLoc) { |
8898 | if (!AStmt) |
8899 | return StmtError(); |
8900 | |
8901 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8901, __PRETTY_FUNCTION__)); |
8902 | auto BaseStmt = AStmt; |
8903 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) |
8904 | BaseStmt = CS->getCapturedStmt(); |
8905 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { |
8906 | auto S = C->children(); |
8907 | if (S.begin() == S.end()) |
8908 | return StmtError(); |
8909 | // All associated statements must be '#pragma omp section' except for |
8910 | // the first one. |
8911 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { |
8912 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { |
8913 | if (SectionStmt) |
8914 | Diag(SectionStmt->getBeginLoc(), |
8915 | diag::err_omp_sections_substmt_not_section); |
8916 | return StmtError(); |
8917 | } |
8918 | cast<OMPSectionDirective>(SectionStmt) |
8919 | ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
8920 | } |
8921 | } else { |
8922 | Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); |
8923 | return StmtError(); |
8924 | } |
8925 | |
8926 | setFunctionHasBranchProtectedScope(); |
8927 | |
8928 | return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
8929 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), |
8930 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
8931 | } |
8932 | |
8933 | StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, |
8934 | SourceLocation StartLoc, |
8935 | SourceLocation EndLoc) { |
8936 | if (!AStmt) |
8937 | return StmtError(); |
8938 | |
8939 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8939, __PRETTY_FUNCTION__)); |
8940 | |
8941 | setFunctionHasBranchProtectedScope(); |
8942 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
8943 | |
8944 | return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, |
8945 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
8946 | } |
8947 | |
8948 | StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, |
8949 | Stmt *AStmt, |
8950 | SourceLocation StartLoc, |
8951 | SourceLocation EndLoc) { |
8952 | if (!AStmt) |
8953 | return StmtError(); |
8954 | |
8955 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8955, __PRETTY_FUNCTION__)); |
8956 | |
8957 | setFunctionHasBranchProtectedScope(); |
8958 | |
8959 | // OpenMP [2.7.3, single Construct, Restrictions] |
8960 | // The copyprivate clause must not be used with the nowait clause. |
8961 | const OMPClause *Nowait = nullptr; |
8962 | const OMPClause *Copyprivate = nullptr; |
8963 | for (const OMPClause *Clause : Clauses) { |
8964 | if (Clause->getClauseKind() == OMPC_nowait) |
8965 | Nowait = Clause; |
8966 | else if (Clause->getClauseKind() == OMPC_copyprivate) |
8967 | Copyprivate = Clause; |
8968 | if (Copyprivate && Nowait) { |
8969 | Diag(Copyprivate->getBeginLoc(), |
8970 | diag::err_omp_single_copyprivate_with_nowait); |
8971 | Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); |
8972 | return StmtError(); |
8973 | } |
8974 | } |
8975 | |
8976 | return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); |
8977 | } |
8978 | |
8979 | StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, |
8980 | SourceLocation StartLoc, |
8981 | SourceLocation EndLoc) { |
8982 | if (!AStmt) |
8983 | return StmtError(); |
8984 | |
8985 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8985, __PRETTY_FUNCTION__)); |
8986 | |
8987 | setFunctionHasBranchProtectedScope(); |
8988 | |
8989 | return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); |
8990 | } |
8991 | |
8992 | StmtResult Sema::ActOnOpenMPCriticalDirective( |
8993 | const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, |
8994 | Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { |
8995 | if (!AStmt) |
8996 | return StmtError(); |
8997 | |
8998 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 8998, __PRETTY_FUNCTION__)); |
8999 | |
9000 | bool ErrorFound = false; |
9001 | llvm::APSInt Hint; |
9002 | SourceLocation HintLoc; |
9003 | bool DependentHint = false; |
9004 | for (const OMPClause *C : Clauses) { |
9005 | if (C->getClauseKind() == OMPC_hint) { |
9006 | if (!DirName.getName()) { |
9007 | Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); |
9008 | ErrorFound = true; |
9009 | } |
9010 | Expr *E = cast<OMPHintClause>(C)->getHint(); |
9011 | if (E->isTypeDependent() || E->isValueDependent() || |
9012 | E->isInstantiationDependent()) { |
9013 | DependentHint = true; |
9014 | } else { |
9015 | Hint = E->EvaluateKnownConstInt(Context); |
9016 | HintLoc = C->getBeginLoc(); |
9017 | } |
9018 | } |
9019 | } |
9020 | if (ErrorFound) |
9021 | return StmtError(); |
9022 | const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCriticalWithHint(DirName); |
9023 | if (Pair.first && DirName.getName() && !DependentHint) { |
9024 | if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { |
9025 | Diag(StartLoc, diag::err_omp_critical_with_hint); |
9026 | if (HintLoc.isValid()) |
9027 | Diag(HintLoc, diag::note_omp_critical_hint_here) |
9028 | << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); |
9029 | else |
9030 | Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; |
9031 | if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { |
9032 | Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) |
9033 | << 1 |
9034 | << C->getHint()->EvaluateKnownConstInt(Context).toString( |
9035 | /*Radix=*/10, /*Signed=*/false); |
9036 | } else { |
9037 | Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; |
9038 | } |
9039 | } |
9040 | } |
9041 | |
9042 | setFunctionHasBranchProtectedScope(); |
9043 | |
9044 | auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, |
9045 | Clauses, AStmt); |
9046 | if (!Pair.first && DirName.getName() && !DependentHint) |
9047 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addCriticalWithHint(Dir, Hint); |
9048 | return Dir; |
9049 | } |
9050 | |
9051 | StmtResult Sema::ActOnOpenMPParallelForDirective( |
9052 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
9053 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
9054 | if (!AStmt) |
9055 | return StmtError(); |
9056 | |
9057 | auto *CS = cast<CapturedStmt>(AStmt); |
9058 | // 1.2.2 OpenMP Language Terminology |
9059 | // Structured block - An executable statement with a single entry at the |
9060 | // top and a single exit at the bottom. |
9061 | // The point of exit cannot be a branch out of the structured block. |
9062 | // longjmp() and throw() must not violate the entry/exit criteria. |
9063 | CS->getCapturedDecl()->setNothrow(); |
9064 | |
9065 | OMPLoopDirective::HelperExprs B; |
9066 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
9067 | // define the nested loops number. |
9068 | unsigned NestedLoopCount = |
9069 | checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), |
9070 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
9071 | VarsWithImplicitDSA, B); |
9072 | if (NestedLoopCount == 0) |
9073 | return StmtError(); |
9074 | |
9075 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp parallel for loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9076, __PRETTY_FUNCTION__)) |
9076 | "omp parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp parallel for loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9076, __PRETTY_FUNCTION__)); |
9077 | |
9078 | if (!CurContext->isDependentContext()) { |
9079 | // Finalize the clauses that need pre-built expressions for CodeGen. |
9080 | for (OMPClause *C : Clauses) { |
9081 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
9082 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
9083 | B.NumIterations, *this, CurScope, |
9084 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
9085 | return StmtError(); |
9086 | } |
9087 | } |
9088 | |
9089 | setFunctionHasBranchProtectedScope(); |
9090 | return OMPParallelForDirective::Create( |
9091 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
9092 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
9093 | } |
9094 | |
9095 | StmtResult Sema::ActOnOpenMPParallelForSimdDirective( |
9096 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
9097 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
9098 | if (!AStmt) |
9099 | return StmtError(); |
9100 | |
9101 | auto *CS = cast<CapturedStmt>(AStmt); |
9102 | // 1.2.2 OpenMP Language Terminology |
9103 | // Structured block - An executable statement with a single entry at the |
9104 | // top and a single exit at the bottom. |
9105 | // The point of exit cannot be a branch out of the structured block. |
9106 | // longjmp() and throw() must not violate the entry/exit criteria. |
9107 | CS->getCapturedDecl()->setNothrow(); |
9108 | |
9109 | OMPLoopDirective::HelperExprs B; |
9110 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
9111 | // define the nested loops number. |
9112 | unsigned NestedLoopCount = |
9113 | checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), |
9114 | getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
9115 | VarsWithImplicitDSA, B); |
9116 | if (NestedLoopCount == 0) |
9117 | return StmtError(); |
9118 | |
9119 | if (!CurContext->isDependentContext()) { |
9120 | // Finalize the clauses that need pre-built expressions for CodeGen. |
9121 | for (OMPClause *C : Clauses) { |
9122 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
9123 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
9124 | B.NumIterations, *this, CurScope, |
9125 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
9126 | return StmtError(); |
9127 | } |
9128 | } |
9129 | |
9130 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
9131 | return StmtError(); |
9132 | |
9133 | setFunctionHasBranchProtectedScope(); |
9134 | return OMPParallelForSimdDirective::Create( |
9135 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
9136 | } |
9137 | |
9138 | StmtResult |
9139 | Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, |
9140 | Stmt *AStmt, SourceLocation StartLoc, |
9141 | SourceLocation EndLoc) { |
9142 | if (!AStmt) |
9143 | return StmtError(); |
9144 | |
9145 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9145, __PRETTY_FUNCTION__)); |
9146 | auto *CS = cast<CapturedStmt>(AStmt); |
9147 | // 1.2.2 OpenMP Language Terminology |
9148 | // Structured block - An executable statement with a single entry at the |
9149 | // top and a single exit at the bottom. |
9150 | // The point of exit cannot be a branch out of the structured block. |
9151 | // longjmp() and throw() must not violate the entry/exit criteria. |
9152 | CS->getCapturedDecl()->setNothrow(); |
9153 | |
9154 | setFunctionHasBranchProtectedScope(); |
9155 | |
9156 | return OMPParallelMasterDirective::Create( |
9157 | Context, StartLoc, EndLoc, Clauses, AStmt, |
9158 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef()); |
9159 | } |
9160 | |
9161 | StmtResult |
9162 | Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, |
9163 | Stmt *AStmt, SourceLocation StartLoc, |
9164 | SourceLocation EndLoc) { |
9165 | if (!AStmt) |
9166 | return StmtError(); |
9167 | |
9168 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9168, __PRETTY_FUNCTION__)); |
9169 | auto BaseStmt = AStmt; |
9170 | while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) |
9171 | BaseStmt = CS->getCapturedStmt(); |
9172 | if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { |
9173 | auto S = C->children(); |
9174 | if (S.begin() == S.end()) |
9175 | return StmtError(); |
9176 | // All associated statements must be '#pragma omp section' except for |
9177 | // the first one. |
9178 | for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { |
9179 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { |
9180 | if (SectionStmt) |
9181 | Diag(SectionStmt->getBeginLoc(), |
9182 | diag::err_omp_parallel_sections_substmt_not_section); |
9183 | return StmtError(); |
9184 | } |
9185 | cast<OMPSectionDirective>(SectionStmt) |
9186 | ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
9187 | } |
9188 | } else { |
9189 | Diag(AStmt->getBeginLoc(), |
9190 | diag::err_omp_parallel_sections_not_compound_stmt); |
9191 | return StmtError(); |
9192 | } |
9193 | |
9194 | setFunctionHasBranchProtectedScope(); |
9195 | |
9196 | return OMPParallelSectionsDirective::Create( |
9197 | Context, StartLoc, EndLoc, Clauses, AStmt, |
9198 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
9199 | } |
9200 | |
9201 | /// detach and mergeable clauses are mutially exclusive, check for it. |
9202 | static bool checkDetachMergeableClauses(Sema &S, |
9203 | ArrayRef<OMPClause *> Clauses) { |
9204 | const OMPClause *PrevClause = nullptr; |
9205 | bool ErrorFound = false; |
9206 | for (const OMPClause *C : Clauses) { |
9207 | if (C->getClauseKind() == OMPC_detach || |
9208 | C->getClauseKind() == OMPC_mergeable) { |
9209 | if (!PrevClause) { |
9210 | PrevClause = C; |
9211 | } else if (PrevClause->getClauseKind() != C->getClauseKind()) { |
9212 | S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) |
9213 | << getOpenMPClauseName(C->getClauseKind()) |
9214 | << getOpenMPClauseName(PrevClause->getClauseKind()); |
9215 | S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) |
9216 | << getOpenMPClauseName(PrevClause->getClauseKind()); |
9217 | ErrorFound = true; |
9218 | } |
9219 | } |
9220 | } |
9221 | return ErrorFound; |
9222 | } |
9223 | |
9224 | StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, |
9225 | Stmt *AStmt, SourceLocation StartLoc, |
9226 | SourceLocation EndLoc) { |
9227 | if (!AStmt) |
9228 | return StmtError(); |
9229 | |
9230 | // OpenMP 5.0, 2.10.1 task Construct |
9231 | // If a detach clause appears on the directive, then a mergeable clause cannot |
9232 | // appear on the same directive. |
9233 | if (checkDetachMergeableClauses(*this, Clauses)) |
9234 | return StmtError(); |
9235 | |
9236 | auto *CS = cast<CapturedStmt>(AStmt); |
9237 | // 1.2.2 OpenMP Language Terminology |
9238 | // Structured block - An executable statement with a single entry at the |
9239 | // top and a single exit at the bottom. |
9240 | // The point of exit cannot be a branch out of the structured block. |
9241 | // longjmp() and throw() must not violate the entry/exit criteria. |
9242 | CS->getCapturedDecl()->setNothrow(); |
9243 | |
9244 | setFunctionHasBranchProtectedScope(); |
9245 | |
9246 | return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
9247 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
9248 | } |
9249 | |
9250 | StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, |
9251 | SourceLocation EndLoc) { |
9252 | return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); |
9253 | } |
9254 | |
9255 | StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, |
9256 | SourceLocation EndLoc) { |
9257 | return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); |
9258 | } |
9259 | |
9260 | StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, |
9261 | SourceLocation EndLoc) { |
9262 | return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); |
9263 | } |
9264 | |
9265 | StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, |
9266 | Stmt *AStmt, |
9267 | SourceLocation StartLoc, |
9268 | SourceLocation EndLoc) { |
9269 | if (!AStmt) |
9270 | return StmtError(); |
9271 | |
9272 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9272, __PRETTY_FUNCTION__)); |
9273 | |
9274 | setFunctionHasBranchProtectedScope(); |
9275 | |
9276 | return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, |
9277 | AStmt, |
9278 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef()); |
9279 | } |
9280 | |
9281 | StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, |
9282 | SourceLocation StartLoc, |
9283 | SourceLocation EndLoc) { |
9284 | OMPFlushClause *FC = nullptr; |
9285 | OMPClause *OrderClause = nullptr; |
9286 | for (OMPClause *C : Clauses) { |
9287 | if (C->getClauseKind() == OMPC_flush) |
9288 | FC = cast<OMPFlushClause>(C); |
9289 | else |
9290 | OrderClause = C; |
9291 | } |
9292 | OpenMPClauseKind MemOrderKind = OMPC_unknown; |
9293 | SourceLocation MemOrderLoc; |
9294 | for (const OMPClause *C : Clauses) { |
9295 | if (C->getClauseKind() == OMPC_acq_rel || |
9296 | C->getClauseKind() == OMPC_acquire || |
9297 | C->getClauseKind() == OMPC_release) { |
9298 | if (MemOrderKind != OMPC_unknown) { |
9299 | Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) |
9300 | << getOpenMPDirectiveName(OMPD_flush) << 1 |
9301 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); |
9302 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) |
9303 | << getOpenMPClauseName(MemOrderKind); |
9304 | } else { |
9305 | MemOrderKind = C->getClauseKind(); |
9306 | MemOrderLoc = C->getBeginLoc(); |
9307 | } |
9308 | } |
9309 | } |
9310 | if (FC && OrderClause) { |
9311 | Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) |
9312 | << getOpenMPClauseName(OrderClause->getClauseKind()); |
9313 | Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) |
9314 | << getOpenMPClauseName(OrderClause->getClauseKind()); |
9315 | return StmtError(); |
9316 | } |
9317 | return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); |
9318 | } |
9319 | |
9320 | StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, |
9321 | SourceLocation StartLoc, |
9322 | SourceLocation EndLoc) { |
9323 | if (Clauses.empty()) { |
9324 | Diag(StartLoc, diag::err_omp_depobj_expected); |
9325 | return StmtError(); |
9326 | } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { |
9327 | Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); |
9328 | return StmtError(); |
9329 | } |
9330 | // Only depobj expression and another single clause is allowed. |
9331 | if (Clauses.size() > 2) { |
9332 | Diag(Clauses[2]->getBeginLoc(), |
9333 | diag::err_omp_depobj_single_clause_expected); |
9334 | return StmtError(); |
9335 | } else if (Clauses.size() < 1) { |
9336 | Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); |
9337 | return StmtError(); |
9338 | } |
9339 | return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); |
9340 | } |
9341 | |
9342 | StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, |
9343 | SourceLocation StartLoc, |
9344 | SourceLocation EndLoc) { |
9345 | // Check that exactly one clause is specified. |
9346 | if (Clauses.size() != 1) { |
9347 | Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), |
9348 | diag::err_omp_scan_single_clause_expected); |
9349 | return StmtError(); |
9350 | } |
9351 | // Check that scan directive is used in the scopeof the OpenMP loop body. |
9352 | if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope()) { |
9353 | Scope *ParentS = S->getParent(); |
9354 | if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || |
9355 | !ParentS->getBreakParent()->isOpenMPLoopScope()) |
9356 | return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) |
9357 | << getOpenMPDirectiveName(OMPD_scan) << 5); |
9358 | } |
9359 | // Check that only one instance of scan directives is used in the same outer |
9360 | // region. |
9361 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->doesParentHasScanDirective()) { |
9362 | Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; |
9363 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentScanDirectiveLoc(), |
9364 | diag::note_omp_previous_directive) |
9365 | << "scan"; |
9366 | return StmtError(); |
9367 | } |
9368 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentHasScanDirective(StartLoc); |
9369 | return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); |
9370 | } |
9371 | |
9372 | StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, |
9373 | Stmt *AStmt, |
9374 | SourceLocation StartLoc, |
9375 | SourceLocation EndLoc) { |
9376 | const OMPClause *DependFound = nullptr; |
9377 | const OMPClause *DependSourceClause = nullptr; |
9378 | const OMPClause *DependSinkClause = nullptr; |
9379 | bool ErrorFound = false; |
9380 | const OMPThreadsClause *TC = nullptr; |
9381 | const OMPSIMDClause *SC = nullptr; |
9382 | for (const OMPClause *C : Clauses) { |
9383 | if (auto *DC = dyn_cast<OMPDependClause>(C)) { |
9384 | DependFound = C; |
9385 | if (DC->getDependencyKind() == OMPC_DEPEND_source) { |
9386 | if (DependSourceClause) { |
9387 | Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) |
9388 | << getOpenMPDirectiveName(OMPD_ordered) |
9389 | << getOpenMPClauseName(OMPC_depend) << 2; |
9390 | ErrorFound = true; |
9391 | } else { |
9392 | DependSourceClause = C; |
9393 | } |
9394 | if (DependSinkClause) { |
9395 | Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) |
9396 | << 0; |
9397 | ErrorFound = true; |
9398 | } |
9399 | } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { |
9400 | if (DependSourceClause) { |
9401 | Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) |
9402 | << 1; |
9403 | ErrorFound = true; |
9404 | } |
9405 | DependSinkClause = C; |
9406 | } |
9407 | } else if (C->getClauseKind() == OMPC_threads) { |
9408 | TC = cast<OMPThreadsClause>(C); |
9409 | } else if (C->getClauseKind() == OMPC_simd) { |
9410 | SC = cast<OMPSIMDClause>(C); |
9411 | } |
9412 | } |
9413 | if (!ErrorFound && !SC && |
9414 | isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective())) { |
9415 | // OpenMP [2.8.1,simd Construct, Restrictions] |
9416 | // An ordered construct with the simd clause is the only OpenMP construct |
9417 | // that can appear in the simd region. |
9418 | Diag(StartLoc, diag::err_omp_prohibited_region_simd) |
9419 | << (LangOpts.OpenMP >= 50 ? 1 : 0); |
9420 | ErrorFound = true; |
9421 | } else if (DependFound && (TC || SC)) { |
9422 | Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) |
9423 | << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); |
9424 | ErrorFound = true; |
9425 | } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { |
9426 | Diag(DependFound->getBeginLoc(), |
9427 | diag::err_omp_ordered_directive_without_param); |
9428 | ErrorFound = true; |
9429 | } else if (TC || Clauses.empty()) { |
9430 | if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { |
9431 | SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; |
9432 | Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) |
9433 | << (TC != nullptr); |
9434 | Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; |
9435 | ErrorFound = true; |
9436 | } |
9437 | } |
9438 | if ((!AStmt && !DependFound) || ErrorFound) |
9439 | return StmtError(); |
9440 | |
9441 | // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. |
9442 | // During execution of an iteration of a worksharing-loop or a loop nest |
9443 | // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread |
9444 | // must not execute more than one ordered region corresponding to an ordered |
9445 | // construct without a depend clause. |
9446 | if (!DependFound) { |
9447 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->doesParentHasOrderedDirective()) { |
9448 | Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; |
9449 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedDirectiveLoc(), |
9450 | diag::note_omp_previous_directive) |
9451 | << "ordered"; |
9452 | return StmtError(); |
9453 | } |
9454 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentHasOrderedDirective(StartLoc); |
9455 | } |
9456 | |
9457 | if (AStmt) { |
9458 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 9458, __PRETTY_FUNCTION__)); |
9459 | |
9460 | setFunctionHasBranchProtectedScope(); |
9461 | } |
9462 | |
9463 | return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); |
9464 | } |
9465 | |
9466 | namespace { |
9467 | /// Helper class for checking expression in 'omp atomic [update]' |
9468 | /// construct. |
9469 | class OpenMPAtomicUpdateChecker { |
9470 | /// Error results for atomic update expressions. |
9471 | enum ExprAnalysisErrorCode { |
9472 | /// A statement is not an expression statement. |
9473 | NotAnExpression, |
9474 | /// Expression is not builtin binary or unary operation. |
9475 | NotABinaryOrUnaryExpression, |
9476 | /// Unary operation is not post-/pre- increment/decrement operation. |
9477 | NotAnUnaryIncDecExpression, |
9478 | /// An expression is not of scalar type. |
9479 | NotAScalarType, |
9480 | /// A binary operation is not an assignment operation. |
9481 | NotAnAssignmentOp, |
9482 | /// RHS part of the binary operation is not a binary expression. |
9483 | NotABinaryExpression, |
9484 | /// RHS part is not additive/multiplicative/shift/biwise binary |
9485 | /// expression. |
9486 | NotABinaryOperator, |
9487 | /// RHS binary operation does not have reference to the updated LHS |
9488 | /// part. |
9489 | NotAnUpdateExpression, |
9490 | /// No errors is found. |
9491 | NoError |
9492 | }; |
9493 | /// Reference to Sema. |
9494 | Sema &SemaRef; |
9495 | /// A location for note diagnostics (when error is found). |
9496 | SourceLocation NoteLoc; |
9497 | /// 'x' lvalue part of the source atomic expression. |
9498 | Expr *X; |
9499 | /// 'expr' rvalue part of the source atomic expression. |
9500 | Expr *E; |
9501 | /// Helper expression of the form |
9502 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
9503 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
9504 | Expr *UpdateExpr; |
9505 | /// Is 'x' a LHS in a RHS part of full update expression. It is |
9506 | /// important for non-associative operations. |
9507 | bool IsXLHSInRHSPart; |
9508 | BinaryOperatorKind Op; |
9509 | SourceLocation OpLoc; |
9510 | /// true if the source expression is a postfix unary operation, false |
9511 | /// if it is a prefix unary operation. |
9512 | bool IsPostfixUpdate; |
9513 | |
9514 | public: |
9515 | OpenMPAtomicUpdateChecker(Sema &SemaRef) |
9516 | : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), |
9517 | IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} |
9518 | /// Check specified statement that it is suitable for 'atomic update' |
9519 | /// constructs and extract 'x', 'expr' and Operation from the original |
9520 | /// expression. If DiagId and NoteId == 0, then only check is performed |
9521 | /// without error notification. |
9522 | /// \param DiagId Diagnostic which should be emitted if error is found. |
9523 | /// \param NoteId Diagnostic note for the main error message. |
9524 | /// \return true if statement is not an update expression, false otherwise. |
9525 | bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); |
9526 | /// Return the 'x' lvalue part of the source atomic expression. |
9527 | Expr *getX() const { return X; } |
9528 | /// Return the 'expr' rvalue part of the source atomic expression. |
9529 | Expr *getExpr() const { return E; } |
9530 | /// Return the update expression used in calculation of the updated |
9531 | /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
9532 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
9533 | Expr *getUpdateExpr() const { return UpdateExpr; } |
9534 | /// Return true if 'x' is LHS in RHS part of full update expression, |
9535 | /// false otherwise. |
9536 | bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } |
9537 | |
9538 | /// true if the source expression is a postfix unary operation, false |
9539 | /// if it is a prefix unary operation. |
9540 | bool isPostfixUpdate() const { return IsPostfixUpdate; } |
9541 | |
9542 | private: |
9543 | bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, |
9544 | unsigned NoteId = 0); |
9545 | }; |
9546 | } // namespace |
9547 | |
9548 | bool OpenMPAtomicUpdateChecker::checkBinaryOperation( |
9549 | BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { |
9550 | ExprAnalysisErrorCode ErrorFound = NoError; |
9551 | SourceLocation ErrorLoc, NoteLoc; |
9552 | SourceRange ErrorRange, NoteRange; |
9553 | // Allowed constructs are: |
9554 | // x = x binop expr; |
9555 | // x = expr binop x; |
9556 | if (AtomicBinOp->getOpcode() == BO_Assign) { |
9557 | X = AtomicBinOp->getLHS(); |
9558 | if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( |
9559 | AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { |
9560 | if (AtomicInnerBinOp->isMultiplicativeOp() || |
9561 | AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || |
9562 | AtomicInnerBinOp->isBitwiseOp()) { |
9563 | Op = AtomicInnerBinOp->getOpcode(); |
9564 | OpLoc = AtomicInnerBinOp->getOperatorLoc(); |
9565 | Expr *LHS = AtomicInnerBinOp->getLHS(); |
9566 | Expr *RHS = AtomicInnerBinOp->getRHS(); |
9567 | llvm::FoldingSetNodeID XId, LHSId, RHSId; |
9568 | X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), |
9569 | /*Canonical=*/true); |
9570 | LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), |
9571 | /*Canonical=*/true); |
9572 | RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), |
9573 | /*Canonical=*/true); |
9574 | if (XId == LHSId) { |
9575 | E = RHS; |
9576 | IsXLHSInRHSPart = true; |
9577 | } else if (XId == RHSId) { |
9578 | E = LHS; |
9579 | IsXLHSInRHSPart = false; |
9580 | } else { |
9581 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); |
9582 | ErrorRange = AtomicInnerBinOp->getSourceRange(); |
9583 | NoteLoc = X->getExprLoc(); |
9584 | NoteRange = X->getSourceRange(); |
9585 | ErrorFound = NotAnUpdateExpression; |
9586 | } |
9587 | } else { |
9588 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); |
9589 | ErrorRange = AtomicInnerBinOp->getSourceRange(); |
9590 | NoteLoc = AtomicInnerBinOp->getOperatorLoc(); |
9591 | NoteRange = SourceRange(NoteLoc, NoteLoc); |
9592 | ErrorFound = NotABinaryOperator; |
9593 | } |
9594 | } else { |
9595 | NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); |
9596 | NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); |
9597 | ErrorFound = NotABinaryExpression; |
9598 | } |
9599 | } else { |
9600 | ErrorLoc = AtomicBinOp->getExprLoc(); |
9601 | ErrorRange = AtomicBinOp->getSourceRange(); |
9602 | NoteLoc = AtomicBinOp->getOperatorLoc(); |
9603 | NoteRange = SourceRange(NoteLoc, NoteLoc); |
9604 | ErrorFound = NotAnAssignmentOp; |
9605 | } |
9606 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { |
9607 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; |
9608 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; |
9609 | return true; |
9610 | } |
9611 | if (SemaRef.CurContext->isDependentContext()) |
9612 | E = X = UpdateExpr = nullptr; |
9613 | return ErrorFound != NoError; |
9614 | } |
9615 | |
9616 | bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, |
9617 | unsigned NoteId) { |
9618 | ExprAnalysisErrorCode ErrorFound = NoError; |
9619 | SourceLocation ErrorLoc, NoteLoc; |
9620 | SourceRange ErrorRange, NoteRange; |
9621 | // Allowed constructs are: |
9622 | // x++; |
9623 | // x--; |
9624 | // ++x; |
9625 | // --x; |
9626 | // x binop= expr; |
9627 | // x = x binop expr; |
9628 | // x = expr binop x; |
9629 | if (auto *AtomicBody = dyn_cast<Expr>(S)) { |
9630 | AtomicBody = AtomicBody->IgnoreParenImpCasts(); |
9631 | if (AtomicBody->getType()->isScalarType() || |
9632 | AtomicBody->isInstantiationDependent()) { |
9633 | if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( |
9634 | AtomicBody->IgnoreParenImpCasts())) { |
9635 | // Check for Compound Assignment Operation |
9636 | Op = BinaryOperator::getOpForCompoundAssignment( |
9637 | AtomicCompAssignOp->getOpcode()); |
9638 | OpLoc = AtomicCompAssignOp->getOperatorLoc(); |
9639 | E = AtomicCompAssignOp->getRHS(); |
9640 | X = AtomicCompAssignOp->getLHS()->IgnoreParens(); |
9641 | IsXLHSInRHSPart = true; |
9642 | } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( |
9643 | AtomicBody->IgnoreParenImpCasts())) { |
9644 | // Check for Binary Operation |
9645 | if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) |
9646 | return true; |
9647 | } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( |
9648 | AtomicBody->IgnoreParenImpCasts())) { |
9649 | // Check for Unary Operation |
9650 | if (AtomicUnaryOp->isIncrementDecrementOp()) { |
9651 | IsPostfixUpdate = AtomicUnaryOp->isPostfix(); |
9652 | Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; |
9653 | OpLoc = AtomicUnaryOp->getOperatorLoc(); |
9654 | X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); |
9655 | E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); |
9656 | IsXLHSInRHSPart = true; |
9657 | } else { |
9658 | ErrorFound = NotAnUnaryIncDecExpression; |
9659 | ErrorLoc = AtomicUnaryOp->getExprLoc(); |
9660 | ErrorRange = AtomicUnaryOp->getSourceRange(); |
9661 | NoteLoc = AtomicUnaryOp->getOperatorLoc(); |
9662 | NoteRange = SourceRange(NoteLoc, NoteLoc); |
9663 | } |
9664 | } else if (!AtomicBody->isInstantiationDependent()) { |
9665 | ErrorFound = NotABinaryOrUnaryExpression; |
9666 | NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); |
9667 | NoteRange = ErrorRange = AtomicBody->getSourceRange(); |
9668 | } |
9669 | } else { |
9670 | ErrorFound = NotAScalarType; |
9671 | NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); |
9672 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); |
9673 | } |
9674 | } else { |
9675 | ErrorFound = NotAnExpression; |
9676 | NoteLoc = ErrorLoc = S->getBeginLoc(); |
9677 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); |
9678 | } |
9679 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { |
9680 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; |
9681 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; |
9682 | return true; |
9683 | } |
9684 | if (SemaRef.CurContext->isDependentContext()) |
9685 | E = X = UpdateExpr = nullptr; |
9686 | if (ErrorFound == NoError && E && X) { |
9687 | // Build an update expression of form 'OpaqueValueExpr(x) binop |
9688 | // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop |
9689 | // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. |
9690 | auto *OVEX = new (SemaRef.getASTContext()) |
9691 | OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); |
9692 | auto *OVEExpr = new (SemaRef.getASTContext()) |
9693 | OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); |
9694 | ExprResult Update = |
9695 | SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, |
9696 | IsXLHSInRHSPart ? OVEExpr : OVEX); |
9697 | if (Update.isInvalid()) |
9698 | return true; |
9699 | Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), |
9700 | Sema::AA_Casting); |
9701 | if (Update.isInvalid()) |
9702 | return true; |
9703 | UpdateExpr = Update.get(); |
9704 | } |
9705 | return ErrorFound != NoError; |
9706 | } |
9707 | |
9708 | StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, |
9709 | Stmt *AStmt, |
9710 | SourceLocation StartLoc, |
9711 | SourceLocation EndLoc) { |
9712 | // Register location of the first atomic directive. |
9713 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addAtomicDirectiveLoc(StartLoc); |
9714 | if (!AStmt) |
9715 | return StmtError(); |
9716 | |
9717 | auto *CS = cast<CapturedStmt>(AStmt); |
9718 | // 1.2.2 OpenMP Language Terminology |
9719 | // Structured block - An executable statement with a single entry at the |
9720 | // top and a single exit at the bottom. |
9721 | // The point of exit cannot be a branch out of the structured block. |
9722 | // longjmp() and throw() must not violate the entry/exit criteria. |
9723 | OpenMPClauseKind AtomicKind = OMPC_unknown; |
9724 | SourceLocation AtomicKindLoc; |
9725 | OpenMPClauseKind MemOrderKind = OMPC_unknown; |
9726 | SourceLocation MemOrderLoc; |
9727 | for (const OMPClause *C : Clauses) { |
9728 | if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || |
9729 | C->getClauseKind() == OMPC_update || |
9730 | C->getClauseKind() == OMPC_capture) { |
9731 | if (AtomicKind != OMPC_unknown) { |
9732 | Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) |
9733 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); |
9734 | Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) |
9735 | << getOpenMPClauseName(AtomicKind); |
9736 | } else { |
9737 | AtomicKind = C->getClauseKind(); |
9738 | AtomicKindLoc = C->getBeginLoc(); |
9739 | } |
9740 | } |
9741 | if (C->getClauseKind() == OMPC_seq_cst || |
9742 | C->getClauseKind() == OMPC_acq_rel || |
9743 | C->getClauseKind() == OMPC_acquire || |
9744 | C->getClauseKind() == OMPC_release || |
9745 | C->getClauseKind() == OMPC_relaxed) { |
9746 | if (MemOrderKind != OMPC_unknown) { |
9747 | Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) |
9748 | << getOpenMPDirectiveName(OMPD_atomic) << 0 |
9749 | << SourceRange(C->getBeginLoc(), C->getEndLoc()); |
9750 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) |
9751 | << getOpenMPClauseName(MemOrderKind); |
9752 | } else { |
9753 | MemOrderKind = C->getClauseKind(); |
9754 | MemOrderLoc = C->getBeginLoc(); |
9755 | } |
9756 | } |
9757 | } |
9758 | // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions |
9759 | // If atomic-clause is read then memory-order-clause must not be acq_rel or |
9760 | // release. |
9761 | // If atomic-clause is write then memory-order-clause must not be acq_rel or |
9762 | // acquire. |
9763 | // If atomic-clause is update or not present then memory-order-clause must not |
9764 | // be acq_rel or acquire. |
9765 | if ((AtomicKind == OMPC_read && |
9766 | (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || |
9767 | ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || |
9768 | AtomicKind == OMPC_unknown) && |
9769 | (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { |
9770 | SourceLocation Loc = AtomicKindLoc; |
9771 | if (AtomicKind == OMPC_unknown) |
9772 | Loc = StartLoc; |
9773 | Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) |
9774 | << getOpenMPClauseName(AtomicKind) |
9775 | << (AtomicKind == OMPC_unknown ? 1 : 0) |
9776 | << getOpenMPClauseName(MemOrderKind); |
9777 | Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) |
9778 | << getOpenMPClauseName(MemOrderKind); |
9779 | } |
9780 | |
9781 | Stmt *Body = CS->getCapturedStmt(); |
9782 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) |
9783 | Body = EWC->getSubExpr(); |
9784 | |
9785 | Expr *X = nullptr; |
9786 | Expr *V = nullptr; |
9787 | Expr *E = nullptr; |
9788 | Expr *UE = nullptr; |
9789 | bool IsXLHSInRHSPart = false; |
9790 | bool IsPostfixUpdate = false; |
9791 | // OpenMP [2.12.6, atomic Construct] |
9792 | // In the next expressions: |
9793 | // * x and v (as applicable) are both l-value expressions with scalar type. |
9794 | // * During the execution of an atomic region, multiple syntactic |
9795 | // occurrences of x must designate the same storage location. |
9796 | // * Neither of v and expr (as applicable) may access the storage location |
9797 | // designated by x. |
9798 | // * Neither of x and expr (as applicable) may access the storage location |
9799 | // designated by v. |
9800 | // * expr is an expression with scalar type. |
9801 | // * binop is one of +, *, -, /, &, ^, |, <<, or >>. |
9802 | // * binop, binop=, ++, and -- are not overloaded operators. |
9803 | // * The expression x binop expr must be numerically equivalent to x binop |
9804 | // (expr). This requirement is satisfied if the operators in expr have |
9805 | // precedence greater than binop, or by using parentheses around expr or |
9806 | // subexpressions of expr. |
9807 | // * The expression expr binop x must be numerically equivalent to (expr) |
9808 | // binop x. This requirement is satisfied if the operators in expr have |
9809 | // precedence equal to or greater than binop, or by using parentheses around |
9810 | // expr or subexpressions of expr. |
9811 | // * For forms that allow multiple occurrences of x, the number of times |
9812 | // that x is evaluated is unspecified. |
9813 | if (AtomicKind == OMPC_read) { |
9814 | enum { |
9815 | NotAnExpression, |
9816 | NotAnAssignmentOp, |
9817 | NotAScalarType, |
9818 | NotAnLValue, |
9819 | NoError |
9820 | } ErrorFound = NoError; |
9821 | SourceLocation ErrorLoc, NoteLoc; |
9822 | SourceRange ErrorRange, NoteRange; |
9823 | // If clause is read: |
9824 | // v = x; |
9825 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { |
9826 | const auto *AtomicBinOp = |
9827 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); |
9828 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { |
9829 | X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); |
9830 | V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); |
9831 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && |
9832 | (V->isInstantiationDependent() || V->getType()->isScalarType())) { |
9833 | if (!X->isLValue() || !V->isLValue()) { |
9834 | const Expr *NotLValueExpr = X->isLValue() ? V : X; |
9835 | ErrorFound = NotAnLValue; |
9836 | ErrorLoc = AtomicBinOp->getExprLoc(); |
9837 | ErrorRange = AtomicBinOp->getSourceRange(); |
9838 | NoteLoc = NotLValueExpr->getExprLoc(); |
9839 | NoteRange = NotLValueExpr->getSourceRange(); |
9840 | } |
9841 | } else if (!X->isInstantiationDependent() || |
9842 | !V->isInstantiationDependent()) { |
9843 | const Expr *NotScalarExpr = |
9844 | (X->isInstantiationDependent() || X->getType()->isScalarType()) |
9845 | ? V |
9846 | : X; |
9847 | ErrorFound = NotAScalarType; |
9848 | ErrorLoc = AtomicBinOp->getExprLoc(); |
9849 | ErrorRange = AtomicBinOp->getSourceRange(); |
9850 | NoteLoc = NotScalarExpr->getExprLoc(); |
9851 | NoteRange = NotScalarExpr->getSourceRange(); |
9852 | } |
9853 | } else if (!AtomicBody->isInstantiationDependent()) { |
9854 | ErrorFound = NotAnAssignmentOp; |
9855 | ErrorLoc = AtomicBody->getExprLoc(); |
9856 | ErrorRange = AtomicBody->getSourceRange(); |
9857 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() |
9858 | : AtomicBody->getExprLoc(); |
9859 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() |
9860 | : AtomicBody->getSourceRange(); |
9861 | } |
9862 | } else { |
9863 | ErrorFound = NotAnExpression; |
9864 | NoteLoc = ErrorLoc = Body->getBeginLoc(); |
9865 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); |
9866 | } |
9867 | if (ErrorFound != NoError) { |
9868 | Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) |
9869 | << ErrorRange; |
9870 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound |
9871 | << NoteRange; |
9872 | return StmtError(); |
9873 | } |
9874 | if (CurContext->isDependentContext()) |
9875 | V = X = nullptr; |
9876 | } else if (AtomicKind == OMPC_write) { |
9877 | enum { |
9878 | NotAnExpression, |
9879 | NotAnAssignmentOp, |
9880 | NotAScalarType, |
9881 | NotAnLValue, |
9882 | NoError |
9883 | } ErrorFound = NoError; |
9884 | SourceLocation ErrorLoc, NoteLoc; |
9885 | SourceRange ErrorRange, NoteRange; |
9886 | // If clause is write: |
9887 | // x = expr; |
9888 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { |
9889 | const auto *AtomicBinOp = |
9890 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); |
9891 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { |
9892 | X = AtomicBinOp->getLHS(); |
9893 | E = AtomicBinOp->getRHS(); |
9894 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && |
9895 | (E->isInstantiationDependent() || E->getType()->isScalarType())) { |
9896 | if (!X->isLValue()) { |
9897 | ErrorFound = NotAnLValue; |
9898 | ErrorLoc = AtomicBinOp->getExprLoc(); |
9899 | ErrorRange = AtomicBinOp->getSourceRange(); |
9900 | NoteLoc = X->getExprLoc(); |
9901 | NoteRange = X->getSourceRange(); |
9902 | } |
9903 | } else if (!X->isInstantiationDependent() || |
9904 | !E->isInstantiationDependent()) { |
9905 | const Expr *NotScalarExpr = |
9906 | (X->isInstantiationDependent() || X->getType()->isScalarType()) |
9907 | ? E |
9908 | : X; |
9909 | ErrorFound = NotAScalarType; |
9910 | ErrorLoc = AtomicBinOp->getExprLoc(); |
9911 | ErrorRange = AtomicBinOp->getSourceRange(); |
9912 | NoteLoc = NotScalarExpr->getExprLoc(); |
9913 | NoteRange = NotScalarExpr->getSourceRange(); |
9914 | } |
9915 | } else if (!AtomicBody->isInstantiationDependent()) { |
9916 | ErrorFound = NotAnAssignmentOp; |
9917 | ErrorLoc = AtomicBody->getExprLoc(); |
9918 | ErrorRange = AtomicBody->getSourceRange(); |
9919 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() |
9920 | : AtomicBody->getExprLoc(); |
9921 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() |
9922 | : AtomicBody->getSourceRange(); |
9923 | } |
9924 | } else { |
9925 | ErrorFound = NotAnExpression; |
9926 | NoteLoc = ErrorLoc = Body->getBeginLoc(); |
9927 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); |
9928 | } |
9929 | if (ErrorFound != NoError) { |
9930 | Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) |
9931 | << ErrorRange; |
9932 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound |
9933 | << NoteRange; |
9934 | return StmtError(); |
9935 | } |
9936 | if (CurContext->isDependentContext()) |
9937 | E = X = nullptr; |
9938 | } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { |
9939 | // If clause is update: |
9940 | // x++; |
9941 | // x--; |
9942 | // ++x; |
9943 | // --x; |
9944 | // x binop= expr; |
9945 | // x = x binop expr; |
9946 | // x = expr binop x; |
9947 | OpenMPAtomicUpdateChecker Checker(*this); |
9948 | if (Checker.checkStatement( |
9949 | Body, (AtomicKind == OMPC_update) |
9950 | ? diag::err_omp_atomic_update_not_expression_statement |
9951 | : diag::err_omp_atomic_not_expression_statement, |
9952 | diag::note_omp_atomic_update)) |
9953 | return StmtError(); |
9954 | if (!CurContext->isDependentContext()) { |
9955 | E = Checker.getExpr(); |
9956 | X = Checker.getX(); |
9957 | UE = Checker.getUpdateExpr(); |
9958 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); |
9959 | } |
9960 | } else if (AtomicKind == OMPC_capture) { |
9961 | enum { |
9962 | NotAnAssignmentOp, |
9963 | NotACompoundStatement, |
9964 | NotTwoSubstatements, |
9965 | NotASpecificExpression, |
9966 | NoError |
9967 | } ErrorFound = NoError; |
9968 | SourceLocation ErrorLoc, NoteLoc; |
9969 | SourceRange ErrorRange, NoteRange; |
9970 | if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { |
9971 | // If clause is a capture: |
9972 | // v = x++; |
9973 | // v = x--; |
9974 | // v = ++x; |
9975 | // v = --x; |
9976 | // v = x binop= expr; |
9977 | // v = x = x binop expr; |
9978 | // v = x = expr binop x; |
9979 | const auto *AtomicBinOp = |
9980 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); |
9981 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { |
9982 | V = AtomicBinOp->getLHS(); |
9983 | Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); |
9984 | OpenMPAtomicUpdateChecker Checker(*this); |
9985 | if (Checker.checkStatement( |
9986 | Body, diag::err_omp_atomic_capture_not_expression_statement, |
9987 | diag::note_omp_atomic_update)) |
9988 | return StmtError(); |
9989 | E = Checker.getExpr(); |
9990 | X = Checker.getX(); |
9991 | UE = Checker.getUpdateExpr(); |
9992 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); |
9993 | IsPostfixUpdate = Checker.isPostfixUpdate(); |
9994 | } else if (!AtomicBody->isInstantiationDependent()) { |
9995 | ErrorLoc = AtomicBody->getExprLoc(); |
9996 | ErrorRange = AtomicBody->getSourceRange(); |
9997 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() |
9998 | : AtomicBody->getExprLoc(); |
9999 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() |
10000 | : AtomicBody->getSourceRange(); |
10001 | ErrorFound = NotAnAssignmentOp; |
10002 | } |
10003 | if (ErrorFound != NoError) { |
10004 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) |
10005 | << ErrorRange; |
10006 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; |
10007 | return StmtError(); |
10008 | } |
10009 | if (CurContext->isDependentContext()) |
10010 | UE = V = E = X = nullptr; |
10011 | } else { |
10012 | // If clause is a capture: |
10013 | // { v = x; x = expr; } |
10014 | // { v = x; x++; } |
10015 | // { v = x; x--; } |
10016 | // { v = x; ++x; } |
10017 | // { v = x; --x; } |
10018 | // { v = x; x binop= expr; } |
10019 | // { v = x; x = x binop expr; } |
10020 | // { v = x; x = expr binop x; } |
10021 | // { x++; v = x; } |
10022 | // { x--; v = x; } |
10023 | // { ++x; v = x; } |
10024 | // { --x; v = x; } |
10025 | // { x binop= expr; v = x; } |
10026 | // { x = x binop expr; v = x; } |
10027 | // { x = expr binop x; v = x; } |
10028 | if (auto *CS = dyn_cast<CompoundStmt>(Body)) { |
10029 | // Check that this is { expr1; expr2; } |
10030 | if (CS->size() == 2) { |
10031 | Stmt *First = CS->body_front(); |
10032 | Stmt *Second = CS->body_back(); |
10033 | if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) |
10034 | First = EWC->getSubExpr()->IgnoreParenImpCasts(); |
10035 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) |
10036 | Second = EWC->getSubExpr()->IgnoreParenImpCasts(); |
10037 | // Need to find what subexpression is 'v' and what is 'x'. |
10038 | OpenMPAtomicUpdateChecker Checker(*this); |
10039 | bool IsUpdateExprFound = !Checker.checkStatement(Second); |
10040 | BinaryOperator *BinOp = nullptr; |
10041 | if (IsUpdateExprFound) { |
10042 | BinOp = dyn_cast<BinaryOperator>(First); |
10043 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; |
10044 | } |
10045 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { |
10046 | // { v = x; x++; } |
10047 | // { v = x; x--; } |
10048 | // { v = x; ++x; } |
10049 | // { v = x; --x; } |
10050 | // { v = x; x binop= expr; } |
10051 | // { v = x; x = x binop expr; } |
10052 | // { v = x; x = expr binop x; } |
10053 | // Check that the first expression has form v = x. |
10054 | Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); |
10055 | llvm::FoldingSetNodeID XId, PossibleXId; |
10056 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); |
10057 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); |
10058 | IsUpdateExprFound = XId == PossibleXId; |
10059 | if (IsUpdateExprFound) { |
10060 | V = BinOp->getLHS(); |
10061 | X = Checker.getX(); |
10062 | E = Checker.getExpr(); |
10063 | UE = Checker.getUpdateExpr(); |
10064 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); |
10065 | IsPostfixUpdate = true; |
10066 | } |
10067 | } |
10068 | if (!IsUpdateExprFound) { |
10069 | IsUpdateExprFound = !Checker.checkStatement(First); |
10070 | BinOp = nullptr; |
10071 | if (IsUpdateExprFound) { |
10072 | BinOp = dyn_cast<BinaryOperator>(Second); |
10073 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; |
10074 | } |
10075 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { |
10076 | // { x++; v = x; } |
10077 | // { x--; v = x; } |
10078 | // { ++x; v = x; } |
10079 | // { --x; v = x; } |
10080 | // { x binop= expr; v = x; } |
10081 | // { x = x binop expr; v = x; } |
10082 | // { x = expr binop x; v = x; } |
10083 | // Check that the second expression has form v = x. |
10084 | Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); |
10085 | llvm::FoldingSetNodeID XId, PossibleXId; |
10086 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); |
10087 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); |
10088 | IsUpdateExprFound = XId == PossibleXId; |
10089 | if (IsUpdateExprFound) { |
10090 | V = BinOp->getLHS(); |
10091 | X = Checker.getX(); |
10092 | E = Checker.getExpr(); |
10093 | UE = Checker.getUpdateExpr(); |
10094 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); |
10095 | IsPostfixUpdate = false; |
10096 | } |
10097 | } |
10098 | } |
10099 | if (!IsUpdateExprFound) { |
10100 | // { v = x; x = expr; } |
10101 | auto *FirstExpr = dyn_cast<Expr>(First); |
10102 | auto *SecondExpr = dyn_cast<Expr>(Second); |
10103 | if (!FirstExpr || !SecondExpr || |
10104 | !(FirstExpr->isInstantiationDependent() || |
10105 | SecondExpr->isInstantiationDependent())) { |
10106 | auto *FirstBinOp = dyn_cast<BinaryOperator>(First); |
10107 | if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { |
10108 | ErrorFound = NotAnAssignmentOp; |
10109 | NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() |
10110 | : First->getBeginLoc(); |
10111 | NoteRange = ErrorRange = FirstBinOp |
10112 | ? FirstBinOp->getSourceRange() |
10113 | : SourceRange(ErrorLoc, ErrorLoc); |
10114 | } else { |
10115 | auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); |
10116 | if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { |
10117 | ErrorFound = NotAnAssignmentOp; |
10118 | NoteLoc = ErrorLoc = SecondBinOp |
10119 | ? SecondBinOp->getOperatorLoc() |
10120 | : Second->getBeginLoc(); |
10121 | NoteRange = ErrorRange = |
10122 | SecondBinOp ? SecondBinOp->getSourceRange() |
10123 | : SourceRange(ErrorLoc, ErrorLoc); |
10124 | } else { |
10125 | Expr *PossibleXRHSInFirst = |
10126 | FirstBinOp->getRHS()->IgnoreParenImpCasts(); |
10127 | Expr *PossibleXLHSInSecond = |
10128 | SecondBinOp->getLHS()->IgnoreParenImpCasts(); |
10129 | llvm::FoldingSetNodeID X1Id, X2Id; |
10130 | PossibleXRHSInFirst->Profile(X1Id, Context, |
10131 | /*Canonical=*/true); |
10132 | PossibleXLHSInSecond->Profile(X2Id, Context, |
10133 | /*Canonical=*/true); |
10134 | IsUpdateExprFound = X1Id == X2Id; |
10135 | if (IsUpdateExprFound) { |
10136 | V = FirstBinOp->getLHS(); |
10137 | X = SecondBinOp->getLHS(); |
10138 | E = SecondBinOp->getRHS(); |
10139 | UE = nullptr; |
10140 | IsXLHSInRHSPart = false; |
10141 | IsPostfixUpdate = true; |
10142 | } else { |
10143 | ErrorFound = NotASpecificExpression; |
10144 | ErrorLoc = FirstBinOp->getExprLoc(); |
10145 | ErrorRange = FirstBinOp->getSourceRange(); |
10146 | NoteLoc = SecondBinOp->getLHS()->getExprLoc(); |
10147 | NoteRange = SecondBinOp->getRHS()->getSourceRange(); |
10148 | } |
10149 | } |
10150 | } |
10151 | } |
10152 | } |
10153 | } else { |
10154 | NoteLoc = ErrorLoc = Body->getBeginLoc(); |
10155 | NoteRange = ErrorRange = |
10156 | SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); |
10157 | ErrorFound = NotTwoSubstatements; |
10158 | } |
10159 | } else { |
10160 | NoteLoc = ErrorLoc = Body->getBeginLoc(); |
10161 | NoteRange = ErrorRange = |
10162 | SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); |
10163 | ErrorFound = NotACompoundStatement; |
10164 | } |
10165 | if (ErrorFound != NoError) { |
10166 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) |
10167 | << ErrorRange; |
10168 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; |
10169 | return StmtError(); |
10170 | } |
10171 | if (CurContext->isDependentContext()) |
10172 | UE = V = E = X = nullptr; |
10173 | } |
10174 | } |
10175 | |
10176 | setFunctionHasBranchProtectedScope(); |
10177 | |
10178 | return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, |
10179 | X, V, E, UE, IsXLHSInRHSPart, |
10180 | IsPostfixUpdate); |
10181 | } |
10182 | |
10183 | StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, |
10184 | Stmt *AStmt, |
10185 | SourceLocation StartLoc, |
10186 | SourceLocation EndLoc) { |
10187 | if (!AStmt) |
10188 | return StmtError(); |
10189 | |
10190 | auto *CS = cast<CapturedStmt>(AStmt); |
10191 | // 1.2.2 OpenMP Language Terminology |
10192 | // Structured block - An executable statement with a single entry at the |
10193 | // top and a single exit at the bottom. |
10194 | // The point of exit cannot be a branch out of the structured block. |
10195 | // longjmp() and throw() must not violate the entry/exit criteria. |
10196 | CS->getCapturedDecl()->setNothrow(); |
10197 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); |
10198 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10199 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10200 | // 1.2.2 OpenMP Language Terminology |
10201 | // Structured block - An executable statement with a single entry at the |
10202 | // top and a single exit at the bottom. |
10203 | // The point of exit cannot be a branch out of the structured block. |
10204 | // longjmp() and throw() must not violate the entry/exit criteria. |
10205 | CS->getCapturedDecl()->setNothrow(); |
10206 | } |
10207 | |
10208 | // OpenMP [2.16, Nesting of Regions] |
10209 | // If specified, a teams construct must be contained within a target |
10210 | // construct. That target construct must contain no statements or directives |
10211 | // outside of the teams construct. |
10212 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnerTeamsRegion()) { |
10213 | const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); |
10214 | bool OMPTeamsFound = true; |
10215 | if (const auto *CS = dyn_cast<CompoundStmt>(S)) { |
10216 | auto I = CS->body_begin(); |
10217 | while (I != CS->body_end()) { |
10218 | const auto *OED = dyn_cast<OMPExecutableDirective>(*I); |
10219 | if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || |
10220 | OMPTeamsFound) { |
10221 | |
10222 | OMPTeamsFound = false; |
10223 | break; |
10224 | } |
10225 | ++I; |
10226 | } |
10227 | assert(I != CS->body_end() && "Not found statement")((I != CS->body_end() && "Not found statement") ? static_cast <void> (0) : __assert_fail ("I != CS->body_end() && \"Not found statement\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10227, __PRETTY_FUNCTION__)); |
10228 | S = *I; |
10229 | } else { |
10230 | const auto *OED = dyn_cast<OMPExecutableDirective>(S); |
10231 | OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); |
10232 | } |
10233 | if (!OMPTeamsFound) { |
10234 | Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); |
10235 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getInnerTeamsRegionLoc(), |
10236 | diag::note_omp_nested_teams_construct_here); |
10237 | Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) |
10238 | << isa<OMPExecutableDirective>(S); |
10239 | return StmtError(); |
10240 | } |
10241 | } |
10242 | |
10243 | setFunctionHasBranchProtectedScope(); |
10244 | |
10245 | return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); |
10246 | } |
10247 | |
10248 | StmtResult |
10249 | Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, |
10250 | Stmt *AStmt, SourceLocation StartLoc, |
10251 | SourceLocation EndLoc) { |
10252 | if (!AStmt) |
10253 | return StmtError(); |
10254 | |
10255 | auto *CS = cast<CapturedStmt>(AStmt); |
10256 | // 1.2.2 OpenMP Language Terminology |
10257 | // Structured block - An executable statement with a single entry at the |
10258 | // top and a single exit at the bottom. |
10259 | // The point of exit cannot be a branch out of the structured block. |
10260 | // longjmp() and throw() must not violate the entry/exit criteria. |
10261 | CS->getCapturedDecl()->setNothrow(); |
10262 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); |
10263 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10264 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10265 | // 1.2.2 OpenMP Language Terminology |
10266 | // Structured block - An executable statement with a single entry at the |
10267 | // top and a single exit at the bottom. |
10268 | // The point of exit cannot be a branch out of the structured block. |
10269 | // longjmp() and throw() must not violate the entry/exit criteria. |
10270 | CS->getCapturedDecl()->setNothrow(); |
10271 | } |
10272 | |
10273 | setFunctionHasBranchProtectedScope(); |
10274 | |
10275 | return OMPTargetParallelDirective::Create( |
10276 | Context, StartLoc, EndLoc, Clauses, AStmt, |
10277 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
10278 | } |
10279 | |
10280 | StmtResult Sema::ActOnOpenMPTargetParallelForDirective( |
10281 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10282 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10283 | if (!AStmt) |
10284 | return StmtError(); |
10285 | |
10286 | auto *CS = cast<CapturedStmt>(AStmt); |
10287 | // 1.2.2 OpenMP Language Terminology |
10288 | // Structured block - An executable statement with a single entry at the |
10289 | // top and a single exit at the bottom. |
10290 | // The point of exit cannot be a branch out of the structured block. |
10291 | // longjmp() and throw() must not violate the entry/exit criteria. |
10292 | CS->getCapturedDecl()->setNothrow(); |
10293 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); |
10294 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10295 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10296 | // 1.2.2 OpenMP Language Terminology |
10297 | // Structured block - An executable statement with a single entry at the |
10298 | // top and a single exit at the bottom. |
10299 | // The point of exit cannot be a branch out of the structured block. |
10300 | // longjmp() and throw() must not violate the entry/exit criteria. |
10301 | CS->getCapturedDecl()->setNothrow(); |
10302 | } |
10303 | |
10304 | OMPLoopDirective::HelperExprs B; |
10305 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
10306 | // define the nested loops number. |
10307 | unsigned NestedLoopCount = |
10308 | checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), |
10309 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10310 | VarsWithImplicitDSA, B); |
10311 | if (NestedLoopCount == 0) |
10312 | return StmtError(); |
10313 | |
10314 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10315, __PRETTY_FUNCTION__)) |
10315 | "omp target parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10315, __PRETTY_FUNCTION__)); |
10316 | |
10317 | if (!CurContext->isDependentContext()) { |
10318 | // Finalize the clauses that need pre-built expressions for CodeGen. |
10319 | for (OMPClause *C : Clauses) { |
10320 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
10321 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
10322 | B.NumIterations, *this, CurScope, |
10323 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
10324 | return StmtError(); |
10325 | } |
10326 | } |
10327 | |
10328 | setFunctionHasBranchProtectedScope(); |
10329 | return OMPTargetParallelForDirective::Create( |
10330 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
10331 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
10332 | } |
10333 | |
10334 | /// Check for existence of a map clause in the list of clauses. |
10335 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, |
10336 | const OpenMPClauseKind K) { |
10337 | return llvm::any_of( |
10338 | Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); |
10339 | } |
10340 | |
10341 | template <typename... Params> |
10342 | static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, |
10343 | const Params... ClauseTypes) { |
10344 | return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); |
10345 | } |
10346 | |
10347 | StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, |
10348 | Stmt *AStmt, |
10349 | SourceLocation StartLoc, |
10350 | SourceLocation EndLoc) { |
10351 | if (!AStmt) |
10352 | return StmtError(); |
10353 | |
10354 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10354, __PRETTY_FUNCTION__)); |
10355 | |
10356 | // OpenMP [2.12.2, target data Construct, Restrictions] |
10357 | // At least one map, use_device_addr or use_device_ptr clause must appear on |
10358 | // the directive. |
10359 | if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && |
10360 | (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { |
10361 | StringRef Expected; |
10362 | if (LangOpts.OpenMP < 50) |
10363 | Expected = "'map' or 'use_device_ptr'"; |
10364 | else |
10365 | Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; |
10366 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) |
10367 | << Expected << getOpenMPDirectiveName(OMPD_target_data); |
10368 | return StmtError(); |
10369 | } |
10370 | |
10371 | setFunctionHasBranchProtectedScope(); |
10372 | |
10373 | return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, |
10374 | AStmt); |
10375 | } |
10376 | |
10377 | StmtResult |
10378 | Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, |
10379 | SourceLocation StartLoc, |
10380 | SourceLocation EndLoc, Stmt *AStmt) { |
10381 | if (!AStmt) |
10382 | return StmtError(); |
10383 | |
10384 | auto *CS = cast<CapturedStmt>(AStmt); |
10385 | // 1.2.2 OpenMP Language Terminology |
10386 | // Structured block - An executable statement with a single entry at the |
10387 | // top and a single exit at the bottom. |
10388 | // The point of exit cannot be a branch out of the structured block. |
10389 | // longjmp() and throw() must not violate the entry/exit criteria. |
10390 | CS->getCapturedDecl()->setNothrow(); |
10391 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); |
10392 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10393 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10394 | // 1.2.2 OpenMP Language Terminology |
10395 | // Structured block - An executable statement with a single entry at the |
10396 | // top and a single exit at the bottom. |
10397 | // The point of exit cannot be a branch out of the structured block. |
10398 | // longjmp() and throw() must not violate the entry/exit criteria. |
10399 | CS->getCapturedDecl()->setNothrow(); |
10400 | } |
10401 | |
10402 | // OpenMP [2.10.2, Restrictions, p. 99] |
10403 | // At least one map clause must appear on the directive. |
10404 | if (!hasClauses(Clauses, OMPC_map)) { |
10405 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) |
10406 | << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); |
10407 | return StmtError(); |
10408 | } |
10409 | |
10410 | return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, |
10411 | AStmt); |
10412 | } |
10413 | |
10414 | StmtResult |
10415 | Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, |
10416 | SourceLocation StartLoc, |
10417 | SourceLocation EndLoc, Stmt *AStmt) { |
10418 | if (!AStmt) |
10419 | return StmtError(); |
10420 | |
10421 | auto *CS = cast<CapturedStmt>(AStmt); |
10422 | // 1.2.2 OpenMP Language Terminology |
10423 | // Structured block - An executable statement with a single entry at the |
10424 | // top and a single exit at the bottom. |
10425 | // The point of exit cannot be a branch out of the structured block. |
10426 | // longjmp() and throw() must not violate the entry/exit criteria. |
10427 | CS->getCapturedDecl()->setNothrow(); |
10428 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); |
10429 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10430 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10431 | // 1.2.2 OpenMP Language Terminology |
10432 | // Structured block - An executable statement with a single entry at the |
10433 | // top and a single exit at the bottom. |
10434 | // The point of exit cannot be a branch out of the structured block. |
10435 | // longjmp() and throw() must not violate the entry/exit criteria. |
10436 | CS->getCapturedDecl()->setNothrow(); |
10437 | } |
10438 | |
10439 | // OpenMP [2.10.3, Restrictions, p. 102] |
10440 | // At least one map clause must appear on the directive. |
10441 | if (!hasClauses(Clauses, OMPC_map)) { |
10442 | Diag(StartLoc, diag::err_omp_no_clause_for_directive) |
10443 | << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); |
10444 | return StmtError(); |
10445 | } |
10446 | |
10447 | return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, |
10448 | AStmt); |
10449 | } |
10450 | |
10451 | StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, |
10452 | SourceLocation StartLoc, |
10453 | SourceLocation EndLoc, |
10454 | Stmt *AStmt) { |
10455 | if (!AStmt) |
10456 | return StmtError(); |
10457 | |
10458 | auto *CS = cast<CapturedStmt>(AStmt); |
10459 | // 1.2.2 OpenMP Language Terminology |
10460 | // Structured block - An executable statement with a single entry at the |
10461 | // top and a single exit at the bottom. |
10462 | // The point of exit cannot be a branch out of the structured block. |
10463 | // longjmp() and throw() must not violate the entry/exit criteria. |
10464 | CS->getCapturedDecl()->setNothrow(); |
10465 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); |
10466 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10467 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10468 | // 1.2.2 OpenMP Language Terminology |
10469 | // Structured block - An executable statement with a single entry at the |
10470 | // top and a single exit at the bottom. |
10471 | // The point of exit cannot be a branch out of the structured block. |
10472 | // longjmp() and throw() must not violate the entry/exit criteria. |
10473 | CS->getCapturedDecl()->setNothrow(); |
10474 | } |
10475 | |
10476 | if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { |
10477 | Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); |
10478 | return StmtError(); |
10479 | } |
10480 | return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, |
10481 | AStmt); |
10482 | } |
10483 | |
10484 | StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, |
10485 | Stmt *AStmt, SourceLocation StartLoc, |
10486 | SourceLocation EndLoc) { |
10487 | if (!AStmt) |
10488 | return StmtError(); |
10489 | |
10490 | auto *CS = cast<CapturedStmt>(AStmt); |
10491 | // 1.2.2 OpenMP Language Terminology |
10492 | // Structured block - An executable statement with a single entry at the |
10493 | // top and a single exit at the bottom. |
10494 | // The point of exit cannot be a branch out of the structured block. |
10495 | // longjmp() and throw() must not violate the entry/exit criteria. |
10496 | CS->getCapturedDecl()->setNothrow(); |
10497 | |
10498 | setFunctionHasBranchProtectedScope(); |
10499 | |
10500 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); |
10501 | |
10502 | return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); |
10503 | } |
10504 | |
10505 | StmtResult |
10506 | Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, |
10507 | SourceLocation EndLoc, |
10508 | OpenMPDirectiveKind CancelRegion) { |
10509 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentNowaitRegion()) { |
10510 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; |
10511 | return StmtError(); |
10512 | } |
10513 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) { |
10514 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; |
10515 | return StmtError(); |
10516 | } |
10517 | return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, |
10518 | CancelRegion); |
10519 | } |
10520 | |
10521 | StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, |
10522 | SourceLocation StartLoc, |
10523 | SourceLocation EndLoc, |
10524 | OpenMPDirectiveKind CancelRegion) { |
10525 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentNowaitRegion()) { |
10526 | Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; |
10527 | return StmtError(); |
10528 | } |
10529 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) { |
10530 | Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; |
10531 | return StmtError(); |
10532 | } |
10533 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentCancelRegion(/*Cancel=*/true); |
10534 | return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, |
10535 | CancelRegion); |
10536 | } |
10537 | |
10538 | static bool checkGrainsizeNumTasksClauses(Sema &S, |
10539 | ArrayRef<OMPClause *> Clauses) { |
10540 | const OMPClause *PrevClause = nullptr; |
10541 | bool ErrorFound = false; |
10542 | for (const OMPClause *C : Clauses) { |
10543 | if (C->getClauseKind() == OMPC_grainsize || |
10544 | C->getClauseKind() == OMPC_num_tasks) { |
10545 | if (!PrevClause) |
10546 | PrevClause = C; |
10547 | else if (PrevClause->getClauseKind() != C->getClauseKind()) { |
10548 | S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) |
10549 | << getOpenMPClauseName(C->getClauseKind()) |
10550 | << getOpenMPClauseName(PrevClause->getClauseKind()); |
10551 | S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) |
10552 | << getOpenMPClauseName(PrevClause->getClauseKind()); |
10553 | ErrorFound = true; |
10554 | } |
10555 | } |
10556 | } |
10557 | return ErrorFound; |
10558 | } |
10559 | |
10560 | static bool checkReductionClauseWithNogroup(Sema &S, |
10561 | ArrayRef<OMPClause *> Clauses) { |
10562 | const OMPClause *ReductionClause = nullptr; |
10563 | const OMPClause *NogroupClause = nullptr; |
10564 | for (const OMPClause *C : Clauses) { |
10565 | if (C->getClauseKind() == OMPC_reduction) { |
10566 | ReductionClause = C; |
10567 | if (NogroupClause) |
10568 | break; |
10569 | continue; |
10570 | } |
10571 | if (C->getClauseKind() == OMPC_nogroup) { |
10572 | NogroupClause = C; |
10573 | if (ReductionClause) |
10574 | break; |
10575 | continue; |
10576 | } |
10577 | } |
10578 | if (ReductionClause && NogroupClause) { |
10579 | S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) |
10580 | << SourceRange(NogroupClause->getBeginLoc(), |
10581 | NogroupClause->getEndLoc()); |
10582 | return true; |
10583 | } |
10584 | return false; |
10585 | } |
10586 | |
10587 | StmtResult Sema::ActOnOpenMPTaskLoopDirective( |
10588 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10589 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10590 | if (!AStmt) |
10591 | return StmtError(); |
10592 | |
10593 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10593, __PRETTY_FUNCTION__)); |
10594 | OMPLoopDirective::HelperExprs B; |
10595 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
10596 | // define the nested loops number. |
10597 | unsigned NestedLoopCount = |
10598 | checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), |
10599 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10600 | VarsWithImplicitDSA, B); |
10601 | if (NestedLoopCount == 0) |
10602 | return StmtError(); |
10603 | |
10604 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10605, __PRETTY_FUNCTION__)) |
10605 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10605, __PRETTY_FUNCTION__)); |
10606 | |
10607 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10608 | // The grainsize clause and num_tasks clause are mutually exclusive and may |
10609 | // not appear on the same taskloop directive. |
10610 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) |
10611 | return StmtError(); |
10612 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10613 | // If a reduction clause is present on the taskloop directive, the nogroup |
10614 | // clause must not be specified. |
10615 | if (checkReductionClauseWithNogroup(*this, Clauses)) |
10616 | return StmtError(); |
10617 | |
10618 | setFunctionHasBranchProtectedScope(); |
10619 | return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, |
10620 | NestedLoopCount, Clauses, AStmt, B, |
10621 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
10622 | } |
10623 | |
10624 | StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( |
10625 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10626 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10627 | if (!AStmt) |
10628 | return StmtError(); |
10629 | |
10630 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10630, __PRETTY_FUNCTION__)); |
10631 | OMPLoopDirective::HelperExprs B; |
10632 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
10633 | // define the nested loops number. |
10634 | unsigned NestedLoopCount = |
10635 | checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), |
10636 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10637 | VarsWithImplicitDSA, B); |
10638 | if (NestedLoopCount == 0) |
10639 | return StmtError(); |
10640 | |
10641 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10642, __PRETTY_FUNCTION__)) |
10642 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10642, __PRETTY_FUNCTION__)); |
10643 | |
10644 | if (!CurContext->isDependentContext()) { |
10645 | // Finalize the clauses that need pre-built expressions for CodeGen. |
10646 | for (OMPClause *C : Clauses) { |
10647 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
10648 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
10649 | B.NumIterations, *this, CurScope, |
10650 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
10651 | return StmtError(); |
10652 | } |
10653 | } |
10654 | |
10655 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10656 | // The grainsize clause and num_tasks clause are mutually exclusive and may |
10657 | // not appear on the same taskloop directive. |
10658 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) |
10659 | return StmtError(); |
10660 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10661 | // If a reduction clause is present on the taskloop directive, the nogroup |
10662 | // clause must not be specified. |
10663 | if (checkReductionClauseWithNogroup(*this, Clauses)) |
10664 | return StmtError(); |
10665 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
10666 | return StmtError(); |
10667 | |
10668 | setFunctionHasBranchProtectedScope(); |
10669 | return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, |
10670 | NestedLoopCount, Clauses, AStmt, B); |
10671 | } |
10672 | |
10673 | StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( |
10674 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10675 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10676 | if (!AStmt) |
10677 | return StmtError(); |
10678 | |
10679 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10679, __PRETTY_FUNCTION__)); |
10680 | OMPLoopDirective::HelperExprs B; |
10681 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
10682 | // define the nested loops number. |
10683 | unsigned NestedLoopCount = |
10684 | checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), |
10685 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10686 | VarsWithImplicitDSA, B); |
10687 | if (NestedLoopCount == 0) |
10688 | return StmtError(); |
10689 | |
10690 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10691, __PRETTY_FUNCTION__)) |
10691 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10691, __PRETTY_FUNCTION__)); |
10692 | |
10693 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10694 | // The grainsize clause and num_tasks clause are mutually exclusive and may |
10695 | // not appear on the same taskloop directive. |
10696 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) |
10697 | return StmtError(); |
10698 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10699 | // If a reduction clause is present on the taskloop directive, the nogroup |
10700 | // clause must not be specified. |
10701 | if (checkReductionClauseWithNogroup(*this, Clauses)) |
10702 | return StmtError(); |
10703 | |
10704 | setFunctionHasBranchProtectedScope(); |
10705 | return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, |
10706 | NestedLoopCount, Clauses, AStmt, B, |
10707 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
10708 | } |
10709 | |
10710 | StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( |
10711 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10712 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10713 | if (!AStmt) |
10714 | return StmtError(); |
10715 | |
10716 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10716, __PRETTY_FUNCTION__)); |
10717 | OMPLoopDirective::HelperExprs B; |
10718 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
10719 | // define the nested loops number. |
10720 | unsigned NestedLoopCount = |
10721 | checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), |
10722 | /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10723 | VarsWithImplicitDSA, B); |
10724 | if (NestedLoopCount == 0) |
10725 | return StmtError(); |
10726 | |
10727 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10728, __PRETTY_FUNCTION__)) |
10728 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10728, __PRETTY_FUNCTION__)); |
10729 | |
10730 | if (!CurContext->isDependentContext()) { |
10731 | // Finalize the clauses that need pre-built expressions for CodeGen. |
10732 | for (OMPClause *C : Clauses) { |
10733 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
10734 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
10735 | B.NumIterations, *this, CurScope, |
10736 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
10737 | return StmtError(); |
10738 | } |
10739 | } |
10740 | |
10741 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10742 | // The grainsize clause and num_tasks clause are mutually exclusive and may |
10743 | // not appear on the same taskloop directive. |
10744 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) |
10745 | return StmtError(); |
10746 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10747 | // If a reduction clause is present on the taskloop directive, the nogroup |
10748 | // clause must not be specified. |
10749 | if (checkReductionClauseWithNogroup(*this, Clauses)) |
10750 | return StmtError(); |
10751 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
10752 | return StmtError(); |
10753 | |
10754 | setFunctionHasBranchProtectedScope(); |
10755 | return OMPMasterTaskLoopSimdDirective::Create( |
10756 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
10757 | } |
10758 | |
10759 | StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( |
10760 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10761 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10762 | if (!AStmt) |
10763 | return StmtError(); |
10764 | |
10765 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10765, __PRETTY_FUNCTION__)); |
10766 | auto *CS = cast<CapturedStmt>(AStmt); |
10767 | // 1.2.2 OpenMP Language Terminology |
10768 | // Structured block - An executable statement with a single entry at the |
10769 | // top and a single exit at the bottom. |
10770 | // The point of exit cannot be a branch out of the structured block. |
10771 | // longjmp() and throw() must not violate the entry/exit criteria. |
10772 | CS->getCapturedDecl()->setNothrow(); |
10773 | for (int ThisCaptureLevel = |
10774 | getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); |
10775 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10776 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10777 | // 1.2.2 OpenMP Language Terminology |
10778 | // Structured block - An executable statement with a single entry at the |
10779 | // top and a single exit at the bottom. |
10780 | // The point of exit cannot be a branch out of the structured block. |
10781 | // longjmp() and throw() must not violate the entry/exit criteria. |
10782 | CS->getCapturedDecl()->setNothrow(); |
10783 | } |
10784 | |
10785 | OMPLoopDirective::HelperExprs B; |
10786 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
10787 | // define the nested loops number. |
10788 | unsigned NestedLoopCount = checkOpenMPLoop( |
10789 | OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), |
10790 | /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10791 | VarsWithImplicitDSA, B); |
10792 | if (NestedLoopCount == 0) |
10793 | return StmtError(); |
10794 | |
10795 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10796, __PRETTY_FUNCTION__)) |
10796 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10796, __PRETTY_FUNCTION__)); |
10797 | |
10798 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10799 | // The grainsize clause and num_tasks clause are mutually exclusive and may |
10800 | // not appear on the same taskloop directive. |
10801 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) |
10802 | return StmtError(); |
10803 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10804 | // If a reduction clause is present on the taskloop directive, the nogroup |
10805 | // clause must not be specified. |
10806 | if (checkReductionClauseWithNogroup(*this, Clauses)) |
10807 | return StmtError(); |
10808 | |
10809 | setFunctionHasBranchProtectedScope(); |
10810 | return OMPParallelMasterTaskLoopDirective::Create( |
10811 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
10812 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
10813 | } |
10814 | |
10815 | StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( |
10816 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10817 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10818 | if (!AStmt) |
10819 | return StmtError(); |
10820 | |
10821 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10821, __PRETTY_FUNCTION__)); |
10822 | auto *CS = cast<CapturedStmt>(AStmt); |
10823 | // 1.2.2 OpenMP Language Terminology |
10824 | // Structured block - An executable statement with a single entry at the |
10825 | // top and a single exit at the bottom. |
10826 | // The point of exit cannot be a branch out of the structured block. |
10827 | // longjmp() and throw() must not violate the entry/exit criteria. |
10828 | CS->getCapturedDecl()->setNothrow(); |
10829 | for (int ThisCaptureLevel = |
10830 | getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); |
10831 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10832 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10833 | // 1.2.2 OpenMP Language Terminology |
10834 | // Structured block - An executable statement with a single entry at the |
10835 | // top and a single exit at the bottom. |
10836 | // The point of exit cannot be a branch out of the structured block. |
10837 | // longjmp() and throw() must not violate the entry/exit criteria. |
10838 | CS->getCapturedDecl()->setNothrow(); |
10839 | } |
10840 | |
10841 | OMPLoopDirective::HelperExprs B; |
10842 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
10843 | // define the nested loops number. |
10844 | unsigned NestedLoopCount = checkOpenMPLoop( |
10845 | OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), |
10846 | /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10847 | VarsWithImplicitDSA, B); |
10848 | if (NestedLoopCount == 0) |
10849 | return StmtError(); |
10850 | |
10851 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10852, __PRETTY_FUNCTION__)) |
10852 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10852, __PRETTY_FUNCTION__)); |
10853 | |
10854 | if (!CurContext->isDependentContext()) { |
10855 | // Finalize the clauses that need pre-built expressions for CodeGen. |
10856 | for (OMPClause *C : Clauses) { |
10857 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
10858 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
10859 | B.NumIterations, *this, CurScope, |
10860 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
10861 | return StmtError(); |
10862 | } |
10863 | } |
10864 | |
10865 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10866 | // The grainsize clause and num_tasks clause are mutually exclusive and may |
10867 | // not appear on the same taskloop directive. |
10868 | if (checkGrainsizeNumTasksClauses(*this, Clauses)) |
10869 | return StmtError(); |
10870 | // OpenMP, [2.9.2 taskloop Construct, Restrictions] |
10871 | // If a reduction clause is present on the taskloop directive, the nogroup |
10872 | // clause must not be specified. |
10873 | if (checkReductionClauseWithNogroup(*this, Clauses)) |
10874 | return StmtError(); |
10875 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
10876 | return StmtError(); |
10877 | |
10878 | setFunctionHasBranchProtectedScope(); |
10879 | return OMPParallelMasterTaskLoopSimdDirective::Create( |
10880 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
10881 | } |
10882 | |
10883 | StmtResult Sema::ActOnOpenMPDistributeDirective( |
10884 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10885 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10886 | if (!AStmt) |
10887 | return StmtError(); |
10888 | |
10889 | assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10889, __PRETTY_FUNCTION__)); |
10890 | OMPLoopDirective::HelperExprs B; |
10891 | // In presence of clause 'collapse' with number of loops, it will |
10892 | // define the nested loops number. |
10893 | unsigned NestedLoopCount = |
10894 | checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), |
10895 | nullptr /*ordered not a clause on distribute*/, AStmt, |
10896 | *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); |
10897 | if (NestedLoopCount == 0) |
10898 | return StmtError(); |
10899 | |
10900 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10901, __PRETTY_FUNCTION__)) |
10901 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10901, __PRETTY_FUNCTION__)); |
10902 | |
10903 | setFunctionHasBranchProtectedScope(); |
10904 | return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, |
10905 | NestedLoopCount, Clauses, AStmt, B); |
10906 | } |
10907 | |
10908 | StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( |
10909 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10910 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10911 | if (!AStmt) |
10912 | return StmtError(); |
10913 | |
10914 | auto *CS = cast<CapturedStmt>(AStmt); |
10915 | // 1.2.2 OpenMP Language Terminology |
10916 | // Structured block - An executable statement with a single entry at the |
10917 | // top and a single exit at the bottom. |
10918 | // The point of exit cannot be a branch out of the structured block. |
10919 | // longjmp() and throw() must not violate the entry/exit criteria. |
10920 | CS->getCapturedDecl()->setNothrow(); |
10921 | for (int ThisCaptureLevel = |
10922 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for); |
10923 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10924 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10925 | // 1.2.2 OpenMP Language Terminology |
10926 | // Structured block - An executable statement with a single entry at the |
10927 | // top and a single exit at the bottom. |
10928 | // The point of exit cannot be a branch out of the structured block. |
10929 | // longjmp() and throw() must not violate the entry/exit criteria. |
10930 | CS->getCapturedDecl()->setNothrow(); |
10931 | } |
10932 | |
10933 | OMPLoopDirective::HelperExprs B; |
10934 | // In presence of clause 'collapse' with number of loops, it will |
10935 | // define the nested loops number. |
10936 | unsigned NestedLoopCount = checkOpenMPLoop( |
10937 | OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), |
10938 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10939 | VarsWithImplicitDSA, B); |
10940 | if (NestedLoopCount == 0) |
10941 | return StmtError(); |
10942 | |
10943 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10944, __PRETTY_FUNCTION__)) |
10944 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10944, __PRETTY_FUNCTION__)); |
10945 | |
10946 | setFunctionHasBranchProtectedScope(); |
10947 | return OMPDistributeParallelForDirective::Create( |
10948 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
10949 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
10950 | } |
10951 | |
10952 | StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( |
10953 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
10954 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
10955 | if (!AStmt) |
10956 | return StmtError(); |
10957 | |
10958 | auto *CS = cast<CapturedStmt>(AStmt); |
10959 | // 1.2.2 OpenMP Language Terminology |
10960 | // Structured block - An executable statement with a single entry at the |
10961 | // top and a single exit at the bottom. |
10962 | // The point of exit cannot be a branch out of the structured block. |
10963 | // longjmp() and throw() must not violate the entry/exit criteria. |
10964 | CS->getCapturedDecl()->setNothrow(); |
10965 | for (int ThisCaptureLevel = |
10966 | getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); |
10967 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
10968 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
10969 | // 1.2.2 OpenMP Language Terminology |
10970 | // Structured block - An executable statement with a single entry at the |
10971 | // top and a single exit at the bottom. |
10972 | // The point of exit cannot be a branch out of the structured block. |
10973 | // longjmp() and throw() must not violate the entry/exit criteria. |
10974 | CS->getCapturedDecl()->setNothrow(); |
10975 | } |
10976 | |
10977 | OMPLoopDirective::HelperExprs B; |
10978 | // In presence of clause 'collapse' with number of loops, it will |
10979 | // define the nested loops number. |
10980 | unsigned NestedLoopCount = checkOpenMPLoop( |
10981 | OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), |
10982 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
10983 | VarsWithImplicitDSA, B); |
10984 | if (NestedLoopCount == 0) |
10985 | return StmtError(); |
10986 | |
10987 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10988, __PRETTY_FUNCTION__)) |
10988 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 10988, __PRETTY_FUNCTION__)); |
10989 | |
10990 | if (!CurContext->isDependentContext()) { |
10991 | // Finalize the clauses that need pre-built expressions for CodeGen. |
10992 | for (OMPClause *C : Clauses) { |
10993 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
10994 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
10995 | B.NumIterations, *this, CurScope, |
10996 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
10997 | return StmtError(); |
10998 | } |
10999 | } |
11000 | |
11001 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11002 | return StmtError(); |
11003 | |
11004 | setFunctionHasBranchProtectedScope(); |
11005 | return OMPDistributeParallelForSimdDirective::Create( |
11006 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11007 | } |
11008 | |
11009 | StmtResult Sema::ActOnOpenMPDistributeSimdDirective( |
11010 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11011 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11012 | if (!AStmt) |
11013 | return StmtError(); |
11014 | |
11015 | auto *CS = cast<CapturedStmt>(AStmt); |
11016 | // 1.2.2 OpenMP Language Terminology |
11017 | // Structured block - An executable statement with a single entry at the |
11018 | // top and a single exit at the bottom. |
11019 | // The point of exit cannot be a branch out of the structured block. |
11020 | // longjmp() and throw() must not violate the entry/exit criteria. |
11021 | CS->getCapturedDecl()->setNothrow(); |
11022 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); |
11023 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11024 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11025 | // 1.2.2 OpenMP Language Terminology |
11026 | // Structured block - An executable statement with a single entry at the |
11027 | // top and a single exit at the bottom. |
11028 | // The point of exit cannot be a branch out of the structured block. |
11029 | // longjmp() and throw() must not violate the entry/exit criteria. |
11030 | CS->getCapturedDecl()->setNothrow(); |
11031 | } |
11032 | |
11033 | OMPLoopDirective::HelperExprs B; |
11034 | // In presence of clause 'collapse' with number of loops, it will |
11035 | // define the nested loops number. |
11036 | unsigned NestedLoopCount = |
11037 | checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), |
11038 | nullptr /*ordered not a clause on distribute*/, CS, *this, |
11039 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); |
11040 | if (NestedLoopCount == 0) |
11041 | return StmtError(); |
11042 | |
11043 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11044, __PRETTY_FUNCTION__)) |
11044 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11044, __PRETTY_FUNCTION__)); |
11045 | |
11046 | if (!CurContext->isDependentContext()) { |
11047 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11048 | for (OMPClause *C : Clauses) { |
11049 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11050 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11051 | B.NumIterations, *this, CurScope, |
11052 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11053 | return StmtError(); |
11054 | } |
11055 | } |
11056 | |
11057 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11058 | return StmtError(); |
11059 | |
11060 | setFunctionHasBranchProtectedScope(); |
11061 | return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, |
11062 | NestedLoopCount, Clauses, AStmt, B); |
11063 | } |
11064 | |
11065 | StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( |
11066 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11067 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11068 | if (!AStmt) |
11069 | return StmtError(); |
11070 | |
11071 | auto *CS = cast<CapturedStmt>(AStmt); |
11072 | // 1.2.2 OpenMP Language Terminology |
11073 | // Structured block - An executable statement with a single entry at the |
11074 | // top and a single exit at the bottom. |
11075 | // The point of exit cannot be a branch out of the structured block. |
11076 | // longjmp() and throw() must not violate the entry/exit criteria. |
11077 | CS->getCapturedDecl()->setNothrow(); |
11078 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); |
11079 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11080 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11081 | // 1.2.2 OpenMP Language Terminology |
11082 | // Structured block - An executable statement with a single entry at the |
11083 | // top and a single exit at the bottom. |
11084 | // The point of exit cannot be a branch out of the structured block. |
11085 | // longjmp() and throw() must not violate the entry/exit criteria. |
11086 | CS->getCapturedDecl()->setNothrow(); |
11087 | } |
11088 | |
11089 | OMPLoopDirective::HelperExprs B; |
11090 | // In presence of clause 'collapse' or 'ordered' with number of loops, it will |
11091 | // define the nested loops number. |
11092 | unsigned NestedLoopCount = checkOpenMPLoop( |
11093 | OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), |
11094 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11095 | VarsWithImplicitDSA, B); |
11096 | if (NestedLoopCount == 0) |
11097 | return StmtError(); |
11098 | |
11099 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11100, __PRETTY_FUNCTION__)) |
11100 | "omp target parallel for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target parallel for simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11100, __PRETTY_FUNCTION__)); |
11101 | |
11102 | if (!CurContext->isDependentContext()) { |
11103 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11104 | for (OMPClause *C : Clauses) { |
11105 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11106 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11107 | B.NumIterations, *this, CurScope, |
11108 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11109 | return StmtError(); |
11110 | } |
11111 | } |
11112 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11113 | return StmtError(); |
11114 | |
11115 | setFunctionHasBranchProtectedScope(); |
11116 | return OMPTargetParallelForSimdDirective::Create( |
11117 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11118 | } |
11119 | |
11120 | StmtResult Sema::ActOnOpenMPTargetSimdDirective( |
11121 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11122 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11123 | if (!AStmt) |
11124 | return StmtError(); |
11125 | |
11126 | auto *CS = cast<CapturedStmt>(AStmt); |
11127 | // 1.2.2 OpenMP Language Terminology |
11128 | // Structured block - An executable statement with a single entry at the |
11129 | // top and a single exit at the bottom. |
11130 | // The point of exit cannot be a branch out of the structured block. |
11131 | // longjmp() and throw() must not violate the entry/exit criteria. |
11132 | CS->getCapturedDecl()->setNothrow(); |
11133 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); |
11134 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11135 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11136 | // 1.2.2 OpenMP Language Terminology |
11137 | // Structured block - An executable statement with a single entry at the |
11138 | // top and a single exit at the bottom. |
11139 | // The point of exit cannot be a branch out of the structured block. |
11140 | // longjmp() and throw() must not violate the entry/exit criteria. |
11141 | CS->getCapturedDecl()->setNothrow(); |
11142 | } |
11143 | |
11144 | OMPLoopDirective::HelperExprs B; |
11145 | // In presence of clause 'collapse' with number of loops, it will define the |
11146 | // nested loops number. |
11147 | unsigned NestedLoopCount = |
11148 | checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), |
11149 | getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11150 | VarsWithImplicitDSA, B); |
11151 | if (NestedLoopCount == 0) |
11152 | return StmtError(); |
11153 | |
11154 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target simd loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11155, __PRETTY_FUNCTION__)) |
11155 | "omp target simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target simd loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11155, __PRETTY_FUNCTION__)); |
11156 | |
11157 | if (!CurContext->isDependentContext()) { |
11158 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11159 | for (OMPClause *C : Clauses) { |
11160 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11161 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11162 | B.NumIterations, *this, CurScope, |
11163 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11164 | return StmtError(); |
11165 | } |
11166 | } |
11167 | |
11168 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11169 | return StmtError(); |
11170 | |
11171 | setFunctionHasBranchProtectedScope(); |
11172 | return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, |
11173 | NestedLoopCount, Clauses, AStmt, B); |
11174 | } |
11175 | |
11176 | StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( |
11177 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11178 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11179 | if (!AStmt) |
11180 | return StmtError(); |
11181 | |
11182 | auto *CS = cast<CapturedStmt>(AStmt); |
11183 | // 1.2.2 OpenMP Language Terminology |
11184 | // Structured block - An executable statement with a single entry at the |
11185 | // top and a single exit at the bottom. |
11186 | // The point of exit cannot be a branch out of the structured block. |
11187 | // longjmp() and throw() must not violate the entry/exit criteria. |
11188 | CS->getCapturedDecl()->setNothrow(); |
11189 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); |
11190 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11191 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11192 | // 1.2.2 OpenMP Language Terminology |
11193 | // Structured block - An executable statement with a single entry at the |
11194 | // top and a single exit at the bottom. |
11195 | // The point of exit cannot be a branch out of the structured block. |
11196 | // longjmp() and throw() must not violate the entry/exit criteria. |
11197 | CS->getCapturedDecl()->setNothrow(); |
11198 | } |
11199 | |
11200 | OMPLoopDirective::HelperExprs B; |
11201 | // In presence of clause 'collapse' with number of loops, it will |
11202 | // define the nested loops number. |
11203 | unsigned NestedLoopCount = |
11204 | checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), |
11205 | nullptr /*ordered not a clause on distribute*/, CS, *this, |
11206 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); |
11207 | if (NestedLoopCount == 0) |
11208 | return StmtError(); |
11209 | |
11210 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11211, __PRETTY_FUNCTION__)) |
11211 | "omp teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11211, __PRETTY_FUNCTION__)); |
11212 | |
11213 | setFunctionHasBranchProtectedScope(); |
11214 | |
11215 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); |
11216 | |
11217 | return OMPTeamsDistributeDirective::Create( |
11218 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11219 | } |
11220 | |
11221 | StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( |
11222 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11223 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11224 | if (!AStmt) |
11225 | return StmtError(); |
11226 | |
11227 | auto *CS = cast<CapturedStmt>(AStmt); |
11228 | // 1.2.2 OpenMP Language Terminology |
11229 | // Structured block - An executable statement with a single entry at the |
11230 | // top and a single exit at the bottom. |
11231 | // The point of exit cannot be a branch out of the structured block. |
11232 | // longjmp() and throw() must not violate the entry/exit criteria. |
11233 | CS->getCapturedDecl()->setNothrow(); |
11234 | for (int ThisCaptureLevel = |
11235 | getOpenMPCaptureLevels(OMPD_teams_distribute_simd); |
11236 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11237 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11238 | // 1.2.2 OpenMP Language Terminology |
11239 | // Structured block - An executable statement with a single entry at the |
11240 | // top and a single exit at the bottom. |
11241 | // The point of exit cannot be a branch out of the structured block. |
11242 | // longjmp() and throw() must not violate the entry/exit criteria. |
11243 | CS->getCapturedDecl()->setNothrow(); |
11244 | } |
11245 | |
11246 | OMPLoopDirective::HelperExprs B; |
11247 | // In presence of clause 'collapse' with number of loops, it will |
11248 | // define the nested loops number. |
11249 | unsigned NestedLoopCount = checkOpenMPLoop( |
11250 | OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), |
11251 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11252 | VarsWithImplicitDSA, B); |
11253 | |
11254 | if (NestedLoopCount == 0) |
11255 | return StmtError(); |
11256 | |
11257 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11258, __PRETTY_FUNCTION__)) |
11258 | "omp teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp teams distribute simd loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11258, __PRETTY_FUNCTION__)); |
11259 | |
11260 | if (!CurContext->isDependentContext()) { |
11261 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11262 | for (OMPClause *C : Clauses) { |
11263 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11264 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11265 | B.NumIterations, *this, CurScope, |
11266 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11267 | return StmtError(); |
11268 | } |
11269 | } |
11270 | |
11271 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11272 | return StmtError(); |
11273 | |
11274 | setFunctionHasBranchProtectedScope(); |
11275 | |
11276 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); |
11277 | |
11278 | return OMPTeamsDistributeSimdDirective::Create( |
11279 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11280 | } |
11281 | |
11282 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( |
11283 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11284 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11285 | if (!AStmt) |
11286 | return StmtError(); |
11287 | |
11288 | auto *CS = cast<CapturedStmt>(AStmt); |
11289 | // 1.2.2 OpenMP Language Terminology |
11290 | // Structured block - An executable statement with a single entry at the |
11291 | // top and a single exit at the bottom. |
11292 | // The point of exit cannot be a branch out of the structured block. |
11293 | // longjmp() and throw() must not violate the entry/exit criteria. |
11294 | CS->getCapturedDecl()->setNothrow(); |
11295 | |
11296 | for (int ThisCaptureLevel = |
11297 | getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); |
11298 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11299 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11300 | // 1.2.2 OpenMP Language Terminology |
11301 | // Structured block - An executable statement with a single entry at the |
11302 | // top and a single exit at the bottom. |
11303 | // The point of exit cannot be a branch out of the structured block. |
11304 | // longjmp() and throw() must not violate the entry/exit criteria. |
11305 | CS->getCapturedDecl()->setNothrow(); |
11306 | } |
11307 | |
11308 | OMPLoopDirective::HelperExprs B; |
11309 | // In presence of clause 'collapse' with number of loops, it will |
11310 | // define the nested loops number. |
11311 | unsigned NestedLoopCount = checkOpenMPLoop( |
11312 | OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), |
11313 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11314 | VarsWithImplicitDSA, B); |
11315 | |
11316 | if (NestedLoopCount == 0) |
11317 | return StmtError(); |
11318 | |
11319 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11320, __PRETTY_FUNCTION__)) |
11320 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11320, __PRETTY_FUNCTION__)); |
11321 | |
11322 | if (!CurContext->isDependentContext()) { |
11323 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11324 | for (OMPClause *C : Clauses) { |
11325 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11326 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11327 | B.NumIterations, *this, CurScope, |
11328 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11329 | return StmtError(); |
11330 | } |
11331 | } |
11332 | |
11333 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11334 | return StmtError(); |
11335 | |
11336 | setFunctionHasBranchProtectedScope(); |
11337 | |
11338 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); |
11339 | |
11340 | return OMPTeamsDistributeParallelForSimdDirective::Create( |
11341 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11342 | } |
11343 | |
11344 | StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( |
11345 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11346 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11347 | if (!AStmt) |
11348 | return StmtError(); |
11349 | |
11350 | auto *CS = cast<CapturedStmt>(AStmt); |
11351 | // 1.2.2 OpenMP Language Terminology |
11352 | // Structured block - An executable statement with a single entry at the |
11353 | // top and a single exit at the bottom. |
11354 | // The point of exit cannot be a branch out of the structured block. |
11355 | // longjmp() and throw() must not violate the entry/exit criteria. |
11356 | CS->getCapturedDecl()->setNothrow(); |
11357 | |
11358 | for (int ThisCaptureLevel = |
11359 | getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); |
11360 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11361 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11362 | // 1.2.2 OpenMP Language Terminology |
11363 | // Structured block - An executable statement with a single entry at the |
11364 | // top and a single exit at the bottom. |
11365 | // The point of exit cannot be a branch out of the structured block. |
11366 | // longjmp() and throw() must not violate the entry/exit criteria. |
11367 | CS->getCapturedDecl()->setNothrow(); |
11368 | } |
11369 | |
11370 | OMPLoopDirective::HelperExprs B; |
11371 | // In presence of clause 'collapse' with number of loops, it will |
11372 | // define the nested loops number. |
11373 | unsigned NestedLoopCount = checkOpenMPLoop( |
11374 | OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), |
11375 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11376 | VarsWithImplicitDSA, B); |
11377 | |
11378 | if (NestedLoopCount == 0) |
11379 | return StmtError(); |
11380 | |
11381 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11382, __PRETTY_FUNCTION__)) |
11382 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11382, __PRETTY_FUNCTION__)); |
11383 | |
11384 | setFunctionHasBranchProtectedScope(); |
11385 | |
11386 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setParentTeamsRegionLoc(StartLoc); |
11387 | |
11388 | return OMPTeamsDistributeParallelForDirective::Create( |
11389 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
11390 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
11391 | } |
11392 | |
11393 | StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, |
11394 | Stmt *AStmt, |
11395 | 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 | for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); |
11409 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11410 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11411 | // 1.2.2 OpenMP Language Terminology |
11412 | // Structured block - An executable statement with a single entry at the |
11413 | // top and a single exit at the bottom. |
11414 | // The point of exit cannot be a branch out of the structured block. |
11415 | // longjmp() and throw() must not violate the entry/exit criteria. |
11416 | CS->getCapturedDecl()->setNothrow(); |
11417 | } |
11418 | setFunctionHasBranchProtectedScope(); |
11419 | |
11420 | return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, |
11421 | AStmt); |
11422 | } |
11423 | |
11424 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( |
11425 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11426 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11427 | if (!AStmt) |
11428 | return StmtError(); |
11429 | |
11430 | auto *CS = cast<CapturedStmt>(AStmt); |
11431 | // 1.2.2 OpenMP Language Terminology |
11432 | // Structured block - An executable statement with a single entry at the |
11433 | // top and a single exit at the bottom. |
11434 | // The point of exit cannot be a branch out of the structured block. |
11435 | // longjmp() and throw() must not violate the entry/exit criteria. |
11436 | CS->getCapturedDecl()->setNothrow(); |
11437 | for (int ThisCaptureLevel = |
11438 | getOpenMPCaptureLevels(OMPD_target_teams_distribute); |
11439 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11440 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11441 | // 1.2.2 OpenMP Language Terminology |
11442 | // Structured block - An executable statement with a single entry at the |
11443 | // top and a single exit at the bottom. |
11444 | // The point of exit cannot be a branch out of the structured block. |
11445 | // longjmp() and throw() must not violate the entry/exit criteria. |
11446 | CS->getCapturedDecl()->setNothrow(); |
11447 | } |
11448 | |
11449 | OMPLoopDirective::HelperExprs B; |
11450 | // In presence of clause 'collapse' with number of loops, it will |
11451 | // define the nested loops number. |
11452 | unsigned NestedLoopCount = checkOpenMPLoop( |
11453 | OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), |
11454 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11455 | VarsWithImplicitDSA, B); |
11456 | if (NestedLoopCount == 0) |
11457 | return StmtError(); |
11458 | |
11459 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11460, __PRETTY_FUNCTION__)) |
11460 | "omp target teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute loop exprs were not built") ? static_cast <void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11460, __PRETTY_FUNCTION__)); |
11461 | |
11462 | setFunctionHasBranchProtectedScope(); |
11463 | return OMPTargetTeamsDistributeDirective::Create( |
11464 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11465 | } |
11466 | |
11467 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( |
11468 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11469 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11470 | if (!AStmt) |
11471 | return StmtError(); |
11472 | |
11473 | auto *CS = cast<CapturedStmt>(AStmt); |
11474 | // 1.2.2 OpenMP Language Terminology |
11475 | // Structured block - An executable statement with a single entry at the |
11476 | // top and a single exit at the bottom. |
11477 | // The point of exit cannot be a branch out of the structured block. |
11478 | // longjmp() and throw() must not violate the entry/exit criteria. |
11479 | CS->getCapturedDecl()->setNothrow(); |
11480 | for (int ThisCaptureLevel = |
11481 | getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); |
11482 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11483 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11484 | // 1.2.2 OpenMP Language Terminology |
11485 | // Structured block - An executable statement with a single entry at the |
11486 | // top and a single exit at the bottom. |
11487 | // The point of exit cannot be a branch out of the structured block. |
11488 | // longjmp() and throw() must not violate the entry/exit criteria. |
11489 | CS->getCapturedDecl()->setNothrow(); |
11490 | } |
11491 | |
11492 | OMPLoopDirective::HelperExprs B; |
11493 | // In presence of clause 'collapse' with number of loops, it will |
11494 | // define the nested loops number. |
11495 | unsigned NestedLoopCount = checkOpenMPLoop( |
11496 | OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), |
11497 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11498 | VarsWithImplicitDSA, B); |
11499 | if (NestedLoopCount == 0) |
11500 | return StmtError(); |
11501 | |
11502 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11503, __PRETTY_FUNCTION__)) |
11503 | "omp target teams distribute parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11503, __PRETTY_FUNCTION__)); |
11504 | |
11505 | if (!CurContext->isDependentContext()) { |
11506 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11507 | for (OMPClause *C : Clauses) { |
11508 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11509 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11510 | B.NumIterations, *this, CurScope, |
11511 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11512 | return StmtError(); |
11513 | } |
11514 | } |
11515 | |
11516 | setFunctionHasBranchProtectedScope(); |
11517 | return OMPTargetTeamsDistributeParallelForDirective::Create( |
11518 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, |
11519 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isCancelRegion()); |
11520 | } |
11521 | |
11522 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( |
11523 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11524 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11525 | if (!AStmt) |
11526 | return StmtError(); |
11527 | |
11528 | auto *CS = cast<CapturedStmt>(AStmt); |
11529 | // 1.2.2 OpenMP Language Terminology |
11530 | // Structured block - An executable statement with a single entry at the |
11531 | // top and a single exit at the bottom. |
11532 | // The point of exit cannot be a branch out of the structured block. |
11533 | // longjmp() and throw() must not violate the entry/exit criteria. |
11534 | CS->getCapturedDecl()->setNothrow(); |
11535 | for (int ThisCaptureLevel = getOpenMPCaptureLevels( |
11536 | OMPD_target_teams_distribute_parallel_for_simd); |
11537 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11538 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11539 | // 1.2.2 OpenMP Language Terminology |
11540 | // Structured block - An executable statement with a single entry at the |
11541 | // top and a single exit at the bottom. |
11542 | // The point of exit cannot be a branch out of the structured block. |
11543 | // longjmp() and throw() must not violate the entry/exit criteria. |
11544 | CS->getCapturedDecl()->setNothrow(); |
11545 | } |
11546 | |
11547 | OMPLoopDirective::HelperExprs B; |
11548 | // In presence of clause 'collapse' with number of loops, it will |
11549 | // define the nested loops number. |
11550 | unsigned NestedLoopCount = |
11551 | checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, |
11552 | getCollapseNumberExpr(Clauses), |
11553 | nullptr /*ordered not a clause on distribute*/, CS, *this, |
11554 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); |
11555 | if (NestedLoopCount == 0) |
11556 | return StmtError(); |
11557 | |
11558 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not " "built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11560, __PRETTY_FUNCTION__)) |
11559 | "omp target teams distribute parallel for simd loop exprs were not "(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not " "built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11560, __PRETTY_FUNCTION__)) |
11560 | "built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not " "built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11560, __PRETTY_FUNCTION__)); |
11561 | |
11562 | if (!CurContext->isDependentContext()) { |
11563 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11564 | for (OMPClause *C : Clauses) { |
11565 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11566 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11567 | B.NumIterations, *this, CurScope, |
11568 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11569 | return StmtError(); |
11570 | } |
11571 | } |
11572 | |
11573 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11574 | return StmtError(); |
11575 | |
11576 | setFunctionHasBranchProtectedScope(); |
11577 | return OMPTargetTeamsDistributeParallelForSimdDirective::Create( |
11578 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11579 | } |
11580 | |
11581 | StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( |
11582 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, |
11583 | SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { |
11584 | if (!AStmt) |
11585 | return StmtError(); |
11586 | |
11587 | auto *CS = cast<CapturedStmt>(AStmt); |
11588 | // 1.2.2 OpenMP Language Terminology |
11589 | // Structured block - An executable statement with a single entry at the |
11590 | // top and a single exit at the bottom. |
11591 | // The point of exit cannot be a branch out of the structured block. |
11592 | // longjmp() and throw() must not violate the entry/exit criteria. |
11593 | CS->getCapturedDecl()->setNothrow(); |
11594 | for (int ThisCaptureLevel = |
11595 | getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); |
11596 | ThisCaptureLevel > 1; --ThisCaptureLevel) { |
11597 | CS = cast<CapturedStmt>(CS->getCapturedStmt()); |
11598 | // 1.2.2 OpenMP Language Terminology |
11599 | // Structured block - An executable statement with a single entry at the |
11600 | // top and a single exit at the bottom. |
11601 | // The point of exit cannot be a branch out of the structured block. |
11602 | // longjmp() and throw() must not violate the entry/exit criteria. |
11603 | CS->getCapturedDecl()->setNothrow(); |
11604 | } |
11605 | |
11606 | OMPLoopDirective::HelperExprs B; |
11607 | // In presence of clause 'collapse' with number of loops, it will |
11608 | // define the nested loops number. |
11609 | unsigned NestedLoopCount = checkOpenMPLoop( |
11610 | OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), |
11611 | nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
11612 | VarsWithImplicitDSA, B); |
11613 | if (NestedLoopCount == 0) |
11614 | return StmtError(); |
11615 | |
11616 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11617, __PRETTY_FUNCTION__)) |
11617 | "omp target teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built" ) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11617, __PRETTY_FUNCTION__)); |
11618 | |
11619 | if (!CurContext->isDependentContext()) { |
11620 | // Finalize the clauses that need pre-built expressions for CodeGen. |
11621 | for (OMPClause *C : Clauses) { |
11622 | if (auto *LC = dyn_cast<OMPLinearClause>(C)) |
11623 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), |
11624 | B.NumIterations, *this, CurScope, |
11625 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
11626 | return StmtError(); |
11627 | } |
11628 | } |
11629 | |
11630 | if (checkSimdlenSafelenSpecified(*this, Clauses)) |
11631 | return StmtError(); |
11632 | |
11633 | setFunctionHasBranchProtectedScope(); |
11634 | return OMPTargetTeamsDistributeSimdDirective::Create( |
11635 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); |
11636 | } |
11637 | |
11638 | OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, |
11639 | SourceLocation StartLoc, |
11640 | SourceLocation LParenLoc, |
11641 | SourceLocation EndLoc) { |
11642 | OMPClause *Res = nullptr; |
11643 | switch (Kind) { |
11644 | case OMPC_final: |
11645 | Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); |
11646 | break; |
11647 | case OMPC_num_threads: |
11648 | Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); |
11649 | break; |
11650 | case OMPC_safelen: |
11651 | Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); |
11652 | break; |
11653 | case OMPC_simdlen: |
11654 | Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); |
11655 | break; |
11656 | case OMPC_allocator: |
11657 | Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); |
11658 | break; |
11659 | case OMPC_collapse: |
11660 | Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); |
11661 | break; |
11662 | case OMPC_ordered: |
11663 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); |
11664 | break; |
11665 | case OMPC_num_teams: |
11666 | Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); |
11667 | break; |
11668 | case OMPC_thread_limit: |
11669 | Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); |
11670 | break; |
11671 | case OMPC_priority: |
11672 | Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); |
11673 | break; |
11674 | case OMPC_grainsize: |
11675 | Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); |
11676 | break; |
11677 | case OMPC_num_tasks: |
11678 | Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); |
11679 | break; |
11680 | case OMPC_hint: |
11681 | Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); |
11682 | break; |
11683 | case OMPC_depobj: |
11684 | Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); |
11685 | break; |
11686 | case OMPC_detach: |
11687 | Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); |
11688 | break; |
11689 | case OMPC_device: |
11690 | case OMPC_if: |
11691 | case OMPC_default: |
11692 | case OMPC_proc_bind: |
11693 | case OMPC_schedule: |
11694 | case OMPC_private: |
11695 | case OMPC_firstprivate: |
11696 | case OMPC_lastprivate: |
11697 | case OMPC_shared: |
11698 | case OMPC_reduction: |
11699 | case OMPC_task_reduction: |
11700 | case OMPC_in_reduction: |
11701 | case OMPC_linear: |
11702 | case OMPC_aligned: |
11703 | case OMPC_copyin: |
11704 | case OMPC_copyprivate: |
11705 | case OMPC_nowait: |
11706 | case OMPC_untied: |
11707 | case OMPC_mergeable: |
11708 | case OMPC_threadprivate: |
11709 | case OMPC_allocate: |
11710 | case OMPC_flush: |
11711 | case OMPC_read: |
11712 | case OMPC_write: |
11713 | case OMPC_update: |
11714 | case OMPC_capture: |
11715 | case OMPC_seq_cst: |
11716 | case OMPC_acq_rel: |
11717 | case OMPC_acquire: |
11718 | case OMPC_release: |
11719 | case OMPC_relaxed: |
11720 | case OMPC_depend: |
11721 | case OMPC_threads: |
11722 | case OMPC_simd: |
11723 | case OMPC_map: |
11724 | case OMPC_nogroup: |
11725 | case OMPC_dist_schedule: |
11726 | case OMPC_defaultmap: |
11727 | case OMPC_unknown: |
11728 | case OMPC_uniform: |
11729 | case OMPC_to: |
11730 | case OMPC_from: |
11731 | case OMPC_use_device_ptr: |
11732 | case OMPC_use_device_addr: |
11733 | case OMPC_is_device_ptr: |
11734 | case OMPC_unified_address: |
11735 | case OMPC_unified_shared_memory: |
11736 | case OMPC_reverse_offload: |
11737 | case OMPC_dynamic_allocators: |
11738 | case OMPC_atomic_default_mem_order: |
11739 | case OMPC_device_type: |
11740 | case OMPC_match: |
11741 | case OMPC_nontemporal: |
11742 | case OMPC_order: |
11743 | case OMPC_destroy: |
11744 | case OMPC_inclusive: |
11745 | case OMPC_exclusive: |
11746 | case OMPC_uses_allocators: |
11747 | case OMPC_affinity: |
11748 | default: |
11749 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11749); |
11750 | } |
11751 | return Res; |
11752 | } |
11753 | |
11754 | // An OpenMP directive such as 'target parallel' has two captured regions: |
11755 | // for the 'target' and 'parallel' respectively. This function returns |
11756 | // the region in which to capture expressions associated with a clause. |
11757 | // A return value of OMPD_unknown signifies that the expression should not |
11758 | // be captured. |
11759 | static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( |
11760 | OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, |
11761 | OpenMPDirectiveKind NameModifier = OMPD_unknown) { |
11762 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; |
11763 | switch (CKind) { |
11764 | case OMPC_if: |
11765 | switch (DKind) { |
11766 | case OMPD_target_parallel_for_simd: |
11767 | if (OpenMPVersion >= 50 && |
11768 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { |
11769 | CaptureRegion = OMPD_parallel; |
11770 | break; |
11771 | } |
11772 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
11773 | case OMPD_target_parallel: |
11774 | case OMPD_target_parallel_for: |
11775 | // If this clause applies to the nested 'parallel' region, capture within |
11776 | // the 'target' region, otherwise do not capture. |
11777 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) |
11778 | CaptureRegion = OMPD_target; |
11779 | break; |
11780 | case OMPD_target_teams_distribute_parallel_for_simd: |
11781 | if (OpenMPVersion >= 50 && |
11782 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { |
11783 | CaptureRegion = OMPD_parallel; |
11784 | break; |
11785 | } |
11786 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
11787 | case OMPD_target_teams_distribute_parallel_for: |
11788 | // If this clause applies to the nested 'parallel' region, capture within |
11789 | // the 'teams' region, otherwise do not capture. |
11790 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) |
11791 | CaptureRegion = OMPD_teams; |
11792 | break; |
11793 | case OMPD_teams_distribute_parallel_for_simd: |
11794 | if (OpenMPVersion >= 50 && |
11795 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { |
11796 | CaptureRegion = OMPD_parallel; |
11797 | break; |
11798 | } |
11799 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
11800 | case OMPD_teams_distribute_parallel_for: |
11801 | CaptureRegion = OMPD_teams; |
11802 | break; |
11803 | case OMPD_target_update: |
11804 | case OMPD_target_enter_data: |
11805 | case OMPD_target_exit_data: |
11806 | CaptureRegion = OMPD_task; |
11807 | break; |
11808 | case OMPD_parallel_master_taskloop: |
11809 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) |
11810 | CaptureRegion = OMPD_parallel; |
11811 | break; |
11812 | case OMPD_parallel_master_taskloop_simd: |
11813 | if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || |
11814 | NameModifier == OMPD_taskloop) { |
11815 | CaptureRegion = OMPD_parallel; |
11816 | break; |
11817 | } |
11818 | if (OpenMPVersion <= 45) |
11819 | break; |
11820 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) |
11821 | CaptureRegion = OMPD_taskloop; |
11822 | break; |
11823 | case OMPD_parallel_for_simd: |
11824 | if (OpenMPVersion <= 45) |
11825 | break; |
11826 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) |
11827 | CaptureRegion = OMPD_parallel; |
11828 | break; |
11829 | case OMPD_taskloop_simd: |
11830 | case OMPD_master_taskloop_simd: |
11831 | if (OpenMPVersion <= 45) |
11832 | break; |
11833 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) |
11834 | CaptureRegion = OMPD_taskloop; |
11835 | break; |
11836 | case OMPD_distribute_parallel_for_simd: |
11837 | if (OpenMPVersion <= 45) |
11838 | break; |
11839 | if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) |
11840 | CaptureRegion = OMPD_parallel; |
11841 | break; |
11842 | case OMPD_target_simd: |
11843 | if (OpenMPVersion >= 50 && |
11844 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) |
11845 | CaptureRegion = OMPD_target; |
11846 | break; |
11847 | case OMPD_teams_distribute_simd: |
11848 | case OMPD_target_teams_distribute_simd: |
11849 | if (OpenMPVersion >= 50 && |
11850 | (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) |
11851 | CaptureRegion = OMPD_teams; |
11852 | break; |
11853 | case OMPD_cancel: |
11854 | case OMPD_parallel: |
11855 | case OMPD_parallel_master: |
11856 | case OMPD_parallel_sections: |
11857 | case OMPD_parallel_for: |
11858 | case OMPD_target: |
11859 | case OMPD_target_teams: |
11860 | case OMPD_target_teams_distribute: |
11861 | case OMPD_distribute_parallel_for: |
11862 | case OMPD_task: |
11863 | case OMPD_taskloop: |
11864 | case OMPD_master_taskloop: |
11865 | case OMPD_target_data: |
11866 | case OMPD_simd: |
11867 | case OMPD_for_simd: |
11868 | case OMPD_distribute_simd: |
11869 | // Do not capture if-clause expressions. |
11870 | break; |
11871 | case OMPD_threadprivate: |
11872 | case OMPD_allocate: |
11873 | case OMPD_taskyield: |
11874 | case OMPD_barrier: |
11875 | case OMPD_taskwait: |
11876 | case OMPD_cancellation_point: |
11877 | case OMPD_flush: |
11878 | case OMPD_depobj: |
11879 | case OMPD_scan: |
11880 | case OMPD_declare_reduction: |
11881 | case OMPD_declare_mapper: |
11882 | case OMPD_declare_simd: |
11883 | case OMPD_declare_variant: |
11884 | case OMPD_begin_declare_variant: |
11885 | case OMPD_end_declare_variant: |
11886 | case OMPD_declare_target: |
11887 | case OMPD_end_declare_target: |
11888 | case OMPD_teams: |
11889 | case OMPD_for: |
11890 | case OMPD_sections: |
11891 | case OMPD_section: |
11892 | case OMPD_single: |
11893 | case OMPD_master: |
11894 | case OMPD_critical: |
11895 | case OMPD_taskgroup: |
11896 | case OMPD_distribute: |
11897 | case OMPD_ordered: |
11898 | case OMPD_atomic: |
11899 | case OMPD_teams_distribute: |
11900 | case OMPD_requires: |
11901 | llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11901); |
11902 | case OMPD_unknown: |
11903 | default: |
11904 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11904); |
11905 | } |
11906 | break; |
11907 | case OMPC_num_threads: |
11908 | switch (DKind) { |
11909 | case OMPD_target_parallel: |
11910 | case OMPD_target_parallel_for: |
11911 | case OMPD_target_parallel_for_simd: |
11912 | CaptureRegion = OMPD_target; |
11913 | break; |
11914 | case OMPD_teams_distribute_parallel_for: |
11915 | case OMPD_teams_distribute_parallel_for_simd: |
11916 | case OMPD_target_teams_distribute_parallel_for: |
11917 | case OMPD_target_teams_distribute_parallel_for_simd: |
11918 | CaptureRegion = OMPD_teams; |
11919 | break; |
11920 | case OMPD_parallel: |
11921 | case OMPD_parallel_master: |
11922 | case OMPD_parallel_sections: |
11923 | case OMPD_parallel_for: |
11924 | case OMPD_parallel_for_simd: |
11925 | case OMPD_distribute_parallel_for: |
11926 | case OMPD_distribute_parallel_for_simd: |
11927 | case OMPD_parallel_master_taskloop: |
11928 | case OMPD_parallel_master_taskloop_simd: |
11929 | // Do not capture num_threads-clause expressions. |
11930 | break; |
11931 | case OMPD_target_data: |
11932 | case OMPD_target_enter_data: |
11933 | case OMPD_target_exit_data: |
11934 | case OMPD_target_update: |
11935 | case OMPD_target: |
11936 | case OMPD_target_simd: |
11937 | case OMPD_target_teams: |
11938 | case OMPD_target_teams_distribute: |
11939 | case OMPD_target_teams_distribute_simd: |
11940 | case OMPD_cancel: |
11941 | case OMPD_task: |
11942 | case OMPD_taskloop: |
11943 | case OMPD_taskloop_simd: |
11944 | case OMPD_master_taskloop: |
11945 | case OMPD_master_taskloop_simd: |
11946 | case OMPD_threadprivate: |
11947 | case OMPD_allocate: |
11948 | case OMPD_taskyield: |
11949 | case OMPD_barrier: |
11950 | case OMPD_taskwait: |
11951 | case OMPD_cancellation_point: |
11952 | case OMPD_flush: |
11953 | case OMPD_depobj: |
11954 | case OMPD_scan: |
11955 | case OMPD_declare_reduction: |
11956 | case OMPD_declare_mapper: |
11957 | case OMPD_declare_simd: |
11958 | case OMPD_declare_variant: |
11959 | case OMPD_begin_declare_variant: |
11960 | case OMPD_end_declare_variant: |
11961 | case OMPD_declare_target: |
11962 | case OMPD_end_declare_target: |
11963 | case OMPD_teams: |
11964 | case OMPD_simd: |
11965 | case OMPD_for: |
11966 | case OMPD_for_simd: |
11967 | case OMPD_sections: |
11968 | case OMPD_section: |
11969 | case OMPD_single: |
11970 | case OMPD_master: |
11971 | case OMPD_critical: |
11972 | case OMPD_taskgroup: |
11973 | case OMPD_distribute: |
11974 | case OMPD_ordered: |
11975 | case OMPD_atomic: |
11976 | case OMPD_distribute_simd: |
11977 | case OMPD_teams_distribute: |
11978 | case OMPD_teams_distribute_simd: |
11979 | case OMPD_requires: |
11980 | llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11980); |
11981 | case OMPD_unknown: |
11982 | default: |
11983 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 11983); |
11984 | } |
11985 | break; |
11986 | case OMPC_num_teams: |
11987 | switch (DKind) { |
11988 | case OMPD_target_teams: |
11989 | case OMPD_target_teams_distribute: |
11990 | case OMPD_target_teams_distribute_simd: |
11991 | case OMPD_target_teams_distribute_parallel_for: |
11992 | case OMPD_target_teams_distribute_parallel_for_simd: |
11993 | CaptureRegion = OMPD_target; |
11994 | break; |
11995 | case OMPD_teams_distribute_parallel_for: |
11996 | case OMPD_teams_distribute_parallel_for_simd: |
11997 | case OMPD_teams: |
11998 | case OMPD_teams_distribute: |
11999 | case OMPD_teams_distribute_simd: |
12000 | // Do not capture num_teams-clause expressions. |
12001 | break; |
12002 | case OMPD_distribute_parallel_for: |
12003 | case OMPD_distribute_parallel_for_simd: |
12004 | case OMPD_task: |
12005 | case OMPD_taskloop: |
12006 | case OMPD_taskloop_simd: |
12007 | case OMPD_master_taskloop: |
12008 | case OMPD_master_taskloop_simd: |
12009 | case OMPD_parallel_master_taskloop: |
12010 | case OMPD_parallel_master_taskloop_simd: |
12011 | case OMPD_target_data: |
12012 | case OMPD_target_enter_data: |
12013 | case OMPD_target_exit_data: |
12014 | case OMPD_target_update: |
12015 | case OMPD_cancel: |
12016 | case OMPD_parallel: |
12017 | case OMPD_parallel_master: |
12018 | case OMPD_parallel_sections: |
12019 | case OMPD_parallel_for: |
12020 | case OMPD_parallel_for_simd: |
12021 | case OMPD_target: |
12022 | case OMPD_target_simd: |
12023 | case OMPD_target_parallel: |
12024 | case OMPD_target_parallel_for: |
12025 | case OMPD_target_parallel_for_simd: |
12026 | case OMPD_threadprivate: |
12027 | case OMPD_allocate: |
12028 | case OMPD_taskyield: |
12029 | case OMPD_barrier: |
12030 | case OMPD_taskwait: |
12031 | case OMPD_cancellation_point: |
12032 | case OMPD_flush: |
12033 | case OMPD_depobj: |
12034 | case OMPD_scan: |
12035 | case OMPD_declare_reduction: |
12036 | case OMPD_declare_mapper: |
12037 | case OMPD_declare_simd: |
12038 | case OMPD_declare_variant: |
12039 | case OMPD_begin_declare_variant: |
12040 | case OMPD_end_declare_variant: |
12041 | case OMPD_declare_target: |
12042 | case OMPD_end_declare_target: |
12043 | case OMPD_simd: |
12044 | case OMPD_for: |
12045 | case OMPD_for_simd: |
12046 | case OMPD_sections: |
12047 | case OMPD_section: |
12048 | case OMPD_single: |
12049 | case OMPD_master: |
12050 | case OMPD_critical: |
12051 | case OMPD_taskgroup: |
12052 | case OMPD_distribute: |
12053 | case OMPD_ordered: |
12054 | case OMPD_atomic: |
12055 | case OMPD_distribute_simd: |
12056 | case OMPD_requires: |
12057 | llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12057); |
12058 | case OMPD_unknown: |
12059 | default: |
12060 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12060); |
12061 | } |
12062 | break; |
12063 | case OMPC_thread_limit: |
12064 | switch (DKind) { |
12065 | case OMPD_target_teams: |
12066 | case OMPD_target_teams_distribute: |
12067 | case OMPD_target_teams_distribute_simd: |
12068 | case OMPD_target_teams_distribute_parallel_for: |
12069 | case OMPD_target_teams_distribute_parallel_for_simd: |
12070 | CaptureRegion = OMPD_target; |
12071 | break; |
12072 | case OMPD_teams_distribute_parallel_for: |
12073 | case OMPD_teams_distribute_parallel_for_simd: |
12074 | case OMPD_teams: |
12075 | case OMPD_teams_distribute: |
12076 | case OMPD_teams_distribute_simd: |
12077 | // Do not capture thread_limit-clause expressions. |
12078 | break; |
12079 | case OMPD_distribute_parallel_for: |
12080 | case OMPD_distribute_parallel_for_simd: |
12081 | case OMPD_task: |
12082 | case OMPD_taskloop: |
12083 | case OMPD_taskloop_simd: |
12084 | case OMPD_master_taskloop: |
12085 | case OMPD_master_taskloop_simd: |
12086 | case OMPD_parallel_master_taskloop: |
12087 | case OMPD_parallel_master_taskloop_simd: |
12088 | case OMPD_target_data: |
12089 | case OMPD_target_enter_data: |
12090 | case OMPD_target_exit_data: |
12091 | case OMPD_target_update: |
12092 | case OMPD_cancel: |
12093 | case OMPD_parallel: |
12094 | case OMPD_parallel_master: |
12095 | case OMPD_parallel_sections: |
12096 | case OMPD_parallel_for: |
12097 | case OMPD_parallel_for_simd: |
12098 | case OMPD_target: |
12099 | case OMPD_target_simd: |
12100 | case OMPD_target_parallel: |
12101 | case OMPD_target_parallel_for: |
12102 | case OMPD_target_parallel_for_simd: |
12103 | case OMPD_threadprivate: |
12104 | case OMPD_allocate: |
12105 | case OMPD_taskyield: |
12106 | case OMPD_barrier: |
12107 | case OMPD_taskwait: |
12108 | case OMPD_cancellation_point: |
12109 | case OMPD_flush: |
12110 | case OMPD_depobj: |
12111 | case OMPD_scan: |
12112 | case OMPD_declare_reduction: |
12113 | case OMPD_declare_mapper: |
12114 | case OMPD_declare_simd: |
12115 | case OMPD_declare_variant: |
12116 | case OMPD_begin_declare_variant: |
12117 | case OMPD_end_declare_variant: |
12118 | case OMPD_declare_target: |
12119 | case OMPD_end_declare_target: |
12120 | case OMPD_simd: |
12121 | case OMPD_for: |
12122 | case OMPD_for_simd: |
12123 | case OMPD_sections: |
12124 | case OMPD_section: |
12125 | case OMPD_single: |
12126 | case OMPD_master: |
12127 | case OMPD_critical: |
12128 | case OMPD_taskgroup: |
12129 | case OMPD_distribute: |
12130 | case OMPD_ordered: |
12131 | case OMPD_atomic: |
12132 | case OMPD_distribute_simd: |
12133 | case OMPD_requires: |
12134 | llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12134); |
12135 | case OMPD_unknown: |
12136 | default: |
12137 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12137); |
12138 | } |
12139 | break; |
12140 | case OMPC_schedule: |
12141 | switch (DKind) { |
12142 | case OMPD_parallel_for: |
12143 | case OMPD_parallel_for_simd: |
12144 | case OMPD_distribute_parallel_for: |
12145 | case OMPD_distribute_parallel_for_simd: |
12146 | case OMPD_teams_distribute_parallel_for: |
12147 | case OMPD_teams_distribute_parallel_for_simd: |
12148 | case OMPD_target_parallel_for: |
12149 | case OMPD_target_parallel_for_simd: |
12150 | case OMPD_target_teams_distribute_parallel_for: |
12151 | case OMPD_target_teams_distribute_parallel_for_simd: |
12152 | CaptureRegion = OMPD_parallel; |
12153 | break; |
12154 | case OMPD_for: |
12155 | case OMPD_for_simd: |
12156 | // Do not capture schedule-clause expressions. |
12157 | break; |
12158 | case OMPD_task: |
12159 | case OMPD_taskloop: |
12160 | case OMPD_taskloop_simd: |
12161 | case OMPD_master_taskloop: |
12162 | case OMPD_master_taskloop_simd: |
12163 | case OMPD_parallel_master_taskloop: |
12164 | case OMPD_parallel_master_taskloop_simd: |
12165 | case OMPD_target_data: |
12166 | case OMPD_target_enter_data: |
12167 | case OMPD_target_exit_data: |
12168 | case OMPD_target_update: |
12169 | case OMPD_teams: |
12170 | case OMPD_teams_distribute: |
12171 | case OMPD_teams_distribute_simd: |
12172 | case OMPD_target_teams_distribute: |
12173 | case OMPD_target_teams_distribute_simd: |
12174 | case OMPD_target: |
12175 | case OMPD_target_simd: |
12176 | case OMPD_target_parallel: |
12177 | case OMPD_cancel: |
12178 | case OMPD_parallel: |
12179 | case OMPD_parallel_master: |
12180 | case OMPD_parallel_sections: |
12181 | case OMPD_threadprivate: |
12182 | case OMPD_allocate: |
12183 | case OMPD_taskyield: |
12184 | case OMPD_barrier: |
12185 | case OMPD_taskwait: |
12186 | case OMPD_cancellation_point: |
12187 | case OMPD_flush: |
12188 | case OMPD_depobj: |
12189 | case OMPD_scan: |
12190 | case OMPD_declare_reduction: |
12191 | case OMPD_declare_mapper: |
12192 | case OMPD_declare_simd: |
12193 | case OMPD_declare_variant: |
12194 | case OMPD_begin_declare_variant: |
12195 | case OMPD_end_declare_variant: |
12196 | case OMPD_declare_target: |
12197 | case OMPD_end_declare_target: |
12198 | case OMPD_simd: |
12199 | case OMPD_sections: |
12200 | case OMPD_section: |
12201 | case OMPD_single: |
12202 | case OMPD_master: |
12203 | case OMPD_critical: |
12204 | case OMPD_taskgroup: |
12205 | case OMPD_distribute: |
12206 | case OMPD_ordered: |
12207 | case OMPD_atomic: |
12208 | case OMPD_distribute_simd: |
12209 | case OMPD_target_teams: |
12210 | case OMPD_requires: |
12211 | llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12211); |
12212 | case OMPD_unknown: |
12213 | default: |
12214 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12214); |
12215 | } |
12216 | break; |
12217 | case OMPC_dist_schedule: |
12218 | switch (DKind) { |
12219 | case OMPD_teams_distribute_parallel_for: |
12220 | case OMPD_teams_distribute_parallel_for_simd: |
12221 | case OMPD_teams_distribute: |
12222 | case OMPD_teams_distribute_simd: |
12223 | case OMPD_target_teams_distribute_parallel_for: |
12224 | case OMPD_target_teams_distribute_parallel_for_simd: |
12225 | case OMPD_target_teams_distribute: |
12226 | case OMPD_target_teams_distribute_simd: |
12227 | CaptureRegion = OMPD_teams; |
12228 | break; |
12229 | case OMPD_distribute_parallel_for: |
12230 | case OMPD_distribute_parallel_for_simd: |
12231 | case OMPD_distribute: |
12232 | case OMPD_distribute_simd: |
12233 | // Do not capture thread_limit-clause expressions. |
12234 | break; |
12235 | case OMPD_parallel_for: |
12236 | case OMPD_parallel_for_simd: |
12237 | case OMPD_target_parallel_for_simd: |
12238 | case OMPD_target_parallel_for: |
12239 | case OMPD_task: |
12240 | case OMPD_taskloop: |
12241 | case OMPD_taskloop_simd: |
12242 | case OMPD_master_taskloop: |
12243 | case OMPD_master_taskloop_simd: |
12244 | case OMPD_parallel_master_taskloop: |
12245 | case OMPD_parallel_master_taskloop_simd: |
12246 | case OMPD_target_data: |
12247 | case OMPD_target_enter_data: |
12248 | case OMPD_target_exit_data: |
12249 | case OMPD_target_update: |
12250 | case OMPD_teams: |
12251 | case OMPD_target: |
12252 | case OMPD_target_simd: |
12253 | case OMPD_target_parallel: |
12254 | case OMPD_cancel: |
12255 | case OMPD_parallel: |
12256 | case OMPD_parallel_master: |
12257 | case OMPD_parallel_sections: |
12258 | case OMPD_threadprivate: |
12259 | case OMPD_allocate: |
12260 | case OMPD_taskyield: |
12261 | case OMPD_barrier: |
12262 | case OMPD_taskwait: |
12263 | case OMPD_cancellation_point: |
12264 | case OMPD_flush: |
12265 | case OMPD_depobj: |
12266 | case OMPD_scan: |
12267 | case OMPD_declare_reduction: |
12268 | case OMPD_declare_mapper: |
12269 | case OMPD_declare_simd: |
12270 | case OMPD_declare_variant: |
12271 | case OMPD_begin_declare_variant: |
12272 | case OMPD_end_declare_variant: |
12273 | case OMPD_declare_target: |
12274 | case OMPD_end_declare_target: |
12275 | case OMPD_simd: |
12276 | case OMPD_for: |
12277 | case OMPD_for_simd: |
12278 | case OMPD_sections: |
12279 | case OMPD_section: |
12280 | case OMPD_single: |
12281 | case OMPD_master: |
12282 | case OMPD_critical: |
12283 | case OMPD_taskgroup: |
12284 | case OMPD_ordered: |
12285 | case OMPD_atomic: |
12286 | case OMPD_target_teams: |
12287 | case OMPD_requires: |
12288 | llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12288); |
12289 | case OMPD_unknown: |
12290 | default: |
12291 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12291); |
12292 | } |
12293 | break; |
12294 | case OMPC_device: |
12295 | switch (DKind) { |
12296 | case OMPD_target_update: |
12297 | case OMPD_target_enter_data: |
12298 | case OMPD_target_exit_data: |
12299 | case OMPD_target: |
12300 | case OMPD_target_simd: |
12301 | case OMPD_target_teams: |
12302 | case OMPD_target_parallel: |
12303 | case OMPD_target_teams_distribute: |
12304 | case OMPD_target_teams_distribute_simd: |
12305 | case OMPD_target_parallel_for: |
12306 | case OMPD_target_parallel_for_simd: |
12307 | case OMPD_target_teams_distribute_parallel_for: |
12308 | case OMPD_target_teams_distribute_parallel_for_simd: |
12309 | CaptureRegion = OMPD_task; |
12310 | break; |
12311 | case OMPD_target_data: |
12312 | // Do not capture device-clause expressions. |
12313 | break; |
12314 | case OMPD_teams_distribute_parallel_for: |
12315 | case OMPD_teams_distribute_parallel_for_simd: |
12316 | case OMPD_teams: |
12317 | case OMPD_teams_distribute: |
12318 | case OMPD_teams_distribute_simd: |
12319 | case OMPD_distribute_parallel_for: |
12320 | case OMPD_distribute_parallel_for_simd: |
12321 | case OMPD_task: |
12322 | case OMPD_taskloop: |
12323 | case OMPD_taskloop_simd: |
12324 | case OMPD_master_taskloop: |
12325 | case OMPD_master_taskloop_simd: |
12326 | case OMPD_parallel_master_taskloop: |
12327 | case OMPD_parallel_master_taskloop_simd: |
12328 | case OMPD_cancel: |
12329 | case OMPD_parallel: |
12330 | case OMPD_parallel_master: |
12331 | case OMPD_parallel_sections: |
12332 | case OMPD_parallel_for: |
12333 | case OMPD_parallel_for_simd: |
12334 | case OMPD_threadprivate: |
12335 | case OMPD_allocate: |
12336 | case OMPD_taskyield: |
12337 | case OMPD_barrier: |
12338 | case OMPD_taskwait: |
12339 | case OMPD_cancellation_point: |
12340 | case OMPD_flush: |
12341 | case OMPD_depobj: |
12342 | case OMPD_scan: |
12343 | case OMPD_declare_reduction: |
12344 | case OMPD_declare_mapper: |
12345 | case OMPD_declare_simd: |
12346 | case OMPD_declare_variant: |
12347 | case OMPD_begin_declare_variant: |
12348 | case OMPD_end_declare_variant: |
12349 | case OMPD_declare_target: |
12350 | case OMPD_end_declare_target: |
12351 | case OMPD_simd: |
12352 | case OMPD_for: |
12353 | case OMPD_for_simd: |
12354 | case OMPD_sections: |
12355 | case OMPD_section: |
12356 | case OMPD_single: |
12357 | case OMPD_master: |
12358 | case OMPD_critical: |
12359 | case OMPD_taskgroup: |
12360 | case OMPD_distribute: |
12361 | case OMPD_ordered: |
12362 | case OMPD_atomic: |
12363 | case OMPD_distribute_simd: |
12364 | case OMPD_requires: |
12365 | llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12365); |
12366 | case OMPD_unknown: |
12367 | default: |
12368 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12368); |
12369 | } |
12370 | break; |
12371 | case OMPC_grainsize: |
12372 | case OMPC_num_tasks: |
12373 | case OMPC_final: |
12374 | case OMPC_priority: |
12375 | switch (DKind) { |
12376 | case OMPD_task: |
12377 | case OMPD_taskloop: |
12378 | case OMPD_taskloop_simd: |
12379 | case OMPD_master_taskloop: |
12380 | case OMPD_master_taskloop_simd: |
12381 | break; |
12382 | case OMPD_parallel_master_taskloop: |
12383 | case OMPD_parallel_master_taskloop_simd: |
12384 | CaptureRegion = OMPD_parallel; |
12385 | break; |
12386 | case OMPD_target_update: |
12387 | case OMPD_target_enter_data: |
12388 | case OMPD_target_exit_data: |
12389 | case OMPD_target: |
12390 | case OMPD_target_simd: |
12391 | case OMPD_target_teams: |
12392 | case OMPD_target_parallel: |
12393 | case OMPD_target_teams_distribute: |
12394 | case OMPD_target_teams_distribute_simd: |
12395 | case OMPD_target_parallel_for: |
12396 | case OMPD_target_parallel_for_simd: |
12397 | case OMPD_target_teams_distribute_parallel_for: |
12398 | case OMPD_target_teams_distribute_parallel_for_simd: |
12399 | case OMPD_target_data: |
12400 | case OMPD_teams_distribute_parallel_for: |
12401 | case OMPD_teams_distribute_parallel_for_simd: |
12402 | case OMPD_teams: |
12403 | case OMPD_teams_distribute: |
12404 | case OMPD_teams_distribute_simd: |
12405 | case OMPD_distribute_parallel_for: |
12406 | case OMPD_distribute_parallel_for_simd: |
12407 | case OMPD_cancel: |
12408 | case OMPD_parallel: |
12409 | case OMPD_parallel_master: |
12410 | case OMPD_parallel_sections: |
12411 | case OMPD_parallel_for: |
12412 | case OMPD_parallel_for_simd: |
12413 | case OMPD_threadprivate: |
12414 | case OMPD_allocate: |
12415 | case OMPD_taskyield: |
12416 | case OMPD_barrier: |
12417 | case OMPD_taskwait: |
12418 | case OMPD_cancellation_point: |
12419 | case OMPD_flush: |
12420 | case OMPD_depobj: |
12421 | case OMPD_scan: |
12422 | case OMPD_declare_reduction: |
12423 | case OMPD_declare_mapper: |
12424 | case OMPD_declare_simd: |
12425 | case OMPD_declare_variant: |
12426 | case OMPD_begin_declare_variant: |
12427 | case OMPD_end_declare_variant: |
12428 | case OMPD_declare_target: |
12429 | case OMPD_end_declare_target: |
12430 | case OMPD_simd: |
12431 | case OMPD_for: |
12432 | case OMPD_for_simd: |
12433 | case OMPD_sections: |
12434 | case OMPD_section: |
12435 | case OMPD_single: |
12436 | case OMPD_master: |
12437 | case OMPD_critical: |
12438 | case OMPD_taskgroup: |
12439 | case OMPD_distribute: |
12440 | case OMPD_ordered: |
12441 | case OMPD_atomic: |
12442 | case OMPD_distribute_simd: |
12443 | case OMPD_requires: |
12444 | llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12444); |
12445 | case OMPD_unknown: |
12446 | default: |
12447 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12447); |
12448 | } |
12449 | break; |
12450 | case OMPC_firstprivate: |
12451 | case OMPC_lastprivate: |
12452 | case OMPC_reduction: |
12453 | case OMPC_task_reduction: |
12454 | case OMPC_in_reduction: |
12455 | case OMPC_linear: |
12456 | case OMPC_default: |
12457 | case OMPC_proc_bind: |
12458 | case OMPC_safelen: |
12459 | case OMPC_simdlen: |
12460 | case OMPC_allocator: |
12461 | case OMPC_collapse: |
12462 | case OMPC_private: |
12463 | case OMPC_shared: |
12464 | case OMPC_aligned: |
12465 | case OMPC_copyin: |
12466 | case OMPC_copyprivate: |
12467 | case OMPC_ordered: |
12468 | case OMPC_nowait: |
12469 | case OMPC_untied: |
12470 | case OMPC_mergeable: |
12471 | case OMPC_threadprivate: |
12472 | case OMPC_allocate: |
12473 | case OMPC_flush: |
12474 | case OMPC_depobj: |
12475 | case OMPC_read: |
12476 | case OMPC_write: |
12477 | case OMPC_update: |
12478 | case OMPC_capture: |
12479 | case OMPC_seq_cst: |
12480 | case OMPC_acq_rel: |
12481 | case OMPC_acquire: |
12482 | case OMPC_release: |
12483 | case OMPC_relaxed: |
12484 | case OMPC_depend: |
12485 | case OMPC_threads: |
12486 | case OMPC_simd: |
12487 | case OMPC_map: |
12488 | case OMPC_nogroup: |
12489 | case OMPC_hint: |
12490 | case OMPC_defaultmap: |
12491 | case OMPC_unknown: |
12492 | case OMPC_uniform: |
12493 | case OMPC_to: |
12494 | case OMPC_from: |
12495 | case OMPC_use_device_ptr: |
12496 | case OMPC_use_device_addr: |
12497 | case OMPC_is_device_ptr: |
12498 | case OMPC_unified_address: |
12499 | case OMPC_unified_shared_memory: |
12500 | case OMPC_reverse_offload: |
12501 | case OMPC_dynamic_allocators: |
12502 | case OMPC_atomic_default_mem_order: |
12503 | case OMPC_device_type: |
12504 | case OMPC_match: |
12505 | case OMPC_nontemporal: |
12506 | case OMPC_order: |
12507 | case OMPC_destroy: |
12508 | case OMPC_detach: |
12509 | case OMPC_inclusive: |
12510 | case OMPC_exclusive: |
12511 | case OMPC_uses_allocators: |
12512 | case OMPC_affinity: |
12513 | default: |
12514 | llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause." , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12514); |
12515 | } |
12516 | return CaptureRegion; |
12517 | } |
12518 | |
12519 | OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, |
12520 | Expr *Condition, SourceLocation StartLoc, |
12521 | SourceLocation LParenLoc, |
12522 | SourceLocation NameModifierLoc, |
12523 | SourceLocation ColonLoc, |
12524 | SourceLocation EndLoc) { |
12525 | Expr *ValExpr = Condition; |
12526 | Stmt *HelperValStmt = nullptr; |
12527 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; |
12528 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && |
12529 | !Condition->isInstantiationDependent() && |
12530 | !Condition->containsUnexpandedParameterPack()) { |
12531 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); |
12532 | if (Val.isInvalid()) |
12533 | return nullptr; |
12534 | |
12535 | ValExpr = Val.get(); |
12536 | |
12537 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
12538 | CaptureRegion = getOpenMPCaptureRegionForClause( |
12539 | DKind, OMPC_if, LangOpts.OpenMP, NameModifier); |
12540 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { |
12541 | ValExpr = MakeFullExpr(ValExpr).get(); |
12542 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
12543 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
12544 | HelperValStmt = buildPreInits(Context, Captures); |
12545 | } |
12546 | } |
12547 | |
12548 | return new (Context) |
12549 | OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, |
12550 | LParenLoc, NameModifierLoc, ColonLoc, EndLoc); |
12551 | } |
12552 | |
12553 | OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, |
12554 | SourceLocation StartLoc, |
12555 | SourceLocation LParenLoc, |
12556 | SourceLocation EndLoc) { |
12557 | Expr *ValExpr = Condition; |
12558 | Stmt *HelperValStmt = nullptr; |
12559 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; |
12560 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && |
12561 | !Condition->isInstantiationDependent() && |
12562 | !Condition->containsUnexpandedParameterPack()) { |
12563 | ExprResult Val = CheckBooleanCondition(StartLoc, Condition); |
12564 | if (Val.isInvalid()) |
12565 | return nullptr; |
12566 | |
12567 | ValExpr = MakeFullExpr(Val.get()).get(); |
12568 | |
12569 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
12570 | CaptureRegion = |
12571 | getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); |
12572 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { |
12573 | ValExpr = MakeFullExpr(ValExpr).get(); |
12574 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
12575 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
12576 | HelperValStmt = buildPreInits(Context, Captures); |
12577 | } |
12578 | } |
12579 | |
12580 | return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, |
12581 | StartLoc, LParenLoc, EndLoc); |
12582 | } |
12583 | |
12584 | ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, |
12585 | Expr *Op) { |
12586 | if (!Op) |
12587 | return ExprError(); |
12588 | |
12589 | class IntConvertDiagnoser : public ICEConvertDiagnoser { |
12590 | public: |
12591 | IntConvertDiagnoser() |
12592 | : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} |
12593 | SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, |
12594 | QualType T) override { |
12595 | return S.Diag(Loc, diag::err_omp_not_integral) << T; |
12596 | } |
12597 | SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, |
12598 | QualType T) override { |
12599 | return S.Diag(Loc, diag::err_omp_incomplete_type) << T; |
12600 | } |
12601 | SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, |
12602 | QualType T, |
12603 | QualType ConvTy) override { |
12604 | return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; |
12605 | } |
12606 | SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, |
12607 | QualType ConvTy) override { |
12608 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) |
12609 | << ConvTy->isEnumeralType() << ConvTy; |
12610 | } |
12611 | SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, |
12612 | QualType T) override { |
12613 | return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; |
12614 | } |
12615 | SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, |
12616 | QualType ConvTy) override { |
12617 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) |
12618 | << ConvTy->isEnumeralType() << ConvTy; |
12619 | } |
12620 | SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, |
12621 | QualType) override { |
12622 | llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12622); |
12623 | } |
12624 | } ConvertDiagnoser; |
12625 | return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); |
12626 | } |
12627 | |
12628 | static bool |
12629 | isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, |
12630 | bool StrictlyPositive, bool BuildCapture = false, |
12631 | OpenMPDirectiveKind DKind = OMPD_unknown, |
12632 | OpenMPDirectiveKind *CaptureRegion = nullptr, |
12633 | Stmt **HelperValStmt = nullptr) { |
12634 | if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && |
12635 | !ValExpr->isInstantiationDependent()) { |
12636 | SourceLocation Loc = ValExpr->getExprLoc(); |
12637 | ExprResult Value = |
12638 | SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); |
12639 | if (Value.isInvalid()) |
12640 | return false; |
12641 | |
12642 | ValExpr = Value.get(); |
12643 | // The expression must evaluate to a non-negative integer value. |
12644 | if (Optional<llvm::APSInt> Result = |
12645 | ValExpr->getIntegerConstantExpr(SemaRef.Context)) { |
12646 | if (Result->isSigned() && |
12647 | !((!StrictlyPositive && Result->isNonNegative()) || |
12648 | (StrictlyPositive && Result->isStrictlyPositive()))) { |
12649 | SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) |
12650 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) |
12651 | << ValExpr->getSourceRange(); |
12652 | return false; |
12653 | } |
12654 | } |
12655 | if (!BuildCapture) |
12656 | return true; |
12657 | *CaptureRegion = |
12658 | getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); |
12659 | if (*CaptureRegion != OMPD_unknown && |
12660 | !SemaRef.CurContext->isDependentContext()) { |
12661 | ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); |
12662 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
12663 | ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); |
12664 | *HelperValStmt = buildPreInits(SemaRef.Context, Captures); |
12665 | } |
12666 | } |
12667 | return true; |
12668 | } |
12669 | |
12670 | OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, |
12671 | SourceLocation StartLoc, |
12672 | SourceLocation LParenLoc, |
12673 | SourceLocation EndLoc) { |
12674 | Expr *ValExpr = NumThreads; |
12675 | Stmt *HelperValStmt = nullptr; |
12676 | |
12677 | // OpenMP [2.5, Restrictions] |
12678 | // The num_threads expression must evaluate to a positive integer value. |
12679 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, |
12680 | /*StrictlyPositive=*/true)) |
12681 | return nullptr; |
12682 | |
12683 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
12684 | OpenMPDirectiveKind CaptureRegion = |
12685 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); |
12686 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { |
12687 | ValExpr = MakeFullExpr(ValExpr).get(); |
12688 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
12689 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
12690 | HelperValStmt = buildPreInits(Context, Captures); |
12691 | } |
12692 | |
12693 | return new (Context) OMPNumThreadsClause( |
12694 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); |
12695 | } |
12696 | |
12697 | ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, |
12698 | OpenMPClauseKind CKind, |
12699 | bool StrictlyPositive) { |
12700 | if (!E) |
12701 | return ExprError(); |
12702 | if (E->isValueDependent() || E->isTypeDependent() || |
12703 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) |
12704 | return E; |
12705 | llvm::APSInt Result; |
12706 | ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); |
12707 | if (ICE.isInvalid()) |
12708 | return ExprError(); |
12709 | if ((StrictlyPositive && !Result.isStrictlyPositive()) || |
12710 | (!StrictlyPositive && !Result.isNonNegative())) { |
12711 | Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) |
12712 | << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) |
12713 | << E->getSourceRange(); |
12714 | return ExprError(); |
12715 | } |
12716 | if (CKind == OMPC_aligned && !Result.isPowerOf2()) { |
12717 | Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) |
12718 | << E->getSourceRange(); |
12719 | return ExprError(); |
12720 | } |
12721 | if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() == 1) |
12722 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(Result.getExtValue()); |
12723 | else if (CKind == OMPC_ordered) |
12724 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setAssociatedLoops(Result.getExtValue()); |
12725 | return ICE; |
12726 | } |
12727 | |
12728 | OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, |
12729 | SourceLocation LParenLoc, |
12730 | SourceLocation EndLoc) { |
12731 | // OpenMP [2.8.1, simd construct, Description] |
12732 | // The parameter of the safelen clause must be a constant |
12733 | // positive integer expression. |
12734 | ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); |
12735 | if (Safelen.isInvalid()) |
12736 | return nullptr; |
12737 | return new (Context) |
12738 | OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); |
12739 | } |
12740 | |
12741 | OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, |
12742 | SourceLocation LParenLoc, |
12743 | SourceLocation EndLoc) { |
12744 | // OpenMP [2.8.1, simd construct, Description] |
12745 | // The parameter of the simdlen clause must be a constant |
12746 | // positive integer expression. |
12747 | ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); |
12748 | if (Simdlen.isInvalid()) |
12749 | return nullptr; |
12750 | return new (Context) |
12751 | OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); |
12752 | } |
12753 | |
12754 | /// Tries to find omp_allocator_handle_t type. |
12755 | static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, |
12756 | DSAStackTy *Stack) { |
12757 | QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); |
12758 | if (!OMPAllocatorHandleT.isNull()) |
12759 | return true; |
12760 | // Build the predefined allocator expressions. |
12761 | bool ErrorFound = false; |
12762 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { |
12763 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); |
12764 | StringRef Allocator = |
12765 | OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); |
12766 | DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); |
12767 | auto *VD = dyn_cast_or_null<ValueDecl>( |
12768 | S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); |
12769 | if (!VD) { |
12770 | ErrorFound = true; |
12771 | break; |
12772 | } |
12773 | QualType AllocatorType = |
12774 | VD->getType().getNonLValueExprType(S.getASTContext()); |
12775 | ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); |
12776 | if (!Res.isUsable()) { |
12777 | ErrorFound = true; |
12778 | break; |
12779 | } |
12780 | if (OMPAllocatorHandleT.isNull()) |
12781 | OMPAllocatorHandleT = AllocatorType; |
12782 | if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { |
12783 | ErrorFound = true; |
12784 | break; |
12785 | } |
12786 | Stack->setAllocator(AllocatorKind, Res.get()); |
12787 | } |
12788 | if (ErrorFound) { |
12789 | S.Diag(Loc, diag::err_omp_implied_type_not_found) |
12790 | << "omp_allocator_handle_t"; |
12791 | return false; |
12792 | } |
12793 | OMPAllocatorHandleT.addConst(); |
12794 | Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); |
12795 | return true; |
12796 | } |
12797 | |
12798 | OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, |
12799 | SourceLocation LParenLoc, |
12800 | SourceLocation EndLoc) { |
12801 | // OpenMP [2.11.3, allocate Directive, Description] |
12802 | // allocator is an expression of omp_allocator_handle_t type. |
12803 | if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
12804 | return nullptr; |
12805 | |
12806 | ExprResult Allocator = DefaultLvalueConversion(A); |
12807 | if (Allocator.isInvalid()) |
12808 | return nullptr; |
12809 | Allocator = PerformImplicitConversion(Allocator.get(), |
12810 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), |
12811 | Sema::AA_Initializing, |
12812 | /*AllowExplicit=*/true); |
12813 | if (Allocator.isInvalid()) |
12814 | return nullptr; |
12815 | return new (Context) |
12816 | OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); |
12817 | } |
12818 | |
12819 | OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, |
12820 | SourceLocation StartLoc, |
12821 | SourceLocation LParenLoc, |
12822 | SourceLocation EndLoc) { |
12823 | // OpenMP [2.7.1, loop construct, Description] |
12824 | // OpenMP [2.8.1, simd construct, Description] |
12825 | // OpenMP [2.9.6, distribute construct, Description] |
12826 | // The parameter of the collapse clause must be a constant |
12827 | // positive integer expression. |
12828 | ExprResult NumForLoopsResult = |
12829 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); |
12830 | if (NumForLoopsResult.isInvalid()) |
12831 | return nullptr; |
12832 | return new (Context) |
12833 | OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); |
12834 | } |
12835 | |
12836 | OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, |
12837 | SourceLocation EndLoc, |
12838 | SourceLocation LParenLoc, |
12839 | Expr *NumForLoops) { |
12840 | // OpenMP [2.7.1, loop construct, Description] |
12841 | // OpenMP [2.8.1, simd construct, Description] |
12842 | // OpenMP [2.9.6, distribute construct, Description] |
12843 | // The parameter of the ordered clause must be a constant |
12844 | // positive integer expression if any. |
12845 | if (NumForLoops && LParenLoc.isValid()) { |
12846 | ExprResult NumForLoopsResult = |
12847 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); |
12848 | if (NumForLoopsResult.isInvalid()) |
12849 | return nullptr; |
12850 | NumForLoops = NumForLoopsResult.get(); |
12851 | } else { |
12852 | NumForLoops = nullptr; |
12853 | } |
12854 | auto *Clause = OMPOrderedClause::Create( |
12855 | Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getAssociatedLoops() : 0, |
12856 | StartLoc, LParenLoc, EndLoc); |
12857 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); |
12858 | return Clause; |
12859 | } |
12860 | |
12861 | OMPClause *Sema::ActOnOpenMPSimpleClause( |
12862 | OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, |
12863 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { |
12864 | OMPClause *Res = nullptr; |
12865 | switch (Kind) { |
12866 | case OMPC_default: |
12867 | Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), |
12868 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); |
12869 | break; |
12870 | case OMPC_proc_bind: |
12871 | Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), |
12872 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); |
12873 | break; |
12874 | case OMPC_atomic_default_mem_order: |
12875 | Res = ActOnOpenMPAtomicDefaultMemOrderClause( |
12876 | static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), |
12877 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); |
12878 | break; |
12879 | case OMPC_order: |
12880 | Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), |
12881 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); |
12882 | break; |
12883 | case OMPC_update: |
12884 | Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), |
12885 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); |
12886 | break; |
12887 | case OMPC_if: |
12888 | case OMPC_final: |
12889 | case OMPC_num_threads: |
12890 | case OMPC_safelen: |
12891 | case OMPC_simdlen: |
12892 | case OMPC_allocator: |
12893 | case OMPC_collapse: |
12894 | case OMPC_schedule: |
12895 | case OMPC_private: |
12896 | case OMPC_firstprivate: |
12897 | case OMPC_lastprivate: |
12898 | case OMPC_shared: |
12899 | case OMPC_reduction: |
12900 | case OMPC_task_reduction: |
12901 | case OMPC_in_reduction: |
12902 | case OMPC_linear: |
12903 | case OMPC_aligned: |
12904 | case OMPC_copyin: |
12905 | case OMPC_copyprivate: |
12906 | case OMPC_ordered: |
12907 | case OMPC_nowait: |
12908 | case OMPC_untied: |
12909 | case OMPC_mergeable: |
12910 | case OMPC_threadprivate: |
12911 | case OMPC_allocate: |
12912 | case OMPC_flush: |
12913 | case OMPC_depobj: |
12914 | case OMPC_read: |
12915 | case OMPC_write: |
12916 | case OMPC_capture: |
12917 | case OMPC_seq_cst: |
12918 | case OMPC_acq_rel: |
12919 | case OMPC_acquire: |
12920 | case OMPC_release: |
12921 | case OMPC_relaxed: |
12922 | case OMPC_depend: |
12923 | case OMPC_device: |
12924 | case OMPC_threads: |
12925 | case OMPC_simd: |
12926 | case OMPC_map: |
12927 | case OMPC_num_teams: |
12928 | case OMPC_thread_limit: |
12929 | case OMPC_priority: |
12930 | case OMPC_grainsize: |
12931 | case OMPC_nogroup: |
12932 | case OMPC_num_tasks: |
12933 | case OMPC_hint: |
12934 | case OMPC_dist_schedule: |
12935 | case OMPC_defaultmap: |
12936 | case OMPC_unknown: |
12937 | case OMPC_uniform: |
12938 | case OMPC_to: |
12939 | case OMPC_from: |
12940 | case OMPC_use_device_ptr: |
12941 | case OMPC_use_device_addr: |
12942 | case OMPC_is_device_ptr: |
12943 | case OMPC_unified_address: |
12944 | case OMPC_unified_shared_memory: |
12945 | case OMPC_reverse_offload: |
12946 | case OMPC_dynamic_allocators: |
12947 | case OMPC_device_type: |
12948 | case OMPC_match: |
12949 | case OMPC_nontemporal: |
12950 | case OMPC_destroy: |
12951 | case OMPC_detach: |
12952 | case OMPC_inclusive: |
12953 | case OMPC_exclusive: |
12954 | case OMPC_uses_allocators: |
12955 | case OMPC_affinity: |
12956 | default: |
12957 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 12957); |
12958 | } |
12959 | return Res; |
12960 | } |
12961 | |
12962 | static std::string |
12963 | getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, |
12964 | ArrayRef<unsigned> Exclude = llvm::None) { |
12965 | SmallString<256> Buffer; |
12966 | llvm::raw_svector_ostream Out(Buffer); |
12967 | unsigned Skipped = Exclude.size(); |
12968 | auto S = Exclude.begin(), E = Exclude.end(); |
12969 | for (unsigned I = First; I < Last; ++I) { |
12970 | if (std::find(S, E, I) != E) { |
12971 | --Skipped; |
12972 | continue; |
12973 | } |
12974 | Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; |
12975 | if (I + Skipped + 2 == Last) |
12976 | Out << " or "; |
12977 | else if (I + Skipped + 1 != Last) |
12978 | Out << ", "; |
12979 | } |
12980 | return std::string(Out.str()); |
12981 | } |
12982 | |
12983 | OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, |
12984 | SourceLocation KindKwLoc, |
12985 | SourceLocation StartLoc, |
12986 | SourceLocation LParenLoc, |
12987 | SourceLocation EndLoc) { |
12988 | if (Kind == OMP_DEFAULT_unknown) { |
12989 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) |
12990 | << getListOfPossibleValues(OMPC_default, /*First=*/0, |
12991 | /*Last=*/unsigned(OMP_DEFAULT_unknown)) |
12992 | << getOpenMPClauseName(OMPC_default); |
12993 | return nullptr; |
12994 | } |
12995 | |
12996 | switch (Kind) { |
12997 | case OMP_DEFAULT_none: |
12998 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSANone(KindKwLoc); |
12999 | break; |
13000 | case OMP_DEFAULT_shared: |
13001 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSAShared(KindKwLoc); |
13002 | break; |
13003 | case OMP_DEFAULT_firstprivate: |
13004 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSAFirstPrivate(KindKwLoc); |
13005 | break; |
13006 | default: |
13007 | llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13007); |
13008 | } |
13009 | |
13010 | return new (Context) |
13011 | OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); |
13012 | } |
13013 | |
13014 | OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, |
13015 | SourceLocation KindKwLoc, |
13016 | SourceLocation StartLoc, |
13017 | SourceLocation LParenLoc, |
13018 | SourceLocation EndLoc) { |
13019 | if (Kind == OMP_PROC_BIND_unknown) { |
13020 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) |
13021 | << getListOfPossibleValues(OMPC_proc_bind, |
13022 | /*First=*/unsigned(OMP_PROC_BIND_master), |
13023 | /*Last=*/5) |
13024 | << getOpenMPClauseName(OMPC_proc_bind); |
13025 | return nullptr; |
13026 | } |
13027 | return new (Context) |
13028 | OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); |
13029 | } |
13030 | |
13031 | OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( |
13032 | OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, |
13033 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { |
13034 | if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { |
13035 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) |
13036 | << getListOfPossibleValues( |
13037 | OMPC_atomic_default_mem_order, /*First=*/0, |
13038 | /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) |
13039 | << getOpenMPClauseName(OMPC_atomic_default_mem_order); |
13040 | return nullptr; |
13041 | } |
13042 | return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, |
13043 | LParenLoc, EndLoc); |
13044 | } |
13045 | |
13046 | OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, |
13047 | SourceLocation KindKwLoc, |
13048 | SourceLocation StartLoc, |
13049 | SourceLocation LParenLoc, |
13050 | SourceLocation EndLoc) { |
13051 | if (Kind == OMPC_ORDER_unknown) { |
13052 | static_assert(OMPC_ORDER_unknown > 0, |
13053 | "OMPC_ORDER_unknown not greater than 0"); |
13054 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) |
13055 | << getListOfPossibleValues(OMPC_order, /*First=*/0, |
13056 | /*Last=*/OMPC_ORDER_unknown) |
13057 | << getOpenMPClauseName(OMPC_order); |
13058 | return nullptr; |
13059 | } |
13060 | return new (Context) |
13061 | OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); |
13062 | } |
13063 | |
13064 | OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, |
13065 | SourceLocation KindKwLoc, |
13066 | SourceLocation StartLoc, |
13067 | SourceLocation LParenLoc, |
13068 | SourceLocation EndLoc) { |
13069 | if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || |
13070 | Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { |
13071 | unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, |
13072 | OMPC_DEPEND_depobj}; |
13073 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) |
13074 | << getListOfPossibleValues(OMPC_depend, /*First=*/0, |
13075 | /*Last=*/OMPC_DEPEND_unknown, Except) |
13076 | << getOpenMPClauseName(OMPC_update); |
13077 | return nullptr; |
13078 | } |
13079 | return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, |
13080 | EndLoc); |
13081 | } |
13082 | |
13083 | OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( |
13084 | OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, |
13085 | SourceLocation StartLoc, SourceLocation LParenLoc, |
13086 | ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, |
13087 | SourceLocation EndLoc) { |
13088 | OMPClause *Res = nullptr; |
13089 | switch (Kind) { |
13090 | case OMPC_schedule: |
13091 | enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; |
13092 | assert(Argument.size() == NumberOfElements &&((Argument.size() == NumberOfElements && ArgumentLoc. size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13093, __PRETTY_FUNCTION__)) |
13093 | ArgumentLoc.size() == NumberOfElements)((Argument.size() == NumberOfElements && ArgumentLoc. size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13093, __PRETTY_FUNCTION__)); |
13094 | Res = ActOnOpenMPScheduleClause( |
13095 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), |
13096 | static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), |
13097 | static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, |
13098 | StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], |
13099 | ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); |
13100 | break; |
13101 | case OMPC_if: |
13102 | assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast <void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13102, __PRETTY_FUNCTION__)); |
13103 | Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), |
13104 | Expr, StartLoc, LParenLoc, ArgumentLoc.back(), |
13105 | DelimLoc, EndLoc); |
13106 | break; |
13107 | case OMPC_dist_schedule: |
13108 | Res = ActOnOpenMPDistScheduleClause( |
13109 | static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, |
13110 | StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); |
13111 | break; |
13112 | case OMPC_defaultmap: |
13113 | enum { Modifier, DefaultmapKind }; |
13114 | Res = ActOnOpenMPDefaultmapClause( |
13115 | static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), |
13116 | static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), |
13117 | StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], |
13118 | EndLoc); |
13119 | break; |
13120 | case OMPC_device: |
13121 | assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast <void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13121, __PRETTY_FUNCTION__)); |
13122 | Res = ActOnOpenMPDeviceClause( |
13123 | static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, |
13124 | StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); |
13125 | break; |
13126 | case OMPC_final: |
13127 | case OMPC_num_threads: |
13128 | case OMPC_safelen: |
13129 | case OMPC_simdlen: |
13130 | case OMPC_allocator: |
13131 | case OMPC_collapse: |
13132 | case OMPC_default: |
13133 | case OMPC_proc_bind: |
13134 | case OMPC_private: |
13135 | case OMPC_firstprivate: |
13136 | case OMPC_lastprivate: |
13137 | case OMPC_shared: |
13138 | case OMPC_reduction: |
13139 | case OMPC_task_reduction: |
13140 | case OMPC_in_reduction: |
13141 | case OMPC_linear: |
13142 | case OMPC_aligned: |
13143 | case OMPC_copyin: |
13144 | case OMPC_copyprivate: |
13145 | case OMPC_ordered: |
13146 | case OMPC_nowait: |
13147 | case OMPC_untied: |
13148 | case OMPC_mergeable: |
13149 | case OMPC_threadprivate: |
13150 | case OMPC_allocate: |
13151 | case OMPC_flush: |
13152 | case OMPC_depobj: |
13153 | case OMPC_read: |
13154 | case OMPC_write: |
13155 | case OMPC_update: |
13156 | case OMPC_capture: |
13157 | case OMPC_seq_cst: |
13158 | case OMPC_acq_rel: |
13159 | case OMPC_acquire: |
13160 | case OMPC_release: |
13161 | case OMPC_relaxed: |
13162 | case OMPC_depend: |
13163 | case OMPC_threads: |
13164 | case OMPC_simd: |
13165 | case OMPC_map: |
13166 | case OMPC_num_teams: |
13167 | case OMPC_thread_limit: |
13168 | case OMPC_priority: |
13169 | case OMPC_grainsize: |
13170 | case OMPC_nogroup: |
13171 | case OMPC_num_tasks: |
13172 | case OMPC_hint: |
13173 | case OMPC_unknown: |
13174 | case OMPC_uniform: |
13175 | case OMPC_to: |
13176 | case OMPC_from: |
13177 | case OMPC_use_device_ptr: |
13178 | case OMPC_use_device_addr: |
13179 | case OMPC_is_device_ptr: |
13180 | case OMPC_unified_address: |
13181 | case OMPC_unified_shared_memory: |
13182 | case OMPC_reverse_offload: |
13183 | case OMPC_dynamic_allocators: |
13184 | case OMPC_atomic_default_mem_order: |
13185 | case OMPC_device_type: |
13186 | case OMPC_match: |
13187 | case OMPC_nontemporal: |
13188 | case OMPC_order: |
13189 | case OMPC_destroy: |
13190 | case OMPC_detach: |
13191 | case OMPC_inclusive: |
13192 | case OMPC_exclusive: |
13193 | case OMPC_uses_allocators: |
13194 | case OMPC_affinity: |
13195 | default: |
13196 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13196); |
13197 | } |
13198 | return Res; |
13199 | } |
13200 | |
13201 | static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, |
13202 | OpenMPScheduleClauseModifier M2, |
13203 | SourceLocation M1Loc, SourceLocation M2Loc) { |
13204 | if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { |
13205 | SmallVector<unsigned, 2> Excluded; |
13206 | if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) |
13207 | Excluded.push_back(M2); |
13208 | if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) |
13209 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); |
13210 | if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) |
13211 | Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); |
13212 | S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) |
13213 | << getListOfPossibleValues(OMPC_schedule, |
13214 | /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, |
13215 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, |
13216 | Excluded) |
13217 | << getOpenMPClauseName(OMPC_schedule); |
13218 | return true; |
13219 | } |
13220 | return false; |
13221 | } |
13222 | |
13223 | OMPClause *Sema::ActOnOpenMPScheduleClause( |
13224 | OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, |
13225 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, |
13226 | SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, |
13227 | SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { |
13228 | if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || |
13229 | checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) |
13230 | return nullptr; |
13231 | // OpenMP, 2.7.1, Loop Construct, Restrictions |
13232 | // Either the monotonic modifier or the nonmonotonic modifier can be specified |
13233 | // but not both. |
13234 | if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || |
13235 | (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && |
13236 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || |
13237 | (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && |
13238 | M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { |
13239 | Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) |
13240 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) |
13241 | << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); |
13242 | return nullptr; |
13243 | } |
13244 | if (Kind == OMPC_SCHEDULE_unknown) { |
13245 | std::string Values; |
13246 | if (M1Loc.isInvalid() && M2Loc.isInvalid()) { |
13247 | unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; |
13248 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, |
13249 | /*Last=*/OMPC_SCHEDULE_MODIFIER_last, |
13250 | Exclude); |
13251 | } else { |
13252 | Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, |
13253 | /*Last=*/OMPC_SCHEDULE_unknown); |
13254 | } |
13255 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) |
13256 | << Values << getOpenMPClauseName(OMPC_schedule); |
13257 | return nullptr; |
13258 | } |
13259 | // OpenMP, 2.7.1, Loop Construct, Restrictions |
13260 | // The nonmonotonic modifier can only be specified with schedule(dynamic) or |
13261 | // schedule(guided). |
13262 | // OpenMP 5.0 does not have this restriction. |
13263 | if (LangOpts.OpenMP < 50 && |
13264 | (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || |
13265 | M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && |
13266 | Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { |
13267 | Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, |
13268 | diag::err_omp_schedule_nonmonotonic_static); |
13269 | return nullptr; |
13270 | } |
13271 | Expr *ValExpr = ChunkSize; |
13272 | Stmt *HelperValStmt = nullptr; |
13273 | if (ChunkSize) { |
13274 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && |
13275 | !ChunkSize->isInstantiationDependent() && |
13276 | !ChunkSize->containsUnexpandedParameterPack()) { |
13277 | SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); |
13278 | ExprResult Val = |
13279 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); |
13280 | if (Val.isInvalid()) |
13281 | return nullptr; |
13282 | |
13283 | ValExpr = Val.get(); |
13284 | |
13285 | // OpenMP [2.7.1, Restrictions] |
13286 | // chunk_size must be a loop invariant integer expression with a positive |
13287 | // value. |
13288 | if (Optional<llvm::APSInt> Result = |
13289 | ValExpr->getIntegerConstantExpr(Context)) { |
13290 | if (Result->isSigned() && !Result->isStrictlyPositive()) { |
13291 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) |
13292 | << "schedule" << 1 << ChunkSize->getSourceRange(); |
13293 | return nullptr; |
13294 | } |
13295 | } else if (getOpenMPCaptureRegionForClause( |
13296 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), OMPC_schedule, |
13297 | LangOpts.OpenMP) != OMPD_unknown && |
13298 | !CurContext->isDependentContext()) { |
13299 | ValExpr = MakeFullExpr(ValExpr).get(); |
13300 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
13301 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
13302 | HelperValStmt = buildPreInits(Context, Captures); |
13303 | } |
13304 | } |
13305 | } |
13306 | |
13307 | return new (Context) |
13308 | OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, |
13309 | ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); |
13310 | } |
13311 | |
13312 | OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, |
13313 | SourceLocation StartLoc, |
13314 | SourceLocation EndLoc) { |
13315 | OMPClause *Res = nullptr; |
13316 | switch (Kind) { |
13317 | case OMPC_ordered: |
13318 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); |
13319 | break; |
13320 | case OMPC_nowait: |
13321 | Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); |
13322 | break; |
13323 | case OMPC_untied: |
13324 | Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); |
13325 | break; |
13326 | case OMPC_mergeable: |
13327 | Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); |
13328 | break; |
13329 | case OMPC_read: |
13330 | Res = ActOnOpenMPReadClause(StartLoc, EndLoc); |
13331 | break; |
13332 | case OMPC_write: |
13333 | Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); |
13334 | break; |
13335 | case OMPC_update: |
13336 | Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); |
13337 | break; |
13338 | case OMPC_capture: |
13339 | Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); |
13340 | break; |
13341 | case OMPC_seq_cst: |
13342 | Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); |
13343 | break; |
13344 | case OMPC_acq_rel: |
13345 | Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); |
13346 | break; |
13347 | case OMPC_acquire: |
13348 | Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); |
13349 | break; |
13350 | case OMPC_release: |
13351 | Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); |
13352 | break; |
13353 | case OMPC_relaxed: |
13354 | Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); |
13355 | break; |
13356 | case OMPC_threads: |
13357 | Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); |
13358 | break; |
13359 | case OMPC_simd: |
13360 | Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); |
13361 | break; |
13362 | case OMPC_nogroup: |
13363 | Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); |
13364 | break; |
13365 | case OMPC_unified_address: |
13366 | Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); |
13367 | break; |
13368 | case OMPC_unified_shared_memory: |
13369 | Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); |
13370 | break; |
13371 | case OMPC_reverse_offload: |
13372 | Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); |
13373 | break; |
13374 | case OMPC_dynamic_allocators: |
13375 | Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); |
13376 | break; |
13377 | case OMPC_destroy: |
13378 | Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); |
13379 | break; |
13380 | case OMPC_if: |
13381 | case OMPC_final: |
13382 | case OMPC_num_threads: |
13383 | case OMPC_safelen: |
13384 | case OMPC_simdlen: |
13385 | case OMPC_allocator: |
13386 | case OMPC_collapse: |
13387 | case OMPC_schedule: |
13388 | case OMPC_private: |
13389 | case OMPC_firstprivate: |
13390 | case OMPC_lastprivate: |
13391 | case OMPC_shared: |
13392 | case OMPC_reduction: |
13393 | case OMPC_task_reduction: |
13394 | case OMPC_in_reduction: |
13395 | case OMPC_linear: |
13396 | case OMPC_aligned: |
13397 | case OMPC_copyin: |
13398 | case OMPC_copyprivate: |
13399 | case OMPC_default: |
13400 | case OMPC_proc_bind: |
13401 | case OMPC_threadprivate: |
13402 | case OMPC_allocate: |
13403 | case OMPC_flush: |
13404 | case OMPC_depobj: |
13405 | case OMPC_depend: |
13406 | case OMPC_device: |
13407 | case OMPC_map: |
13408 | case OMPC_num_teams: |
13409 | case OMPC_thread_limit: |
13410 | case OMPC_priority: |
13411 | case OMPC_grainsize: |
13412 | case OMPC_num_tasks: |
13413 | case OMPC_hint: |
13414 | case OMPC_dist_schedule: |
13415 | case OMPC_defaultmap: |
13416 | case OMPC_unknown: |
13417 | case OMPC_uniform: |
13418 | case OMPC_to: |
13419 | case OMPC_from: |
13420 | case OMPC_use_device_ptr: |
13421 | case OMPC_use_device_addr: |
13422 | case OMPC_is_device_ptr: |
13423 | case OMPC_atomic_default_mem_order: |
13424 | case OMPC_device_type: |
13425 | case OMPC_match: |
13426 | case OMPC_nontemporal: |
13427 | case OMPC_order: |
13428 | case OMPC_detach: |
13429 | case OMPC_inclusive: |
13430 | case OMPC_exclusive: |
13431 | case OMPC_uses_allocators: |
13432 | case OMPC_affinity: |
13433 | default: |
13434 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13434); |
13435 | } |
13436 | return Res; |
13437 | } |
13438 | |
13439 | OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, |
13440 | SourceLocation EndLoc) { |
13441 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setNowaitRegion(); |
13442 | return new (Context) OMPNowaitClause(StartLoc, EndLoc); |
13443 | } |
13444 | |
13445 | OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, |
13446 | SourceLocation EndLoc) { |
13447 | return new (Context) OMPUntiedClause(StartLoc, EndLoc); |
13448 | } |
13449 | |
13450 | OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, |
13451 | SourceLocation EndLoc) { |
13452 | return new (Context) OMPMergeableClause(StartLoc, EndLoc); |
13453 | } |
13454 | |
13455 | OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, |
13456 | SourceLocation EndLoc) { |
13457 | return new (Context) OMPReadClause(StartLoc, EndLoc); |
13458 | } |
13459 | |
13460 | OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, |
13461 | SourceLocation EndLoc) { |
13462 | return new (Context) OMPWriteClause(StartLoc, EndLoc); |
13463 | } |
13464 | |
13465 | OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, |
13466 | SourceLocation EndLoc) { |
13467 | return OMPUpdateClause::Create(Context, StartLoc, EndLoc); |
13468 | } |
13469 | |
13470 | OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, |
13471 | SourceLocation EndLoc) { |
13472 | return new (Context) OMPCaptureClause(StartLoc, EndLoc); |
13473 | } |
13474 | |
13475 | OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, |
13476 | SourceLocation EndLoc) { |
13477 | return new (Context) OMPSeqCstClause(StartLoc, EndLoc); |
13478 | } |
13479 | |
13480 | OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, |
13481 | SourceLocation EndLoc) { |
13482 | return new (Context) OMPAcqRelClause(StartLoc, EndLoc); |
13483 | } |
13484 | |
13485 | OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, |
13486 | SourceLocation EndLoc) { |
13487 | return new (Context) OMPAcquireClause(StartLoc, EndLoc); |
13488 | } |
13489 | |
13490 | OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, |
13491 | SourceLocation EndLoc) { |
13492 | return new (Context) OMPReleaseClause(StartLoc, EndLoc); |
13493 | } |
13494 | |
13495 | OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, |
13496 | SourceLocation EndLoc) { |
13497 | return new (Context) OMPRelaxedClause(StartLoc, EndLoc); |
13498 | } |
13499 | |
13500 | OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, |
13501 | SourceLocation EndLoc) { |
13502 | return new (Context) OMPThreadsClause(StartLoc, EndLoc); |
13503 | } |
13504 | |
13505 | OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, |
13506 | SourceLocation EndLoc) { |
13507 | return new (Context) OMPSIMDClause(StartLoc, EndLoc); |
13508 | } |
13509 | |
13510 | OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, |
13511 | SourceLocation EndLoc) { |
13512 | return new (Context) OMPNogroupClause(StartLoc, EndLoc); |
13513 | } |
13514 | |
13515 | OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, |
13516 | SourceLocation EndLoc) { |
13517 | return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); |
13518 | } |
13519 | |
13520 | OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, |
13521 | SourceLocation EndLoc) { |
13522 | return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); |
13523 | } |
13524 | |
13525 | OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, |
13526 | SourceLocation EndLoc) { |
13527 | return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); |
13528 | } |
13529 | |
13530 | OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, |
13531 | SourceLocation EndLoc) { |
13532 | return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); |
13533 | } |
13534 | |
13535 | OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, |
13536 | SourceLocation EndLoc) { |
13537 | return new (Context) OMPDestroyClause(StartLoc, EndLoc); |
13538 | } |
13539 | |
13540 | OMPClause *Sema::ActOnOpenMPVarListClause( |
13541 | OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, |
13542 | const OMPVarListLocTy &Locs, SourceLocation ColonLoc, |
13543 | CXXScopeSpec &ReductionOrMapperIdScopeSpec, |
13544 | DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, |
13545 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, |
13546 | ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, |
13547 | SourceLocation ExtraModifierLoc, |
13548 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
13549 | ArrayRef<SourceLocation> MotionModifiersLoc) { |
13550 | SourceLocation StartLoc = Locs.StartLoc; |
13551 | SourceLocation LParenLoc = Locs.LParenLoc; |
13552 | SourceLocation EndLoc = Locs.EndLoc; |
13553 | OMPClause *Res = nullptr; |
13554 | switch (Kind) { |
13555 | case OMPC_private: |
13556 | Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); |
13557 | break; |
13558 | case OMPC_firstprivate: |
13559 | Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); |
13560 | break; |
13561 | case OMPC_lastprivate: |
13562 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13563, __PRETTY_FUNCTION__)) |
13563 | "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13563, __PRETTY_FUNCTION__)); |
13564 | Res = ActOnOpenMPLastprivateClause( |
13565 | VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), |
13566 | ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); |
13567 | break; |
13568 | case OMPC_shared: |
13569 | Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); |
13570 | break; |
13571 | case OMPC_reduction: |
13572 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13573, __PRETTY_FUNCTION__)) |
13573 | "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && "Unexpected lastprivate modifier.") ? static_cast <void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13573, __PRETTY_FUNCTION__)); |
13574 | Res = ActOnOpenMPReductionClause( |
13575 | VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), |
13576 | StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, |
13577 | ReductionOrMapperIdScopeSpec, ReductionOrMapperId); |
13578 | break; |
13579 | case OMPC_task_reduction: |
13580 | Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, |
13581 | EndLoc, ReductionOrMapperIdScopeSpec, |
13582 | ReductionOrMapperId); |
13583 | break; |
13584 | case OMPC_in_reduction: |
13585 | Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, |
13586 | EndLoc, ReductionOrMapperIdScopeSpec, |
13587 | ReductionOrMapperId); |
13588 | break; |
13589 | case OMPC_linear: |
13590 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && "Unexpected linear modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13591, __PRETTY_FUNCTION__)) |
13591 | "Unexpected linear modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && "Unexpected linear modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13591, __PRETTY_FUNCTION__)); |
13592 | Res = ActOnOpenMPLinearClause( |
13593 | VarList, DepModOrTailExpr, StartLoc, LParenLoc, |
13594 | static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, |
13595 | ColonLoc, EndLoc); |
13596 | break; |
13597 | case OMPC_aligned: |
13598 | Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, |
13599 | LParenLoc, ColonLoc, EndLoc); |
13600 | break; |
13601 | case OMPC_copyin: |
13602 | Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); |
13603 | break; |
13604 | case OMPC_copyprivate: |
13605 | Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); |
13606 | break; |
13607 | case OMPC_flush: |
13608 | Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); |
13609 | break; |
13610 | case OMPC_depend: |
13611 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && "Unexpected depend modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13612, __PRETTY_FUNCTION__)) |
13612 | "Unexpected depend modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && "Unexpected depend modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13612, __PRETTY_FUNCTION__)); |
13613 | Res = ActOnOpenMPDependClause( |
13614 | DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), |
13615 | ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); |
13616 | break; |
13617 | case OMPC_map: |
13618 | assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && "Unexpected map modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13619, __PRETTY_FUNCTION__)) |
13619 | "Unexpected map modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && "Unexpected map modifier.") ? static_cast<void > (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13619, __PRETTY_FUNCTION__)); |
13620 | Res = ActOnOpenMPMapClause( |
13621 | MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, |
13622 | ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), |
13623 | IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); |
13624 | break; |
13625 | case OMPC_to: |
13626 | Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, |
13627 | ReductionOrMapperIdScopeSpec, ReductionOrMapperId, |
13628 | ColonLoc, VarList, Locs); |
13629 | break; |
13630 | case OMPC_from: |
13631 | Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc, |
13632 | ReductionOrMapperIdScopeSpec, |
13633 | ReductionOrMapperId, ColonLoc, VarList, Locs); |
13634 | break; |
13635 | case OMPC_use_device_ptr: |
13636 | Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); |
13637 | break; |
13638 | case OMPC_use_device_addr: |
13639 | Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); |
13640 | break; |
13641 | case OMPC_is_device_ptr: |
13642 | Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); |
13643 | break; |
13644 | case OMPC_allocate: |
13645 | Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, |
13646 | LParenLoc, ColonLoc, EndLoc); |
13647 | break; |
13648 | case OMPC_nontemporal: |
13649 | Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); |
13650 | break; |
13651 | case OMPC_inclusive: |
13652 | Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); |
13653 | break; |
13654 | case OMPC_exclusive: |
13655 | Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); |
13656 | break; |
13657 | case OMPC_affinity: |
13658 | Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, |
13659 | DepModOrTailExpr, VarList); |
13660 | break; |
13661 | case OMPC_if: |
13662 | case OMPC_depobj: |
13663 | case OMPC_final: |
13664 | case OMPC_num_threads: |
13665 | case OMPC_safelen: |
13666 | case OMPC_simdlen: |
13667 | case OMPC_allocator: |
13668 | case OMPC_collapse: |
13669 | case OMPC_default: |
13670 | case OMPC_proc_bind: |
13671 | case OMPC_schedule: |
13672 | case OMPC_ordered: |
13673 | case OMPC_nowait: |
13674 | case OMPC_untied: |
13675 | case OMPC_mergeable: |
13676 | case OMPC_threadprivate: |
13677 | case OMPC_read: |
13678 | case OMPC_write: |
13679 | case OMPC_update: |
13680 | case OMPC_capture: |
13681 | case OMPC_seq_cst: |
13682 | case OMPC_acq_rel: |
13683 | case OMPC_acquire: |
13684 | case OMPC_release: |
13685 | case OMPC_relaxed: |
13686 | case OMPC_device: |
13687 | case OMPC_threads: |
13688 | case OMPC_simd: |
13689 | case OMPC_num_teams: |
13690 | case OMPC_thread_limit: |
13691 | case OMPC_priority: |
13692 | case OMPC_grainsize: |
13693 | case OMPC_nogroup: |
13694 | case OMPC_num_tasks: |
13695 | case OMPC_hint: |
13696 | case OMPC_dist_schedule: |
13697 | case OMPC_defaultmap: |
13698 | case OMPC_unknown: |
13699 | case OMPC_uniform: |
13700 | case OMPC_unified_address: |
13701 | case OMPC_unified_shared_memory: |
13702 | case OMPC_reverse_offload: |
13703 | case OMPC_dynamic_allocators: |
13704 | case OMPC_atomic_default_mem_order: |
13705 | case OMPC_device_type: |
13706 | case OMPC_match: |
13707 | case OMPC_order: |
13708 | case OMPC_destroy: |
13709 | case OMPC_detach: |
13710 | case OMPC_uses_allocators: |
13711 | default: |
13712 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13712); |
13713 | } |
13714 | return Res; |
13715 | } |
13716 | |
13717 | ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, |
13718 | ExprObjectKind OK, SourceLocation Loc) { |
13719 | ExprResult Res = BuildDeclRefExpr( |
13720 | Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); |
13721 | if (!Res.isUsable()) |
13722 | return ExprError(); |
13723 | if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { |
13724 | Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); |
13725 | if (!Res.isUsable()) |
13726 | return ExprError(); |
13727 | } |
13728 | if (VK != VK_LValue && Res.get()->isGLValue()) { |
13729 | Res = DefaultLvalueConversion(Res.get()); |
13730 | if (!Res.isUsable()) |
13731 | return ExprError(); |
13732 | } |
13733 | return Res; |
13734 | } |
13735 | |
13736 | OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, |
13737 | SourceLocation StartLoc, |
13738 | SourceLocation LParenLoc, |
13739 | SourceLocation EndLoc) { |
13740 | SmallVector<Expr *, 8> Vars; |
13741 | SmallVector<Expr *, 8> PrivateCopies; |
13742 | for (Expr *RefExpr : VarList) { |
13743 | assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13743, __PRETTY_FUNCTION__)); |
13744 | SourceLocation ELoc; |
13745 | SourceRange ERange; |
13746 | Expr *SimpleRefExpr = RefExpr; |
13747 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
13748 | if (Res.second) { |
13749 | // It will be analyzed later. |
13750 | Vars.push_back(RefExpr); |
13751 | PrivateCopies.push_back(nullptr); |
13752 | } |
13753 | ValueDecl *D = Res.first; |
13754 | if (!D) |
13755 | continue; |
13756 | |
13757 | QualType Type = D->getType(); |
13758 | auto *VD = dyn_cast<VarDecl>(D); |
13759 | |
13760 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] |
13761 | // A variable that appears in a private clause must not have an incomplete |
13762 | // type or a reference type. |
13763 | if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) |
13764 | continue; |
13765 | Type = Type.getNonReferenceType(); |
13766 | |
13767 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] |
13768 | // A variable that is privatized must not have a const-qualified type |
13769 | // unless it is of class type with a mutable member. This restriction does |
13770 | // not apply to the firstprivate clause. |
13771 | // |
13772 | // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] |
13773 | // A variable that appears in a private clause must not have a |
13774 | // const-qualified type unless it is of class type with a mutable member. |
13775 | if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) |
13776 | continue; |
13777 | |
13778 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
13779 | // in a Construct] |
13780 | // Variables with the predetermined data-sharing attributes may not be |
13781 | // listed in data-sharing attributes clauses, except for the cases |
13782 | // listed below. For these exceptions only, listing a predetermined |
13783 | // variable in a data-sharing attribute clause is allowed and overrides |
13784 | // the variable's predetermined data-sharing attributes. |
13785 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
13786 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { |
13787 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) |
13788 | << getOpenMPClauseName(OMPC_private); |
13789 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
13790 | continue; |
13791 | } |
13792 | |
13793 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
13794 | // Variably modified types are not supported for tasks. |
13795 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && |
13796 | isOpenMPTaskingDirective(CurrDir)) { |
13797 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) |
13798 | << getOpenMPClauseName(OMPC_private) << Type |
13799 | << getOpenMPDirectiveName(CurrDir); |
13800 | bool IsDecl = |
13801 | !VD || |
13802 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
13803 | Diag(D->getLocation(), |
13804 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
13805 | << D; |
13806 | continue; |
13807 | } |
13808 | |
13809 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] |
13810 | // A list item cannot appear in both a map clause and a data-sharing |
13811 | // attribute clause on the same construct |
13812 | // |
13813 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] |
13814 | // A list item cannot appear in both a map clause and a data-sharing |
13815 | // attribute clause on the same construct unless the construct is a |
13816 | // combined construct. |
13817 | if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || |
13818 | CurrDir == OMPD_target) { |
13819 | OpenMPClauseKind ConflictKind; |
13820 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( |
13821 | VD, /*CurrentRegionOnly=*/true, |
13822 | [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, |
13823 | OpenMPClauseKind WhereFoundClauseKind) -> bool { |
13824 | ConflictKind = WhereFoundClauseKind; |
13825 | return true; |
13826 | })) { |
13827 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) |
13828 | << getOpenMPClauseName(OMPC_private) |
13829 | << getOpenMPClauseName(ConflictKind) |
13830 | << getOpenMPDirectiveName(CurrDir); |
13831 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
13832 | continue; |
13833 | } |
13834 | } |
13835 | |
13836 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] |
13837 | // A variable of class type (or array thereof) that appears in a private |
13838 | // clause requires an accessible, unambiguous default constructor for the |
13839 | // class type. |
13840 | // Generate helper private variable and initialize it with the default |
13841 | // value. The address of the original variable is replaced by the address of |
13842 | // the new private variable in CodeGen. This new variable is not added to |
13843 | // IdResolver, so the code in the OpenMP region uses original variable for |
13844 | // proper diagnostics. |
13845 | Type = Type.getUnqualifiedType(); |
13846 | VarDecl *VDPrivate = |
13847 | buildVarDecl(*this, ELoc, Type, D->getName(), |
13848 | D->hasAttrs() ? &D->getAttrs() : nullptr, |
13849 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); |
13850 | ActOnUninitializedDecl(VDPrivate); |
13851 | if (VDPrivate->isInvalidDecl()) |
13852 | continue; |
13853 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( |
13854 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); |
13855 | |
13856 | DeclRefExpr *Ref = nullptr; |
13857 | if (!VD && !CurContext->isDependentContext()) |
13858 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); |
13859 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); |
13860 | Vars.push_back((VD || CurContext->isDependentContext()) |
13861 | ? RefExpr->IgnoreParens() |
13862 | : Ref); |
13863 | PrivateCopies.push_back(VDPrivateRefExpr); |
13864 | } |
13865 | |
13866 | if (Vars.empty()) |
13867 | return nullptr; |
13868 | |
13869 | return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, |
13870 | PrivateCopies); |
13871 | } |
13872 | |
13873 | namespace { |
13874 | class DiagsUninitializedSeveretyRAII { |
13875 | private: |
13876 | DiagnosticsEngine &Diags; |
13877 | SourceLocation SavedLoc; |
13878 | bool IsIgnored = false; |
13879 | |
13880 | public: |
13881 | DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, |
13882 | bool IsIgnored) |
13883 | : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { |
13884 | if (!IsIgnored) { |
13885 | Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, |
13886 | /*Map*/ diag::Severity::Ignored, Loc); |
13887 | } |
13888 | } |
13889 | ~DiagsUninitializedSeveretyRAII() { |
13890 | if (!IsIgnored) |
13891 | Diags.popMappings(SavedLoc); |
13892 | } |
13893 | }; |
13894 | } |
13895 | |
13896 | OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, |
13897 | SourceLocation StartLoc, |
13898 | SourceLocation LParenLoc, |
13899 | SourceLocation EndLoc) { |
13900 | SmallVector<Expr *, 8> Vars; |
13901 | SmallVector<Expr *, 8> PrivateCopies; |
13902 | SmallVector<Expr *, 8> Inits; |
13903 | SmallVector<Decl *, 4> ExprCaptures; |
13904 | bool IsImplicitClause = |
13905 | StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); |
13906 | SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(); |
13907 | |
13908 | for (Expr *RefExpr : VarList) { |
13909 | assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")((RefExpr && "NULL expr in OpenMP firstprivate clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 13909, __PRETTY_FUNCTION__)); |
13910 | SourceLocation ELoc; |
13911 | SourceRange ERange; |
13912 | Expr *SimpleRefExpr = RefExpr; |
13913 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
13914 | if (Res.second) { |
13915 | // It will be analyzed later. |
13916 | Vars.push_back(RefExpr); |
13917 | PrivateCopies.push_back(nullptr); |
13918 | Inits.push_back(nullptr); |
13919 | } |
13920 | ValueDecl *D = Res.first; |
13921 | if (!D) |
13922 | continue; |
13923 | |
13924 | ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; |
13925 | QualType Type = D->getType(); |
13926 | auto *VD = dyn_cast<VarDecl>(D); |
13927 | |
13928 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] |
13929 | // A variable that appears in a private clause must not have an incomplete |
13930 | // type or a reference type. |
13931 | if (RequireCompleteType(ELoc, Type, |
13932 | diag::err_omp_firstprivate_incomplete_type)) |
13933 | continue; |
13934 | Type = Type.getNonReferenceType(); |
13935 | |
13936 | // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] |
13937 | // A variable of class type (or array thereof) that appears in a private |
13938 | // clause requires an accessible, unambiguous copy constructor for the |
13939 | // class type. |
13940 | QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); |
13941 | |
13942 | // If an implicit firstprivate variable found it was checked already. |
13943 | DSAStackTy::DSAVarData TopDVar; |
13944 | if (!IsImplicitClause) { |
13945 | DSAStackTy::DSAVarData DVar = |
13946 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
13947 | TopDVar = DVar; |
13948 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
13949 | bool IsConstant = ElemType.isConstant(Context); |
13950 | // OpenMP [2.4.13, Data-sharing Attribute Clauses] |
13951 | // A list item that specifies a given variable may not appear in more |
13952 | // than one clause on the same directive, except that a variable may be |
13953 | // specified in both firstprivate and lastprivate clauses. |
13954 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] |
13955 | // A list item may appear in a firstprivate or lastprivate clause but not |
13956 | // both. |
13957 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && |
13958 | (isOpenMPDistributeDirective(CurrDir) || |
13959 | DVar.CKind != OMPC_lastprivate) && |
13960 | DVar.RefExpr) { |
13961 | Diag(ELoc, diag::err_omp_wrong_dsa) |
13962 | << getOpenMPClauseName(DVar.CKind) |
13963 | << getOpenMPClauseName(OMPC_firstprivate); |
13964 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
13965 | continue; |
13966 | } |
13967 | |
13968 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
13969 | // in a Construct] |
13970 | // Variables with the predetermined data-sharing attributes may not be |
13971 | // listed in data-sharing attributes clauses, except for the cases |
13972 | // listed below. For these exceptions only, listing a predetermined |
13973 | // variable in a data-sharing attribute clause is allowed and overrides |
13974 | // the variable's predetermined data-sharing attributes. |
13975 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
13976 | // in a Construct, C/C++, p.2] |
13977 | // Variables with const-qualified type having no mutable member may be |
13978 | // listed in a firstprivate clause, even if they are static data members. |
13979 | if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && |
13980 | DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { |
13981 | Diag(ELoc, diag::err_omp_wrong_dsa) |
13982 | << getOpenMPClauseName(DVar.CKind) |
13983 | << getOpenMPClauseName(OMPC_firstprivate); |
13984 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
13985 | continue; |
13986 | } |
13987 | |
13988 | // OpenMP [2.9.3.4, Restrictions, p.2] |
13989 | // A list item that is private within a parallel region must not appear |
13990 | // in a firstprivate clause on a worksharing construct if any of the |
13991 | // worksharing regions arising from the worksharing construct ever bind |
13992 | // to any of the parallel regions arising from the parallel construct. |
13993 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] |
13994 | // A list item that is private within a teams region must not appear in a |
13995 | // firstprivate clause on a distribute construct if any of the distribute |
13996 | // regions arising from the distribute construct ever bind to any of the |
13997 | // teams regions arising from the teams construct. |
13998 | // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] |
13999 | // A list item that appears in a reduction clause of a teams construct |
14000 | // must not appear in a firstprivate clause on a distribute construct if |
14001 | // any of the distribute regions arising from the distribute construct |
14002 | // ever bind to any of the teams regions arising from the teams construct. |
14003 | if ((isOpenMPWorksharingDirective(CurrDir) || |
14004 | isOpenMPDistributeDirective(CurrDir)) && |
14005 | !isOpenMPParallelDirective(CurrDir) && |
14006 | !isOpenMPTeamsDirective(CurrDir)) { |
14007 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, true); |
14008 | if (DVar.CKind != OMPC_shared && |
14009 | (isOpenMPParallelDirective(DVar.DKind) || |
14010 | isOpenMPTeamsDirective(DVar.DKind) || |
14011 | DVar.DKind == OMPD_unknown)) { |
14012 | Diag(ELoc, diag::err_omp_required_access) |
14013 | << getOpenMPClauseName(OMPC_firstprivate) |
14014 | << getOpenMPClauseName(OMPC_shared); |
14015 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
14016 | continue; |
14017 | } |
14018 | } |
14019 | // OpenMP [2.9.3.4, Restrictions, p.3] |
14020 | // A list item that appears in a reduction clause of a parallel construct |
14021 | // must not appear in a firstprivate clause on a worksharing or task |
14022 | // construct if any of the worksharing or task regions arising from the |
14023 | // worksharing or task construct ever bind to any of the parallel regions |
14024 | // arising from the parallel construct. |
14025 | // OpenMP [2.9.3.4, Restrictions, p.4] |
14026 | // A list item that appears in a reduction clause in worksharing |
14027 | // construct must not appear in a firstprivate clause in a task construct |
14028 | // encountered during execution of any of the worksharing regions arising |
14029 | // from the worksharing construct. |
14030 | if (isOpenMPTaskingDirective(CurrDir)) { |
14031 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnermostDSA( |
14032 | D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, |
14033 | [](OpenMPDirectiveKind K) { |
14034 | return isOpenMPParallelDirective(K) || |
14035 | isOpenMPWorksharingDirective(K) || |
14036 | isOpenMPTeamsDirective(K); |
14037 | }, |
14038 | /*FromParent=*/true); |
14039 | if (DVar.CKind == OMPC_reduction && |
14040 | (isOpenMPParallelDirective(DVar.DKind) || |
14041 | isOpenMPWorksharingDirective(DVar.DKind) || |
14042 | isOpenMPTeamsDirective(DVar.DKind))) { |
14043 | Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) |
14044 | << getOpenMPDirectiveName(DVar.DKind); |
14045 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
14046 | continue; |
14047 | } |
14048 | } |
14049 | |
14050 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] |
14051 | // A list item cannot appear in both a map clause and a data-sharing |
14052 | // attribute clause on the same construct |
14053 | // |
14054 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] |
14055 | // A list item cannot appear in both a map clause and a data-sharing |
14056 | // attribute clause on the same construct unless the construct is a |
14057 | // combined construct. |
14058 | if ((LangOpts.OpenMP <= 45 && |
14059 | isOpenMPTargetExecutionDirective(CurrDir)) || |
14060 | CurrDir == OMPD_target) { |
14061 | OpenMPClauseKind ConflictKind; |
14062 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( |
14063 | VD, /*CurrentRegionOnly=*/true, |
14064 | [&ConflictKind]( |
14065 | OMPClauseMappableExprCommon::MappableExprComponentListRef, |
14066 | OpenMPClauseKind WhereFoundClauseKind) { |
14067 | ConflictKind = WhereFoundClauseKind; |
14068 | return true; |
14069 | })) { |
14070 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) |
14071 | << getOpenMPClauseName(OMPC_firstprivate) |
14072 | << getOpenMPClauseName(ConflictKind) |
14073 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); |
14074 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
14075 | continue; |
14076 | } |
14077 | } |
14078 | } |
14079 | |
14080 | // Variably modified types are not supported for tasks. |
14081 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && |
14082 | isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { |
14083 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) |
14084 | << getOpenMPClauseName(OMPC_firstprivate) << Type |
14085 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); |
14086 | bool IsDecl = |
14087 | !VD || |
14088 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
14089 | Diag(D->getLocation(), |
14090 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
14091 | << D; |
14092 | continue; |
14093 | } |
14094 | |
14095 | Type = Type.getUnqualifiedType(); |
14096 | VarDecl *VDPrivate = |
14097 | buildVarDecl(*this, ELoc, Type, D->getName(), |
14098 | D->hasAttrs() ? &D->getAttrs() : nullptr, |
14099 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); |
14100 | // Generate helper private variable and initialize it with the value of the |
14101 | // original variable. The address of the original variable is replaced by |
14102 | // the address of the new private variable in the CodeGen. This new variable |
14103 | // is not added to IdResolver, so the code in the OpenMP region uses |
14104 | // original variable for proper diagnostics and variable capturing. |
14105 | Expr *VDInitRefExpr = nullptr; |
14106 | // For arrays generate initializer for single element and replace it by the |
14107 | // original array element in CodeGen. |
14108 | if (Type->isArrayType()) { |
14109 | VarDecl *VDInit = |
14110 | buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); |
14111 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); |
14112 | Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); |
14113 | ElemType = ElemType.getUnqualifiedType(); |
14114 | VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, |
14115 | ".firstprivate.temp"); |
14116 | InitializedEntity Entity = |
14117 | InitializedEntity::InitializeVariable(VDInitTemp); |
14118 | InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); |
14119 | |
14120 | InitializationSequence InitSeq(*this, Entity, Kind, Init); |
14121 | ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); |
14122 | if (Result.isInvalid()) |
14123 | VDPrivate->setInvalidDecl(); |
14124 | else |
14125 | VDPrivate->setInit(Result.getAs<Expr>()); |
14126 | // Remove temp variable declaration. |
14127 | Context.Deallocate(VDInitTemp); |
14128 | } else { |
14129 | VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, |
14130 | ".firstprivate.temp"); |
14131 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), |
14132 | RefExpr->getExprLoc()); |
14133 | AddInitializerToDecl(VDPrivate, |
14134 | DefaultLvalueConversion(VDInitRefExpr).get(), |
14135 | /*DirectInit=*/false); |
14136 | } |
14137 | if (VDPrivate->isInvalidDecl()) { |
14138 | if (IsImplicitClause) { |
14139 | Diag(RefExpr->getExprLoc(), |
14140 | diag::note_omp_task_predetermined_firstprivate_here); |
14141 | } |
14142 | continue; |
14143 | } |
14144 | CurContext->addDecl(VDPrivate); |
14145 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( |
14146 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), |
14147 | RefExpr->getExprLoc()); |
14148 | DeclRefExpr *Ref = nullptr; |
14149 | if (!VD && !CurContext->isDependentContext()) { |
14150 | if (TopDVar.CKind == OMPC_lastprivate) { |
14151 | Ref = TopDVar.PrivateCopy; |
14152 | } else { |
14153 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); |
14154 | if (!isOpenMPCapturedDecl(D)) |
14155 | ExprCaptures.push_back(Ref->getDecl()); |
14156 | } |
14157 | } |
14158 | if (!IsImplicitClause) |
14159 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); |
14160 | Vars.push_back((VD || CurContext->isDependentContext()) |
14161 | ? RefExpr->IgnoreParens() |
14162 | : Ref); |
14163 | PrivateCopies.push_back(VDPrivateRefExpr); |
14164 | Inits.push_back(VDInitRefExpr); |
14165 | } |
14166 | |
14167 | if (Vars.empty()) |
14168 | return nullptr; |
14169 | |
14170 | return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
14171 | Vars, PrivateCopies, Inits, |
14172 | buildPreInits(Context, ExprCaptures)); |
14173 | } |
14174 | |
14175 | OMPClause *Sema::ActOnOpenMPLastprivateClause( |
14176 | ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, |
14177 | SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, |
14178 | SourceLocation LParenLoc, SourceLocation EndLoc) { |
14179 | if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { |
14180 | assert(ColonLoc.isValid() && "Colon location must be valid.")((ColonLoc.isValid() && "Colon location must be valid." ) ? static_cast<void> (0) : __assert_fail ("ColonLoc.isValid() && \"Colon location must be valid.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14180, __PRETTY_FUNCTION__)); |
14181 | Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) |
14182 | << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, |
14183 | /*Last=*/OMPC_LASTPRIVATE_unknown) |
14184 | << getOpenMPClauseName(OMPC_lastprivate); |
14185 | return nullptr; |
14186 | } |
14187 | |
14188 | SmallVector<Expr *, 8> Vars; |
14189 | SmallVector<Expr *, 8> SrcExprs; |
14190 | SmallVector<Expr *, 8> DstExprs; |
14191 | SmallVector<Expr *, 8> AssignmentOps; |
14192 | SmallVector<Decl *, 4> ExprCaptures; |
14193 | SmallVector<Expr *, 4> ExprPostUpdates; |
14194 | for (Expr *RefExpr : VarList) { |
14195 | assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14195, __PRETTY_FUNCTION__)); |
14196 | SourceLocation ELoc; |
14197 | SourceRange ERange; |
14198 | Expr *SimpleRefExpr = RefExpr; |
14199 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
14200 | if (Res.second) { |
14201 | // It will be analyzed later. |
14202 | Vars.push_back(RefExpr); |
14203 | SrcExprs.push_back(nullptr); |
14204 | DstExprs.push_back(nullptr); |
14205 | AssignmentOps.push_back(nullptr); |
14206 | } |
14207 | ValueDecl *D = Res.first; |
14208 | if (!D) |
14209 | continue; |
14210 | |
14211 | QualType Type = D->getType(); |
14212 | auto *VD = dyn_cast<VarDecl>(D); |
14213 | |
14214 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] |
14215 | // A variable that appears in a lastprivate clause must not have an |
14216 | // incomplete type or a reference type. |
14217 | if (RequireCompleteType(ELoc, Type, |
14218 | diag::err_omp_lastprivate_incomplete_type)) |
14219 | continue; |
14220 | Type = Type.getNonReferenceType(); |
14221 | |
14222 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] |
14223 | // A variable that is privatized must not have a const-qualified type |
14224 | // unless it is of class type with a mutable member. This restriction does |
14225 | // not apply to the firstprivate clause. |
14226 | // |
14227 | // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] |
14228 | // A variable that appears in a lastprivate clause must not have a |
14229 | // const-qualified type unless it is of class type with a mutable member. |
14230 | if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) |
14231 | continue; |
14232 | |
14233 | // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] |
14234 | // A list item that appears in a lastprivate clause with the conditional |
14235 | // modifier must be a scalar variable. |
14236 | if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { |
14237 | Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); |
14238 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
14239 | VarDecl::DeclarationOnly; |
14240 | Diag(D->getLocation(), |
14241 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
14242 | << D; |
14243 | continue; |
14244 | } |
14245 | |
14246 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
14247 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced |
14248 | // in a Construct] |
14249 | // Variables with the predetermined data-sharing attributes may not be |
14250 | // listed in data-sharing attributes clauses, except for the cases |
14251 | // listed below. |
14252 | // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] |
14253 | // A list item may appear in a firstprivate or lastprivate clause but not |
14254 | // both. |
14255 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
14256 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && |
14257 | (isOpenMPDistributeDirective(CurrDir) || |
14258 | DVar.CKind != OMPC_firstprivate) && |
14259 | (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { |
14260 | Diag(ELoc, diag::err_omp_wrong_dsa) |
14261 | << getOpenMPClauseName(DVar.CKind) |
14262 | << getOpenMPClauseName(OMPC_lastprivate); |
14263 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
14264 | continue; |
14265 | } |
14266 | |
14267 | // OpenMP [2.14.3.5, Restrictions, p.2] |
14268 | // A list item that is private within a parallel region, or that appears in |
14269 | // the reduction clause of a parallel construct, must not appear in a |
14270 | // lastprivate clause on a worksharing construct if any of the corresponding |
14271 | // worksharing regions ever binds to any of the corresponding parallel |
14272 | // regions. |
14273 | DSAStackTy::DSAVarData TopDVar = DVar; |
14274 | if (isOpenMPWorksharingDirective(CurrDir) && |
14275 | !isOpenMPParallelDirective(CurrDir) && |
14276 | !isOpenMPTeamsDirective(CurrDir)) { |
14277 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, true); |
14278 | if (DVar.CKind != OMPC_shared) { |
14279 | Diag(ELoc, diag::err_omp_required_access) |
14280 | << getOpenMPClauseName(OMPC_lastprivate) |
14281 | << getOpenMPClauseName(OMPC_shared); |
14282 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
14283 | continue; |
14284 | } |
14285 | } |
14286 | |
14287 | // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] |
14288 | // A variable of class type (or array thereof) that appears in a |
14289 | // lastprivate clause requires an accessible, unambiguous default |
14290 | // constructor for the class type, unless the list item is also specified |
14291 | // in a firstprivate clause. |
14292 | // A variable of class type (or array thereof) that appears in a |
14293 | // lastprivate clause requires an accessible, unambiguous copy assignment |
14294 | // operator for the class type. |
14295 | Type = Context.getBaseElementType(Type).getNonReferenceType(); |
14296 | VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), |
14297 | Type.getUnqualifiedType(), ".lastprivate.src", |
14298 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
14299 | DeclRefExpr *PseudoSrcExpr = |
14300 | buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); |
14301 | VarDecl *DstVD = |
14302 | buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", |
14303 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
14304 | DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); |
14305 | // For arrays generate assignment operation for single element and replace |
14306 | // it by the original array element in CodeGen. |
14307 | ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, |
14308 | PseudoDstExpr, PseudoSrcExpr); |
14309 | if (AssignmentOp.isInvalid()) |
14310 | continue; |
14311 | AssignmentOp = |
14312 | ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); |
14313 | if (AssignmentOp.isInvalid()) |
14314 | continue; |
14315 | |
14316 | DeclRefExpr *Ref = nullptr; |
14317 | if (!VD && !CurContext->isDependentContext()) { |
14318 | if (TopDVar.CKind == OMPC_firstprivate) { |
14319 | Ref = TopDVar.PrivateCopy; |
14320 | } else { |
14321 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); |
14322 | if (!isOpenMPCapturedDecl(D)) |
14323 | ExprCaptures.push_back(Ref->getDecl()); |
14324 | } |
14325 | if (TopDVar.CKind == OMPC_firstprivate || |
14326 | (!isOpenMPCapturedDecl(D) && |
14327 | Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { |
14328 | ExprResult RefRes = DefaultLvalueConversion(Ref); |
14329 | if (!RefRes.isUsable()) |
14330 | continue; |
14331 | ExprResult PostUpdateRes = |
14332 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, |
14333 | RefRes.get()); |
14334 | if (!PostUpdateRes.isUsable()) |
14335 | continue; |
14336 | ExprPostUpdates.push_back( |
14337 | IgnoredValueConversions(PostUpdateRes.get()).get()); |
14338 | } |
14339 | } |
14340 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); |
14341 | Vars.push_back((VD || CurContext->isDependentContext()) |
14342 | ? RefExpr->IgnoreParens() |
14343 | : Ref); |
14344 | SrcExprs.push_back(PseudoSrcExpr); |
14345 | DstExprs.push_back(PseudoDstExpr); |
14346 | AssignmentOps.push_back(AssignmentOp.get()); |
14347 | } |
14348 | |
14349 | if (Vars.empty()) |
14350 | return nullptr; |
14351 | |
14352 | return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
14353 | Vars, SrcExprs, DstExprs, AssignmentOps, |
14354 | LPKind, LPKindLoc, ColonLoc, |
14355 | buildPreInits(Context, ExprCaptures), |
14356 | buildPostUpdate(*this, ExprPostUpdates)); |
14357 | } |
14358 | |
14359 | OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, |
14360 | SourceLocation StartLoc, |
14361 | SourceLocation LParenLoc, |
14362 | SourceLocation EndLoc) { |
14363 | SmallVector<Expr *, 8> Vars; |
14364 | for (Expr *RefExpr : VarList) { |
14365 | assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14365, __PRETTY_FUNCTION__)); |
14366 | SourceLocation ELoc; |
14367 | SourceRange ERange; |
14368 | Expr *SimpleRefExpr = RefExpr; |
14369 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
14370 | if (Res.second) { |
14371 | // It will be analyzed later. |
14372 | Vars.push_back(RefExpr); |
14373 | } |
14374 | ValueDecl *D = Res.first; |
14375 | if (!D) |
14376 | continue; |
14377 | |
14378 | auto *VD = dyn_cast<VarDecl>(D); |
14379 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced |
14380 | // in a Construct] |
14381 | // Variables with the predetermined data-sharing attributes may not be |
14382 | // listed in data-sharing attributes clauses, except for the cases |
14383 | // listed below. For these exceptions only, listing a predetermined |
14384 | // variable in a data-sharing attribute clause is allowed and overrides |
14385 | // the variable's predetermined data-sharing attributes. |
14386 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
14387 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && |
14388 | DVar.RefExpr) { |
14389 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) |
14390 | << getOpenMPClauseName(OMPC_shared); |
14391 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
14392 | continue; |
14393 | } |
14394 | |
14395 | DeclRefExpr *Ref = nullptr; |
14396 | if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) |
14397 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); |
14398 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); |
14399 | Vars.push_back((VD || !Ref || CurContext->isDependentContext()) |
14400 | ? RefExpr->IgnoreParens() |
14401 | : Ref); |
14402 | } |
14403 | |
14404 | if (Vars.empty()) |
14405 | return nullptr; |
14406 | |
14407 | return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); |
14408 | } |
14409 | |
14410 | namespace { |
14411 | class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { |
14412 | DSAStackTy *Stack; |
14413 | |
14414 | public: |
14415 | bool VisitDeclRefExpr(DeclRefExpr *E) { |
14416 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { |
14417 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); |
14418 | if (DVar.CKind == OMPC_shared && !DVar.RefExpr) |
14419 | return false; |
14420 | if (DVar.CKind != OMPC_unknown) |
14421 | return true; |
14422 | DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( |
14423 | VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, |
14424 | /*FromParent=*/true); |
14425 | return DVarPrivate.CKind != OMPC_unknown; |
14426 | } |
14427 | return false; |
14428 | } |
14429 | bool VisitStmt(Stmt *S) { |
14430 | for (Stmt *Child : S->children()) { |
14431 | if (Child && Visit(Child)) |
14432 | return true; |
14433 | } |
14434 | return false; |
14435 | } |
14436 | explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} |
14437 | }; |
14438 | } // namespace |
14439 | |
14440 | namespace { |
14441 | // Transform MemberExpression for specified FieldDecl of current class to |
14442 | // DeclRefExpr to specified OMPCapturedExprDecl. |
14443 | class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { |
14444 | typedef TreeTransform<TransformExprToCaptures> BaseTransform; |
14445 | ValueDecl *Field = nullptr; |
14446 | DeclRefExpr *CapturedExpr = nullptr; |
14447 | |
14448 | public: |
14449 | TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) |
14450 | : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} |
14451 | |
14452 | ExprResult TransformMemberExpr(MemberExpr *E) { |
14453 | if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && |
14454 | E->getMemberDecl() == Field) { |
14455 | CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); |
14456 | return CapturedExpr; |
14457 | } |
14458 | return BaseTransform::TransformMemberExpr(E); |
14459 | } |
14460 | DeclRefExpr *getCapturedExpr() { return CapturedExpr; } |
14461 | }; |
14462 | } // namespace |
14463 | |
14464 | template <typename T, typename U> |
14465 | static T filterLookupForUDReductionAndMapper( |
14466 | SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { |
14467 | for (U &Set : Lookups) { |
14468 | for (auto *D : Set) { |
14469 | if (T Res = Gen(cast<ValueDecl>(D))) |
14470 | return Res; |
14471 | } |
14472 | } |
14473 | return T(); |
14474 | } |
14475 | |
14476 | static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { |
14477 | assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")((!LookupResult::isVisible(SemaRef, D) && "not in slow case" ) ? static_cast<void> (0) : __assert_fail ("!LookupResult::isVisible(SemaRef, D) && \"not in slow case\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14477, __PRETTY_FUNCTION__)); |
14478 | |
14479 | for (auto RD : D->redecls()) { |
14480 | // Don't bother with extra checks if we already know this one isn't visible. |
14481 | if (RD == D) |
14482 | continue; |
14483 | |
14484 | auto ND = cast<NamedDecl>(RD); |
14485 | if (LookupResult::isVisible(SemaRef, ND)) |
14486 | return ND; |
14487 | } |
14488 | |
14489 | return nullptr; |
14490 | } |
14491 | |
14492 | static void |
14493 | argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, |
14494 | SourceLocation Loc, QualType Ty, |
14495 | SmallVectorImpl<UnresolvedSet<8>> &Lookups) { |
14496 | // Find all of the associated namespaces and classes based on the |
14497 | // arguments we have. |
14498 | Sema::AssociatedNamespaceSet AssociatedNamespaces; |
14499 | Sema::AssociatedClassSet AssociatedClasses; |
14500 | OpaqueValueExpr OVE(Loc, Ty, VK_LValue); |
14501 | SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, |
14502 | AssociatedClasses); |
14503 | |
14504 | // C++ [basic.lookup.argdep]p3: |
14505 | // Let X be the lookup set produced by unqualified lookup (3.4.1) |
14506 | // and let Y be the lookup set produced by argument dependent |
14507 | // lookup (defined as follows). If X contains [...] then Y is |
14508 | // empty. Otherwise Y is the set of declarations found in the |
14509 | // namespaces associated with the argument types as described |
14510 | // below. The set of declarations found by the lookup of the name |
14511 | // is the union of X and Y. |
14512 | // |
14513 | // Here, we compute Y and add its members to the overloaded |
14514 | // candidate set. |
14515 | for (auto *NS : AssociatedNamespaces) { |
14516 | // When considering an associated namespace, the lookup is the |
14517 | // same as the lookup performed when the associated namespace is |
14518 | // used as a qualifier (3.4.3.2) except that: |
14519 | // |
14520 | // -- Any using-directives in the associated namespace are |
14521 | // ignored. |
14522 | // |
14523 | // -- Any namespace-scope friend functions declared in |
14524 | // associated classes are visible within their respective |
14525 | // namespaces even if they are not visible during an ordinary |
14526 | // lookup (11.4). |
14527 | DeclContext::lookup_result R = NS->lookup(Id.getName()); |
14528 | for (auto *D : R) { |
14529 | auto *Underlying = D; |
14530 | if (auto *USD = dyn_cast<UsingShadowDecl>(D)) |
14531 | Underlying = USD->getTargetDecl(); |
14532 | |
14533 | if (!isa<OMPDeclareReductionDecl>(Underlying) && |
14534 | !isa<OMPDeclareMapperDecl>(Underlying)) |
14535 | continue; |
14536 | |
14537 | if (!SemaRef.isVisible(D)) { |
14538 | D = findAcceptableDecl(SemaRef, D); |
14539 | if (!D) |
14540 | continue; |
14541 | if (auto *USD = dyn_cast<UsingShadowDecl>(D)) |
14542 | Underlying = USD->getTargetDecl(); |
14543 | } |
14544 | Lookups.emplace_back(); |
14545 | Lookups.back().addDecl(Underlying); |
14546 | } |
14547 | } |
14548 | } |
14549 | |
14550 | static ExprResult |
14551 | buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, |
14552 | Scope *S, CXXScopeSpec &ReductionIdScopeSpec, |
14553 | const DeclarationNameInfo &ReductionId, QualType Ty, |
14554 | CXXCastPath &BasePath, Expr *UnresolvedReduction) { |
14555 | if (ReductionIdScopeSpec.isInvalid()) |
14556 | return ExprError(); |
14557 | SmallVector<UnresolvedSet<8>, 4> Lookups; |
14558 | if (S) { |
14559 | LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); |
14560 | Lookup.suppressDiagnostics(); |
14561 | while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { |
14562 | NamedDecl *D = Lookup.getRepresentativeDecl(); |
14563 | do { |
14564 | S = S->getParent(); |
14565 | } while (S && !S->isDeclScope(D)); |
14566 | if (S) |
14567 | S = S->getParent(); |
14568 | Lookups.emplace_back(); |
14569 | Lookups.back().append(Lookup.begin(), Lookup.end()); |
14570 | Lookup.clear(); |
14571 | } |
14572 | } else if (auto *ULE = |
14573 | cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { |
14574 | Lookups.push_back(UnresolvedSet<8>()); |
14575 | Decl *PrevD = nullptr; |
14576 | for (NamedDecl *D : ULE->decls()) { |
14577 | if (D == PrevD) |
14578 | Lookups.push_back(UnresolvedSet<8>()); |
14579 | else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) |
14580 | Lookups.back().addDecl(DRD); |
14581 | PrevD = D; |
14582 | } |
14583 | } |
14584 | if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || |
14585 | Ty->isInstantiationDependentType() || |
14586 | Ty->containsUnexpandedParameterPack() || |
14587 | filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { |
14588 | return !D->isInvalidDecl() && |
14589 | (D->getType()->isDependentType() || |
14590 | D->getType()->isInstantiationDependentType() || |
14591 | D->getType()->containsUnexpandedParameterPack()); |
14592 | })) { |
14593 | UnresolvedSet<8> ResSet; |
14594 | for (const UnresolvedSet<8> &Set : Lookups) { |
14595 | if (Set.empty()) |
14596 | continue; |
14597 | ResSet.append(Set.begin(), Set.end()); |
14598 | // The last item marks the end of all declarations at the specified scope. |
14599 | ResSet.addDecl(Set[Set.size() - 1]); |
14600 | } |
14601 | return UnresolvedLookupExpr::Create( |
14602 | SemaRef.Context, /*NamingClass=*/nullptr, |
14603 | ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, |
14604 | /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); |
14605 | } |
14606 | // Lookup inside the classes. |
14607 | // C++ [over.match.oper]p3: |
14608 | // For a unary operator @ with an operand of a type whose |
14609 | // cv-unqualified version is T1, and for a binary operator @ with |
14610 | // a left operand of a type whose cv-unqualified version is T1 and |
14611 | // a right operand of a type whose cv-unqualified version is T2, |
14612 | // three sets of candidate functions, designated member |
14613 | // candidates, non-member candidates and built-in candidates, are |
14614 | // constructed as follows: |
14615 | // -- If T1 is a complete class type or a class currently being |
14616 | // defined, the set of member candidates is the result of the |
14617 | // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, |
14618 | // the set of member candidates is empty. |
14619 | LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); |
14620 | Lookup.suppressDiagnostics(); |
14621 | if (const auto *TyRec = Ty->getAs<RecordType>()) { |
14622 | // Complete the type if it can be completed. |
14623 | // If the type is neither complete nor being defined, bail out now. |
14624 | if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || |
14625 | TyRec->getDecl()->getDefinition()) { |
14626 | Lookup.clear(); |
14627 | SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); |
14628 | if (Lookup.empty()) { |
14629 | Lookups.emplace_back(); |
14630 | Lookups.back().append(Lookup.begin(), Lookup.end()); |
14631 | } |
14632 | } |
14633 | } |
14634 | // Perform ADL. |
14635 | if (SemaRef.getLangOpts().CPlusPlus) |
14636 | argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); |
14637 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( |
14638 | Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { |
14639 | if (!D->isInvalidDecl() && |
14640 | SemaRef.Context.hasSameType(D->getType(), Ty)) |
14641 | return D; |
14642 | return nullptr; |
14643 | })) |
14644 | return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), |
14645 | VK_LValue, Loc); |
14646 | if (SemaRef.getLangOpts().CPlusPlus) { |
14647 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( |
14648 | Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { |
14649 | if (!D->isInvalidDecl() && |
14650 | SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && |
14651 | !Ty.isMoreQualifiedThan(D->getType())) |
14652 | return D; |
14653 | return nullptr; |
14654 | })) { |
14655 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, |
14656 | /*DetectVirtual=*/false); |
14657 | if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { |
14658 | if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( |
14659 | VD->getType().getUnqualifiedType()))) { |
14660 | if (SemaRef.CheckBaseClassAccess( |
14661 | Loc, VD->getType(), Ty, Paths.front(), |
14662 | /*DiagID=*/0) != Sema::AR_inaccessible) { |
14663 | SemaRef.BuildBasePathArray(Paths, BasePath); |
14664 | return SemaRef.BuildDeclRefExpr( |
14665 | VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); |
14666 | } |
14667 | } |
14668 | } |
14669 | } |
14670 | } |
14671 | if (ReductionIdScopeSpec.isSet()) { |
14672 | SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) |
14673 | << Ty << Range; |
14674 | return ExprError(); |
14675 | } |
14676 | return ExprEmpty(); |
14677 | } |
14678 | |
14679 | namespace { |
14680 | /// Data for the reduction-based clauses. |
14681 | struct ReductionData { |
14682 | /// List of original reduction items. |
14683 | SmallVector<Expr *, 8> Vars; |
14684 | /// List of private copies of the reduction items. |
14685 | SmallVector<Expr *, 8> Privates; |
14686 | /// LHS expressions for the reduction_op expressions. |
14687 | SmallVector<Expr *, 8> LHSs; |
14688 | /// RHS expressions for the reduction_op expressions. |
14689 | SmallVector<Expr *, 8> RHSs; |
14690 | /// Reduction operation expression. |
14691 | SmallVector<Expr *, 8> ReductionOps; |
14692 | /// inscan copy operation expressions. |
14693 | SmallVector<Expr *, 8> InscanCopyOps; |
14694 | /// inscan copy temp array expressions for prefix sums. |
14695 | SmallVector<Expr *, 8> InscanCopyArrayTemps; |
14696 | /// inscan copy temp array element expressions for prefix sums. |
14697 | SmallVector<Expr *, 8> InscanCopyArrayElems; |
14698 | /// Taskgroup descriptors for the corresponding reduction items in |
14699 | /// in_reduction clauses. |
14700 | SmallVector<Expr *, 8> TaskgroupDescriptors; |
14701 | /// List of captures for clause. |
14702 | SmallVector<Decl *, 4> ExprCaptures; |
14703 | /// List of postupdate expressions. |
14704 | SmallVector<Expr *, 4> ExprPostUpdates; |
14705 | /// Reduction modifier. |
14706 | unsigned RedModifier = 0; |
14707 | ReductionData() = delete; |
14708 | /// Reserves required memory for the reduction data. |
14709 | ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { |
14710 | Vars.reserve(Size); |
14711 | Privates.reserve(Size); |
14712 | LHSs.reserve(Size); |
14713 | RHSs.reserve(Size); |
14714 | ReductionOps.reserve(Size); |
14715 | if (RedModifier == OMPC_REDUCTION_inscan) { |
14716 | InscanCopyOps.reserve(Size); |
14717 | InscanCopyArrayTemps.reserve(Size); |
14718 | InscanCopyArrayElems.reserve(Size); |
14719 | } |
14720 | TaskgroupDescriptors.reserve(Size); |
14721 | ExprCaptures.reserve(Size); |
14722 | ExprPostUpdates.reserve(Size); |
14723 | } |
14724 | /// Stores reduction item and reduction operation only (required for dependent |
14725 | /// reduction item). |
14726 | void push(Expr *Item, Expr *ReductionOp) { |
14727 | Vars.emplace_back(Item); |
14728 | Privates.emplace_back(nullptr); |
14729 | LHSs.emplace_back(nullptr); |
14730 | RHSs.emplace_back(nullptr); |
14731 | ReductionOps.emplace_back(ReductionOp); |
14732 | TaskgroupDescriptors.emplace_back(nullptr); |
14733 | if (RedModifier == OMPC_REDUCTION_inscan) { |
14734 | InscanCopyOps.push_back(nullptr); |
14735 | InscanCopyArrayTemps.push_back(nullptr); |
14736 | InscanCopyArrayElems.push_back(nullptr); |
14737 | } |
14738 | } |
14739 | /// Stores reduction data. |
14740 | void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, |
14741 | Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, |
14742 | Expr *CopyArrayElem) { |
14743 | Vars.emplace_back(Item); |
14744 | Privates.emplace_back(Private); |
14745 | LHSs.emplace_back(LHS); |
14746 | RHSs.emplace_back(RHS); |
14747 | ReductionOps.emplace_back(ReductionOp); |
14748 | TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); |
14749 | if (RedModifier == OMPC_REDUCTION_inscan) { |
14750 | InscanCopyOps.push_back(CopyOp); |
14751 | InscanCopyArrayTemps.push_back(CopyArrayTemp); |
14752 | InscanCopyArrayElems.push_back(CopyArrayElem); |
14753 | } else { |
14754 | assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only." ) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14756, __PRETTY_FUNCTION__)) |
14755 | CopyArrayElem == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only." ) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14756, __PRETTY_FUNCTION__)) |
14756 | "Copy operation must be used for inscan reductions only.")((CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only." ) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14756, __PRETTY_FUNCTION__)); |
14757 | } |
14758 | } |
14759 | }; |
14760 | } // namespace |
14761 | |
14762 | static bool checkOMPArraySectionConstantForReduction( |
14763 | ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, |
14764 | SmallVectorImpl<llvm::APSInt> &ArraySizes) { |
14765 | const Expr *Length = OASE->getLength(); |
14766 | if (Length == nullptr) { |
14767 | // For array sections of the form [1:] or [:], we would need to analyze |
14768 | // the lower bound... |
14769 | if (OASE->getColonLocFirst().isValid()) |
14770 | return false; |
14771 | |
14772 | // This is an array subscript which has implicit length 1! |
14773 | SingleElement = true; |
14774 | ArraySizes.push_back(llvm::APSInt::get(1)); |
14775 | } else { |
14776 | Expr::EvalResult Result; |
14777 | if (!Length->EvaluateAsInt(Result, Context)) |
14778 | return false; |
14779 | |
14780 | llvm::APSInt ConstantLengthValue = Result.Val.getInt(); |
14781 | SingleElement = (ConstantLengthValue.getSExtValue() == 1); |
14782 | ArraySizes.push_back(ConstantLengthValue); |
14783 | } |
14784 | |
14785 | // Get the base of this array section and walk up from there. |
14786 | const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); |
14787 | |
14788 | // We require length = 1 for all array sections except the right-most to |
14789 | // guarantee that the memory region is contiguous and has no holes in it. |
14790 | while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { |
14791 | Length = TempOASE->getLength(); |
14792 | if (Length == nullptr) { |
14793 | // For array sections of the form [1:] or [:], we would need to analyze |
14794 | // the lower bound... |
14795 | if (OASE->getColonLocFirst().isValid()) |
14796 | return false; |
14797 | |
14798 | // This is an array subscript which has implicit length 1! |
14799 | ArraySizes.push_back(llvm::APSInt::get(1)); |
14800 | } else { |
14801 | Expr::EvalResult Result; |
14802 | if (!Length->EvaluateAsInt(Result, Context)) |
14803 | return false; |
14804 | |
14805 | llvm::APSInt ConstantLengthValue = Result.Val.getInt(); |
14806 | if (ConstantLengthValue.getSExtValue() != 1) |
14807 | return false; |
14808 | |
14809 | ArraySizes.push_back(ConstantLengthValue); |
14810 | } |
14811 | Base = TempOASE->getBase()->IgnoreParenImpCasts(); |
14812 | } |
14813 | |
14814 | // If we have a single element, we don't need to add the implicit lengths. |
14815 | if (!SingleElement) { |
14816 | while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { |
14817 | // Has implicit length 1! |
14818 | ArraySizes.push_back(llvm::APSInt::get(1)); |
14819 | Base = TempASE->getBase()->IgnoreParenImpCasts(); |
14820 | } |
14821 | } |
14822 | |
14823 | // This array section can be privatized as a single value or as a constant |
14824 | // sized array. |
14825 | return true; |
14826 | } |
14827 | |
14828 | static bool actOnOMPReductionKindClause( |
14829 | Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, |
14830 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, |
14831 | SourceLocation ColonLoc, SourceLocation EndLoc, |
14832 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, |
14833 | ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { |
14834 | DeclarationName DN = ReductionId.getName(); |
14835 | OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); |
14836 | BinaryOperatorKind BOK = BO_Comma; |
14837 | |
14838 | ASTContext &Context = S.Context; |
14839 | // OpenMP [2.14.3.6, reduction clause] |
14840 | // C |
14841 | // reduction-identifier is either an identifier or one of the following |
14842 | // operators: +, -, *, &, |, ^, && and || |
14843 | // C++ |
14844 | // reduction-identifier is either an id-expression or one of the following |
14845 | // operators: +, -, *, &, |, ^, && and || |
14846 | switch (OOK) { |
14847 | case OO_Plus: |
14848 | case OO_Minus: |
14849 | BOK = BO_Add; |
14850 | break; |
14851 | case OO_Star: |
14852 | BOK = BO_Mul; |
14853 | break; |
14854 | case OO_Amp: |
14855 | BOK = BO_And; |
14856 | break; |
14857 | case OO_Pipe: |
14858 | BOK = BO_Or; |
14859 | break; |
14860 | case OO_Caret: |
14861 | BOK = BO_Xor; |
14862 | break; |
14863 | case OO_AmpAmp: |
14864 | BOK = BO_LAnd; |
14865 | break; |
14866 | case OO_PipePipe: |
14867 | BOK = BO_LOr; |
14868 | break; |
14869 | case OO_New: |
14870 | case OO_Delete: |
14871 | case OO_Array_New: |
14872 | case OO_Array_Delete: |
14873 | case OO_Slash: |
14874 | case OO_Percent: |
14875 | case OO_Tilde: |
14876 | case OO_Exclaim: |
14877 | case OO_Equal: |
14878 | case OO_Less: |
14879 | case OO_Greater: |
14880 | case OO_LessEqual: |
14881 | case OO_GreaterEqual: |
14882 | case OO_PlusEqual: |
14883 | case OO_MinusEqual: |
14884 | case OO_StarEqual: |
14885 | case OO_SlashEqual: |
14886 | case OO_PercentEqual: |
14887 | case OO_CaretEqual: |
14888 | case OO_AmpEqual: |
14889 | case OO_PipeEqual: |
14890 | case OO_LessLess: |
14891 | case OO_GreaterGreater: |
14892 | case OO_LessLessEqual: |
14893 | case OO_GreaterGreaterEqual: |
14894 | case OO_EqualEqual: |
14895 | case OO_ExclaimEqual: |
14896 | case OO_Spaceship: |
14897 | case OO_PlusPlus: |
14898 | case OO_MinusMinus: |
14899 | case OO_Comma: |
14900 | case OO_ArrowStar: |
14901 | case OO_Arrow: |
14902 | case OO_Call: |
14903 | case OO_Subscript: |
14904 | case OO_Conditional: |
14905 | case OO_Coawait: |
14906 | case NUM_OVERLOADED_OPERATORS: |
14907 | llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14907); |
14908 | case OO_None: |
14909 | if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { |
14910 | if (II->isStr("max")) |
14911 | BOK = BO_GT; |
14912 | else if (II->isStr("min")) |
14913 | BOK = BO_LT; |
14914 | } |
14915 | break; |
14916 | } |
14917 | SourceRange ReductionIdRange; |
14918 | if (ReductionIdScopeSpec.isValid()) |
14919 | ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); |
14920 | else |
14921 | ReductionIdRange.setBegin(ReductionId.getBeginLoc()); |
14922 | ReductionIdRange.setEnd(ReductionId.getEndLoc()); |
14923 | |
14924 | auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); |
14925 | bool FirstIter = true; |
14926 | for (Expr *RefExpr : VarList) { |
14927 | assert(RefExpr && "nullptr expr in OpenMP reduction clause.")((RefExpr && "nullptr expr in OpenMP reduction clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 14927, __PRETTY_FUNCTION__)); |
14928 | // OpenMP [2.1, C/C++] |
14929 | // A list item is a variable or array section, subject to the restrictions |
14930 | // specified in Section 2.4 on page 42 and in each of the sections |
14931 | // describing clauses and directives for which a list appears. |
14932 | // OpenMP [2.14.3.3, Restrictions, p.1] |
14933 | // A variable that is part of another variable (as an array or |
14934 | // structure element) cannot appear in a private clause. |
14935 | if (!FirstIter && IR != ER) |
14936 | ++IR; |
14937 | FirstIter = false; |
14938 | SourceLocation ELoc; |
14939 | SourceRange ERange; |
14940 | Expr *SimpleRefExpr = RefExpr; |
14941 | auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, |
14942 | /*AllowArraySection=*/true); |
14943 | if (Res.second) { |
14944 | // Try to find 'declare reduction' corresponding construct before using |
14945 | // builtin/overloaded operators. |
14946 | QualType Type = Context.DependentTy; |
14947 | CXXCastPath BasePath; |
14948 | ExprResult DeclareReductionRef = buildDeclareReductionRef( |
14949 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, |
14950 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); |
14951 | Expr *ReductionOp = nullptr; |
14952 | if (S.CurContext->isDependentContext() && |
14953 | (DeclareReductionRef.isUnset() || |
14954 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) |
14955 | ReductionOp = DeclareReductionRef.get(); |
14956 | // It will be analyzed later. |
14957 | RD.push(RefExpr, ReductionOp); |
14958 | } |
14959 | ValueDecl *D = Res.first; |
14960 | if (!D) |
14961 | continue; |
14962 | |
14963 | Expr *TaskgroupDescriptor = nullptr; |
14964 | QualType Type; |
14965 | auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); |
14966 | auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); |
14967 | if (ASE) { |
14968 | Type = ASE->getType().getNonReferenceType(); |
14969 | } else if (OASE) { |
14970 | QualType BaseType = |
14971 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); |
14972 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) |
14973 | Type = ATy->getElementType(); |
14974 | else |
14975 | Type = BaseType->getPointeeType(); |
14976 | Type = Type.getNonReferenceType(); |
14977 | } else { |
14978 | Type = Context.getBaseElementType(D->getType().getNonReferenceType()); |
14979 | } |
14980 | auto *VD = dyn_cast<VarDecl>(D); |
14981 | |
14982 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] |
14983 | // A variable that appears in a private clause must not have an incomplete |
14984 | // type or a reference type. |
14985 | if (S.RequireCompleteType(ELoc, D->getType(), |
14986 | diag::err_omp_reduction_incomplete_type)) |
14987 | continue; |
14988 | // OpenMP [2.14.3.6, reduction clause, Restrictions] |
14989 | // A list item that appears in a reduction clause must not be |
14990 | // const-qualified. |
14991 | if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, |
14992 | /*AcceptIfMutable*/ false, ASE || OASE)) |
14993 | continue; |
14994 | |
14995 | OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); |
14996 | // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] |
14997 | // If a list-item is a reference type then it must bind to the same object |
14998 | // for all threads of the team. |
14999 | if (!ASE && !OASE) { |
15000 | if (VD) { |
15001 | VarDecl *VDDef = VD->getDefinition(); |
15002 | if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { |
15003 | DSARefChecker Check(Stack); |
15004 | if (Check.Visit(VDDef->getInit())) { |
15005 | S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) |
15006 | << getOpenMPClauseName(ClauseKind) << ERange; |
15007 | S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; |
15008 | continue; |
15009 | } |
15010 | } |
15011 | } |
15012 | |
15013 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced |
15014 | // in a Construct] |
15015 | // Variables with the predetermined data-sharing attributes may not be |
15016 | // listed in data-sharing attributes clauses, except for the cases |
15017 | // listed below. For these exceptions only, listing a predetermined |
15018 | // variable in a data-sharing attribute clause is allowed and overrides |
15019 | // the variable's predetermined data-sharing attributes. |
15020 | // OpenMP [2.14.3.6, Restrictions, p.3] |
15021 | // Any number of reduction clauses can be specified on the directive, |
15022 | // but a list item can appear only once in the reduction clauses for that |
15023 | // directive. |
15024 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); |
15025 | if (DVar.CKind == OMPC_reduction) { |
15026 | S.Diag(ELoc, diag::err_omp_once_referenced) |
15027 | << getOpenMPClauseName(ClauseKind); |
15028 | if (DVar.RefExpr) |
15029 | S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); |
15030 | continue; |
15031 | } |
15032 | if (DVar.CKind != OMPC_unknown) { |
15033 | S.Diag(ELoc, diag::err_omp_wrong_dsa) |
15034 | << getOpenMPClauseName(DVar.CKind) |
15035 | << getOpenMPClauseName(OMPC_reduction); |
15036 | reportOriginalDsa(S, Stack, D, DVar); |
15037 | continue; |
15038 | } |
15039 | |
15040 | // OpenMP [2.14.3.6, Restrictions, p.1] |
15041 | // A list item that appears in a reduction clause of a worksharing |
15042 | // construct must be shared in the parallel regions to which any of the |
15043 | // worksharing regions arising from the worksharing construct bind. |
15044 | if (isOpenMPWorksharingDirective(CurrDir) && |
15045 | !isOpenMPParallelDirective(CurrDir) && |
15046 | !isOpenMPTeamsDirective(CurrDir)) { |
15047 | DVar = Stack->getImplicitDSA(D, true); |
15048 | if (DVar.CKind != OMPC_shared) { |
15049 | S.Diag(ELoc, diag::err_omp_required_access) |
15050 | << getOpenMPClauseName(OMPC_reduction) |
15051 | << getOpenMPClauseName(OMPC_shared); |
15052 | reportOriginalDsa(S, Stack, D, DVar); |
15053 | continue; |
15054 | } |
15055 | } |
15056 | } |
15057 | |
15058 | // Try to find 'declare reduction' corresponding construct before using |
15059 | // builtin/overloaded operators. |
15060 | CXXCastPath BasePath; |
15061 | ExprResult DeclareReductionRef = buildDeclareReductionRef( |
15062 | S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, |
15063 | ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); |
15064 | if (DeclareReductionRef.isInvalid()) |
15065 | continue; |
15066 | if (S.CurContext->isDependentContext() && |
15067 | (DeclareReductionRef.isUnset() || |
15068 | isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { |
15069 | RD.push(RefExpr, DeclareReductionRef.get()); |
15070 | continue; |
15071 | } |
15072 | if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { |
15073 | // Not allowed reduction identifier is found. |
15074 | S.Diag(ReductionId.getBeginLoc(), |
15075 | diag::err_omp_unknown_reduction_identifier) |
15076 | << Type << ReductionIdRange; |
15077 | continue; |
15078 | } |
15079 | |
15080 | // OpenMP [2.14.3.6, reduction clause, Restrictions] |
15081 | // The type of a list item that appears in a reduction clause must be valid |
15082 | // for the reduction-identifier. For a max or min reduction in C, the type |
15083 | // of the list item must be an allowed arithmetic data type: char, int, |
15084 | // float, double, or _Bool, possibly modified with long, short, signed, or |
15085 | // unsigned. For a max or min reduction in C++, the type of the list item |
15086 | // must be an allowed arithmetic data type: char, wchar_t, int, float, |
15087 | // double, or bool, possibly modified with long, short, signed, or unsigned. |
15088 | if (DeclareReductionRef.isUnset()) { |
15089 | if ((BOK == BO_GT || BOK == BO_LT) && |
15090 | !(Type->isScalarType() || |
15091 | (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { |
15092 | S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) |
15093 | << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; |
15094 | if (!ASE && !OASE) { |
15095 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
15096 | VarDecl::DeclarationOnly; |
15097 | S.Diag(D->getLocation(), |
15098 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
15099 | << D; |
15100 | } |
15101 | continue; |
15102 | } |
15103 | if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && |
15104 | !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { |
15105 | S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) |
15106 | << getOpenMPClauseName(ClauseKind); |
15107 | if (!ASE && !OASE) { |
15108 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
15109 | VarDecl::DeclarationOnly; |
15110 | S.Diag(D->getLocation(), |
15111 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
15112 | << D; |
15113 | } |
15114 | continue; |
15115 | } |
15116 | } |
15117 | |
15118 | Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); |
15119 | VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", |
15120 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
15121 | VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), |
15122 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
15123 | QualType PrivateTy = Type; |
15124 | |
15125 | // Try if we can determine constant lengths for all array sections and avoid |
15126 | // the VLA. |
15127 | bool ConstantLengthOASE = false; |
15128 | if (OASE) { |
15129 | bool SingleElement; |
15130 | llvm::SmallVector<llvm::APSInt, 4> ArraySizes; |
15131 | ConstantLengthOASE = checkOMPArraySectionConstantForReduction( |
15132 | Context, OASE, SingleElement, ArraySizes); |
15133 | |
15134 | // If we don't have a single element, we must emit a constant array type. |
15135 | if (ConstantLengthOASE && !SingleElement) { |
15136 | for (llvm::APSInt &Size : ArraySizes) |
15137 | PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, |
15138 | ArrayType::Normal, |
15139 | /*IndexTypeQuals=*/0); |
15140 | } |
15141 | } |
15142 | |
15143 | if ((OASE && !ConstantLengthOASE) || |
15144 | (!OASE && !ASE && |
15145 | D->getType().getNonReferenceType()->isVariablyModifiedType())) { |
15146 | if (!Context.getTargetInfo().isVLASupported()) { |
15147 | if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { |
15148 | S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; |
15149 | S.Diag(ELoc, diag::note_vla_unsupported); |
15150 | continue; |
15151 | } else { |
15152 | S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; |
15153 | S.targetDiag(ELoc, diag::note_vla_unsupported); |
15154 | } |
15155 | } |
15156 | // For arrays/array sections only: |
15157 | // Create pseudo array type for private copy. The size for this array will |
15158 | // be generated during codegen. |
15159 | // For array subscripts or single variables Private Ty is the same as Type |
15160 | // (type of the variable or single array element). |
15161 | PrivateTy = Context.getVariableArrayType( |
15162 | Type, |
15163 | new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), |
15164 | ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); |
15165 | } else if (!ASE && !OASE && |
15166 | Context.getAsArrayType(D->getType().getNonReferenceType())) { |
15167 | PrivateTy = D->getType().getNonReferenceType(); |
15168 | } |
15169 | // Private copy. |
15170 | VarDecl *PrivateVD = |
15171 | buildVarDecl(S, ELoc, PrivateTy, D->getName(), |
15172 | D->hasAttrs() ? &D->getAttrs() : nullptr, |
15173 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); |
15174 | // Add initializer for private variable. |
15175 | Expr *Init = nullptr; |
15176 | DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); |
15177 | DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); |
15178 | if (DeclareReductionRef.isUsable()) { |
15179 | auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); |
15180 | auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); |
15181 | if (DRD->getInitializer()) { |
15182 | S.ActOnUninitializedDecl(PrivateVD); |
15183 | Init = DRDRef; |
15184 | RHSVD->setInit(DRDRef); |
15185 | RHSVD->setInitStyle(VarDecl::CallInit); |
15186 | } |
15187 | } else { |
15188 | switch (BOK) { |
15189 | case BO_Add: |
15190 | case BO_Xor: |
15191 | case BO_Or: |
15192 | case BO_LOr: |
15193 | // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. |
15194 | if (Type->isScalarType() || Type->isAnyComplexType()) |
15195 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); |
15196 | break; |
15197 | case BO_Mul: |
15198 | case BO_LAnd: |
15199 | if (Type->isScalarType() || Type->isAnyComplexType()) { |
15200 | // '*' and '&&' reduction ops - initializer is '1'. |
15201 | Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); |
15202 | } |
15203 | break; |
15204 | case BO_And: { |
15205 | // '&' reduction op - initializer is '~0'. |
15206 | QualType OrigType = Type; |
15207 | if (auto *ComplexTy = OrigType->getAs<ComplexType>()) |
15208 | Type = ComplexTy->getElementType(); |
15209 | if (Type->isRealFloatingType()) { |
15210 | llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( |
15211 | Context.getFloatTypeSemantics(Type), |
15212 | Context.getTypeSize(Type)); |
15213 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, |
15214 | Type, ELoc); |
15215 | } else if (Type->isScalarType()) { |
15216 | uint64_t Size = Context.getTypeSize(Type); |
15217 | QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); |
15218 | llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); |
15219 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); |
15220 | } |
15221 | if (Init && OrigType->isAnyComplexType()) { |
15222 | // Init = 0xFFFF + 0xFFFFi; |
15223 | auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); |
15224 | Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); |
15225 | } |
15226 | Type = OrigType; |
15227 | break; |
15228 | } |
15229 | case BO_LT: |
15230 | case BO_GT: { |
15231 | // 'min' reduction op - initializer is 'Largest representable number in |
15232 | // the reduction list item type'. |
15233 | // 'max' reduction op - initializer is 'Least representable number in |
15234 | // the reduction list item type'. |
15235 | if (Type->isIntegerType() || Type->isPointerType()) { |
15236 | bool IsSigned = Type->hasSignedIntegerRepresentation(); |
15237 | uint64_t Size = Context.getTypeSize(Type); |
15238 | QualType IntTy = |
15239 | Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); |
15240 | llvm::APInt InitValue = |
15241 | (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) |
15242 | : llvm::APInt::getMinValue(Size) |
15243 | : IsSigned ? llvm::APInt::getSignedMaxValue(Size) |
15244 | : llvm::APInt::getMaxValue(Size); |
15245 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); |
15246 | if (Type->isPointerType()) { |
15247 | // Cast to pointer type. |
15248 | ExprResult CastExpr = S.BuildCStyleCastExpr( |
15249 | ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); |
15250 | if (CastExpr.isInvalid()) |
15251 | continue; |
15252 | Init = CastExpr.get(); |
15253 | } |
15254 | } else if (Type->isRealFloatingType()) { |
15255 | llvm::APFloat InitValue = llvm::APFloat::getLargest( |
15256 | Context.getFloatTypeSemantics(Type), BOK != BO_LT); |
15257 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, |
15258 | Type, ELoc); |
15259 | } |
15260 | break; |
15261 | } |
15262 | case BO_PtrMemD: |
15263 | case BO_PtrMemI: |
15264 | case BO_MulAssign: |
15265 | case BO_Div: |
15266 | case BO_Rem: |
15267 | case BO_Sub: |
15268 | case BO_Shl: |
15269 | case BO_Shr: |
15270 | case BO_LE: |
15271 | case BO_GE: |
15272 | case BO_EQ: |
15273 | case BO_NE: |
15274 | case BO_Cmp: |
15275 | case BO_AndAssign: |
15276 | case BO_XorAssign: |
15277 | case BO_OrAssign: |
15278 | case BO_Assign: |
15279 | case BO_AddAssign: |
15280 | case BO_SubAssign: |
15281 | case BO_DivAssign: |
15282 | case BO_RemAssign: |
15283 | case BO_ShlAssign: |
15284 | case BO_ShrAssign: |
15285 | case BO_Comma: |
15286 | llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15286); |
15287 | } |
15288 | } |
15289 | if (Init && DeclareReductionRef.isUnset()) { |
15290 | S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); |
15291 | // Store initializer for single element in private copy. Will be used |
15292 | // during codegen. |
15293 | PrivateVD->setInit(RHSVD->getInit()); |
15294 | PrivateVD->setInitStyle(RHSVD->getInitStyle()); |
15295 | } else if (!Init) { |
15296 | S.ActOnUninitializedDecl(RHSVD); |
15297 | // Store initializer for single element in private copy. Will be used |
15298 | // during codegen. |
15299 | PrivateVD->setInit(RHSVD->getInit()); |
15300 | PrivateVD->setInitStyle(RHSVD->getInitStyle()); |
15301 | } |
15302 | if (RHSVD->isInvalidDecl()) |
15303 | continue; |
15304 | if (!RHSVD->hasInit() && |
15305 | (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { |
15306 | S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) |
15307 | << Type << ReductionIdRange; |
15308 | bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == |
15309 | VarDecl::DeclarationOnly; |
15310 | S.Diag(D->getLocation(), |
15311 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
15312 | << D; |
15313 | continue; |
15314 | } |
15315 | DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); |
15316 | ExprResult ReductionOp; |
15317 | if (DeclareReductionRef.isUsable()) { |
15318 | QualType RedTy = DeclareReductionRef.get()->getType(); |
15319 | QualType PtrRedTy = Context.getPointerType(RedTy); |
15320 | ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); |
15321 | ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); |
15322 | if (!BasePath.empty()) { |
15323 | LHS = S.DefaultLvalueConversion(LHS.get()); |
15324 | RHS = S.DefaultLvalueConversion(RHS.get()); |
15325 | LHS = ImplicitCastExpr::Create(Context, PtrRedTy, |
15326 | CK_UncheckedDerivedToBase, LHS.get(), |
15327 | &BasePath, LHS.get()->getValueKind()); |
15328 | RHS = ImplicitCastExpr::Create(Context, PtrRedTy, |
15329 | CK_UncheckedDerivedToBase, RHS.get(), |
15330 | &BasePath, RHS.get()->getValueKind()); |
15331 | } |
15332 | FunctionProtoType::ExtProtoInfo EPI; |
15333 | QualType Params[] = {PtrRedTy, PtrRedTy}; |
15334 | QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); |
15335 | auto *OVE = new (Context) OpaqueValueExpr( |
15336 | ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, |
15337 | S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); |
15338 | Expr *Args[] = {LHS.get(), RHS.get()}; |
15339 | ReductionOp = |
15340 | CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc, |
15341 | S.CurFPFeatureOverrides()); |
15342 | } else { |
15343 | ReductionOp = S.BuildBinOp( |
15344 | Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); |
15345 | if (ReductionOp.isUsable()) { |
15346 | if (BOK != BO_LT && BOK != BO_GT) { |
15347 | ReductionOp = |
15348 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), |
15349 | BO_Assign, LHSDRE, ReductionOp.get()); |
15350 | } else { |
15351 | auto *ConditionalOp = new (Context) |
15352 | ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, |
15353 | Type, VK_LValue, OK_Ordinary); |
15354 | ReductionOp = |
15355 | S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), |
15356 | BO_Assign, LHSDRE, ConditionalOp); |
15357 | } |
15358 | if (ReductionOp.isUsable()) |
15359 | ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), |
15360 | /*DiscardedValue*/ false); |
15361 | } |
15362 | if (!ReductionOp.isUsable()) |
15363 | continue; |
15364 | } |
15365 | |
15366 | // Add copy operations for inscan reductions. |
15367 | // LHS = RHS; |
15368 | ExprResult CopyOpRes, TempArrayRes, TempArrayElem; |
15369 | if (ClauseKind == OMPC_reduction && |
15370 | RD.RedModifier == OMPC_REDUCTION_inscan) { |
15371 | ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); |
15372 | CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, |
15373 | RHS.get()); |
15374 | if (!CopyOpRes.isUsable()) |
15375 | continue; |
15376 | CopyOpRes = |
15377 | S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); |
15378 | if (!CopyOpRes.isUsable()) |
15379 | continue; |
15380 | // For simd directive and simd-based directives in simd mode no need to |
15381 | // construct temp array, need just a single temp element. |
15382 | if (Stack->getCurrentDirective() == OMPD_simd || |
15383 | (S.getLangOpts().OpenMPSimd && |
15384 | isOpenMPSimdDirective(Stack->getCurrentDirective()))) { |
15385 | VarDecl *TempArrayVD = |
15386 | buildVarDecl(S, ELoc, PrivateTy, D->getName(), |
15387 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
15388 | // Add a constructor to the temp decl. |
15389 | S.ActOnUninitializedDecl(TempArrayVD); |
15390 | TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); |
15391 | } else { |
15392 | // Build temp array for prefix sum. |
15393 | auto *Dim = new (S.Context) |
15394 | OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); |
15395 | QualType ArrayTy = |
15396 | S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, |
15397 | /*IndexTypeQuals=*/0, {ELoc, ELoc}); |
15398 | VarDecl *TempArrayVD = |
15399 | buildVarDecl(S, ELoc, ArrayTy, D->getName(), |
15400 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
15401 | // Add a constructor to the temp decl. |
15402 | S.ActOnUninitializedDecl(TempArrayVD); |
15403 | TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); |
15404 | TempArrayElem = |
15405 | S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); |
15406 | auto *Idx = new (S.Context) |
15407 | OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); |
15408 | TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), |
15409 | ELoc, Idx, ELoc); |
15410 | } |
15411 | } |
15412 | |
15413 | // OpenMP [2.15.4.6, Restrictions, p.2] |
15414 | // A list item that appears in an in_reduction clause of a task construct |
15415 | // must appear in a task_reduction clause of a construct associated with a |
15416 | // taskgroup region that includes the participating task in its taskgroup |
15417 | // set. The construct associated with the innermost region that meets this |
15418 | // condition must specify the same reduction-identifier as the in_reduction |
15419 | // clause. |
15420 | if (ClauseKind == OMPC_in_reduction) { |
15421 | SourceRange ParentSR; |
15422 | BinaryOperatorKind ParentBOK; |
15423 | const Expr *ParentReductionOp = nullptr; |
15424 | Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; |
15425 | DSAStackTy::DSAVarData ParentBOKDSA = |
15426 | Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, |
15427 | ParentBOKTD); |
15428 | DSAStackTy::DSAVarData ParentReductionOpDSA = |
15429 | Stack->getTopMostTaskgroupReductionData( |
15430 | D, ParentSR, ParentReductionOp, ParentReductionOpTD); |
15431 | bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; |
15432 | bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; |
15433 | if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || |
15434 | (DeclareReductionRef.isUsable() && IsParentBOK) || |
15435 | (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { |
15436 | bool EmitError = true; |
15437 | if (IsParentReductionOp && DeclareReductionRef.isUsable()) { |
15438 | llvm::FoldingSetNodeID RedId, ParentRedId; |
15439 | ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); |
15440 | DeclareReductionRef.get()->Profile(RedId, Context, |
15441 | /*Canonical=*/true); |
15442 | EmitError = RedId != ParentRedId; |
15443 | } |
15444 | if (EmitError) { |
15445 | S.Diag(ReductionId.getBeginLoc(), |
15446 | diag::err_omp_reduction_identifier_mismatch) |
15447 | << ReductionIdRange << RefExpr->getSourceRange(); |
15448 | S.Diag(ParentSR.getBegin(), |
15449 | diag::note_omp_previous_reduction_identifier) |
15450 | << ParentSR |
15451 | << (IsParentBOK ? ParentBOKDSA.RefExpr |
15452 | : ParentReductionOpDSA.RefExpr) |
15453 | ->getSourceRange(); |
15454 | continue; |
15455 | } |
15456 | } |
15457 | TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; |
15458 | } |
15459 | |
15460 | DeclRefExpr *Ref = nullptr; |
15461 | Expr *VarsExpr = RefExpr->IgnoreParens(); |
15462 | if (!VD && !S.CurContext->isDependentContext()) { |
15463 | if (ASE || OASE) { |
15464 | TransformExprToCaptures RebuildToCapture(S, D); |
15465 | VarsExpr = |
15466 | RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); |
15467 | Ref = RebuildToCapture.getCapturedExpr(); |
15468 | } else { |
15469 | VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); |
15470 | } |
15471 | if (!S.isOpenMPCapturedDecl(D)) { |
15472 | RD.ExprCaptures.emplace_back(Ref->getDecl()); |
15473 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { |
15474 | ExprResult RefRes = S.DefaultLvalueConversion(Ref); |
15475 | if (!RefRes.isUsable()) |
15476 | continue; |
15477 | ExprResult PostUpdateRes = |
15478 | S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, |
15479 | RefRes.get()); |
15480 | if (!PostUpdateRes.isUsable()) |
15481 | continue; |
15482 | if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || |
15483 | Stack->getCurrentDirective() == OMPD_taskgroup) { |
15484 | S.Diag(RefExpr->getExprLoc(), |
15485 | diag::err_omp_reduction_non_addressable_expression) |
15486 | << RefExpr->getSourceRange(); |
15487 | continue; |
15488 | } |
15489 | RD.ExprPostUpdates.emplace_back( |
15490 | S.IgnoredValueConversions(PostUpdateRes.get()).get()); |
15491 | } |
15492 | } |
15493 | } |
15494 | // All reduction items are still marked as reduction (to do not increase |
15495 | // code base size). |
15496 | unsigned Modifier = RD.RedModifier; |
15497 | // Consider task_reductions as reductions with task modifier. Required for |
15498 | // correct analysis of in_reduction clauses. |
15499 | if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) |
15500 | Modifier = OMPC_REDUCTION_task; |
15501 | Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier); |
15502 | if (Modifier == OMPC_REDUCTION_task && |
15503 | (CurrDir == OMPD_taskgroup || |
15504 | ((isOpenMPParallelDirective(CurrDir) || |
15505 | isOpenMPWorksharingDirective(CurrDir)) && |
15506 | !isOpenMPSimdDirective(CurrDir)))) { |
15507 | if (DeclareReductionRef.isUsable()) |
15508 | Stack->addTaskgroupReductionData(D, ReductionIdRange, |
15509 | DeclareReductionRef.get()); |
15510 | else |
15511 | Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); |
15512 | } |
15513 | RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), |
15514 | TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), |
15515 | TempArrayElem.get()); |
15516 | } |
15517 | return RD.Vars.empty(); |
15518 | } |
15519 | |
15520 | OMPClause *Sema::ActOnOpenMPReductionClause( |
15521 | ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, |
15522 | SourceLocation StartLoc, SourceLocation LParenLoc, |
15523 | SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, |
15524 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, |
15525 | ArrayRef<Expr *> UnresolvedReductions) { |
15526 | if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { |
15527 | Diag(LParenLoc, diag::err_omp_unexpected_clause_value) |
15528 | << getListOfPossibleValues(OMPC_reduction, /*First=*/0, |
15529 | /*Last=*/OMPC_REDUCTION_unknown) |
15530 | << getOpenMPClauseName(OMPC_reduction); |
15531 | return nullptr; |
15532 | } |
15533 | // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions |
15534 | // A reduction clause with the inscan reduction-modifier may only appear on a |
15535 | // worksharing-loop construct, a worksharing-loop SIMD construct, a simd |
15536 | // construct, a parallel worksharing-loop construct or a parallel |
15537 | // worksharing-loop SIMD construct. |
15538 | if (Modifier == OMPC_REDUCTION_inscan && |
15539 | (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_for && |
15540 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_for_simd && |
15541 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_simd && |
15542 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_parallel_for && |
15543 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_parallel_for_simd)) { |
15544 | Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); |
15545 | return nullptr; |
15546 | } |
15547 | |
15548 | ReductionData RD(VarList.size(), Modifier); |
15549 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_reduction, VarList, |
15550 | StartLoc, LParenLoc, ColonLoc, EndLoc, |
15551 | ReductionIdScopeSpec, ReductionId, |
15552 | UnresolvedReductions, RD)) |
15553 | return nullptr; |
15554 | |
15555 | return OMPReductionClause::Create( |
15556 | Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, |
15557 | RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, |
15558 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, |
15559 | RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, |
15560 | buildPreInits(Context, RD.ExprCaptures), |
15561 | buildPostUpdate(*this, RD.ExprPostUpdates)); |
15562 | } |
15563 | |
15564 | OMPClause *Sema::ActOnOpenMPTaskReductionClause( |
15565 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, |
15566 | SourceLocation ColonLoc, SourceLocation EndLoc, |
15567 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, |
15568 | ArrayRef<Expr *> UnresolvedReductions) { |
15569 | ReductionData RD(VarList.size()); |
15570 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_task_reduction, VarList, |
15571 | StartLoc, LParenLoc, ColonLoc, EndLoc, |
15572 | ReductionIdScopeSpec, ReductionId, |
15573 | UnresolvedReductions, RD)) |
15574 | return nullptr; |
15575 | |
15576 | return OMPTaskReductionClause::Create( |
15577 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, |
15578 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, |
15579 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, |
15580 | buildPreInits(Context, RD.ExprCaptures), |
15581 | buildPostUpdate(*this, RD.ExprPostUpdates)); |
15582 | } |
15583 | |
15584 | OMPClause *Sema::ActOnOpenMPInReductionClause( |
15585 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, |
15586 | SourceLocation ColonLoc, SourceLocation EndLoc, |
15587 | CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, |
15588 | ArrayRef<Expr *> UnresolvedReductions) { |
15589 | ReductionData RD(VarList.size()); |
15590 | if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_in_reduction, VarList, |
15591 | StartLoc, LParenLoc, ColonLoc, EndLoc, |
15592 | ReductionIdScopeSpec, ReductionId, |
15593 | UnresolvedReductions, RD)) |
15594 | return nullptr; |
15595 | |
15596 | return OMPInReductionClause::Create( |
15597 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, |
15598 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, |
15599 | RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, |
15600 | buildPreInits(Context, RD.ExprCaptures), |
15601 | buildPostUpdate(*this, RD.ExprPostUpdates)); |
15602 | } |
15603 | |
15604 | bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, |
15605 | SourceLocation LinLoc) { |
15606 | if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || |
15607 | LinKind == OMPC_LINEAR_unknown) { |
15608 | Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; |
15609 | return true; |
15610 | } |
15611 | return false; |
15612 | } |
15613 | |
15614 | bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, |
15615 | OpenMPLinearClauseKind LinKind, QualType Type, |
15616 | bool IsDeclareSimd) { |
15617 | const auto *VD = dyn_cast_or_null<VarDecl>(D); |
15618 | // A variable must not have an incomplete type or a reference type. |
15619 | if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) |
15620 | return true; |
15621 | if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && |
15622 | !Type->isReferenceType()) { |
15623 | Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) |
15624 | << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); |
15625 | return true; |
15626 | } |
15627 | Type = Type.getNonReferenceType(); |
15628 | |
15629 | // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] |
15630 | // A variable that is privatized must not have a const-qualified type |
15631 | // unless it is of class type with a mutable member. This restriction does |
15632 | // not apply to the firstprivate clause, nor to the linear clause on |
15633 | // declarative directives (like declare simd). |
15634 | if (!IsDeclareSimd && |
15635 | rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) |
15636 | return true; |
15637 | |
15638 | // A list item must be of integral or pointer type. |
15639 | Type = Type.getUnqualifiedType().getCanonicalType(); |
15640 | const auto *Ty = Type.getTypePtrOrNull(); |
15641 | if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && |
15642 | !Ty->isIntegralType(Context) && !Ty->isPointerType())) { |
15643 | Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; |
15644 | if (D) { |
15645 | bool IsDecl = |
15646 | !VD || |
15647 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
15648 | Diag(D->getLocation(), |
15649 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
15650 | << D; |
15651 | } |
15652 | return true; |
15653 | } |
15654 | return false; |
15655 | } |
15656 | |
15657 | OMPClause *Sema::ActOnOpenMPLinearClause( |
15658 | ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, |
15659 | SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, |
15660 | SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { |
15661 | SmallVector<Expr *, 8> Vars; |
15662 | SmallVector<Expr *, 8> Privates; |
15663 | SmallVector<Expr *, 8> Inits; |
15664 | SmallVector<Decl *, 4> ExprCaptures; |
15665 | SmallVector<Expr *, 4> ExprPostUpdates; |
15666 | if (CheckOpenMPLinearModifier(LinKind, LinLoc)) |
15667 | LinKind = OMPC_LINEAR_val; |
15668 | for (Expr *RefExpr : VarList) { |
15669 | assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15669, __PRETTY_FUNCTION__)); |
15670 | SourceLocation ELoc; |
15671 | SourceRange ERange; |
15672 | Expr *SimpleRefExpr = RefExpr; |
15673 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
15674 | if (Res.second) { |
15675 | // It will be analyzed later. |
15676 | Vars.push_back(RefExpr); |
15677 | Privates.push_back(nullptr); |
15678 | Inits.push_back(nullptr); |
15679 | } |
15680 | ValueDecl *D = Res.first; |
15681 | if (!D) |
15682 | continue; |
15683 | |
15684 | QualType Type = D->getType(); |
15685 | auto *VD = dyn_cast<VarDecl>(D); |
15686 | |
15687 | // OpenMP [2.14.3.7, linear clause] |
15688 | // A list-item cannot appear in more than one linear clause. |
15689 | // A list-item that appears in a linear clause cannot appear in any |
15690 | // other data-sharing attribute clause. |
15691 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
15692 | if (DVar.RefExpr) { |
15693 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) |
15694 | << getOpenMPClauseName(OMPC_linear); |
15695 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
15696 | continue; |
15697 | } |
15698 | |
15699 | if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) |
15700 | continue; |
15701 | Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); |
15702 | |
15703 | // Build private copy of original var. |
15704 | VarDecl *Private = |
15705 | buildVarDecl(*this, ELoc, Type, D->getName(), |
15706 | D->hasAttrs() ? &D->getAttrs() : nullptr, |
15707 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); |
15708 | DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); |
15709 | // Build var to save initial value. |
15710 | VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); |
15711 | Expr *InitExpr; |
15712 | DeclRefExpr *Ref = nullptr; |
15713 | if (!VD && !CurContext->isDependentContext()) { |
15714 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); |
15715 | if (!isOpenMPCapturedDecl(D)) { |
15716 | ExprCaptures.push_back(Ref->getDecl()); |
15717 | if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { |
15718 | ExprResult RefRes = DefaultLvalueConversion(Ref); |
15719 | if (!RefRes.isUsable()) |
15720 | continue; |
15721 | ExprResult PostUpdateRes = |
15722 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, |
15723 | SimpleRefExpr, RefRes.get()); |
15724 | if (!PostUpdateRes.isUsable()) |
15725 | continue; |
15726 | ExprPostUpdates.push_back( |
15727 | IgnoredValueConversions(PostUpdateRes.get()).get()); |
15728 | } |
15729 | } |
15730 | } |
15731 | if (LinKind == OMPC_LINEAR_uval) |
15732 | InitExpr = VD ? VD->getInit() : SimpleRefExpr; |
15733 | else |
15734 | InitExpr = VD ? SimpleRefExpr : Ref; |
15735 | AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), |
15736 | /*DirectInit=*/false); |
15737 | DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); |
15738 | |
15739 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); |
15740 | Vars.push_back((VD || CurContext->isDependentContext()) |
15741 | ? RefExpr->IgnoreParens() |
15742 | : Ref); |
15743 | Privates.push_back(PrivateRef); |
15744 | Inits.push_back(InitRef); |
15745 | } |
15746 | |
15747 | if (Vars.empty()) |
15748 | return nullptr; |
15749 | |
15750 | Expr *StepExpr = Step; |
15751 | Expr *CalcStepExpr = nullptr; |
15752 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && |
15753 | !Step->isInstantiationDependent() && |
15754 | !Step->containsUnexpandedParameterPack()) { |
15755 | SourceLocation StepLoc = Step->getBeginLoc(); |
15756 | ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); |
15757 | if (Val.isInvalid()) |
15758 | return nullptr; |
15759 | StepExpr = Val.get(); |
15760 | |
15761 | // Build var to save the step value. |
15762 | VarDecl *SaveVar = |
15763 | buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); |
15764 | ExprResult SaveRef = |
15765 | buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); |
15766 | ExprResult CalcStep = |
15767 | BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); |
15768 | CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); |
15769 | |
15770 | // Warn about zero linear step (it would be probably better specified as |
15771 | // making corresponding variables 'const'). |
15772 | if (Optional<llvm::APSInt> Result = |
15773 | StepExpr->getIntegerConstantExpr(Context)) { |
15774 | if (!Result->isNegative() && !Result->isStrictlyPositive()) |
15775 | Diag(StepLoc, diag::warn_omp_linear_step_zero) |
15776 | << Vars[0] << (Vars.size() > 1); |
15777 | } else if (CalcStep.isUsable()) { |
15778 | // Calculate the step beforehand instead of doing this on each iteration. |
15779 | // (This is not used if the number of iterations may be kfold-ed). |
15780 | CalcStepExpr = CalcStep.get(); |
15781 | } |
15782 | } |
15783 | |
15784 | return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, |
15785 | ColonLoc, EndLoc, Vars, Privates, Inits, |
15786 | StepExpr, CalcStepExpr, |
15787 | buildPreInits(Context, ExprCaptures), |
15788 | buildPostUpdate(*this, ExprPostUpdates)); |
15789 | } |
15790 | |
15791 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, |
15792 | Expr *NumIterations, Sema &SemaRef, |
15793 | Scope *S, DSAStackTy *Stack) { |
15794 | // Walk the vars and build update/final expressions for the CodeGen. |
15795 | SmallVector<Expr *, 8> Updates; |
15796 | SmallVector<Expr *, 8> Finals; |
15797 | SmallVector<Expr *, 8> UsedExprs; |
15798 | Expr *Step = Clause.getStep(); |
15799 | Expr *CalcStep = Clause.getCalcStep(); |
15800 | // OpenMP [2.14.3.7, linear clause] |
15801 | // If linear-step is not specified it is assumed to be 1. |
15802 | if (!Step) |
15803 | Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); |
15804 | else if (CalcStep) |
15805 | Step = cast<BinaryOperator>(CalcStep)->getLHS(); |
15806 | bool HasErrors = false; |
15807 | auto CurInit = Clause.inits().begin(); |
15808 | auto CurPrivate = Clause.privates().begin(); |
15809 | OpenMPLinearClauseKind LinKind = Clause.getModifier(); |
15810 | for (Expr *RefExpr : Clause.varlists()) { |
15811 | SourceLocation ELoc; |
15812 | SourceRange ERange; |
15813 | Expr *SimpleRefExpr = RefExpr; |
15814 | auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); |
15815 | ValueDecl *D = Res.first; |
15816 | if (Res.second || !D) { |
15817 | Updates.push_back(nullptr); |
15818 | Finals.push_back(nullptr); |
15819 | HasErrors = true; |
15820 | continue; |
15821 | } |
15822 | auto &&Info = Stack->isLoopControlVariable(D); |
15823 | // OpenMP [2.15.11, distribute simd Construct] |
15824 | // A list item may not appear in a linear clause, unless it is the loop |
15825 | // iteration variable. |
15826 | if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && |
15827 | isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { |
15828 | SemaRef.Diag(ELoc, |
15829 | diag::err_omp_linear_distribute_var_non_loop_iteration); |
15830 | Updates.push_back(nullptr); |
15831 | Finals.push_back(nullptr); |
15832 | HasErrors = true; |
15833 | continue; |
15834 | } |
15835 | Expr *InitExpr = *CurInit; |
15836 | |
15837 | // Build privatized reference to the current linear var. |
15838 | auto *DE = cast<DeclRefExpr>(SimpleRefExpr); |
15839 | Expr *CapturedRef; |
15840 | if (LinKind == OMPC_LINEAR_uval) |
15841 | CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); |
15842 | else |
15843 | CapturedRef = |
15844 | buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), |
15845 | DE->getType().getUnqualifiedType(), DE->getExprLoc(), |
15846 | /*RefersToCapture=*/true); |
15847 | |
15848 | // Build update: Var = InitExpr + IV * Step |
15849 | ExprResult Update; |
15850 | if (!Info.first) |
15851 | Update = buildCounterUpdate( |
15852 | SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, |
15853 | /*Subtract=*/false, /*IsNonRectangularLB=*/false); |
15854 | else |
15855 | Update = *CurPrivate; |
15856 | Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), |
15857 | /*DiscardedValue*/ false); |
15858 | |
15859 | // Build final: Var = InitExpr + NumIterations * Step |
15860 | ExprResult Final; |
15861 | if (!Info.first) |
15862 | Final = |
15863 | buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, |
15864 | InitExpr, NumIterations, Step, /*Subtract=*/false, |
15865 | /*IsNonRectangularLB=*/false); |
15866 | else |
15867 | Final = *CurPrivate; |
15868 | Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), |
15869 | /*DiscardedValue*/ false); |
15870 | |
15871 | if (!Update.isUsable() || !Final.isUsable()) { |
15872 | Updates.push_back(nullptr); |
15873 | Finals.push_back(nullptr); |
15874 | UsedExprs.push_back(nullptr); |
15875 | HasErrors = true; |
15876 | } else { |
15877 | Updates.push_back(Update.get()); |
15878 | Finals.push_back(Final.get()); |
15879 | if (!Info.first) |
15880 | UsedExprs.push_back(SimpleRefExpr); |
15881 | } |
15882 | ++CurInit; |
15883 | ++CurPrivate; |
15884 | } |
15885 | if (Expr *S = Clause.getStep()) |
15886 | UsedExprs.push_back(S); |
15887 | // Fill the remaining part with the nullptr. |
15888 | UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); |
15889 | Clause.setUpdates(Updates); |
15890 | Clause.setFinals(Finals); |
15891 | Clause.setUsedExprs(UsedExprs); |
15892 | return HasErrors; |
15893 | } |
15894 | |
15895 | OMPClause *Sema::ActOnOpenMPAlignedClause( |
15896 | ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, |
15897 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { |
15898 | SmallVector<Expr *, 8> Vars; |
15899 | for (Expr *RefExpr : VarList) { |
15900 | assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15900, __PRETTY_FUNCTION__)); |
15901 | SourceLocation ELoc; |
15902 | SourceRange ERange; |
15903 | Expr *SimpleRefExpr = RefExpr; |
15904 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
15905 | if (Res.second) { |
15906 | // It will be analyzed later. |
15907 | Vars.push_back(RefExpr); |
15908 | } |
15909 | ValueDecl *D = Res.first; |
15910 | if (!D) |
15911 | continue; |
15912 | |
15913 | QualType QType = D->getType(); |
15914 | auto *VD = dyn_cast<VarDecl>(D); |
15915 | |
15916 | // OpenMP [2.8.1, simd construct, Restrictions] |
15917 | // The type of list items appearing in the aligned clause must be |
15918 | // array, pointer, reference to array, or reference to pointer. |
15919 | QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); |
15920 | const Type *Ty = QType.getTypePtrOrNull(); |
15921 | if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { |
15922 | Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) |
15923 | << QType << getLangOpts().CPlusPlus << ERange; |
15924 | bool IsDecl = |
15925 | !VD || |
15926 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
15927 | Diag(D->getLocation(), |
15928 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
15929 | << D; |
15930 | continue; |
15931 | } |
15932 | |
15933 | // OpenMP [2.8.1, simd construct, Restrictions] |
15934 | // A list-item cannot appear in more than one aligned clause. |
15935 | if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUniqueAligned(D, SimpleRefExpr)) { |
15936 | Diag(ELoc, diag::err_omp_used_in_clause_twice) |
15937 | << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; |
15938 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) |
15939 | << getOpenMPClauseName(OMPC_aligned); |
15940 | continue; |
15941 | } |
15942 | |
15943 | DeclRefExpr *Ref = nullptr; |
15944 | if (!VD && isOpenMPCapturedDecl(D)) |
15945 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); |
15946 | Vars.push_back(DefaultFunctionArrayConversion( |
15947 | (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) |
15948 | .get()); |
15949 | } |
15950 | |
15951 | // OpenMP [2.8.1, simd construct, Description] |
15952 | // The parameter of the aligned clause, alignment, must be a constant |
15953 | // positive integer expression. |
15954 | // If no optional parameter is specified, implementation-defined default |
15955 | // alignments for SIMD instructions on the target platforms are assumed. |
15956 | if (Alignment != nullptr) { |
15957 | ExprResult AlignResult = |
15958 | VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); |
15959 | if (AlignResult.isInvalid()) |
15960 | return nullptr; |
15961 | Alignment = AlignResult.get(); |
15962 | } |
15963 | if (Vars.empty()) |
15964 | return nullptr; |
15965 | |
15966 | return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, |
15967 | EndLoc, Vars, Alignment); |
15968 | } |
15969 | |
15970 | OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, |
15971 | SourceLocation StartLoc, |
15972 | SourceLocation LParenLoc, |
15973 | SourceLocation EndLoc) { |
15974 | SmallVector<Expr *, 8> Vars; |
15975 | SmallVector<Expr *, 8> SrcExprs; |
15976 | SmallVector<Expr *, 8> DstExprs; |
15977 | SmallVector<Expr *, 8> AssignmentOps; |
15978 | for (Expr *RefExpr : VarList) { |
15979 | assert(RefExpr && "NULL expr in OpenMP copyin clause.")((RefExpr && "NULL expr in OpenMP copyin clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 15979, __PRETTY_FUNCTION__)); |
15980 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { |
15981 | // It will be analyzed later. |
15982 | Vars.push_back(RefExpr); |
15983 | SrcExprs.push_back(nullptr); |
15984 | DstExprs.push_back(nullptr); |
15985 | AssignmentOps.push_back(nullptr); |
15986 | continue; |
15987 | } |
15988 | |
15989 | SourceLocation ELoc = RefExpr->getExprLoc(); |
15990 | // OpenMP [2.1, C/C++] |
15991 | // A list item is a variable name. |
15992 | // OpenMP [2.14.4.1, Restrictions, p.1] |
15993 | // A list item that appears in a copyin clause must be threadprivate. |
15994 | auto *DE = dyn_cast<DeclRefExpr>(RefExpr); |
15995 | if (!DE || !isa<VarDecl>(DE->getDecl())) { |
15996 | Diag(ELoc, diag::err_omp_expected_var_name_member_expr) |
15997 | << 0 << RefExpr->getSourceRange(); |
15998 | continue; |
15999 | } |
16000 | |
16001 | Decl *D = DE->getDecl(); |
16002 | auto *VD = cast<VarDecl>(D); |
16003 | |
16004 | QualType Type = VD->getType(); |
16005 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { |
16006 | // It will be analyzed later. |
16007 | Vars.push_back(DE); |
16008 | SrcExprs.push_back(nullptr); |
16009 | DstExprs.push_back(nullptr); |
16010 | AssignmentOps.push_back(nullptr); |
16011 | continue; |
16012 | } |
16013 | |
16014 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] |
16015 | // A list item that appears in a copyin clause must be threadprivate. |
16016 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { |
16017 | Diag(ELoc, diag::err_omp_required_access) |
16018 | << getOpenMPClauseName(OMPC_copyin) |
16019 | << getOpenMPDirectiveName(OMPD_threadprivate); |
16020 | continue; |
16021 | } |
16022 | |
16023 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] |
16024 | // A variable of class type (or array thereof) that appears in a |
16025 | // copyin clause requires an accessible, unambiguous copy assignment |
16026 | // operator for the class type. |
16027 | QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); |
16028 | VarDecl *SrcVD = |
16029 | buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), |
16030 | ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); |
16031 | DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( |
16032 | *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); |
16033 | VarDecl *DstVD = |
16034 | buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", |
16035 | VD->hasAttrs() ? &VD->getAttrs() : nullptr); |
16036 | DeclRefExpr *PseudoDstExpr = |
16037 | buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); |
16038 | // For arrays generate assignment operation for single element and replace |
16039 | // it by the original array element in CodeGen. |
16040 | ExprResult AssignmentOp = |
16041 | BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, |
16042 | PseudoSrcExpr); |
16043 | if (AssignmentOp.isInvalid()) |
16044 | continue; |
16045 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), |
16046 | /*DiscardedValue*/ false); |
16047 | if (AssignmentOp.isInvalid()) |
16048 | continue; |
16049 | |
16050 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_copyin); |
16051 | Vars.push_back(DE); |
16052 | SrcExprs.push_back(PseudoSrcExpr); |
16053 | DstExprs.push_back(PseudoDstExpr); |
16054 | AssignmentOps.push_back(AssignmentOp.get()); |
16055 | } |
16056 | |
16057 | if (Vars.empty()) |
16058 | return nullptr; |
16059 | |
16060 | return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, |
16061 | SrcExprs, DstExprs, AssignmentOps); |
16062 | } |
16063 | |
16064 | OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, |
16065 | SourceLocation StartLoc, |
16066 | SourceLocation LParenLoc, |
16067 | SourceLocation EndLoc) { |
16068 | SmallVector<Expr *, 8> Vars; |
16069 | SmallVector<Expr *, 8> SrcExprs; |
16070 | SmallVector<Expr *, 8> DstExprs; |
16071 | SmallVector<Expr *, 8> AssignmentOps; |
16072 | for (Expr *RefExpr : VarList) { |
16073 | assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16073, __PRETTY_FUNCTION__)); |
16074 | SourceLocation ELoc; |
16075 | SourceRange ERange; |
16076 | Expr *SimpleRefExpr = RefExpr; |
16077 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
16078 | if (Res.second) { |
16079 | // It will be analyzed later. |
16080 | Vars.push_back(RefExpr); |
16081 | SrcExprs.push_back(nullptr); |
16082 | DstExprs.push_back(nullptr); |
16083 | AssignmentOps.push_back(nullptr); |
16084 | } |
16085 | ValueDecl *D = Res.first; |
16086 | if (!D) |
16087 | continue; |
16088 | |
16089 | QualType Type = D->getType(); |
16090 | auto *VD = dyn_cast<VarDecl>(D); |
16091 | |
16092 | // OpenMP [2.14.4.2, Restrictions, p.2] |
16093 | // A list item that appears in a copyprivate clause may not appear in a |
16094 | // private or firstprivate clause on the single construct. |
16095 | if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { |
16096 | DSAStackTy::DSAVarData DVar = |
16097 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
16098 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && |
16099 | DVar.RefExpr) { |
16100 | Diag(ELoc, diag::err_omp_wrong_dsa) |
16101 | << getOpenMPClauseName(DVar.CKind) |
16102 | << getOpenMPClauseName(OMPC_copyprivate); |
16103 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
16104 | continue; |
16105 | } |
16106 | |
16107 | // OpenMP [2.11.4.2, Restrictions, p.1] |
16108 | // All list items that appear in a copyprivate clause must be either |
16109 | // threadprivate or private in the enclosing context. |
16110 | if (DVar.CKind == OMPC_unknown) { |
16111 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(D, false); |
16112 | if (DVar.CKind == OMPC_shared) { |
16113 | Diag(ELoc, diag::err_omp_required_access) |
16114 | << getOpenMPClauseName(OMPC_copyprivate) |
16115 | << "threadprivate or private in the enclosing context"; |
16116 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
16117 | continue; |
16118 | } |
16119 | } |
16120 | } |
16121 | |
16122 | // Variably modified types are not supported. |
16123 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { |
16124 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) |
16125 | << getOpenMPClauseName(OMPC_copyprivate) << Type |
16126 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); |
16127 | bool IsDecl = |
16128 | !VD || |
16129 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; |
16130 | Diag(D->getLocation(), |
16131 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) |
16132 | << D; |
16133 | continue; |
16134 | } |
16135 | |
16136 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] |
16137 | // A variable of class type (or array thereof) that appears in a |
16138 | // copyin clause requires an accessible, unambiguous copy assignment |
16139 | // operator for the class type. |
16140 | Type = Context.getBaseElementType(Type.getNonReferenceType()) |
16141 | .getUnqualifiedType(); |
16142 | VarDecl *SrcVD = |
16143 | buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", |
16144 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
16145 | DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); |
16146 | VarDecl *DstVD = |
16147 | buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", |
16148 | D->hasAttrs() ? &D->getAttrs() : nullptr); |
16149 | DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); |
16150 | ExprResult AssignmentOp = BuildBinOp( |
16151 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); |
16152 | if (AssignmentOp.isInvalid()) |
16153 | continue; |
16154 | AssignmentOp = |
16155 | ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); |
16156 | if (AssignmentOp.isInvalid()) |
16157 | continue; |
16158 | |
16159 | // No need to mark vars as copyprivate, they are already threadprivate or |
16160 | // implicitly private. |
16161 | assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0 ) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16161, __PRETTY_FUNCTION__)); |
16162 | Vars.push_back( |
16163 | VD ? RefExpr->IgnoreParens() |
16164 | : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); |
16165 | SrcExprs.push_back(PseudoSrcExpr); |
16166 | DstExprs.push_back(PseudoDstExpr); |
16167 | AssignmentOps.push_back(AssignmentOp.get()); |
16168 | } |
16169 | |
16170 | if (Vars.empty()) |
16171 | return nullptr; |
16172 | |
16173 | return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
16174 | Vars, SrcExprs, DstExprs, AssignmentOps); |
16175 | } |
16176 | |
16177 | OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, |
16178 | SourceLocation StartLoc, |
16179 | SourceLocation LParenLoc, |
16180 | SourceLocation EndLoc) { |
16181 | if (VarList.empty()) |
16182 | return nullptr; |
16183 | |
16184 | return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); |
16185 | } |
16186 | |
16187 | /// Tries to find omp_depend_t. type. |
16188 | static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, |
16189 | bool Diagnose = true) { |
16190 | QualType OMPDependT = Stack->getOMPDependT(); |
16191 | if (!OMPDependT.isNull()) |
16192 | return true; |
16193 | IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); |
16194 | ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); |
16195 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { |
16196 | if (Diagnose) |
16197 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; |
16198 | return false; |
16199 | } |
16200 | Stack->setOMPDependT(PT.get()); |
16201 | return true; |
16202 | } |
16203 | |
16204 | OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, |
16205 | SourceLocation LParenLoc, |
16206 | SourceLocation EndLoc) { |
16207 | if (!Depobj) |
16208 | return nullptr; |
16209 | |
16210 | bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )); |
16211 | |
16212 | // OpenMP 5.0, 2.17.10.1 depobj Construct |
16213 | // depobj is an lvalue expression of type omp_depend_t. |
16214 | if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && |
16215 | !Depobj->isInstantiationDependent() && |
16216 | !Depobj->containsUnexpandedParameterPack() && |
16217 | (OMPDependTFound && |
16218 | !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT(), Depobj->getType(), |
16219 | /*CompareUnqualified=*/true))) { |
16220 | Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) |
16221 | << 0 << Depobj->getType() << Depobj->getSourceRange(); |
16222 | } |
16223 | |
16224 | if (!Depobj->isLValue()) { |
16225 | Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) |
16226 | << 1 << Depobj->getSourceRange(); |
16227 | } |
16228 | |
16229 | return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); |
16230 | } |
16231 | |
16232 | OMPClause * |
16233 | Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, |
16234 | SourceLocation DepLoc, SourceLocation ColonLoc, |
16235 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
16236 | SourceLocation LParenLoc, SourceLocation EndLoc) { |
16237 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_ordered && |
16238 | DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { |
16239 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) |
16240 | << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); |
16241 | return nullptr; |
16242 | } |
16243 | if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_ordered || |
16244 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) && |
16245 | (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || |
16246 | DepKind == OMPC_DEPEND_sink || |
16247 | ((LangOpts.OpenMP < 50 || |
16248 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) && |
16249 | DepKind == OMPC_DEPEND_depobj))) { |
16250 | SmallVector<unsigned, 3> Except; |
16251 | Except.push_back(OMPC_DEPEND_source); |
16252 | Except.push_back(OMPC_DEPEND_sink); |
16253 | if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_depobj) |
16254 | Except.push_back(OMPC_DEPEND_depobj); |
16255 | std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) |
16256 | ? "depend modifier(iterator) or " |
16257 | : ""; |
16258 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) |
16259 | << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, |
16260 | /*Last=*/OMPC_DEPEND_unknown, |
16261 | Except) |
16262 | << getOpenMPClauseName(OMPC_depend); |
16263 | return nullptr; |
16264 | } |
16265 | if (DepModifier && |
16266 | (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { |
16267 | Diag(DepModifier->getExprLoc(), |
16268 | diag::err_omp_depend_sink_source_with_modifier); |
16269 | return nullptr; |
16270 | } |
16271 | if (DepModifier && |
16272 | !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) |
16273 | Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); |
16274 | |
16275 | SmallVector<Expr *, 8> Vars; |
16276 | DSAStackTy::OperatorOffsetTy OpsOffs; |
16277 | llvm::APSInt DepCounter(/*BitWidth=*/32); |
16278 | llvm::APSInt TotalDepCount(/*BitWidth=*/32); |
16279 | if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { |
16280 | if (const Expr *OrderedCountExpr = |
16281 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first) { |
16282 | TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); |
16283 | TotalDepCount.setIsUnsigned(/*Val=*/true); |
16284 | } |
16285 | } |
16286 | for (Expr *RefExpr : VarList) { |
16287 | assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16287, __PRETTY_FUNCTION__)); |
16288 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { |
16289 | // It will be analyzed later. |
16290 | Vars.push_back(RefExpr); |
16291 | continue; |
16292 | } |
16293 | |
16294 | SourceLocation ELoc = RefExpr->getExprLoc(); |
16295 | Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); |
16296 | if (DepKind == OMPC_DEPEND_sink) { |
16297 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && |
16298 | DepCounter >= TotalDepCount) { |
16299 | Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); |
16300 | continue; |
16301 | } |
16302 | ++DepCounter; |
16303 | // OpenMP [2.13.9, Summary] |
16304 | // depend(dependence-type : vec), where dependence-type is: |
16305 | // 'sink' and where vec is the iteration vector, which has the form: |
16306 | // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] |
16307 | // where n is the value specified by the ordered clause in the loop |
16308 | // directive, xi denotes the loop iteration variable of the i-th nested |
16309 | // loop associated with the loop directive, and di is a constant |
16310 | // non-negative integer. |
16311 | if (CurContext->isDependentContext()) { |
16312 | // It will be analyzed later. |
16313 | Vars.push_back(RefExpr); |
16314 | continue; |
16315 | } |
16316 | SimpleExpr = SimpleExpr->IgnoreImplicit(); |
16317 | OverloadedOperatorKind OOK = OO_None; |
16318 | SourceLocation OOLoc; |
16319 | Expr *LHS = SimpleExpr; |
16320 | Expr *RHS = nullptr; |
16321 | if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { |
16322 | OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); |
16323 | OOLoc = BO->getOperatorLoc(); |
16324 | LHS = BO->getLHS()->IgnoreParenImpCasts(); |
16325 | RHS = BO->getRHS()->IgnoreParenImpCasts(); |
16326 | } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { |
16327 | OOK = OCE->getOperator(); |
16328 | OOLoc = OCE->getOperatorLoc(); |
16329 | LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); |
16330 | RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); |
16331 | } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { |
16332 | OOK = MCE->getMethodDecl() |
16333 | ->getNameInfo() |
16334 | .getName() |
16335 | .getCXXOverloadedOperator(); |
16336 | OOLoc = MCE->getCallee()->getExprLoc(); |
16337 | LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); |
16338 | RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); |
16339 | } |
16340 | SourceLocation ELoc; |
16341 | SourceRange ERange; |
16342 | auto Res = getPrivateItem(*this, LHS, ELoc, ERange); |
16343 | if (Res.second) { |
16344 | // It will be analyzed later. |
16345 | Vars.push_back(RefExpr); |
16346 | } |
16347 | ValueDecl *D = Res.first; |
16348 | if (!D) |
16349 | continue; |
16350 | |
16351 | if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { |
16352 | Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); |
16353 | continue; |
16354 | } |
16355 | if (RHS) { |
16356 | ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( |
16357 | RHS, OMPC_depend, /*StrictlyPositive=*/false); |
16358 | if (RHSRes.isInvalid()) |
16359 | continue; |
16360 | } |
16361 | if (!CurContext->isDependentContext() && |
16362 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && |
16363 | DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentLoopControlVariable(D).first) { |
16364 | const ValueDecl *VD = |
16365 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(DepCounter.getZExtValue()); |
16366 | if (VD) |
16367 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) |
16368 | << 1 << VD; |
16369 | else |
16370 | Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; |
16371 | continue; |
16372 | } |
16373 | OpsOffs.emplace_back(RHS, OOK); |
16374 | } else { |
16375 | bool OMPDependTFound = LangOpts.OpenMP >= 50; |
16376 | if (OMPDependTFound) |
16377 | OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), |
16378 | DepKind == OMPC_DEPEND_depobj); |
16379 | if (DepKind == OMPC_DEPEND_depobj) { |
16380 | // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ |
16381 | // List items used in depend clauses with the depobj dependence type |
16382 | // must be expressions of the omp_depend_t type. |
16383 | if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && |
16384 | !RefExpr->isInstantiationDependent() && |
16385 | !RefExpr->containsUnexpandedParameterPack() && |
16386 | (OMPDependTFound && |
16387 | !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT(), |
16388 | RefExpr->getType()))) { |
16389 | Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) |
16390 | << 0 << RefExpr->getType() << RefExpr->getSourceRange(); |
16391 | continue; |
16392 | } |
16393 | if (!RefExpr->isLValue()) { |
16394 | Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) |
16395 | << 1 << RefExpr->getType() << RefExpr->getSourceRange(); |
16396 | continue; |
16397 | } |
16398 | } else { |
16399 | // OpenMP 5.0 [2.17.11, Restrictions] |
16400 | // List items used in depend clauses cannot be zero-length array |
16401 | // sections. |
16402 | QualType ExprTy = RefExpr->getType().getNonReferenceType(); |
16403 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); |
16404 | if (OASE) { |
16405 | QualType BaseType = |
16406 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); |
16407 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) |
16408 | ExprTy = ATy->getElementType(); |
16409 | else |
16410 | ExprTy = BaseType->getPointeeType(); |
16411 | ExprTy = ExprTy.getNonReferenceType(); |
16412 | const Expr *Length = OASE->getLength(); |
16413 | Expr::EvalResult Result; |
16414 | if (Length && !Length->isValueDependent() && |
16415 | Length->EvaluateAsInt(Result, Context) && |
16416 | Result.Val.getInt().isNullValue()) { |
16417 | Diag(ELoc, |
16418 | diag::err_omp_depend_zero_length_array_section_not_allowed) |
16419 | << SimpleExpr->getSourceRange(); |
16420 | continue; |
16421 | } |
16422 | } |
16423 | |
16424 | // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ |
16425 | // List items used in depend clauses with the in, out, inout or |
16426 | // mutexinoutset dependence types cannot be expressions of the |
16427 | // omp_depend_t type. |
16428 | if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && |
16429 | !RefExpr->isInstantiationDependent() && |
16430 | !RefExpr->containsUnexpandedParameterPack() && |
16431 | (OMPDependTFound && |
16432 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { |
16433 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) |
16434 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 |
16435 | << RefExpr->getSourceRange(); |
16436 | continue; |
16437 | } |
16438 | |
16439 | auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); |
16440 | if (!RefExpr->IgnoreParenImpCasts()->isLValue() || |
16441 | (ASE && !ASE->getBase()->isTypeDependent() && |
16442 | !ASE->getBase() |
16443 | ->getType() |
16444 | .getNonReferenceType() |
16445 | ->isPointerType() && |
16446 | !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { |
16447 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) |
16448 | << (LangOpts.OpenMP >= 50 ? 1 : 0) |
16449 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); |
16450 | continue; |
16451 | } |
16452 | |
16453 | ExprResult Res; |
16454 | { |
16455 | Sema::TentativeAnalysisScope Trap(*this); |
16456 | Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, |
16457 | RefExpr->IgnoreParenImpCasts()); |
16458 | } |
16459 | if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && |
16460 | !isa<OMPArrayShapingExpr>(SimpleExpr)) { |
16461 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) |
16462 | << (LangOpts.OpenMP >= 50 ? 1 : 0) |
16463 | << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); |
16464 | continue; |
16465 | } |
16466 | } |
16467 | } |
16468 | Vars.push_back(RefExpr->IgnoreParenImpCasts()); |
16469 | } |
16470 | |
16471 | if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && |
16472 | TotalDepCount > VarList.size() && |
16473 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentOrderedRegionParam().first && |
16474 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(VarList.size() + 1)) { |
16475 | Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) |
16476 | << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentLoopControlVariable(VarList.size() + 1); |
16477 | } |
16478 | if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && |
16479 | Vars.empty()) |
16480 | return nullptr; |
16481 | |
16482 | auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
16483 | DepModifier, DepKind, DepLoc, ColonLoc, |
16484 | Vars, TotalDepCount.getZExtValue()); |
16485 | if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && |
16486 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isParentOrderedRegion()) |
16487 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDoacrossDependClause(C, OpsOffs); |
16488 | return C; |
16489 | } |
16490 | |
16491 | OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, |
16492 | Expr *Device, SourceLocation StartLoc, |
16493 | SourceLocation LParenLoc, |
16494 | SourceLocation ModifierLoc, |
16495 | SourceLocation EndLoc) { |
16496 | assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && "Unexpected device modifier in OpenMP < 50.") ? static_cast <void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16497, __PRETTY_FUNCTION__)) |
16497 | "Unexpected device modifier in OpenMP < 50.")(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && "Unexpected device modifier in OpenMP < 50.") ? static_cast <void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16497, __PRETTY_FUNCTION__)); |
16498 | |
16499 | bool ErrorFound = false; |
16500 | if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { |
16501 | std::string Values = |
16502 | getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); |
16503 | Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) |
16504 | << Values << getOpenMPClauseName(OMPC_device); |
16505 | ErrorFound = true; |
16506 | } |
16507 | |
16508 | Expr *ValExpr = Device; |
16509 | Stmt *HelperValStmt = nullptr; |
16510 | |
16511 | // OpenMP [2.9.1, Restrictions] |
16512 | // The device expression must evaluate to a non-negative integer value. |
16513 | ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, |
16514 | /*StrictlyPositive=*/false) || |
16515 | ErrorFound; |
16516 | if (ErrorFound) |
16517 | return nullptr; |
16518 | |
16519 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
16520 | OpenMPDirectiveKind CaptureRegion = |
16521 | getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); |
16522 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { |
16523 | ValExpr = MakeFullExpr(ValExpr).get(); |
16524 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
16525 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
16526 | HelperValStmt = buildPreInits(Context, Captures); |
16527 | } |
16528 | |
16529 | return new (Context) |
16530 | OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, |
16531 | LParenLoc, ModifierLoc, EndLoc); |
16532 | } |
16533 | |
16534 | static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, |
16535 | DSAStackTy *Stack, QualType QTy, |
16536 | bool FullCheck = true) { |
16537 | NamedDecl *ND; |
16538 | if (QTy->isIncompleteType(&ND)) { |
16539 | SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; |
16540 | return false; |
16541 | } |
16542 | if (FullCheck && !SemaRef.CurContext->isDependentContext() && |
16543 | !QTy.isTriviallyCopyableType(SemaRef.Context)) |
16544 | SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; |
16545 | return true; |
16546 | } |
16547 | |
16548 | /// Return true if it can be proven that the provided array expression |
16549 | /// (array section or array subscript) does NOT specify the whole size of the |
16550 | /// array whose base type is \a BaseQTy. |
16551 | static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, |
16552 | const Expr *E, |
16553 | QualType BaseQTy) { |
16554 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); |
16555 | |
16556 | // If this is an array subscript, it refers to the whole size if the size of |
16557 | // the dimension is constant and equals 1. Also, an array section assumes the |
16558 | // format of an array subscript if no colon is used. |
16559 | if (isa<ArraySubscriptExpr>(E) || |
16560 | (OASE && OASE->getColonLocFirst().isInvalid())) { |
16561 | if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) |
16562 | return ATy->getSize().getSExtValue() != 1; |
16563 | // Size can't be evaluated statically. |
16564 | return false; |
16565 | } |
16566 | |
16567 | assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript." ) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16567, __PRETTY_FUNCTION__)); |
16568 | const Expr *LowerBound = OASE->getLowerBound(); |
16569 | const Expr *Length = OASE->getLength(); |
16570 | |
16571 | // If there is a lower bound that does not evaluates to zero, we are not |
16572 | // covering the whole dimension. |
16573 | if (LowerBound) { |
16574 | Expr::EvalResult Result; |
16575 | if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) |
16576 | return false; // Can't get the integer value as a constant. |
16577 | |
16578 | llvm::APSInt ConstLowerBound = Result.Val.getInt(); |
16579 | if (ConstLowerBound.getSExtValue()) |
16580 | return true; |
16581 | } |
16582 | |
16583 | // If we don't have a length we covering the whole dimension. |
16584 | if (!Length) |
16585 | return false; |
16586 | |
16587 | // If the base is a pointer, we don't have a way to get the size of the |
16588 | // pointee. |
16589 | if (BaseQTy->isPointerType()) |
16590 | return false; |
16591 | |
16592 | // We can only check if the length is the same as the size of the dimension |
16593 | // if we have a constant array. |
16594 | const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); |
16595 | if (!CATy) |
16596 | return false; |
16597 | |
16598 | Expr::EvalResult Result; |
16599 | if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) |
16600 | return false; // Can't get the integer value as a constant. |
16601 | |
16602 | llvm::APSInt ConstLength = Result.Val.getInt(); |
16603 | return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); |
16604 | } |
16605 | |
16606 | // Return true if it can be proven that the provided array expression (array |
16607 | // section or array subscript) does NOT specify a single element of the array |
16608 | // whose base type is \a BaseQTy. |
16609 | static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, |
16610 | const Expr *E, |
16611 | QualType BaseQTy) { |
16612 | const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); |
16613 | |
16614 | // An array subscript always refer to a single element. Also, an array section |
16615 | // assumes the format of an array subscript if no colon is used. |
16616 | if (isa<ArraySubscriptExpr>(E) || |
16617 | (OASE && OASE->getColonLocFirst().isInvalid())) |
16618 | return false; |
16619 | |
16620 | assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript." ) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16620, __PRETTY_FUNCTION__)); |
16621 | const Expr *Length = OASE->getLength(); |
16622 | |
16623 | // If we don't have a length we have to check if the array has unitary size |
16624 | // for this dimension. Also, we should always expect a length if the base type |
16625 | // is pointer. |
16626 | if (!Length) { |
16627 | if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) |
16628 | return ATy->getSize().getSExtValue() != 1; |
16629 | // We cannot assume anything. |
16630 | return false; |
16631 | } |
16632 | |
16633 | // Check if the length evaluates to 1. |
16634 | Expr::EvalResult Result; |
16635 | if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) |
16636 | return false; // Can't get the integer value as a constant. |
16637 | |
16638 | llvm::APSInt ConstLength = Result.Val.getInt(); |
16639 | return ConstLength.getSExtValue() != 1; |
16640 | } |
16641 | |
16642 | // The base of elements of list in a map clause have to be either: |
16643 | // - a reference to variable or field. |
16644 | // - a member expression. |
16645 | // - an array expression. |
16646 | // |
16647 | // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the |
16648 | // reference to 'r'. |
16649 | // |
16650 | // If we have: |
16651 | // |
16652 | // struct SS { |
16653 | // Bla S; |
16654 | // foo() { |
16655 | // #pragma omp target map (S.Arr[:12]); |
16656 | // } |
16657 | // } |
16658 | // |
16659 | // We want to retrieve the member expression 'this->S'; |
16660 | |
16661 | // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] |
16662 | // If a list item is an array section, it must specify contiguous storage. |
16663 | // |
16664 | // For this restriction it is sufficient that we make sure only references |
16665 | // to variables or fields and array expressions, and that no array sections |
16666 | // exist except in the rightmost expression (unless they cover the whole |
16667 | // dimension of the array). E.g. these would be invalid: |
16668 | // |
16669 | // r.ArrS[3:5].Arr[6:7] |
16670 | // |
16671 | // r.ArrS[3:5].x |
16672 | // |
16673 | // but these would be valid: |
16674 | // r.ArrS[3].Arr[6:7] |
16675 | // |
16676 | // r.ArrS[3].x |
16677 | namespace { |
16678 | class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { |
16679 | Sema &SemaRef; |
16680 | OpenMPClauseKind CKind = OMPC_unknown; |
16681 | OMPClauseMappableExprCommon::MappableExprComponentList &Components; |
16682 | bool NoDiagnose = false; |
16683 | const Expr *RelevantExpr = nullptr; |
16684 | bool AllowUnitySizeArraySection = true; |
16685 | bool AllowWholeSizeArraySection = true; |
16686 | SourceLocation ELoc; |
16687 | SourceRange ERange; |
16688 | |
16689 | void emitErrorMsg() { |
16690 | // If nothing else worked, this is not a valid map clause expression. |
16691 | if (SemaRef.getLangOpts().OpenMP < 50) { |
16692 | SemaRef.Diag(ELoc, |
16693 | diag::err_omp_expected_named_var_member_or_array_expression) |
16694 | << ERange; |
16695 | } else { |
16696 | SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) |
16697 | << getOpenMPClauseName(CKind) << ERange; |
16698 | } |
16699 | } |
16700 | |
16701 | public: |
16702 | bool VisitDeclRefExpr(DeclRefExpr *DRE) { |
16703 | if (!isa<VarDecl>(DRE->getDecl())) { |
16704 | emitErrorMsg(); |
16705 | return false; |
16706 | } |
16707 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16707, __PRETTY_FUNCTION__)); |
16708 | RelevantExpr = DRE; |
16709 | // Record the component. |
16710 | Components.emplace_back(DRE, DRE->getDecl()); |
16711 | return true; |
16712 | } |
16713 | |
16714 | bool VisitMemberExpr(MemberExpr *ME) { |
16715 | Expr *E = ME; |
16716 | Expr *BaseE = ME->getBase()->IgnoreParenCasts(); |
16717 | |
16718 | if (isa<CXXThisExpr>(BaseE)) { |
16719 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16719, __PRETTY_FUNCTION__)); |
16720 | // We found a base expression: this->Val. |
16721 | RelevantExpr = ME; |
16722 | } else { |
16723 | E = BaseE; |
16724 | } |
16725 | |
16726 | if (!isa<FieldDecl>(ME->getMemberDecl())) { |
16727 | if (!NoDiagnose) { |
16728 | SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) |
16729 | << ME->getSourceRange(); |
16730 | return false; |
16731 | } |
16732 | if (RelevantExpr) |
16733 | return false; |
16734 | return Visit(E); |
16735 | } |
16736 | |
16737 | auto *FD = cast<FieldDecl>(ME->getMemberDecl()); |
16738 | |
16739 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] |
16740 | // A bit-field cannot appear in a map clause. |
16741 | // |
16742 | if (FD->isBitField()) { |
16743 | if (!NoDiagnose) { |
16744 | SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) |
16745 | << ME->getSourceRange() << getOpenMPClauseName(CKind); |
16746 | return false; |
16747 | } |
16748 | if (RelevantExpr) |
16749 | return false; |
16750 | return Visit(E); |
16751 | } |
16752 | |
16753 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] |
16754 | // If the type of a list item is a reference to a type T then the type |
16755 | // will be considered to be T for all purposes of this clause. |
16756 | QualType CurType = BaseE->getType().getNonReferenceType(); |
16757 | |
16758 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] |
16759 | // A list item cannot be a variable that is a member of a structure with |
16760 | // a union type. |
16761 | // |
16762 | if (CurType->isUnionType()) { |
16763 | if (!NoDiagnose) { |
16764 | SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) |
16765 | << ME->getSourceRange(); |
16766 | return false; |
16767 | } |
16768 | return RelevantExpr || Visit(E); |
16769 | } |
16770 | |
16771 | // If we got a member expression, we should not expect any array section |
16772 | // before that: |
16773 | // |
16774 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] |
16775 | // If a list item is an element of a structure, only the rightmost symbol |
16776 | // of the variable reference can be an array section. |
16777 | // |
16778 | AllowUnitySizeArraySection = false; |
16779 | AllowWholeSizeArraySection = false; |
16780 | |
16781 | // Record the component. |
16782 | Components.emplace_back(ME, FD); |
16783 | return RelevantExpr || Visit(E); |
16784 | } |
16785 | |
16786 | bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { |
16787 | Expr *E = AE->getBase()->IgnoreParenImpCasts(); |
16788 | |
16789 | if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { |
16790 | if (!NoDiagnose) { |
16791 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) |
16792 | << 0 << AE->getSourceRange(); |
16793 | return false; |
16794 | } |
16795 | return RelevantExpr || Visit(E); |
16796 | } |
16797 | |
16798 | // If we got an array subscript that express the whole dimension we |
16799 | // can have any array expressions before. If it only expressing part of |
16800 | // the dimension, we can only have unitary-size array expressions. |
16801 | if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, |
16802 | E->getType())) |
16803 | AllowWholeSizeArraySection = false; |
16804 | |
16805 | if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { |
16806 | Expr::EvalResult Result; |
16807 | if (!AE->getIdx()->isValueDependent() && |
16808 | AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && |
16809 | !Result.Val.getInt().isNullValue()) { |
16810 | SemaRef.Diag(AE->getIdx()->getExprLoc(), |
16811 | diag::err_omp_invalid_map_this_expr); |
16812 | SemaRef.Diag(AE->getIdx()->getExprLoc(), |
16813 | diag::note_omp_invalid_subscript_on_this_ptr_map); |
16814 | } |
16815 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16815, __PRETTY_FUNCTION__)); |
16816 | RelevantExpr = TE; |
16817 | } |
16818 | |
16819 | // Record the component - we don't have any declaration associated. |
16820 | Components.emplace_back(AE, nullptr); |
16821 | |
16822 | return RelevantExpr || Visit(E); |
16823 | } |
16824 | |
16825 | bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { |
16826 | assert(!NoDiagnose && "Array sections cannot be implicitly mapped.")((!NoDiagnose && "Array sections cannot be implicitly mapped." ) ? static_cast<void> (0) : __assert_fail ("!NoDiagnose && \"Array sections cannot be implicitly mapped.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16826, __PRETTY_FUNCTION__)); |
16827 | Expr *E = OASE->getBase()->IgnoreParenImpCasts(); |
16828 | QualType CurType = |
16829 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); |
16830 | |
16831 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] |
16832 | // If the type of a list item is a reference to a type T then the type |
16833 | // will be considered to be T for all purposes of this clause. |
16834 | if (CurType->isReferenceType()) |
16835 | CurType = CurType->getPointeeType(); |
16836 | |
16837 | bool IsPointer = CurType->isAnyPointerType(); |
16838 | |
16839 | if (!IsPointer && !CurType->isArrayType()) { |
16840 | SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) |
16841 | << 0 << OASE->getSourceRange(); |
16842 | return false; |
16843 | } |
16844 | |
16845 | bool NotWhole = |
16846 | checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); |
16847 | bool NotUnity = |
16848 | checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); |
16849 | |
16850 | if (AllowWholeSizeArraySection) { |
16851 | // Any array section is currently allowed. Allowing a whole size array |
16852 | // section implies allowing a unity array section as well. |
16853 | // |
16854 | // If this array section refers to the whole dimension we can still |
16855 | // accept other array sections before this one, except if the base is a |
16856 | // pointer. Otherwise, only unitary sections are accepted. |
16857 | if (NotWhole || IsPointer) |
16858 | AllowWholeSizeArraySection = false; |
16859 | } else if (AllowUnitySizeArraySection && NotUnity) { |
16860 | // A unity or whole array section is not allowed and that is not |
16861 | // compatible with the properties of the current array section. |
16862 | SemaRef.Diag( |
16863 | ELoc, diag::err_array_section_does_not_specify_contiguous_storage) |
16864 | << OASE->getSourceRange(); |
16865 | return false; |
16866 | } |
16867 | |
16868 | if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { |
16869 | Expr::EvalResult ResultR; |
16870 | Expr::EvalResult ResultL; |
16871 | if (!OASE->getLength()->isValueDependent() && |
16872 | OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && |
16873 | !ResultR.Val.getInt().isOneValue()) { |
16874 | SemaRef.Diag(OASE->getLength()->getExprLoc(), |
16875 | diag::err_omp_invalid_map_this_expr); |
16876 | SemaRef.Diag(OASE->getLength()->getExprLoc(), |
16877 | diag::note_omp_invalid_length_on_this_ptr_mapping); |
16878 | } |
16879 | if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && |
16880 | OASE->getLowerBound()->EvaluateAsInt(ResultL, |
16881 | SemaRef.getASTContext()) && |
16882 | !ResultL.Val.getInt().isNullValue()) { |
16883 | SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), |
16884 | diag::err_omp_invalid_map_this_expr); |
16885 | SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), |
16886 | diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); |
16887 | } |
16888 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16888, __PRETTY_FUNCTION__)); |
16889 | RelevantExpr = TE; |
16890 | } |
16891 | |
16892 | // Record the component - we don't have any declaration associated. |
16893 | Components.emplace_back(OASE, nullptr); |
16894 | return RelevantExpr || Visit(E); |
16895 | } |
16896 | bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { |
16897 | Expr *Base = E->getBase(); |
16898 | |
16899 | // Record the component - we don't have any declaration associated. |
16900 | Components.emplace_back(E, nullptr); |
16901 | |
16902 | return Visit(Base->IgnoreParenImpCasts()); |
16903 | } |
16904 | |
16905 | bool VisitUnaryOperator(UnaryOperator *UO) { |
16906 | if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || |
16907 | UO->getOpcode() != UO_Deref) { |
16908 | emitErrorMsg(); |
16909 | return false; |
16910 | } |
16911 | if (!RelevantExpr) { |
16912 | // Record the component if haven't found base decl. |
16913 | Components.emplace_back(UO, nullptr); |
16914 | } |
16915 | return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); |
16916 | } |
16917 | bool VisitBinaryOperator(BinaryOperator *BO) { |
16918 | if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { |
16919 | emitErrorMsg(); |
16920 | return false; |
16921 | } |
16922 | |
16923 | // Pointer arithmetic is the only thing we expect to happen here so after we |
16924 | // make sure the binary operator is a pointer type, the we only thing need |
16925 | // to to is to visit the subtree that has the same type as root (so that we |
16926 | // know the other subtree is just an offset) |
16927 | Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); |
16928 | Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); |
16929 | Components.emplace_back(BO, nullptr); |
16930 | assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||(((LE->getType().getTypePtr() == BO->getType().getTypePtr () || RE->getType().getTypePtr() == BO->getType().getTypePtr ()) && "Either LHS or RHS have base decl inside") ? static_cast <void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16932, __PRETTY_FUNCTION__)) |
16931 | RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&(((LE->getType().getTypePtr() == BO->getType().getTypePtr () || RE->getType().getTypePtr() == BO->getType().getTypePtr ()) && "Either LHS or RHS have base decl inside") ? static_cast <void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16932, __PRETTY_FUNCTION__)) |
16932 | "Either LHS or RHS have base decl inside")(((LE->getType().getTypePtr() == BO->getType().getTypePtr () || RE->getType().getTypePtr() == BO->getType().getTypePtr ()) && "Either LHS or RHS have base decl inside") ? static_cast <void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16932, __PRETTY_FUNCTION__)); |
16933 | if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) |
16934 | return RelevantExpr || Visit(LE); |
16935 | return RelevantExpr || Visit(RE); |
16936 | } |
16937 | bool VisitCXXThisExpr(CXXThisExpr *CTE) { |
16938 | assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr" ) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16938, __PRETTY_FUNCTION__)); |
16939 | RelevantExpr = CTE; |
16940 | Components.emplace_back(CTE, nullptr); |
16941 | return true; |
16942 | } |
16943 | bool VisitStmt(Stmt *) { |
16944 | emitErrorMsg(); |
16945 | return false; |
16946 | } |
16947 | const Expr *getFoundBase() const { |
16948 | return RelevantExpr; |
16949 | } |
16950 | explicit MapBaseChecker( |
16951 | Sema &SemaRef, OpenMPClauseKind CKind, |
16952 | OMPClauseMappableExprCommon::MappableExprComponentList &Components, |
16953 | bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) |
16954 | : SemaRef(SemaRef), CKind(CKind), Components(Components), |
16955 | NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} |
16956 | }; |
16957 | } // namespace |
16958 | |
16959 | /// Return the expression of the base of the mappable expression or null if it |
16960 | /// cannot be determined and do all the necessary checks to see if the expression |
16961 | /// is valid as a standalone mappable expression. In the process, record all the |
16962 | /// components of the expression. |
16963 | static const Expr *checkMapClauseExpressionBase( |
16964 | Sema &SemaRef, Expr *E, |
16965 | OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, |
16966 | OpenMPClauseKind CKind, bool NoDiagnose) { |
16967 | SourceLocation ELoc = E->getExprLoc(); |
16968 | SourceRange ERange = E->getSourceRange(); |
16969 | MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, |
16970 | ERange); |
16971 | if (Checker.Visit(E->IgnoreParens())) |
16972 | return Checker.getFoundBase(); |
16973 | return nullptr; |
16974 | } |
16975 | |
16976 | // Return true if expression E associated with value VD has conflicts with other |
16977 | // map information. |
16978 | static bool checkMapConflicts( |
16979 | Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, |
16980 | bool CurrentRegionOnly, |
16981 | OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, |
16982 | OpenMPClauseKind CKind) { |
16983 | assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail ("VD && E", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16983, __PRETTY_FUNCTION__)); |
16984 | SourceLocation ELoc = E->getExprLoc(); |
16985 | SourceRange ERange = E->getSourceRange(); |
16986 | |
16987 | // In order to easily check the conflicts we need to match each component of |
16988 | // the expression under test with the components of the expressions that are |
16989 | // already in the stack. |
16990 | |
16991 | assert(!CurComponents.empty() && "Map clause expression with no components!")((!CurComponents.empty() && "Map clause expression with no components!" ) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16991, __PRETTY_FUNCTION__)); |
16992 | assert(CurComponents.back().getAssociatedDeclaration() == VD &&((CurComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16993, __PRETTY_FUNCTION__)) |
16993 | "Map clause expression with unexpected base!")((CurComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 16993, __PRETTY_FUNCTION__)); |
16994 | |
16995 | // Variables to help detecting enclosing problems in data environment nests. |
16996 | bool IsEnclosedByDataEnvironmentExpr = false; |
16997 | const Expr *EnclosingExpr = nullptr; |
16998 | |
16999 | bool FoundError = DSAS->checkMappableExprComponentListsForDecl( |
17000 | VD, CurrentRegionOnly, |
17001 | [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, |
17002 | ERange, CKind, &EnclosingExpr, |
17003 | CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef |
17004 | StackComponents, |
17005 | OpenMPClauseKind) { |
17006 | assert(!StackComponents.empty() &&((!StackComponents.empty() && "Map clause expression with no components!" ) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17007, __PRETTY_FUNCTION__)) |
17007 | "Map clause expression with no components!")((!StackComponents.empty() && "Map clause expression with no components!" ) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17007, __PRETTY_FUNCTION__)); |
17008 | assert(StackComponents.back().getAssociatedDeclaration() == VD &&((StackComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17009, __PRETTY_FUNCTION__)) |
17009 | "Map clause expression with unexpected base!")((StackComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!") ? static_cast <void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17009, __PRETTY_FUNCTION__)); |
17010 | (void)VD; |
17011 | |
17012 | // The whole expression in the stack. |
17013 | const Expr *RE = StackComponents.front().getAssociatedExpression(); |
17014 | |
17015 | // Expressions must start from the same base. Here we detect at which |
17016 | // point both expressions diverge from each other and see if we can |
17017 | // detect if the memory referred to both expressions is contiguous and |
17018 | // do not overlap. |
17019 | auto CI = CurComponents.rbegin(); |
17020 | auto CE = CurComponents.rend(); |
17021 | auto SI = StackComponents.rbegin(); |
17022 | auto SE = StackComponents.rend(); |
17023 | for (; CI != CE && SI != SE; ++CI, ++SI) { |
17024 | |
17025 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] |
17026 | // At most one list item can be an array item derived from a given |
17027 | // variable in map clauses of the same construct. |
17028 | if (CurrentRegionOnly && |
17029 | (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || |
17030 | isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || |
17031 | isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && |
17032 | (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || |
17033 | isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || |
17034 | isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { |
17035 | SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), |
17036 | diag::err_omp_multiple_array_items_in_map_clause) |
17037 | << CI->getAssociatedExpression()->getSourceRange(); |
17038 | SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), |
17039 | diag::note_used_here) |
17040 | << SI->getAssociatedExpression()->getSourceRange(); |
17041 | return true; |
17042 | } |
17043 | |
17044 | // Do both expressions have the same kind? |
17045 | if (CI->getAssociatedExpression()->getStmtClass() != |
17046 | SI->getAssociatedExpression()->getStmtClass()) |
17047 | break; |
17048 | |
17049 | // Are we dealing with different variables/fields? |
17050 | if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) |
17051 | break; |
17052 | } |
17053 | // Check if the extra components of the expressions in the enclosing |
17054 | // data environment are redundant for the current base declaration. |
17055 | // If they are, the maps completely overlap, which is legal. |
17056 | for (; SI != SE; ++SI) { |
17057 | QualType Type; |
17058 | if (const auto *ASE = |
17059 | dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { |
17060 | Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); |
17061 | } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( |
17062 | SI->getAssociatedExpression())) { |
17063 | const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); |
17064 | Type = |
17065 | OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); |
17066 | } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( |
17067 | SI->getAssociatedExpression())) { |
17068 | Type = OASE->getBase()->getType()->getPointeeType(); |
17069 | } |
17070 | if (Type.isNull() || Type->isAnyPointerType() || |
17071 | checkArrayExpressionDoesNotReferToWholeSize( |
17072 | SemaRef, SI->getAssociatedExpression(), Type)) |
17073 | break; |
17074 | } |
17075 | |
17076 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] |
17077 | // List items of map clauses in the same construct must not share |
17078 | // original storage. |
17079 | // |
17080 | // If the expressions are exactly the same or one is a subset of the |
17081 | // other, it means they are sharing storage. |
17082 | if (CI == CE && SI == SE) { |
17083 | if (CurrentRegionOnly) { |
17084 | if (CKind == OMPC_map) { |
17085 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; |
17086 | } else { |
17087 | assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void > (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17087, __PRETTY_FUNCTION__)); |
17088 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) |
17089 | << ERange; |
17090 | } |
17091 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) |
17092 | << RE->getSourceRange(); |
17093 | return true; |
17094 | } |
17095 | // If we find the same expression in the enclosing data environment, |
17096 | // that is legal. |
17097 | IsEnclosedByDataEnvironmentExpr = true; |
17098 | return false; |
17099 | } |
17100 | |
17101 | QualType DerivedType = |
17102 | std::prev(CI)->getAssociatedDeclaration()->getType(); |
17103 | SourceLocation DerivedLoc = |
17104 | std::prev(CI)->getAssociatedExpression()->getExprLoc(); |
17105 | |
17106 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] |
17107 | // If the type of a list item is a reference to a type T then the type |
17108 | // will be considered to be T for all purposes of this clause. |
17109 | DerivedType = DerivedType.getNonReferenceType(); |
17110 | |
17111 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] |
17112 | // A variable for which the type is pointer and an array section |
17113 | // derived from that variable must not appear as list items of map |
17114 | // clauses of the same construct. |
17115 | // |
17116 | // Also, cover one of the cases in: |
17117 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] |
17118 | // If any part of the original storage of a list item has corresponding |
17119 | // storage in the device data environment, all of the original storage |
17120 | // must have corresponding storage in the device data environment. |
17121 | // |
17122 | if (DerivedType->isAnyPointerType()) { |
17123 | if (CI == CE || SI == SE) { |
17124 | SemaRef.Diag( |
17125 | DerivedLoc, |
17126 | diag::err_omp_pointer_mapped_along_with_derived_section) |
17127 | << DerivedLoc; |
17128 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) |
17129 | << RE->getSourceRange(); |
17130 | return true; |
17131 | } |
17132 | if (CI->getAssociatedExpression()->getStmtClass() != |
17133 | SI->getAssociatedExpression()->getStmtClass() || |
17134 | CI->getAssociatedDeclaration()->getCanonicalDecl() == |
17135 | SI->getAssociatedDeclaration()->getCanonicalDecl()) { |
17136 | assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0) : __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17136, __PRETTY_FUNCTION__)); |
17137 | SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) |
17138 | << DerivedLoc; |
17139 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) |
17140 | << RE->getSourceRange(); |
17141 | return true; |
17142 | } |
17143 | } |
17144 | |
17145 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] |
17146 | // List items of map clauses in the same construct must not share |
17147 | // original storage. |
17148 | // |
17149 | // An expression is a subset of the other. |
17150 | if (CurrentRegionOnly && (CI == CE || SI == SE)) { |
17151 | if (CKind == OMPC_map) { |
17152 | if (CI != CE || SI != SE) { |
17153 | // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is |
17154 | // a pointer. |
17155 | auto Begin = |
17156 | CI != CE ? CurComponents.begin() : StackComponents.begin(); |
17157 | auto End = CI != CE ? CurComponents.end() : StackComponents.end(); |
17158 | auto It = Begin; |
17159 | while (It != End && !It->getAssociatedDeclaration()) |
17160 | std::advance(It, 1); |
17161 | assert(It != End &&((It != End && "Expected at least one component with the declaration." ) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17162, __PRETTY_FUNCTION__)) |
17162 | "Expected at least one component with the declaration.")((It != End && "Expected at least one component with the declaration." ) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17162, __PRETTY_FUNCTION__)); |
17163 | if (It != Begin && It->getAssociatedDeclaration() |
17164 | ->getType() |
17165 | .getCanonicalType() |
17166 | ->isAnyPointerType()) { |
17167 | IsEnclosedByDataEnvironmentExpr = false; |
17168 | EnclosingExpr = nullptr; |
17169 | return false; |
17170 | } |
17171 | } |
17172 | SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; |
17173 | } else { |
17174 | assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void > (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17174, __PRETTY_FUNCTION__)); |
17175 | SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) |
17176 | << ERange; |
17177 | } |
17178 | SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) |
17179 | << RE->getSourceRange(); |
17180 | return true; |
17181 | } |
17182 | |
17183 | // The current expression uses the same base as other expression in the |
17184 | // data environment but does not contain it completely. |
17185 | if (!CurrentRegionOnly && SI != SE) |
17186 | EnclosingExpr = RE; |
17187 | |
17188 | // The current expression is a subset of the expression in the data |
17189 | // environment. |
17190 | IsEnclosedByDataEnvironmentExpr |= |
17191 | (!CurrentRegionOnly && CI != CE && SI == SE); |
17192 | |
17193 | return false; |
17194 | }); |
17195 | |
17196 | if (CurrentRegionOnly) |
17197 | return FoundError; |
17198 | |
17199 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] |
17200 | // If any part of the original storage of a list item has corresponding |
17201 | // storage in the device data environment, all of the original storage must |
17202 | // have corresponding storage in the device data environment. |
17203 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] |
17204 | // If a list item is an element of a structure, and a different element of |
17205 | // the structure has a corresponding list item in the device data environment |
17206 | // prior to a task encountering the construct associated with the map clause, |
17207 | // then the list item must also have a corresponding list item in the device |
17208 | // data environment prior to the task encountering the construct. |
17209 | // |
17210 | if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { |
17211 | SemaRef.Diag(ELoc, |
17212 | diag::err_omp_original_storage_is_shared_and_does_not_contain) |
17213 | << ERange; |
17214 | SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) |
17215 | << EnclosingExpr->getSourceRange(); |
17216 | return true; |
17217 | } |
17218 | |
17219 | return FoundError; |
17220 | } |
17221 | |
17222 | // Look up the user-defined mapper given the mapper name and mapped type, and |
17223 | // build a reference to it. |
17224 | static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, |
17225 | CXXScopeSpec &MapperIdScopeSpec, |
17226 | const DeclarationNameInfo &MapperId, |
17227 | QualType Type, |
17228 | Expr *UnresolvedMapper) { |
17229 | if (MapperIdScopeSpec.isInvalid()) |
17230 | return ExprError(); |
17231 | // Get the actual type for the array type. |
17232 | if (Type->isArrayType()) { |
17233 | assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")((Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type" ) ? static_cast<void> (0) : __assert_fail ("Type->getAsArrayTypeUnsafe() && \"Expect to get a valid array type\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17233, __PRETTY_FUNCTION__)); |
17234 | Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); |
17235 | } |
17236 | // Find all user-defined mappers with the given MapperId. |
17237 | SmallVector<UnresolvedSet<8>, 4> Lookups; |
17238 | LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); |
17239 | Lookup.suppressDiagnostics(); |
17240 | if (S) { |
17241 | while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { |
17242 | NamedDecl *D = Lookup.getRepresentativeDecl(); |
17243 | while (S && !S->isDeclScope(D)) |
17244 | S = S->getParent(); |
17245 | if (S) |
17246 | S = S->getParent(); |
17247 | Lookups.emplace_back(); |
17248 | Lookups.back().append(Lookup.begin(), Lookup.end()); |
17249 | Lookup.clear(); |
17250 | } |
17251 | } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { |
17252 | // Extract the user-defined mappers with the given MapperId. |
17253 | Lookups.push_back(UnresolvedSet<8>()); |
17254 | for (NamedDecl *D : ULE->decls()) { |
17255 | auto *DMD = cast<OMPDeclareMapperDecl>(D); |
17256 | assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")((DMD && "Expect valid OMPDeclareMapperDecl during instantiation." ) ? static_cast<void> (0) : __assert_fail ("DMD && \"Expect valid OMPDeclareMapperDecl during instantiation.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17256, __PRETTY_FUNCTION__)); |
17257 | Lookups.back().addDecl(DMD); |
17258 | } |
17259 | } |
17260 | // Defer the lookup for dependent types. The results will be passed through |
17261 | // UnresolvedMapper on instantiation. |
17262 | if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || |
17263 | Type->isInstantiationDependentType() || |
17264 | Type->containsUnexpandedParameterPack() || |
17265 | filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { |
17266 | return !D->isInvalidDecl() && |
17267 | (D->getType()->isDependentType() || |
17268 | D->getType()->isInstantiationDependentType() || |
17269 | D->getType()->containsUnexpandedParameterPack()); |
17270 | })) { |
17271 | UnresolvedSet<8> URS; |
17272 | for (const UnresolvedSet<8> &Set : Lookups) { |
17273 | if (Set.empty()) |
17274 | continue; |
17275 | URS.append(Set.begin(), Set.end()); |
17276 | } |
17277 | return UnresolvedLookupExpr::Create( |
17278 | SemaRef.Context, /*NamingClass=*/nullptr, |
17279 | MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, |
17280 | /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); |
17281 | } |
17282 | SourceLocation Loc = MapperId.getLoc(); |
17283 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions |
17284 | // The type must be of struct, union or class type in C and C++ |
17285 | if (!Type->isStructureOrClassType() && !Type->isUnionType() && |
17286 | (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { |
17287 | SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); |
17288 | return ExprError(); |
17289 | } |
17290 | // Perform argument dependent lookup. |
17291 | if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) |
17292 | argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); |
17293 | // Return the first user-defined mapper with the desired type. |
17294 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( |
17295 | Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { |
17296 | if (!D->isInvalidDecl() && |
17297 | SemaRef.Context.hasSameType(D->getType(), Type)) |
17298 | return D; |
17299 | return nullptr; |
17300 | })) |
17301 | return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); |
17302 | // Find the first user-defined mapper with a type derived from the desired |
17303 | // type. |
17304 | if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( |
17305 | Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { |
17306 | if (!D->isInvalidDecl() && |
17307 | SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && |
17308 | !Type.isMoreQualifiedThan(D->getType())) |
17309 | return D; |
17310 | return nullptr; |
17311 | })) { |
17312 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, |
17313 | /*DetectVirtual=*/false); |
17314 | if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { |
17315 | if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( |
17316 | VD->getType().getUnqualifiedType()))) { |
17317 | if (SemaRef.CheckBaseClassAccess( |
17318 | Loc, VD->getType(), Type, Paths.front(), |
17319 | /*DiagID=*/0) != Sema::AR_inaccessible) { |
17320 | return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); |
17321 | } |
17322 | } |
17323 | } |
17324 | } |
17325 | // Report error if a mapper is specified, but cannot be found. |
17326 | if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { |
17327 | SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) |
17328 | << Type << MapperId.getName(); |
17329 | return ExprError(); |
17330 | } |
17331 | return ExprEmpty(); |
17332 | } |
17333 | |
17334 | namespace { |
17335 | // Utility struct that gathers all the related lists associated with a mappable |
17336 | // expression. |
17337 | struct MappableVarListInfo { |
17338 | // The list of expressions. |
17339 | ArrayRef<Expr *> VarList; |
17340 | // The list of processed expressions. |
17341 | SmallVector<Expr *, 16> ProcessedVarList; |
17342 | // The mappble components for each expression. |
17343 | OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; |
17344 | // The base declaration of the variable. |
17345 | SmallVector<ValueDecl *, 16> VarBaseDeclarations; |
17346 | // The reference to the user-defined mapper associated with every expression. |
17347 | SmallVector<Expr *, 16> UDMapperList; |
17348 | |
17349 | MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { |
17350 | // We have a list of components and base declarations for each entry in the |
17351 | // variable list. |
17352 | VarComponents.reserve(VarList.size()); |
17353 | VarBaseDeclarations.reserve(VarList.size()); |
17354 | } |
17355 | }; |
17356 | } |
17357 | |
17358 | // Check the validity of the provided variable list for the provided clause kind |
17359 | // \a CKind. In the check process the valid expressions, mappable expression |
17360 | // components, variables, and user-defined mappers are extracted and used to |
17361 | // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a |
17362 | // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, |
17363 | // and \a MapperId are expected to be valid if the clause kind is 'map'. |
17364 | static void checkMappableExpressionList( |
17365 | Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, |
17366 | MappableVarListInfo &MVLI, SourceLocation StartLoc, |
17367 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, |
17368 | ArrayRef<Expr *> UnresolvedMappers, |
17369 | OpenMPMapClauseKind MapType = OMPC_MAP_unknown, |
17370 | bool IsMapTypeImplicit = false) { |
17371 | // We only expect mappable expressions in 'to', 'from', and 'map' clauses. |
17372 | assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from ) && "Unexpected clause kind with mappable expressions!" ) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17373, __PRETTY_FUNCTION__)) |
17373 | "Unexpected clause kind with mappable expressions!")(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from ) && "Unexpected clause kind with mappable expressions!" ) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17373, __PRETTY_FUNCTION__)); |
17374 | |
17375 | // If the identifier of user-defined mapper is not specified, it is "default". |
17376 | // We do not change the actual name in this clause to distinguish whether a |
17377 | // mapper is specified explicitly, i.e., it is not explicitly specified when |
17378 | // MapperId.getName() is empty. |
17379 | if (!MapperId.getName() || MapperId.getName().isEmpty()) { |
17380 | auto &DeclNames = SemaRef.getASTContext().DeclarationNames; |
17381 | MapperId.setName(DeclNames.getIdentifier( |
17382 | &SemaRef.getASTContext().Idents.get("default"))); |
17383 | } |
17384 | |
17385 | // Iterators to find the current unresolved mapper expression. |
17386 | auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); |
17387 | bool UpdateUMIt = false; |
17388 | Expr *UnresolvedMapper = nullptr; |
17389 | |
17390 | // Keep track of the mappable components and base declarations in this clause. |
17391 | // Each entry in the list is going to have a list of components associated. We |
17392 | // record each set of the components so that we can build the clause later on. |
17393 | // In the end we should have the same amount of declarations and component |
17394 | // lists. |
17395 | |
17396 | for (Expr *RE : MVLI.VarList) { |
17397 | assert(RE && "Null expr in omp to/from/map clause")((RE && "Null expr in omp to/from/map clause") ? static_cast <void> (0) : __assert_fail ("RE && \"Null expr in omp to/from/map clause\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17397, __PRETTY_FUNCTION__)); |
17398 | SourceLocation ELoc = RE->getExprLoc(); |
17399 | |
17400 | // Find the current unresolved mapper expression. |
17401 | if (UpdateUMIt && UMIt != UMEnd) { |
17402 | UMIt++; |
17403 | assert(((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList" ) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17405, __PRETTY_FUNCTION__)) |
17404 | UMIt != UMEnd &&((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList" ) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17405, __PRETTY_FUNCTION__)) |
17405 | "Expect the size of UnresolvedMappers to match with that of VarList")((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList" ) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17405, __PRETTY_FUNCTION__)); |
17406 | } |
17407 | UpdateUMIt = true; |
17408 | if (UMIt != UMEnd) |
17409 | UnresolvedMapper = *UMIt; |
17410 | |
17411 | const Expr *VE = RE->IgnoreParenLValueCasts(); |
17412 | |
17413 | if (VE->isValueDependent() || VE->isTypeDependent() || |
17414 | VE->isInstantiationDependent() || |
17415 | VE->containsUnexpandedParameterPack()) { |
17416 | // Try to find the associated user-defined mapper. |
17417 | ExprResult ER = buildUserDefinedMapperRef( |
17418 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, |
17419 | VE->getType().getCanonicalType(), UnresolvedMapper); |
17420 | if (ER.isInvalid()) |
17421 | continue; |
17422 | MVLI.UDMapperList.push_back(ER.get()); |
17423 | // We can only analyze this information once the missing information is |
17424 | // resolved. |
17425 | MVLI.ProcessedVarList.push_back(RE); |
17426 | continue; |
17427 | } |
17428 | |
17429 | Expr *SimpleExpr = RE->IgnoreParenCasts(); |
17430 | |
17431 | if (!RE->isLValue()) { |
17432 | if (SemaRef.getLangOpts().OpenMP < 50) { |
17433 | SemaRef.Diag( |
17434 | ELoc, diag::err_omp_expected_named_var_member_or_array_expression) |
17435 | << RE->getSourceRange(); |
17436 | } else { |
17437 | SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) |
17438 | << getOpenMPClauseName(CKind) << RE->getSourceRange(); |
17439 | } |
17440 | continue; |
17441 | } |
17442 | |
17443 | OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; |
17444 | ValueDecl *CurDeclaration = nullptr; |
17445 | |
17446 | // Obtain the array or member expression bases if required. Also, fill the |
17447 | // components array with all the components identified in the process. |
17448 | const Expr *BE = checkMapClauseExpressionBase( |
17449 | SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); |
17450 | if (!BE) |
17451 | continue; |
17452 | |
17453 | assert(!CurComponents.empty() &&((!CurComponents.empty() && "Invalid mappable expression information." ) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17454, __PRETTY_FUNCTION__)) |
17454 | "Invalid mappable expression information.")((!CurComponents.empty() && "Invalid mappable expression information." ) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17454, __PRETTY_FUNCTION__)); |
17455 | |
17456 | if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { |
17457 | // Add store "this" pointer to class in DSAStackTy for future checking |
17458 | DSAS->addMappedClassesQualTypes(TE->getType()); |
17459 | // Try to find the associated user-defined mapper. |
17460 | ExprResult ER = buildUserDefinedMapperRef( |
17461 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, |
17462 | VE->getType().getCanonicalType(), UnresolvedMapper); |
17463 | if (ER.isInvalid()) |
17464 | continue; |
17465 | MVLI.UDMapperList.push_back(ER.get()); |
17466 | // Skip restriction checking for variable or field declarations |
17467 | MVLI.ProcessedVarList.push_back(RE); |
17468 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); |
17469 | MVLI.VarComponents.back().append(CurComponents.begin(), |
17470 | CurComponents.end()); |
17471 | MVLI.VarBaseDeclarations.push_back(nullptr); |
17472 | continue; |
17473 | } |
17474 | |
17475 | // For the following checks, we rely on the base declaration which is |
17476 | // expected to be associated with the last component. The declaration is |
17477 | // expected to be a variable or a field (if 'this' is being mapped). |
17478 | CurDeclaration = CurComponents.back().getAssociatedDeclaration(); |
17479 | assert(CurDeclaration && "Null decl on map clause.")((CurDeclaration && "Null decl on map clause.") ? static_cast <void> (0) : __assert_fail ("CurDeclaration && \"Null decl on map clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17479, __PRETTY_FUNCTION__)); |
17480 | assert(((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations." ) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17482, __PRETTY_FUNCTION__)) |
17481 | CurDeclaration->isCanonicalDecl() &&((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations." ) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17482, __PRETTY_FUNCTION__)) |
17482 | "Expecting components to have associated only canonical declarations.")((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations." ) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17482, __PRETTY_FUNCTION__)); |
17483 | |
17484 | auto *VD = dyn_cast<VarDecl>(CurDeclaration); |
17485 | const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); |
17486 | |
17487 | assert((VD || FD) && "Only variables or fields are expected here!")(((VD || FD) && "Only variables or fields are expected here!" ) ? static_cast<void> (0) : __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17487, __PRETTY_FUNCTION__)); |
17488 | (void)FD; |
17489 | |
17490 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] |
17491 | // threadprivate variables cannot appear in a map clause. |
17492 | // OpenMP 4.5 [2.10.5, target update Construct] |
17493 | // threadprivate variables cannot appear in a from clause. |
17494 | if (VD && DSAS->isThreadPrivate(VD)) { |
17495 | DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); |
17496 | SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) |
17497 | << getOpenMPClauseName(CKind); |
17498 | reportOriginalDsa(SemaRef, DSAS, VD, DVar); |
17499 | continue; |
17500 | } |
17501 | |
17502 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] |
17503 | // A list item cannot appear in both a map clause and a data-sharing |
17504 | // attribute clause on the same construct. |
17505 | |
17506 | // Check conflicts with other map clause expressions. We check the conflicts |
17507 | // with the current construct separately from the enclosing data |
17508 | // environment, because the restrictions are different. We only have to |
17509 | // check conflicts across regions for the map clauses. |
17510 | if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, |
17511 | /*CurrentRegionOnly=*/true, CurComponents, CKind)) |
17512 | break; |
17513 | if (CKind == OMPC_map && |
17514 | (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && |
17515 | checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, |
17516 | /*CurrentRegionOnly=*/false, CurComponents, CKind)) |
17517 | break; |
17518 | |
17519 | // OpenMP 4.5 [2.10.5, target update Construct] |
17520 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] |
17521 | // If the type of a list item is a reference to a type T then the type will |
17522 | // be considered to be T for all purposes of this clause. |
17523 | auto I = llvm::find_if( |
17524 | CurComponents, |
17525 | [](const OMPClauseMappableExprCommon::MappableComponent &MC) { |
17526 | return MC.getAssociatedDeclaration(); |
17527 | }); |
17528 | assert(I != CurComponents.end() && "Null decl on map clause.")((I != CurComponents.end() && "Null decl on map clause." ) ? static_cast<void> (0) : __assert_fail ("I != CurComponents.end() && \"Null decl on map clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17528, __PRETTY_FUNCTION__)); |
17529 | QualType Type; |
17530 | auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); |
17531 | auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); |
17532 | auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); |
17533 | if (ASE) { |
17534 | Type = ASE->getType().getNonReferenceType(); |
17535 | } else if (OASE) { |
17536 | QualType BaseType = |
17537 | OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); |
17538 | if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) |
17539 | Type = ATy->getElementType(); |
17540 | else |
17541 | Type = BaseType->getPointeeType(); |
17542 | Type = Type.getNonReferenceType(); |
17543 | } else if (OAShE) { |
17544 | Type = OAShE->getBase()->getType()->getPointeeType(); |
17545 | } else { |
17546 | Type = VE->getType(); |
17547 | } |
17548 | |
17549 | // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] |
17550 | // A list item in a to or from clause must have a mappable type. |
17551 | // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] |
17552 | // A list item must have a mappable type. |
17553 | if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, |
17554 | DSAS, Type)) |
17555 | continue; |
17556 | |
17557 | Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); |
17558 | |
17559 | if (CKind == OMPC_map) { |
17560 | // target enter data |
17561 | // OpenMP [2.10.2, Restrictions, p. 99] |
17562 | // A map-type must be specified in all map clauses and must be either |
17563 | // to or alloc. |
17564 | OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); |
17565 | if (DKind == OMPD_target_enter_data && |
17566 | !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { |
17567 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) |
17568 | << (IsMapTypeImplicit ? 1 : 0) |
17569 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) |
17570 | << getOpenMPDirectiveName(DKind); |
17571 | continue; |
17572 | } |
17573 | |
17574 | // target exit_data |
17575 | // OpenMP [2.10.3, Restrictions, p. 102] |
17576 | // A map-type must be specified in all map clauses and must be either |
17577 | // from, release, or delete. |
17578 | if (DKind == OMPD_target_exit_data && |
17579 | !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || |
17580 | MapType == OMPC_MAP_delete)) { |
17581 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) |
17582 | << (IsMapTypeImplicit ? 1 : 0) |
17583 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) |
17584 | << getOpenMPDirectiveName(DKind); |
17585 | continue; |
17586 | } |
17587 | |
17588 | // target, target data |
17589 | // OpenMP 5.0 [2.12.2, Restrictions, p. 163] |
17590 | // OpenMP 5.0 [2.12.5, Restrictions, p. 174] |
17591 | // A map-type in a map clause must be to, from, tofrom or alloc |
17592 | if ((DKind == OMPD_target_data || |
17593 | isOpenMPTargetExecutionDirective(DKind)) && |
17594 | !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || |
17595 | MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { |
17596 | SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) |
17597 | << (IsMapTypeImplicit ? 1 : 0) |
17598 | << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) |
17599 | << getOpenMPDirectiveName(DKind); |
17600 | continue; |
17601 | } |
17602 | |
17603 | // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] |
17604 | // A list item cannot appear in both a map clause and a data-sharing |
17605 | // attribute clause on the same construct |
17606 | // |
17607 | // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] |
17608 | // A list item cannot appear in both a map clause and a data-sharing |
17609 | // attribute clause on the same construct unless the construct is a |
17610 | // combined construct. |
17611 | if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && |
17612 | isOpenMPTargetExecutionDirective(DKind)) || |
17613 | DKind == OMPD_target)) { |
17614 | DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); |
17615 | if (isOpenMPPrivate(DVar.CKind)) { |
17616 | SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) |
17617 | << getOpenMPClauseName(DVar.CKind) |
17618 | << getOpenMPClauseName(OMPC_map) |
17619 | << getOpenMPDirectiveName(DSAS->getCurrentDirective()); |
17620 | reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); |
17621 | continue; |
17622 | } |
17623 | } |
17624 | } |
17625 | |
17626 | // Try to find the associated user-defined mapper. |
17627 | ExprResult ER = buildUserDefinedMapperRef( |
17628 | SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, |
17629 | Type.getCanonicalType(), UnresolvedMapper); |
17630 | if (ER.isInvalid()) |
17631 | continue; |
17632 | MVLI.UDMapperList.push_back(ER.get()); |
17633 | |
17634 | // Save the current expression. |
17635 | MVLI.ProcessedVarList.push_back(RE); |
17636 | |
17637 | // Store the components in the stack so that they can be used to check |
17638 | // against other clauses later on. |
17639 | DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, |
17640 | /*WhereFoundClauseKind=*/OMPC_map); |
17641 | |
17642 | // Save the components and declaration to create the clause. For purposes of |
17643 | // the clause creation, any component list that has has base 'this' uses |
17644 | // null as base declaration. |
17645 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); |
17646 | MVLI.VarComponents.back().append(CurComponents.begin(), |
17647 | CurComponents.end()); |
17648 | MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr |
17649 | : CurDeclaration); |
17650 | } |
17651 | } |
17652 | |
17653 | OMPClause *Sema::ActOnOpenMPMapClause( |
17654 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, |
17655 | ArrayRef<SourceLocation> MapTypeModifiersLoc, |
17656 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, |
17657 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, |
17658 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, |
17659 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { |
17660 | OpenMPMapModifierKind Modifiers[] = { |
17661 | OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, |
17662 | OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; |
17663 | SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; |
17664 | |
17665 | // Process map-type-modifiers, flag errors for duplicate modifiers. |
17666 | unsigned Count = 0; |
17667 | for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { |
17668 | if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && |
17669 | llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { |
17670 | Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); |
17671 | continue; |
17672 | } |
17673 | assert(Count < NumberOfOMPMapClauseModifiers &&((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17674, __PRETTY_FUNCTION__)) |
17674 | "Modifiers exceed the allowed number of map type modifiers")((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17674, __PRETTY_FUNCTION__)); |
17675 | Modifiers[Count] = MapTypeModifiers[I]; |
17676 | ModifiersLoc[Count] = MapTypeModifiersLoc[I]; |
17677 | ++Count; |
17678 | } |
17679 | |
17680 | MappableVarListInfo MVLI(VarList); |
17681 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_map, MVLI, Locs.StartLoc, |
17682 | MapperIdScopeSpec, MapperId, UnresolvedMappers, |
17683 | MapType, IsMapTypeImplicit); |
17684 | |
17685 | // We need to produce a map clause even if we don't have variables so that |
17686 | // other diagnostics related with non-existing map clauses are accurate. |
17687 | return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, |
17688 | MVLI.VarBaseDeclarations, MVLI.VarComponents, |
17689 | MVLI.UDMapperList, Modifiers, ModifiersLoc, |
17690 | MapperIdScopeSpec.getWithLocInContext(Context), |
17691 | MapperId, MapType, IsMapTypeImplicit, MapLoc); |
17692 | } |
17693 | |
17694 | QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, |
17695 | TypeResult ParsedType) { |
17696 | assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17696, __PRETTY_FUNCTION__)); |
17697 | |
17698 | QualType ReductionType = GetTypeFromParser(ParsedType.get()); |
17699 | if (ReductionType.isNull()) |
17700 | return QualType(); |
17701 | |
17702 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ |
17703 | // A type name in a declare reduction directive cannot be a function type, an |
17704 | // array type, a reference type, or a type qualified with const, volatile or |
17705 | // restrict. |
17706 | if (ReductionType.hasQualifiers()) { |
17707 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; |
17708 | return QualType(); |
17709 | } |
17710 | |
17711 | if (ReductionType->isFunctionType()) { |
17712 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; |
17713 | return QualType(); |
17714 | } |
17715 | if (ReductionType->isReferenceType()) { |
17716 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; |
17717 | return QualType(); |
17718 | } |
17719 | if (ReductionType->isArrayType()) { |
17720 | Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; |
17721 | return QualType(); |
17722 | } |
17723 | return ReductionType; |
17724 | } |
17725 | |
17726 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( |
17727 | Scope *S, DeclContext *DC, DeclarationName Name, |
17728 | ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, |
17729 | AccessSpecifier AS, Decl *PrevDeclInScope) { |
17730 | SmallVector<Decl *, 8> Decls; |
17731 | Decls.reserve(ReductionTypes.size()); |
17732 | |
17733 | LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, |
17734 | forRedeclarationInCurContext()); |
17735 | // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions |
17736 | // A reduction-identifier may not be re-declared in the current scope for the |
17737 | // same type or for a type that is compatible according to the base language |
17738 | // rules. |
17739 | llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; |
17740 | OMPDeclareReductionDecl *PrevDRD = nullptr; |
17741 | bool InCompoundScope = true; |
17742 | if (S != nullptr) { |
17743 | // Find previous declaration with the same name not referenced in other |
17744 | // declarations. |
17745 | FunctionScopeInfo *ParentFn = getEnclosingFunction(); |
17746 | InCompoundScope = |
17747 | (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); |
17748 | LookupName(Lookup, S); |
17749 | FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, |
17750 | /*AllowInlineNamespace=*/false); |
17751 | llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; |
17752 | LookupResult::Filter Filter = Lookup.makeFilter(); |
17753 | while (Filter.hasNext()) { |
17754 | auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); |
17755 | if (InCompoundScope) { |
17756 | auto I = UsedAsPrevious.find(PrevDecl); |
17757 | if (I == UsedAsPrevious.end()) |
17758 | UsedAsPrevious[PrevDecl] = false; |
17759 | if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) |
17760 | UsedAsPrevious[D] = true; |
17761 | } |
17762 | PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = |
17763 | PrevDecl->getLocation(); |
17764 | } |
17765 | Filter.done(); |
17766 | if (InCompoundScope) { |
17767 | for (const auto &PrevData : UsedAsPrevious) { |
17768 | if (!PrevData.second) { |
17769 | PrevDRD = PrevData.first; |
17770 | break; |
17771 | } |
17772 | } |
17773 | } |
17774 | } else if (PrevDeclInScope != nullptr) { |
17775 | auto *PrevDRDInScope = PrevDRD = |
17776 | cast<OMPDeclareReductionDecl>(PrevDeclInScope); |
17777 | do { |
17778 | PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = |
17779 | PrevDRDInScope->getLocation(); |
17780 | PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); |
17781 | } while (PrevDRDInScope != nullptr); |
17782 | } |
17783 | for (const auto &TyData : ReductionTypes) { |
17784 | const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); |
17785 | bool Invalid = false; |
17786 | if (I != PreviousRedeclTypes.end()) { |
17787 | Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) |
17788 | << TyData.first; |
17789 | Diag(I->second, diag::note_previous_definition); |
17790 | Invalid = true; |
17791 | } |
17792 | PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; |
17793 | auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, |
17794 | Name, TyData.first, PrevDRD); |
17795 | DC->addDecl(DRD); |
17796 | DRD->setAccess(AS); |
17797 | Decls.push_back(DRD); |
17798 | if (Invalid) |
17799 | DRD->setInvalidDecl(); |
17800 | else |
17801 | PrevDRD = DRD; |
17802 | } |
17803 | |
17804 | return DeclGroupPtrTy::make( |
17805 | DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); |
17806 | } |
17807 | |
17808 | void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { |
17809 | auto *DRD = cast<OMPDeclareReductionDecl>(D); |
17810 | |
17811 | // Enter new function scope. |
17812 | PushFunctionScope(); |
17813 | setFunctionHasBranchProtectedScope(); |
17814 | getCurFunction()->setHasOMPDeclareReductionCombiner(); |
17815 | |
17816 | if (S != nullptr) |
17817 | PushDeclContext(S, DRD); |
17818 | else |
17819 | CurContext = DRD; |
17820 | |
17821 | PushExpressionEvaluationContext( |
17822 | ExpressionEvaluationContext::PotentiallyEvaluated); |
17823 | |
17824 | QualType ReductionType = DRD->getType(); |
17825 | // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will |
17826 | // be replaced by '*omp_parm' during codegen. This required because 'omp_in' |
17827 | // uses semantics of argument handles by value, but it should be passed by |
17828 | // reference. C lang does not support references, so pass all parameters as |
17829 | // pointers. |
17830 | // Create 'T omp_in;' variable. |
17831 | VarDecl *OmpInParm = |
17832 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); |
17833 | // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will |
17834 | // be replaced by '*omp_parm' during codegen. This required because 'omp_out' |
17835 | // uses semantics of argument handles by value, but it should be passed by |
17836 | // reference. C lang does not support references, so pass all parameters as |
17837 | // pointers. |
17838 | // Create 'T omp_out;' variable. |
17839 | VarDecl *OmpOutParm = |
17840 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); |
17841 | if (S != nullptr) { |
17842 | PushOnScopeChains(OmpInParm, S); |
17843 | PushOnScopeChains(OmpOutParm, S); |
17844 | } else { |
17845 | DRD->addDecl(OmpInParm); |
17846 | DRD->addDecl(OmpOutParm); |
17847 | } |
17848 | Expr *InE = |
17849 | ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); |
17850 | Expr *OutE = |
17851 | ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); |
17852 | DRD->setCombinerData(InE, OutE); |
17853 | } |
17854 | |
17855 | void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { |
17856 | auto *DRD = cast<OMPDeclareReductionDecl>(D); |
17857 | DiscardCleanupsInEvaluationContext(); |
17858 | PopExpressionEvaluationContext(); |
17859 | |
17860 | PopDeclContext(); |
17861 | PopFunctionScopeInfo(); |
17862 | |
17863 | if (Combiner != nullptr) |
17864 | DRD->setCombiner(Combiner); |
17865 | else |
17866 | DRD->setInvalidDecl(); |
17867 | } |
17868 | |
17869 | VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { |
17870 | auto *DRD = cast<OMPDeclareReductionDecl>(D); |
17871 | |
17872 | // Enter new function scope. |
17873 | PushFunctionScope(); |
17874 | setFunctionHasBranchProtectedScope(); |
17875 | |
17876 | if (S != nullptr) |
17877 | PushDeclContext(S, DRD); |
17878 | else |
17879 | CurContext = DRD; |
17880 | |
17881 | PushExpressionEvaluationContext( |
17882 | ExpressionEvaluationContext::PotentiallyEvaluated); |
17883 | |
17884 | QualType ReductionType = DRD->getType(); |
17885 | // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will |
17886 | // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' |
17887 | // uses semantics of argument handles by value, but it should be passed by |
17888 | // reference. C lang does not support references, so pass all parameters as |
17889 | // pointers. |
17890 | // Create 'T omp_priv;' variable. |
17891 | VarDecl *OmpPrivParm = |
17892 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); |
17893 | // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will |
17894 | // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' |
17895 | // uses semantics of argument handles by value, but it should be passed by |
17896 | // reference. C lang does not support references, so pass all parameters as |
17897 | // pointers. |
17898 | // Create 'T omp_orig;' variable. |
17899 | VarDecl *OmpOrigParm = |
17900 | buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); |
17901 | if (S != nullptr) { |
17902 | PushOnScopeChains(OmpPrivParm, S); |
17903 | PushOnScopeChains(OmpOrigParm, S); |
17904 | } else { |
17905 | DRD->addDecl(OmpPrivParm); |
17906 | DRD->addDecl(OmpOrigParm); |
17907 | } |
17908 | Expr *OrigE = |
17909 | ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); |
17910 | Expr *PrivE = |
17911 | ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); |
17912 | DRD->setInitializerData(OrigE, PrivE); |
17913 | return OmpPrivParm; |
17914 | } |
17915 | |
17916 | void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, |
17917 | VarDecl *OmpPrivParm) { |
17918 | auto *DRD = cast<OMPDeclareReductionDecl>(D); |
17919 | DiscardCleanupsInEvaluationContext(); |
17920 | PopExpressionEvaluationContext(); |
17921 | |
17922 | PopDeclContext(); |
17923 | PopFunctionScopeInfo(); |
17924 | |
17925 | if (Initializer != nullptr) { |
17926 | DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); |
17927 | } else if (OmpPrivParm->hasInit()) { |
17928 | DRD->setInitializer(OmpPrivParm->getInit(), |
17929 | OmpPrivParm->isDirectInit() |
17930 | ? OMPDeclareReductionDecl::DirectInit |
17931 | : OMPDeclareReductionDecl::CopyInit); |
17932 | } else { |
17933 | DRD->setInvalidDecl(); |
17934 | } |
17935 | } |
17936 | |
17937 | Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( |
17938 | Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { |
17939 | for (Decl *D : DeclReductions.get()) { |
17940 | if (IsValid) { |
17941 | if (S) |
17942 | PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, |
17943 | /*AddToContext=*/false); |
17944 | } else { |
17945 | D->setInvalidDecl(); |
17946 | } |
17947 | } |
17948 | return DeclReductions; |
17949 | } |
17950 | |
17951 | TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { |
17952 | TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); |
17953 | QualType T = TInfo->getType(); |
17954 | if (D.isInvalidType()) |
17955 | return true; |
17956 | |
17957 | if (getLangOpts().CPlusPlus) { |
17958 | // Check that there are no default arguments (C++ only). |
17959 | CheckExtraCXXDefaultArguments(D); |
17960 | } |
17961 | |
17962 | return CreateParsedType(T, TInfo); |
17963 | } |
17964 | |
17965 | QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, |
17966 | TypeResult ParsedType) { |
17967 | assert(ParsedType.isUsable() && "Expect usable parsed mapper type")((ParsedType.isUsable() && "Expect usable parsed mapper type" ) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable() && \"Expect usable parsed mapper type\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17967, __PRETTY_FUNCTION__)); |
17968 | |
17969 | QualType MapperType = GetTypeFromParser(ParsedType.get()); |
17970 | assert(!MapperType.isNull() && "Expect valid mapper type")((!MapperType.isNull() && "Expect valid mapper type") ? static_cast<void> (0) : __assert_fail ("!MapperType.isNull() && \"Expect valid mapper type\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 17970, __PRETTY_FUNCTION__)); |
17971 | |
17972 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions |
17973 | // The type must be of struct, union or class type in C and C++ |
17974 | if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { |
17975 | Diag(TyLoc, diag::err_omp_mapper_wrong_type); |
17976 | return QualType(); |
17977 | } |
17978 | return MapperType; |
17979 | } |
17980 | |
17981 | OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( |
17982 | Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, |
17983 | SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, |
17984 | Decl *PrevDeclInScope) { |
17985 | LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, |
17986 | forRedeclarationInCurContext()); |
17987 | // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions |
17988 | // A mapper-identifier may not be redeclared in the current scope for the |
17989 | // same type or for a type that is compatible according to the base language |
17990 | // rules. |
17991 | llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; |
17992 | OMPDeclareMapperDecl *PrevDMD = nullptr; |
17993 | bool InCompoundScope = true; |
17994 | if (S != nullptr) { |
17995 | // Find previous declaration with the same name not referenced in other |
17996 | // declarations. |
17997 | FunctionScopeInfo *ParentFn = getEnclosingFunction(); |
17998 | InCompoundScope = |
17999 | (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); |
18000 | LookupName(Lookup, S); |
18001 | FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, |
18002 | /*AllowInlineNamespace=*/false); |
18003 | llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; |
18004 | LookupResult::Filter Filter = Lookup.makeFilter(); |
18005 | while (Filter.hasNext()) { |
18006 | auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); |
18007 | if (InCompoundScope) { |
18008 | auto I = UsedAsPrevious.find(PrevDecl); |
18009 | if (I == UsedAsPrevious.end()) |
18010 | UsedAsPrevious[PrevDecl] = false; |
18011 | if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) |
18012 | UsedAsPrevious[D] = true; |
18013 | } |
18014 | PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = |
18015 | PrevDecl->getLocation(); |
18016 | } |
18017 | Filter.done(); |
18018 | if (InCompoundScope) { |
18019 | for (const auto &PrevData : UsedAsPrevious) { |
18020 | if (!PrevData.second) { |
18021 | PrevDMD = PrevData.first; |
18022 | break; |
18023 | } |
18024 | } |
18025 | } |
18026 | } else if (PrevDeclInScope) { |
18027 | auto *PrevDMDInScope = PrevDMD = |
18028 | cast<OMPDeclareMapperDecl>(PrevDeclInScope); |
18029 | do { |
18030 | PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = |
18031 | PrevDMDInScope->getLocation(); |
18032 | PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); |
18033 | } while (PrevDMDInScope != nullptr); |
18034 | } |
18035 | const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); |
18036 | bool Invalid = false; |
18037 | if (I != PreviousRedeclTypes.end()) { |
18038 | Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) |
18039 | << MapperType << Name; |
18040 | Diag(I->second, diag::note_previous_definition); |
18041 | Invalid = true; |
18042 | } |
18043 | auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, |
18044 | MapperType, VN, PrevDMD); |
18045 | DC->addDecl(DMD); |
18046 | DMD->setAccess(AS); |
18047 | if (Invalid) |
18048 | DMD->setInvalidDecl(); |
18049 | |
18050 | // Enter new function scope. |
18051 | PushFunctionScope(); |
18052 | setFunctionHasBranchProtectedScope(); |
18053 | |
18054 | CurContext = DMD; |
18055 | |
18056 | return DMD; |
18057 | } |
18058 | |
18059 | void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, |
18060 | Scope *S, |
18061 | QualType MapperType, |
18062 | SourceLocation StartLoc, |
18063 | DeclarationName VN) { |
18064 | VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); |
18065 | if (S) |
18066 | PushOnScopeChains(VD, S); |
18067 | else |
18068 | DMD->addDecl(VD); |
18069 | Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); |
18070 | DMD->setMapperVarRef(MapperVarRefExpr); |
18071 | } |
18072 | |
18073 | Sema::DeclGroupPtrTy |
18074 | Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, |
18075 | ArrayRef<OMPClause *> ClauseList) { |
18076 | PopDeclContext(); |
18077 | PopFunctionScopeInfo(); |
18078 | |
18079 | if (D) { |
18080 | if (S) |
18081 | PushOnScopeChains(D, S, /*AddToContext=*/false); |
18082 | D->CreateClauses(Context, ClauseList); |
18083 | } |
18084 | |
18085 | return DeclGroupPtrTy::make(DeclGroupRef(D)); |
18086 | } |
18087 | |
18088 | OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, |
18089 | SourceLocation StartLoc, |
18090 | SourceLocation LParenLoc, |
18091 | SourceLocation EndLoc) { |
18092 | Expr *ValExpr = NumTeams; |
18093 | Stmt *HelperValStmt = nullptr; |
18094 | |
18095 | // OpenMP [teams Constrcut, Restrictions] |
18096 | // The num_teams expression must evaluate to a positive integer value. |
18097 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, |
18098 | /*StrictlyPositive=*/true)) |
18099 | return nullptr; |
18100 | |
18101 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
18102 | OpenMPDirectiveKind CaptureRegion = |
18103 | getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); |
18104 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { |
18105 | ValExpr = MakeFullExpr(ValExpr).get(); |
18106 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
18107 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
18108 | HelperValStmt = buildPreInits(Context, Captures); |
18109 | } |
18110 | |
18111 | return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, |
18112 | StartLoc, LParenLoc, EndLoc); |
18113 | } |
18114 | |
18115 | OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, |
18116 | SourceLocation StartLoc, |
18117 | SourceLocation LParenLoc, |
18118 | SourceLocation EndLoc) { |
18119 | Expr *ValExpr = ThreadLimit; |
18120 | Stmt *HelperValStmt = nullptr; |
18121 | |
18122 | // OpenMP [teams Constrcut, Restrictions] |
18123 | // The thread_limit expression must evaluate to a positive integer value. |
18124 | if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, |
18125 | /*StrictlyPositive=*/true)) |
18126 | return nullptr; |
18127 | |
18128 | OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); |
18129 | OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( |
18130 | DKind, OMPC_thread_limit, LangOpts.OpenMP); |
18131 | if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { |
18132 | ValExpr = MakeFullExpr(ValExpr).get(); |
18133 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
18134 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
18135 | HelperValStmt = buildPreInits(Context, Captures); |
18136 | } |
18137 | |
18138 | return new (Context) OMPThreadLimitClause( |
18139 | ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); |
18140 | } |
18141 | |
18142 | OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, |
18143 | SourceLocation StartLoc, |
18144 | SourceLocation LParenLoc, |
18145 | SourceLocation EndLoc) { |
18146 | Expr *ValExpr = Priority; |
18147 | Stmt *HelperValStmt = nullptr; |
18148 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; |
18149 | |
18150 | // OpenMP [2.9.1, task Constrcut] |
18151 | // The priority-value is a non-negative numerical scalar expression. |
18152 | if (!isNonNegativeIntegerValue( |
18153 | ValExpr, *this, OMPC_priority, |
18154 | /*StrictlyPositive=*/false, /*BuildCapture=*/true, |
18155 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) |
18156 | return nullptr; |
18157 | |
18158 | return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, |
18159 | StartLoc, LParenLoc, EndLoc); |
18160 | } |
18161 | |
18162 | OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, |
18163 | SourceLocation StartLoc, |
18164 | SourceLocation LParenLoc, |
18165 | SourceLocation EndLoc) { |
18166 | Expr *ValExpr = Grainsize; |
18167 | Stmt *HelperValStmt = nullptr; |
18168 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; |
18169 | |
18170 | // OpenMP [2.9.2, taskloop Constrcut] |
18171 | // The parameter of the grainsize clause must be a positive integer |
18172 | // expression. |
18173 | if (!isNonNegativeIntegerValue( |
18174 | ValExpr, *this, OMPC_grainsize, |
18175 | /*StrictlyPositive=*/true, /*BuildCapture=*/true, |
18176 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) |
18177 | return nullptr; |
18178 | |
18179 | return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, |
18180 | StartLoc, LParenLoc, EndLoc); |
18181 | } |
18182 | |
18183 | OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, |
18184 | SourceLocation StartLoc, |
18185 | SourceLocation LParenLoc, |
18186 | SourceLocation EndLoc) { |
18187 | Expr *ValExpr = NumTasks; |
18188 | Stmt *HelperValStmt = nullptr; |
18189 | OpenMPDirectiveKind CaptureRegion = OMPD_unknown; |
18190 | |
18191 | // OpenMP [2.9.2, taskloop Constrcut] |
18192 | // The parameter of the num_tasks clause must be a positive integer |
18193 | // expression. |
18194 | if (!isNonNegativeIntegerValue( |
18195 | ValExpr, *this, OMPC_num_tasks, |
18196 | /*StrictlyPositive=*/true, /*BuildCapture=*/true, |
18197 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) |
18198 | return nullptr; |
18199 | |
18200 | return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, |
18201 | StartLoc, LParenLoc, EndLoc); |
18202 | } |
18203 | |
18204 | OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, |
18205 | SourceLocation LParenLoc, |
18206 | SourceLocation EndLoc) { |
18207 | // OpenMP [2.13.2, critical construct, Description] |
18208 | // ... where hint-expression is an integer constant expression that evaluates |
18209 | // to a valid lock hint. |
18210 | ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); |
18211 | if (HintExpr.isInvalid()) |
18212 | return nullptr; |
18213 | return new (Context) |
18214 | OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); |
18215 | } |
18216 | |
18217 | /// Tries to find omp_event_handle_t type. |
18218 | static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, |
18219 | DSAStackTy *Stack) { |
18220 | QualType OMPEventHandleT = Stack->getOMPEventHandleT(); |
18221 | if (!OMPEventHandleT.isNull()) |
18222 | return true; |
18223 | IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); |
18224 | ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); |
18225 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { |
18226 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; |
18227 | return false; |
18228 | } |
18229 | Stack->setOMPEventHandleT(PT.get()); |
18230 | return true; |
18231 | } |
18232 | |
18233 | OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, |
18234 | SourceLocation LParenLoc, |
18235 | SourceLocation EndLoc) { |
18236 | if (!Evt->isValueDependent() && !Evt->isTypeDependent() && |
18237 | !Evt->isInstantiationDependent() && |
18238 | !Evt->containsUnexpandedParameterPack()) { |
18239 | if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
18240 | return nullptr; |
18241 | // OpenMP 5.0, 2.10.1 task Construct. |
18242 | // event-handle is a variable of the omp_event_handle_t type. |
18243 | auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); |
18244 | if (!Ref) { |
18245 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) |
18246 | << "omp_event_handle_t" << 0 << Evt->getSourceRange(); |
18247 | return nullptr; |
18248 | } |
18249 | auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); |
18250 | if (!VD) { |
18251 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) |
18252 | << "omp_event_handle_t" << 0 << Evt->getSourceRange(); |
18253 | return nullptr; |
18254 | } |
18255 | if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPEventHandleT(), |
18256 | VD->getType()) || |
18257 | VD->getType().isConstant(Context)) { |
18258 | Diag(Evt->getExprLoc(), diag::err_omp_var_expected) |
18259 | << "omp_event_handle_t" << 1 << VD->getType() |
18260 | << Evt->getSourceRange(); |
18261 | return nullptr; |
18262 | } |
18263 | // OpenMP 5.0, 2.10.1 task Construct |
18264 | // [detach clause]... The event-handle will be considered as if it was |
18265 | // specified on a firstprivate clause. |
18266 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, /*FromParent=*/false); |
18267 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && |
18268 | DVar.RefExpr) { |
18269 | Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) |
18270 | << getOpenMPClauseName(DVar.CKind) |
18271 | << getOpenMPClauseName(OMPC_firstprivate); |
18272 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); |
18273 | return nullptr; |
18274 | } |
18275 | } |
18276 | |
18277 | return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); |
18278 | } |
18279 | |
18280 | OMPClause *Sema::ActOnOpenMPDistScheduleClause( |
18281 | OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, |
18282 | SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, |
18283 | SourceLocation EndLoc) { |
18284 | if (Kind == OMPC_DIST_SCHEDULE_unknown) { |
18285 | std::string Values; |
18286 | Values += "'"; |
18287 | Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); |
18288 | Values += "'"; |
18289 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) |
18290 | << Values << getOpenMPClauseName(OMPC_dist_schedule); |
18291 | return nullptr; |
18292 | } |
18293 | Expr *ValExpr = ChunkSize; |
18294 | Stmt *HelperValStmt = nullptr; |
18295 | if (ChunkSize) { |
18296 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && |
18297 | !ChunkSize->isInstantiationDependent() && |
18298 | !ChunkSize->containsUnexpandedParameterPack()) { |
18299 | SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); |
18300 | ExprResult Val = |
18301 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); |
18302 | if (Val.isInvalid()) |
18303 | return nullptr; |
18304 | |
18305 | ValExpr = Val.get(); |
18306 | |
18307 | // OpenMP [2.7.1, Restrictions] |
18308 | // chunk_size must be a loop invariant integer expression with a positive |
18309 | // value. |
18310 | if (Optional<llvm::APSInt> Result = |
18311 | ValExpr->getIntegerConstantExpr(Context)) { |
18312 | if (Result->isSigned() && !Result->isStrictlyPositive()) { |
18313 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) |
18314 | << "dist_schedule" << ChunkSize->getSourceRange(); |
18315 | return nullptr; |
18316 | } |
18317 | } else if (getOpenMPCaptureRegionForClause( |
18318 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(), OMPC_dist_schedule, |
18319 | LangOpts.OpenMP) != OMPD_unknown && |
18320 | !CurContext->isDependentContext()) { |
18321 | ValExpr = MakeFullExpr(ValExpr).get(); |
18322 | llvm::MapVector<const Expr *, DeclRefExpr *> Captures; |
18323 | ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); |
18324 | HelperValStmt = buildPreInits(Context, Captures); |
18325 | } |
18326 | } |
18327 | } |
18328 | |
18329 | return new (Context) |
18330 | OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, |
18331 | Kind, ValExpr, HelperValStmt); |
18332 | } |
18333 | |
18334 | OMPClause *Sema::ActOnOpenMPDefaultmapClause( |
18335 | OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, |
18336 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, |
18337 | SourceLocation KindLoc, SourceLocation EndLoc) { |
18338 | if (getLangOpts().OpenMP < 50) { |
18339 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || |
18340 | Kind != OMPC_DEFAULTMAP_scalar) { |
18341 | std::string Value; |
18342 | SourceLocation Loc; |
18343 | Value += "'"; |
18344 | if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { |
18345 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, |
18346 | OMPC_DEFAULTMAP_MODIFIER_tofrom); |
18347 | Loc = MLoc; |
18348 | } else { |
18349 | Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, |
18350 | OMPC_DEFAULTMAP_scalar); |
18351 | Loc = KindLoc; |
18352 | } |
18353 | Value += "'"; |
18354 | Diag(Loc, diag::err_omp_unexpected_clause_value) |
18355 | << Value << getOpenMPClauseName(OMPC_defaultmap); |
18356 | return nullptr; |
18357 | } |
18358 | } else { |
18359 | bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); |
18360 | bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || |
18361 | (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); |
18362 | if (!isDefaultmapKind || !isDefaultmapModifier) { |
18363 | std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " |
18364 | "'firstprivate', 'none', 'default'"; |
18365 | std::string KindValue = "'scalar', 'aggregate', 'pointer'"; |
18366 | if (!isDefaultmapKind && isDefaultmapModifier) { |
18367 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) |
18368 | << KindValue << getOpenMPClauseName(OMPC_defaultmap); |
18369 | } else if (isDefaultmapKind && !isDefaultmapModifier) { |
18370 | Diag(MLoc, diag::err_omp_unexpected_clause_value) |
18371 | << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); |
18372 | } else { |
18373 | Diag(MLoc, diag::err_omp_unexpected_clause_value) |
18374 | << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); |
18375 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) |
18376 | << KindValue << getOpenMPClauseName(OMPC_defaultmap); |
18377 | } |
18378 | return nullptr; |
18379 | } |
18380 | |
18381 | // OpenMP [5.0, 2.12.5, Restrictions, p. 174] |
18382 | // At most one defaultmap clause for each category can appear on the |
18383 | // directive. |
18384 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkDefaultmapCategory(Kind)) { |
18385 | Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); |
18386 | return nullptr; |
18387 | } |
18388 | } |
18389 | if (Kind == OMPC_DEFAULTMAP_unknown) { |
18390 | // Variable category is not specified - mark all categories. |
18391 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); |
18392 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); |
18393 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); |
18394 | } else { |
18395 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDMAAttr(M, Kind, StartLoc); |
18396 | } |
18397 | |
18398 | return new (Context) |
18399 | OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); |
18400 | } |
18401 | |
18402 | bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { |
18403 | DeclContext *CurLexicalContext = getCurLexicalContext(); |
18404 | if (!CurLexicalContext->isFileContext() && |
18405 | !CurLexicalContext->isExternCContext() && |
18406 | !CurLexicalContext->isExternCXXContext() && |
18407 | !isa<CXXRecordDecl>(CurLexicalContext) && |
18408 | !isa<ClassTemplateDecl>(CurLexicalContext) && |
18409 | !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && |
18410 | !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { |
18411 | Diag(Loc, diag::err_omp_region_not_file_context); |
18412 | return false; |
18413 | } |
18414 | ++DeclareTargetNestingLevel; |
18415 | return true; |
18416 | } |
18417 | |
18418 | void Sema::ActOnFinishOpenMPDeclareTargetDirective() { |
18419 | assert(DeclareTargetNestingLevel > 0 &&((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective" ) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18420, __PRETTY_FUNCTION__)) |
18420 | "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective" ) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18420, __PRETTY_FUNCTION__)); |
18421 | --DeclareTargetNestingLevel; |
18422 | } |
18423 | |
18424 | NamedDecl * |
18425 | Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, |
18426 | const DeclarationNameInfo &Id, |
18427 | NamedDeclSetType &SameDirectiveDecls) { |
18428 | LookupResult Lookup(*this, Id, LookupOrdinaryName); |
18429 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); |
18430 | |
18431 | if (Lookup.isAmbiguous()) |
18432 | return nullptr; |
18433 | Lookup.suppressDiagnostics(); |
18434 | |
18435 | if (!Lookup.isSingleResult()) { |
18436 | VarOrFuncDeclFilterCCC CCC(*this); |
18437 | if (TypoCorrection Corrected = |
18438 | CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, |
18439 | CTK_ErrorRecovery)) { |
18440 | diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) |
18441 | << Id.getName()); |
18442 | checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); |
18443 | return nullptr; |
18444 | } |
18445 | |
18446 | Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); |
18447 | return nullptr; |
18448 | } |
18449 | |
18450 | NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); |
18451 | if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && |
18452 | !isa<FunctionTemplateDecl>(ND)) { |
18453 | Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); |
18454 | return nullptr; |
18455 | } |
18456 | if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) |
18457 | Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); |
18458 | return ND; |
18459 | } |
18460 | |
18461 | void Sema::ActOnOpenMPDeclareTargetName( |
18462 | NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, |
18463 | OMPDeclareTargetDeclAttr::DevTypeTy DT) { |
18464 | assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa <FunctionTemplateDecl>(ND)) && "Expected variable, function or function template." ) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18466, __PRETTY_FUNCTION__)) |
18465 | isa<FunctionTemplateDecl>(ND)) &&(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa <FunctionTemplateDecl>(ND)) && "Expected variable, function or function template." ) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18466, __PRETTY_FUNCTION__)) |
18466 | "Expected variable, function or function template.")(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa <FunctionTemplateDecl>(ND)) && "Expected variable, function or function template." ) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18466, __PRETTY_FUNCTION__)); |
18467 | |
18468 | // Diagnose marking after use as it may lead to incorrect diagnosis and |
18469 | // codegen. |
18470 | if (LangOpts.OpenMP >= 50 && |
18471 | (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) |
18472 | Diag(Loc, diag::warn_omp_declare_target_after_first_use); |
18473 | |
18474 | Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = |
18475 | OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); |
18476 | if (DevTy.hasValue() && *DevTy != DT) { |
18477 | Diag(Loc, diag::err_omp_device_type_mismatch) |
18478 | << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) |
18479 | << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); |
18480 | return; |
18481 | } |
18482 | Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = |
18483 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); |
18484 | if (!Res) { |
18485 | auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, |
18486 | SourceRange(Loc, Loc)); |
18487 | ND->addAttr(A); |
18488 | if (ASTMutationListener *ML = Context.getASTMutationListener()) |
18489 | ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); |
18490 | checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); |
18491 | } else if (*Res != MT) { |
18492 | Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; |
18493 | } |
18494 | } |
18495 | |
18496 | static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, |
18497 | Sema &SemaRef, Decl *D) { |
18498 | if (!D || !isa<VarDecl>(D)) |
18499 | return; |
18500 | auto *VD = cast<VarDecl>(D); |
18501 | Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = |
18502 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); |
18503 | if (SemaRef.LangOpts.OpenMP >= 50 && |
18504 | (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || |
18505 | SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && |
18506 | VD->hasGlobalStorage()) { |
18507 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = |
18508 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); |
18509 | if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { |
18510 | // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions |
18511 | // If a lambda declaration and definition appears between a |
18512 | // declare target directive and the matching end declare target |
18513 | // directive, all variables that are captured by the lambda |
18514 | // expression must also appear in a to clause. |
18515 | SemaRef.Diag(VD->getLocation(), |
18516 | diag::err_omp_lambda_capture_in_declare_target_not_to); |
18517 | SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) |
18518 | << VD << 0 << SR; |
18519 | return; |
18520 | } |
18521 | } |
18522 | if (MapTy.hasValue()) |
18523 | return; |
18524 | SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); |
18525 | SemaRef.Diag(SL, diag::note_used_here) << SR; |
18526 | } |
18527 | |
18528 | static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, |
18529 | Sema &SemaRef, DSAStackTy *Stack, |
18530 | ValueDecl *VD) { |
18531 | return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || |
18532 | checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), |
18533 | /*FullCheck=*/false); |
18534 | } |
18535 | |
18536 | void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, |
18537 | SourceLocation IdLoc) { |
18538 | if (!D || D->isInvalidDecl()) |
18539 | return; |
18540 | SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); |
18541 | SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); |
18542 | if (auto *VD = dyn_cast<VarDecl>(D)) { |
18543 | // Only global variables can be marked as declare target. |
18544 | if (!VD->isFileVarDecl() && !VD->isStaticLocal() && |
18545 | !VD->isStaticDataMember()) |
18546 | return; |
18547 | // 2.10.6: threadprivate variable cannot appear in a declare target |
18548 | // directive. |
18549 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { |
18550 | Diag(SL, diag::err_omp_threadprivate_in_target); |
18551 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false)); |
18552 | return; |
18553 | } |
18554 | } |
18555 | if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) |
18556 | D = FTD->getTemplatedDecl(); |
18557 | if (auto *FD = dyn_cast<FunctionDecl>(D)) { |
18558 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = |
18559 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); |
18560 | if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { |
18561 | Diag(IdLoc, diag::err_omp_function_in_link_clause); |
18562 | Diag(FD->getLocation(), diag::note_defined_here) << FD; |
18563 | return; |
18564 | } |
18565 | } |
18566 | if (auto *VD = dyn_cast<ValueDecl>(D)) { |
18567 | // Problem if any with var declared with incomplete type will be reported |
18568 | // as normal, so no need to check it here. |
18569 | if ((E || !VD->getType()->isIncompleteType()) && |
18570 | !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD)) |
18571 | return; |
18572 | if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { |
18573 | // Checking declaration inside declare target region. |
18574 | if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || |
18575 | isa<FunctionTemplateDecl>(D)) { |
18576 | auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( |
18577 | Context, OMPDeclareTargetDeclAttr::MT_To, |
18578 | OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); |
18579 | D->addAttr(A); |
18580 | if (ASTMutationListener *ML = Context.getASTMutationListener()) |
18581 | ML->DeclarationMarkedOpenMPDeclareTarget(D, A); |
18582 | } |
18583 | return; |
18584 | } |
18585 | } |
18586 | if (!E) |
18587 | return; |
18588 | checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); |
18589 | } |
18590 | |
18591 | OMPClause *Sema::ActOnOpenMPToClause( |
18592 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
18593 | ArrayRef<SourceLocation> MotionModifiersLoc, |
18594 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, |
18595 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, |
18596 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { |
18597 | OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, |
18598 | OMPC_MOTION_MODIFIER_unknown}; |
18599 | SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; |
18600 | |
18601 | // Process motion-modifiers, flag errors for duplicate modifiers. |
18602 | unsigned Count = 0; |
18603 | for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { |
18604 | if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && |
18605 | llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { |
18606 | Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); |
18607 | continue; |
18608 | } |
18609 | assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18610, __PRETTY_FUNCTION__)) |
18610 | "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18610, __PRETTY_FUNCTION__)); |
18611 | Modifiers[Count] = MotionModifiers[I]; |
18612 | ModifiersLoc[Count] = MotionModifiersLoc[I]; |
18613 | ++Count; |
18614 | } |
18615 | |
18616 | MappableVarListInfo MVLI(VarList); |
18617 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_to, MVLI, Locs.StartLoc, |
18618 | MapperIdScopeSpec, MapperId, UnresolvedMappers); |
18619 | if (MVLI.ProcessedVarList.empty()) |
18620 | return nullptr; |
18621 | |
18622 | return OMPToClause::Create( |
18623 | Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, |
18624 | MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, |
18625 | MapperIdScopeSpec.getWithLocInContext(Context), MapperId); |
18626 | } |
18627 | |
18628 | OMPClause *Sema::ActOnOpenMPFromClause( |
18629 | ArrayRef<OpenMPMotionModifierKind> MotionModifiers, |
18630 | ArrayRef<SourceLocation> MotionModifiersLoc, |
18631 | CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, |
18632 | SourceLocation ColonLoc, ArrayRef<Expr *> VarList, |
18633 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { |
18634 | OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, |
18635 | OMPC_MOTION_MODIFIER_unknown}; |
18636 | SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; |
18637 | |
18638 | // Process motion-modifiers, flag errors for duplicate modifiers. |
18639 | unsigned Count = 0; |
18640 | for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { |
18641 | if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && |
18642 | llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { |
18643 | Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); |
18644 | continue; |
18645 | } |
18646 | assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18647, __PRETTY_FUNCTION__)) |
18647 | "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers" ) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18647, __PRETTY_FUNCTION__)); |
18648 | Modifiers[Count] = MotionModifiers[I]; |
18649 | ModifiersLoc[Count] = MotionModifiersLoc[I]; |
18650 | ++Count; |
18651 | } |
18652 | |
18653 | MappableVarListInfo MVLI(VarList); |
18654 | checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), OMPC_from, MVLI, Locs.StartLoc, |
18655 | MapperIdScopeSpec, MapperId, UnresolvedMappers); |
18656 | if (MVLI.ProcessedVarList.empty()) |
18657 | return nullptr; |
18658 | |
18659 | return OMPFromClause::Create( |
18660 | Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, |
18661 | MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, |
18662 | MapperIdScopeSpec.getWithLocInContext(Context), MapperId); |
18663 | } |
18664 | |
18665 | OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, |
18666 | const OMPVarListLocTy &Locs) { |
18667 | MappableVarListInfo MVLI(VarList); |
18668 | SmallVector<Expr *, 8> PrivateCopies; |
18669 | SmallVector<Expr *, 8> Inits; |
18670 | |
18671 | for (Expr *RefExpr : VarList) { |
18672 | assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")((RefExpr && "NULL expr in OpenMP use_device_ptr clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18672, __PRETTY_FUNCTION__)); |
18673 | SourceLocation ELoc; |
18674 | SourceRange ERange; |
18675 | Expr *SimpleRefExpr = RefExpr; |
18676 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
18677 | if (Res.second) { |
18678 | // It will be analyzed later. |
18679 | MVLI.ProcessedVarList.push_back(RefExpr); |
18680 | PrivateCopies.push_back(nullptr); |
18681 | Inits.push_back(nullptr); |
18682 | } |
18683 | ValueDecl *D = Res.first; |
18684 | if (!D) |
18685 | continue; |
18686 | |
18687 | QualType Type = D->getType(); |
18688 | Type = Type.getNonReferenceType().getUnqualifiedType(); |
18689 | |
18690 | auto *VD = dyn_cast<VarDecl>(D); |
18691 | |
18692 | // Item should be a pointer or reference to pointer. |
18693 | if (!Type->isPointerType()) { |
18694 | Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) |
18695 | << 0 << RefExpr->getSourceRange(); |
18696 | continue; |
18697 | } |
18698 | |
18699 | // Build the private variable and the expression that refers to it. |
18700 | auto VDPrivate = |
18701 | buildVarDecl(*this, ELoc, Type, D->getName(), |
18702 | D->hasAttrs() ? &D->getAttrs() : nullptr, |
18703 | VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); |
18704 | if (VDPrivate->isInvalidDecl()) |
18705 | continue; |
18706 | |
18707 | CurContext->addDecl(VDPrivate); |
18708 | DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( |
18709 | *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); |
18710 | |
18711 | // Add temporary variable to initialize the private copy of the pointer. |
18712 | VarDecl *VDInit = |
18713 | buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); |
18714 | DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( |
18715 | *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); |
18716 | AddInitializerToDecl(VDPrivate, |
18717 | DefaultLvalueConversion(VDInitRefExpr).get(), |
18718 | /*DirectInit=*/false); |
18719 | |
18720 | // If required, build a capture to implement the privatization initialized |
18721 | // with the current list item value. |
18722 | DeclRefExpr *Ref = nullptr; |
18723 | if (!VD) |
18724 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); |
18725 | MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); |
18726 | PrivateCopies.push_back(VDPrivateRefExpr); |
18727 | Inits.push_back(VDInitRefExpr); |
18728 | |
18729 | // We need to add a data sharing attribute for this variable to make sure it |
18730 | // is correctly captured. A variable that shows up in a use_device_ptr has |
18731 | // similar properties of a first private variable. |
18732 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); |
18733 | |
18734 | // Create a mappable component for the list item. List items in this clause |
18735 | // only need a component. |
18736 | MVLI.VarBaseDeclarations.push_back(D); |
18737 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); |
18738 | MVLI.VarComponents.back().push_back( |
18739 | OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); |
18740 | } |
18741 | |
18742 | if (MVLI.ProcessedVarList.empty()) |
18743 | return nullptr; |
18744 | |
18745 | return OMPUseDevicePtrClause::Create( |
18746 | Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, |
18747 | MVLI.VarBaseDeclarations, MVLI.VarComponents); |
18748 | } |
18749 | |
18750 | OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, |
18751 | const OMPVarListLocTy &Locs) { |
18752 | MappableVarListInfo MVLI(VarList); |
18753 | |
18754 | for (Expr *RefExpr : VarList) { |
18755 | assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")((RefExpr && "NULL expr in OpenMP use_device_addr clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_addr clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18755, __PRETTY_FUNCTION__)); |
18756 | SourceLocation ELoc; |
18757 | SourceRange ERange; |
18758 | Expr *SimpleRefExpr = RefExpr; |
18759 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, |
18760 | /*AllowArraySection=*/true); |
18761 | if (Res.second) { |
18762 | // It will be analyzed later. |
18763 | MVLI.ProcessedVarList.push_back(RefExpr); |
18764 | } |
18765 | ValueDecl *D = Res.first; |
18766 | if (!D) |
18767 | continue; |
18768 | auto *VD = dyn_cast<VarDecl>(D); |
18769 | |
18770 | // If required, build a capture to implement the privatization initialized |
18771 | // with the current list item value. |
18772 | DeclRefExpr *Ref = nullptr; |
18773 | if (!VD) |
18774 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); |
18775 | MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); |
18776 | |
18777 | // We need to add a data sharing attribute for this variable to make sure it |
18778 | // is correctly captured. A variable that shows up in a use_device_addr has |
18779 | // similar properties of a first private variable. |
18780 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); |
18781 | |
18782 | // Create a mappable component for the list item. List items in this clause |
18783 | // only need a component. |
18784 | MVLI.VarBaseDeclarations.push_back(D); |
18785 | MVLI.VarComponents.emplace_back(); |
18786 | Expr *Component = SimpleRefExpr; |
18787 | if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || |
18788 | isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) |
18789 | Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); |
18790 | MVLI.VarComponents.back().push_back( |
18791 | OMPClauseMappableExprCommon::MappableComponent(Component, D)); |
18792 | } |
18793 | |
18794 | if (MVLI.ProcessedVarList.empty()) |
18795 | return nullptr; |
18796 | |
18797 | return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, |
18798 | MVLI.VarBaseDeclarations, |
18799 | MVLI.VarComponents); |
18800 | } |
18801 | |
18802 | OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, |
18803 | const OMPVarListLocTy &Locs) { |
18804 | MappableVarListInfo MVLI(VarList); |
18805 | for (Expr *RefExpr : VarList) { |
18806 | assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")((RefExpr && "NULL expr in OpenMP is_device_ptr clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18806, __PRETTY_FUNCTION__)); |
18807 | SourceLocation ELoc; |
18808 | SourceRange ERange; |
18809 | Expr *SimpleRefExpr = RefExpr; |
18810 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
18811 | if (Res.second) { |
18812 | // It will be analyzed later. |
18813 | MVLI.ProcessedVarList.push_back(RefExpr); |
18814 | } |
18815 | ValueDecl *D = Res.first; |
18816 | if (!D) |
18817 | continue; |
18818 | |
18819 | QualType Type = D->getType(); |
18820 | // item should be a pointer or array or reference to pointer or array |
18821 | if (!Type.getNonReferenceType()->isPointerType() && |
18822 | !Type.getNonReferenceType()->isArrayType()) { |
18823 | Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) |
18824 | << 0 << RefExpr->getSourceRange(); |
18825 | continue; |
18826 | } |
18827 | |
18828 | // Check if the declaration in the clause does not show up in any data |
18829 | // sharing attribute. |
18830 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/false); |
18831 | if (isOpenMPPrivate(DVar.CKind)) { |
18832 | Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) |
18833 | << getOpenMPClauseName(DVar.CKind) |
18834 | << getOpenMPClauseName(OMPC_is_device_ptr) |
18835 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); |
18836 | reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), D, DVar); |
18837 | continue; |
18838 | } |
18839 | |
18840 | const Expr *ConflictExpr; |
18841 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->checkMappableExprComponentListsForDecl( |
18842 | D, /*CurrentRegionOnly=*/true, |
18843 | [&ConflictExpr]( |
18844 | OMPClauseMappableExprCommon::MappableExprComponentListRef R, |
18845 | OpenMPClauseKind) -> bool { |
18846 | ConflictExpr = R.front().getAssociatedExpression(); |
18847 | return true; |
18848 | })) { |
18849 | Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); |
18850 | Diag(ConflictExpr->getExprLoc(), diag::note_used_here) |
18851 | << ConflictExpr->getSourceRange(); |
18852 | continue; |
18853 | } |
18854 | |
18855 | // Store the components in the stack so that they can be used to check |
18856 | // against other clauses later on. |
18857 | OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); |
18858 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addMappableExpressionComponents( |
18859 | D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); |
18860 | |
18861 | // Record the expression we've just processed. |
18862 | MVLI.ProcessedVarList.push_back(SimpleRefExpr); |
18863 | |
18864 | // Create a mappable component for the list item. List items in this clause |
18865 | // only need a component. We use a null declaration to signal fields in |
18866 | // 'this'. |
18867 | assert((isa<DeclRefExpr>(SimpleRefExpr) ||(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr >(cast<MemberExpr>(SimpleRefExpr)->getBase())) && "Unexpected device pointer expression!") ? static_cast<void > (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18869, __PRETTY_FUNCTION__)) |
18868 | isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr >(cast<MemberExpr>(SimpleRefExpr)->getBase())) && "Unexpected device pointer expression!") ? static_cast<void > (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18869, __PRETTY_FUNCTION__)) |
18869 | "Unexpected device pointer expression!")(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr >(cast<MemberExpr>(SimpleRefExpr)->getBase())) && "Unexpected device pointer expression!") ? static_cast<void > (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18869, __PRETTY_FUNCTION__)); |
18870 | MVLI.VarBaseDeclarations.push_back( |
18871 | isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); |
18872 | MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); |
18873 | MVLI.VarComponents.back().push_back(MC); |
18874 | } |
18875 | |
18876 | if (MVLI.ProcessedVarList.empty()) |
18877 | return nullptr; |
18878 | |
18879 | return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, |
18880 | MVLI.VarBaseDeclarations, |
18881 | MVLI.VarComponents); |
18882 | } |
18883 | |
18884 | OMPClause *Sema::ActOnOpenMPAllocateClause( |
18885 | Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, |
18886 | SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { |
18887 | if (Allocator) { |
18888 | // OpenMP [2.11.4 allocate Clause, Description] |
18889 | // allocator is an expression of omp_allocator_handle_t type. |
18890 | if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
18891 | return nullptr; |
18892 | |
18893 | ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); |
18894 | if (AllocatorRes.isInvalid()) |
18895 | return nullptr; |
18896 | AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), |
18897 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), |
18898 | Sema::AA_Initializing, |
18899 | /*AllowExplicit=*/true); |
18900 | if (AllocatorRes.isInvalid()) |
18901 | return nullptr; |
18902 | Allocator = AllocatorRes.get(); |
18903 | } else { |
18904 | // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. |
18905 | // allocate clauses that appear on a target construct or on constructs in a |
18906 | // target region must specify an allocator expression unless a requires |
18907 | // directive with the dynamic_allocators clause is present in the same |
18908 | // compilation unit. |
18909 | if (LangOpts.OpenMPIsDevice && |
18910 | !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) |
18911 | targetDiag(StartLoc, diag::err_expected_allocator_expression); |
18912 | } |
18913 | // Analyze and build list of variables. |
18914 | SmallVector<Expr *, 8> Vars; |
18915 | for (Expr *RefExpr : VarList) { |
18916 | assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18916, __PRETTY_FUNCTION__)); |
18917 | SourceLocation ELoc; |
18918 | SourceRange ERange; |
18919 | Expr *SimpleRefExpr = RefExpr; |
18920 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
18921 | if (Res.second) { |
18922 | // It will be analyzed later. |
18923 | Vars.push_back(RefExpr); |
18924 | } |
18925 | ValueDecl *D = Res.first; |
18926 | if (!D) |
18927 | continue; |
18928 | |
18929 | auto *VD = dyn_cast<VarDecl>(D); |
18930 | DeclRefExpr *Ref = nullptr; |
18931 | if (!VD && !CurContext->isDependentContext()) |
18932 | Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); |
18933 | Vars.push_back((VD || CurContext->isDependentContext()) |
18934 | ? RefExpr->IgnoreParens() |
18935 | : Ref); |
18936 | } |
18937 | |
18938 | if (Vars.empty()) |
18939 | return nullptr; |
18940 | |
18941 | if (Allocator) |
18942 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addInnerAllocatorExpr(Allocator); |
18943 | return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, |
18944 | ColonLoc, EndLoc, Vars); |
18945 | } |
18946 | |
18947 | OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, |
18948 | SourceLocation StartLoc, |
18949 | SourceLocation LParenLoc, |
18950 | SourceLocation EndLoc) { |
18951 | SmallVector<Expr *, 8> Vars; |
18952 | for (Expr *RefExpr : VarList) { |
18953 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18953, __PRETTY_FUNCTION__)); |
18954 | SourceLocation ELoc; |
18955 | SourceRange ERange; |
18956 | Expr *SimpleRefExpr = RefExpr; |
18957 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); |
18958 | if (Res.second) |
18959 | // It will be analyzed later. |
18960 | Vars.push_back(RefExpr); |
18961 | ValueDecl *D = Res.first; |
18962 | if (!D) |
18963 | continue; |
18964 | |
18965 | // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. |
18966 | // A list-item cannot appear in more than one nontemporal clause. |
18967 | if (const Expr *PrevRef = |
18968 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUniqueNontemporal(D, SimpleRefExpr)) { |
18969 | Diag(ELoc, diag::err_omp_used_in_clause_twice) |
18970 | << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; |
18971 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) |
18972 | << getOpenMPClauseName(OMPC_nontemporal); |
18973 | continue; |
18974 | } |
18975 | |
18976 | Vars.push_back(RefExpr); |
18977 | } |
18978 | |
18979 | if (Vars.empty()) |
18980 | return nullptr; |
18981 | |
18982 | return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
18983 | Vars); |
18984 | } |
18985 | |
18986 | OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, |
18987 | SourceLocation StartLoc, |
18988 | SourceLocation LParenLoc, |
18989 | SourceLocation EndLoc) { |
18990 | SmallVector<Expr *, 8> Vars; |
18991 | for (Expr *RefExpr : VarList) { |
18992 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 18992, __PRETTY_FUNCTION__)); |
18993 | SourceLocation ELoc; |
18994 | SourceRange ERange; |
18995 | Expr *SimpleRefExpr = RefExpr; |
18996 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, |
18997 | /*AllowArraySection=*/true); |
18998 | if (Res.second) |
18999 | // It will be analyzed later. |
19000 | Vars.push_back(RefExpr); |
19001 | ValueDecl *D = Res.first; |
19002 | if (!D) |
19003 | continue; |
19004 | |
19005 | const DSAStackTy::DSAVarData DVar = |
19006 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/true); |
19007 | // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. |
19008 | // A list item that appears in the inclusive or exclusive clause must appear |
19009 | // in a reduction clause with the inscan modifier on the enclosing |
19010 | // worksharing-loop, worksharing-loop SIMD, or simd construct. |
19011 | if (DVar.CKind != OMPC_reduction || |
19012 | DVar.Modifier != OMPC_REDUCTION_inscan) |
19013 | Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) |
19014 | << RefExpr->getSourceRange(); |
19015 | |
19016 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective() != OMPD_unknown) |
19017 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->markDeclAsUsedInScanDirective(D); |
19018 | Vars.push_back(RefExpr); |
19019 | } |
19020 | |
19021 | if (Vars.empty()) |
19022 | return nullptr; |
19023 | |
19024 | return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); |
19025 | } |
19026 | |
19027 | OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, |
19028 | SourceLocation StartLoc, |
19029 | SourceLocation LParenLoc, |
19030 | SourceLocation EndLoc) { |
19031 | SmallVector<Expr *, 8> Vars; |
19032 | for (Expr *RefExpr : VarList) { |
19033 | assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 19033, __PRETTY_FUNCTION__)); |
19034 | SourceLocation ELoc; |
19035 | SourceRange ERange; |
19036 | Expr *SimpleRefExpr = RefExpr; |
19037 | auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, |
19038 | /*AllowArraySection=*/true); |
19039 | if (Res.second) |
19040 | // It will be analyzed later. |
19041 | Vars.push_back(RefExpr); |
19042 | ValueDecl *D = Res.first; |
19043 | if (!D) |
19044 | continue; |
19045 | |
19046 | OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getParentDirective(); |
19047 | DSAStackTy::DSAVarData DVar; |
19048 | if (ParentDirective != OMPD_unknown) |
19049 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(D, /*FromParent=*/true); |
19050 | // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. |
19051 | // A list item that appears in the inclusive or exclusive clause must appear |
19052 | // in a reduction clause with the inscan modifier on the enclosing |
19053 | // worksharing-loop, worksharing-loop SIMD, or simd construct. |
19054 | if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || |
19055 | DVar.Modifier != OMPC_REDUCTION_inscan) { |
19056 | Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) |
19057 | << RefExpr->getSourceRange(); |
19058 | } else { |
19059 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->markDeclAsUsedInScanDirective(D); |
19060 | } |
19061 | Vars.push_back(RefExpr); |
19062 | } |
19063 | |
19064 | if (Vars.empty()) |
19065 | return nullptr; |
19066 | |
19067 | return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); |
19068 | } |
19069 | |
19070 | /// Tries to find omp_alloctrait_t type. |
19071 | static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { |
19072 | QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); |
19073 | if (!OMPAlloctraitT.isNull()) |
19074 | return true; |
19075 | IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); |
19076 | ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); |
19077 | if (!PT.getAsOpaquePtr() || PT.get().isNull()) { |
19078 | S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; |
19079 | return false; |
19080 | } |
19081 | Stack->setOMPAlloctraitT(PT.get()); |
19082 | return true; |
19083 | } |
19084 | |
19085 | OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( |
19086 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, |
19087 | ArrayRef<UsesAllocatorsData> Data) { |
19088 | // OpenMP [2.12.5, target Construct] |
19089 | // allocator is an identifier of omp_allocator_handle_t type. |
19090 | if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
19091 | return nullptr; |
19092 | // OpenMP [2.12.5, target Construct] |
19093 | // allocator-traits-array is an identifier of const omp_alloctrait_t * type. |
19094 | if (llvm::any_of( |
19095 | Data, |
19096 | [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && |
19097 | !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ))) |
19098 | return nullptr; |
19099 | llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; |
19100 | for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { |
19101 | auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); |
19102 | StringRef Allocator = |
19103 | OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); |
19104 | DeclarationName AllocatorName = &Context.Idents.get(Allocator); |
19105 | PredefinedAllocators.insert(LookupSingleName( |
19106 | TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); |
19107 | } |
19108 | |
19109 | SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; |
19110 | for (const UsesAllocatorsData &D : Data) { |
19111 | Expr *AllocatorExpr = nullptr; |
19112 | // Check allocator expression. |
19113 | if (D.Allocator->isTypeDependent()) { |
19114 | AllocatorExpr = D.Allocator; |
19115 | } else { |
19116 | // Traits were specified - need to assign new allocator to the specified |
19117 | // allocator, so it must be an lvalue. |
19118 | AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); |
19119 | auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); |
19120 | bool IsPredefinedAllocator = false; |
19121 | if (DRE) |
19122 | IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); |
19123 | if (!DRE || |
19124 | !(Context.hasSameUnqualifiedType( |
19125 | AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT()) || |
19126 | Context.typesAreCompatible(AllocatorExpr->getType(), |
19127 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAllocatorHandleT(), |
19128 | /*CompareUnqualified=*/true)) || |
19129 | (!IsPredefinedAllocator && |
19130 | (AllocatorExpr->getType().isConstant(Context) || |
19131 | !AllocatorExpr->isLValue()))) { |
19132 | Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) |
19133 | << "omp_allocator_handle_t" << (DRE ? 1 : 0) |
19134 | << AllocatorExpr->getType() << D.Allocator->getSourceRange(); |
19135 | continue; |
19136 | } |
19137 | // OpenMP [2.12.5, target Construct] |
19138 | // Predefined allocators appearing in a uses_allocators clause cannot have |
19139 | // traits specified. |
19140 | if (IsPredefinedAllocator && D.AllocatorTraits) { |
19141 | Diag(D.AllocatorTraits->getExprLoc(), |
19142 | diag::err_omp_predefined_allocator_with_traits) |
19143 | << D.AllocatorTraits->getSourceRange(); |
19144 | Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) |
19145 | << cast<NamedDecl>(DRE->getDecl())->getName() |
19146 | << D.Allocator->getSourceRange(); |
19147 | continue; |
19148 | } |
19149 | // OpenMP [2.12.5, target Construct] |
19150 | // Non-predefined allocators appearing in a uses_allocators clause must |
19151 | // have traits specified. |
19152 | if (!IsPredefinedAllocator && !D.AllocatorTraits) { |
19153 | Diag(D.Allocator->getExprLoc(), |
19154 | diag::err_omp_nonpredefined_allocator_without_traits); |
19155 | continue; |
19156 | } |
19157 | // No allocator traits - just convert it to rvalue. |
19158 | if (!D.AllocatorTraits) |
19159 | AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); |
19160 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUsesAllocatorsDecl( |
19161 | DRE->getDecl(), |
19162 | IsPredefinedAllocator |
19163 | ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator |
19164 | : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); |
19165 | } |
19166 | Expr *AllocatorTraitsExpr = nullptr; |
19167 | if (D.AllocatorTraits) { |
19168 | if (D.AllocatorTraits->isTypeDependent()) { |
19169 | AllocatorTraitsExpr = D.AllocatorTraits; |
19170 | } else { |
19171 | // OpenMP [2.12.5, target Construct] |
19172 | // Arrays that contain allocator traits that appear in a uses_allocators |
19173 | // clause must be constant arrays, have constant values and be defined |
19174 | // in the same scope as the construct in which the clause appears. |
19175 | AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); |
19176 | // Check that traits expr is a constant array. |
19177 | QualType TraitTy; |
19178 | if (const ArrayType *Ty = |
19179 | AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) |
19180 | if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) |
19181 | TraitTy = ConstArrayTy->getElementType(); |
19182 | if (TraitTy.isNull() || |
19183 | !(Context.hasSameUnqualifiedType(TraitTy, |
19184 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAlloctraitT()) || |
19185 | Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getOMPAlloctraitT(), |
19186 | /*CompareUnqualified=*/true))) { |
19187 | Diag(D.AllocatorTraits->getExprLoc(), |
19188 | diag::err_omp_expected_array_alloctraits) |
19189 | << AllocatorTraitsExpr->getType(); |
19190 | continue; |
19191 | } |
19192 | // Do not map by default allocator traits if it is a standalone |
19193 | // variable. |
19194 | if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) |
19195 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUsesAllocatorsDecl( |
19196 | DRE->getDecl(), |
19197 | DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); |
19198 | } |
19199 | } |
19200 | OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); |
19201 | NewD.Allocator = AllocatorExpr; |
19202 | NewD.AllocatorTraits = AllocatorTraitsExpr; |
19203 | NewD.LParenLoc = D.LParenLoc; |
19204 | NewD.RParenLoc = D.RParenLoc; |
19205 | } |
19206 | return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, |
19207 | NewData); |
19208 | } |
19209 | |
19210 | OMPClause *Sema::ActOnOpenMPAffinityClause( |
19211 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, |
19212 | SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { |
19213 | SmallVector<Expr *, 8> Vars; |
19214 | for (Expr *RefExpr : Locators) { |
19215 | assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\"" , "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp" , 19215, __PRETTY_FUNCTION__)); |
19216 | if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { |
19217 | // It will be analyzed later. |
19218 | Vars.push_back(RefExpr); |
19219 | continue; |
19220 | } |
19221 | |
19222 | SourceLocation ELoc = RefExpr->getExprLoc(); |
19223 | Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); |
19224 | |
19225 | if (!SimpleExpr->isLValue()) { |
19226 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) |
19227 | << 1 << 0 << RefExpr->getSourceRange(); |
19228 | continue; |
19229 | } |
19230 | |
19231 | ExprResult Res; |
19232 | { |
19233 | Sema::TentativeAnalysisScope Trap(*this); |
19234 | Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); |
19235 | } |
19236 | if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && |
19237 | !isa<OMPArrayShapingExpr>(SimpleExpr)) { |
19238 | Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) |
19239 | << 1 << 0 << RefExpr->getSourceRange(); |
19240 | continue; |
19241 | } |
19242 | Vars.push_back(SimpleExpr); |
19243 | } |
19244 | |
19245 | return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, |
19246 | EndLoc, Modifier, Vars); |
19247 | } |