Bug Summary

File:clang/lib/Sema/SemaOpenMP.cpp
Warning:line 4335, column 5
Value stored to 'ErrorFound' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-09-17-195756-12974-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp
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
41using namespace clang;
42using namespace llvm::omp;
43
44//===----------------------------------------------------------------------===//
45// Stack of data-sharing attributes for variables
46//===----------------------------------------------------------------------===//
47
48static const Expr *checkMapClauseExpressionBase(
49 Sema &SemaRef, Expr *E,
50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
51 OpenMPClauseKind CKind, bool NoDiagnose);
52
53namespace {
54/// Default data sharing attributes, which can be applied to directive.
55enum 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.
64class DSAStackTy {
65public:
66 struct DSAVarData {
67 OpenMPDirectiveKind DKind = OMPD_unknown;
68 OpenMPClauseKind CKind = OMPC_unknown;
69 unsigned Modifier = 0;
70 const Expr *RefExpr = nullptr;
71 DeclRefExpr *PrivateCopy = nullptr;
72 SourceLocation ImplicitDSALoc;
73 bool AppliedToPointee = false;
74 DSAVarData() = default;
75 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
76 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
77 SourceLocation ImplicitDSALoc, unsigned Modifier,
78 bool AppliedToPointee)
79 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
80 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
81 AppliedToPointee(AppliedToPointee) {}
82 };
83 using OperatorOffsetTy =
84 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
85 using DoacrossDependMapTy =
86 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
87 /// Kind of the declaration used in the uses_allocators clauses.
88 enum class UsesAllocatorsDeclKind {
89 /// Predefined allocator
90 PredefinedAllocator,
91 /// User-defined allocator
92 UserDefinedAllocator,
93 /// The declaration that represent allocator trait
94 AllocatorTrait,
95 };
96
97private:
98 struct DSAInfo {
99 OpenMPClauseKind Attributes = OMPC_unknown;
100 unsigned Modifier = 0;
101 /// Pointer to a reference expression and a flag which shows that the
102 /// variable is marked as lastprivate(true) or not (false).
103 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
104 DeclRefExpr *PrivateCopy = nullptr;
105 /// true if the attribute is applied to the pointee, not the variable
106 /// itself.
107 bool AppliedToPointee = false;
108 };
109 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
110 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
111 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
112 using LoopControlVariablesMapTy =
113 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
114 /// Struct that associates a component with the clause kind where they are
115 /// found.
116 struct MappedExprComponentTy {
117 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
118 OpenMPClauseKind Kind = OMPC_unknown;
119 };
120 using MappedExprComponentsTy =
121 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
122 using CriticalsWithHintsTy =
123 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
124 struct ReductionData {
125 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
126 SourceRange ReductionRange;
127 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
128 ReductionData() = default;
129 void set(BinaryOperatorKind BO, SourceRange RR) {
130 ReductionRange = RR;
131 ReductionOp = BO;
132 }
133 void set(const Expr *RefExpr, SourceRange RR) {
134 ReductionRange = RR;
135 ReductionOp = RefExpr;
136 }
137 };
138 using DeclReductionMapTy =
139 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
140 struct DefaultmapInfo {
141 OpenMPDefaultmapClauseModifier ImplicitBehavior =
142 OMPC_DEFAULTMAP_MODIFIER_unknown;
143 SourceLocation SLoc;
144 DefaultmapInfo() = default;
145 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
146 : ImplicitBehavior(M), SLoc(Loc) {}
147 };
148
149 struct SharingMapTy {
150 DeclSAMapTy SharingMap;
151 DeclReductionMapTy ReductionMap;
152 UsedRefMapTy AlignedMap;
153 UsedRefMapTy NontemporalMap;
154 MappedExprComponentsTy MappedExprComponents;
155 LoopControlVariablesMapTy LCVMap;
156 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
157 SourceLocation DefaultAttrLoc;
158 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
159 OpenMPDirectiveKind Directive = OMPD_unknown;
160 DeclarationNameInfo DirectiveName;
161 Scope *CurScope = nullptr;
162 SourceLocation ConstructLoc;
163 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
164 /// get the data (loop counters etc.) about enclosing loop-based construct.
165 /// This data is required during codegen.
166 DoacrossDependMapTy DoacrossDepends;
167 /// First argument (Expr *) contains optional argument of the
168 /// 'ordered' clause, the second one is true if the regions has 'ordered'
169 /// clause, false otherwise.
170 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
171 unsigned AssociatedLoops = 1;
172 bool HasMutipleLoops = false;
173 const Decl *PossiblyLoopCounter = nullptr;
174 bool NowaitRegion = false;
175 bool CancelRegion = false;
176 bool LoopStart = false;
177 bool BodyComplete = false;
178 SourceLocation PrevScanLocation;
179 SourceLocation PrevOrderedLocation;
180 SourceLocation InnerTeamsRegionLoc;
181 /// Reference to the taskgroup task_reduction reference expression.
182 Expr *TaskgroupReductionRef = nullptr;
183 llvm::DenseSet<QualType> MappedClassesQualTypes;
184 SmallVector<Expr *, 4> InnerUsedAllocators;
185 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
186 /// List of globals marked as declare target link in this target region
187 /// (isOpenMPTargetExecutionDirective(Directive) == true).
188 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
189 /// List of decls used in inclusive/exclusive clauses of the scan directive.
190 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
191 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
192 UsesAllocatorsDecls;
193 Expr *DeclareMapperVar = nullptr;
194 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
195 Scope *CurScope, SourceLocation Loc)
196 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
197 ConstructLoc(Loc) {}
198 SharingMapTy() = default;
199 };
200
201 using StackTy = SmallVector<SharingMapTy, 4>;
202
203 /// Stack of used declaration and their data-sharing attributes.
204 DeclSAMapTy Threadprivates;
205 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
206 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
207 /// true, if check for DSA must be from parent directive, false, if
208 /// from current directive.
209 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
210 Sema &SemaRef;
211 bool ForceCapturing = false;
212 /// true if all the variables in the target executable directives must be
213 /// captured by reference.
214 bool ForceCaptureByReferenceInTargetExecutable = false;
215 CriticalsWithHintsTy Criticals;
216 unsigned IgnoredStackElements = 0;
217
218 /// Iterators over the stack iterate in order from innermost to outermost
219 /// directive.
220 using const_iterator = StackTy::const_reverse_iterator;
221 const_iterator begin() const {
222 return Stack.empty() ? const_iterator()
223 : Stack.back().first.rbegin() + IgnoredStackElements;
224 }
225 const_iterator end() const {
226 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
227 }
228 using iterator = StackTy::reverse_iterator;
229 iterator begin() {
230 return Stack.empty() ? iterator()
231 : Stack.back().first.rbegin() + IgnoredStackElements;
232 }
233 iterator end() {
234 return Stack.empty() ? iterator() : Stack.back().first.rend();
235 }
236
237 // Convenience operations to get at the elements of the stack.
238
239 bool isStackEmpty() const {
240 return Stack.empty() ||
241 Stack.back().second != CurrentNonCapturingFunctionScope ||
242 Stack.back().first.size() <= IgnoredStackElements;
243 }
244 size_t getStackSize() const {
245 return isStackEmpty() ? 0
246 : Stack.back().first.size() - IgnoredStackElements;
247 }
248
249 SharingMapTy *getTopOfStackOrNull() {
250 size_t Size = getStackSize();
251 if (Size == 0)
252 return nullptr;
253 return &Stack.back().first[Size - 1];
254 }
255 const SharingMapTy *getTopOfStackOrNull() const {
256 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
257 }
258 SharingMapTy &getTopOfStack() {
259 assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 259, __PRETTY_FUNCTION__))
;
260 return *getTopOfStackOrNull();
261 }
262 const SharingMapTy &getTopOfStack() const {
263 return const_cast<DSAStackTy&>(*this).getTopOfStack();
264 }
265
266 SharingMapTy *getSecondOnStackOrNull() {
267 size_t Size = getStackSize();
268 if (Size <= 1)
269 return nullptr;
270 return &Stack.back().first[Size - 2];
271 }
272 const SharingMapTy *getSecondOnStackOrNull() const {
273 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
274 }
275
276 /// Get the stack element at a certain level (previously returned by
277 /// \c getNestingLevel).
278 ///
279 /// Note that nesting levels count from outermost to innermost, and this is
280 /// the reverse of our iteration order where new inner levels are pushed at
281 /// the front of the stack.
282 SharingMapTy &getStackElemAtLevel(unsigned Level) {
283 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 283, __PRETTY_FUNCTION__))
;
284 return Stack.back().first[Level];
285 }
286 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
287 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
288 }
289
290 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
291
292 /// Checks if the variable is a local for OpenMP region.
293 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
294
295 /// Vector of previously declared requires directives
296 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
297 /// omp_allocator_handle_t type.
298 QualType OMPAllocatorHandleT;
299 /// omp_depend_t type.
300 QualType OMPDependT;
301 /// omp_event_handle_t type.
302 QualType OMPEventHandleT;
303 /// omp_alloctrait_t type.
304 QualType OMPAlloctraitT;
305 /// Expression for the predefined allocators.
306 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
307 nullptr};
308 /// Vector of previously encountered target directives
309 SmallVector<SourceLocation, 2> TargetLocations;
310 SourceLocation AtomicLocation;
311
312public:
313 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
314
315 /// Sets omp_allocator_handle_t type.
316 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
317 /// Gets omp_allocator_handle_t type.
318 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
319 /// Sets omp_alloctrait_t type.
320 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
321 /// Gets omp_alloctrait_t type.
322 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
323 /// Sets the given default allocator.
324 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
325 Expr *Allocator) {
326 OMPPredefinedAllocators[AllocatorKind] = Allocator;
327 }
328 /// Returns the specified default allocator.
329 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
330 return OMPPredefinedAllocators[AllocatorKind];
331 }
332 /// Sets omp_depend_t type.
333 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
334 /// Gets omp_depend_t type.
335 QualType getOMPDependT() const { return OMPDependT; }
336
337 /// Sets omp_event_handle_t type.
338 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
339 /// Gets omp_event_handle_t type.
340 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
341
342 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
343 OpenMPClauseKind getClauseParsingMode() const {
344 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 344, __PRETTY_FUNCTION__))
;
345 return ClauseKindMode;
346 }
347 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
348
349 bool isBodyComplete() const {
350 const SharingMapTy *Top = getTopOfStackOrNull();
351 return Top && Top->BodyComplete;
352 }
353 void setBodyComplete() {
354 getTopOfStack().BodyComplete = true;
355 }
356
357 bool isForceVarCapturing() const { return ForceCapturing; }
358 void setForceVarCapturing(bool V) { ForceCapturing = V; }
359
360 void setForceCaptureByReferenceInTargetExecutable(bool V) {
361 ForceCaptureByReferenceInTargetExecutable = V;
362 }
363 bool isForceCaptureByReferenceInTargetExecutable() const {
364 return ForceCaptureByReferenceInTargetExecutable;
365 }
366
367 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
368 Scope *CurScope, SourceLocation Loc) {
369 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 370, __PRETTY_FUNCTION__))
370 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 370, __PRETTY_FUNCTION__))
;
371 if (Stack.empty() ||
372 Stack.back().second != CurrentNonCapturingFunctionScope)
373 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
374 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
375 Stack.back().first.back().DefaultAttrLoc = Loc;
376 }
377
378 void pop() {
379 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 380, __PRETTY_FUNCTION__))
380 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 380, __PRETTY_FUNCTION__))
;
381 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 382, __PRETTY_FUNCTION__))
382 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 382, __PRETTY_FUNCTION__))
;
383 Stack.back().first.pop_back();
384 }
385
386 /// RAII object to temporarily leave the scope of a directive when we want to
387 /// logically operate in its parent.
388 class ParentDirectiveScope {
389 DSAStackTy &Self;
390 bool Active;
391 public:
392 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
393 : Self(Self), Active(false) {
394 if (Activate)
395 enable();
396 }
397 ~ParentDirectiveScope() { disable(); }
398 void disable() {
399 if (Active) {
400 --Self.IgnoredStackElements;
401 Active = false;
402 }
403 }
404 void enable() {
405 if (!Active) {
406 ++Self.IgnoredStackElements;
407 Active = true;
408 }
409 }
410 };
411
412 /// Marks that we're started loop parsing.
413 void loopInit() {
414 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 415, __PRETTY_FUNCTION__))
415 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 415, __PRETTY_FUNCTION__))
;
416 getTopOfStack().LoopStart = true;
417 }
418 /// Start capturing of the variables in the loop context.
419 void loopStart() {
420 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 421, __PRETTY_FUNCTION__))
421 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 421, __PRETTY_FUNCTION__))
;
422 getTopOfStack().LoopStart = false;
423 }
424 /// true, if variables are captured, false otherwise.
425 bool isLoopStarted() const {
426 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 427, __PRETTY_FUNCTION__))
427 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 427, __PRETTY_FUNCTION__))
;
428 return !getTopOfStack().LoopStart;
429 }
430 /// Marks (or clears) declaration as possibly loop counter.
431 void resetPossibleLoopCounter(const Decl *D = nullptr) {
432 getTopOfStack().PossiblyLoopCounter =
433 D ? D->getCanonicalDecl() : D;
434 }
435 /// Gets the possible loop counter decl.
436 const Decl *getPossiblyLoopCunter() const {
437 return getTopOfStack().PossiblyLoopCounter;
438 }
439 /// Start new OpenMP region stack in new non-capturing function.
440 void pushFunction() {
441 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 442, __PRETTY_FUNCTION__))
442 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 442, __PRETTY_FUNCTION__))
;
443 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
444 assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast<
void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 444, __PRETTY_FUNCTION__))
;
445 CurrentNonCapturingFunctionScope = CurFnScope;
446 }
447 /// Pop region stack for non-capturing function.
448 void popFunction(const FunctionScopeInfo *OldFSI) {
449 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 450, __PRETTY_FUNCTION__))
450 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 450, __PRETTY_FUNCTION__))
;
451 if (!Stack.empty() && Stack.back().second == OldFSI) {
452 assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) :
__assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 452, __PRETTY_FUNCTION__))
;
453 Stack.pop_back();
454 }
455 CurrentNonCapturingFunctionScope = nullptr;
456 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
457 if (!isa<CapturingScopeInfo>(FSI)) {
458 CurrentNonCapturingFunctionScope = FSI;
459 break;
460 }
461 }
462 }
463
464 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
465 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
466 }
467 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
468 getCriticalWithHint(const DeclarationNameInfo &Name) const {
469 auto I = Criticals.find(Name.getAsString());
470 if (I != Criticals.end())
471 return I->second;
472 return std::make_pair(nullptr, llvm::APSInt());
473 }
474 /// If 'aligned' declaration for given variable \a D was not seen yet,
475 /// add it and return NULL; otherwise return previous occurrence's expression
476 /// for diagnostics.
477 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
478 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
479 /// add it and return NULL; otherwise return previous occurrence's expression
480 /// for diagnostics.
481 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
482
483 /// Register specified variable as loop control variable.
484 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
485 /// Check if the specified variable is a loop control variable for
486 /// current region.
487 /// \return The index of the loop control variable in the list of associated
488 /// for-loops (from outer to inner).
489 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
490 /// Check if the specified variable is a loop control variable for
491 /// parent region.
492 /// \return The index of the loop control variable in the list of associated
493 /// for-loops (from outer to inner).
494 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
495 /// Check if the specified variable is a loop control variable for
496 /// current region.
497 /// \return The index of the loop control variable in the list of associated
498 /// for-loops (from outer to inner).
499 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
500 unsigned Level) const;
501 /// Get the loop control variable for the I-th loop (or nullptr) in
502 /// parent directive.
503 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
504
505 /// Marks the specified decl \p D as used in scan directive.
506 void markDeclAsUsedInScanDirective(ValueDecl *D) {
507 if (SharingMapTy *Stack = getSecondOnStackOrNull())
508 Stack->UsedInScanDirective.insert(D);
509 }
510
511 /// Checks if the specified declaration was used in the inner scan directive.
512 bool isUsedInScanDirective(ValueDecl *D) const {
513 if (const SharingMapTy *Stack = getTopOfStackOrNull())
514 return Stack->UsedInScanDirective.count(D) > 0;
515 return false;
516 }
517
518 /// Adds explicit data sharing attribute to the specified declaration.
519 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
520 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
521 bool AppliedToPointee = false);
522
523 /// Adds additional information for the reduction items with the reduction id
524 /// represented as an operator.
525 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
526 BinaryOperatorKind BOK);
527 /// Adds additional information for the reduction items with the reduction id
528 /// represented as reduction identifier.
529 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
530 const Expr *ReductionRef);
531 /// Returns the location and reduction operation from the innermost parent
532 /// region for the given \p D.
533 const DSAVarData
534 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
535 BinaryOperatorKind &BOK,
536 Expr *&TaskgroupDescriptor) const;
537 /// Returns the location and reduction operation from the innermost parent
538 /// region for the given \p D.
539 const DSAVarData
540 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
541 const Expr *&ReductionRef,
542 Expr *&TaskgroupDescriptor) const;
543 /// Return reduction reference expression for the current taskgroup or
544 /// parallel/worksharing directives with task reductions.
545 Expr *getTaskgroupReductionRef() const {
546 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 551, __PRETTY_FUNCTION__))
547 ((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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 551, __PRETTY_FUNCTION__))
548 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 551, __PRETTY_FUNCTION__))
549 !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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 551, __PRETTY_FUNCTION__))
550 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 551, __PRETTY_FUNCTION__))
551 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 551, __PRETTY_FUNCTION__))
;
552 return getTopOfStack().TaskgroupReductionRef;
553 }
554 /// Checks if the given \p VD declaration is actually a taskgroup reduction
555 /// descriptor variable at the \p Level of OpenMP regions.
556 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
557 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
558 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
559 ->getDecl() == VD;
560 }
561
562 /// Returns data sharing attributes from top of the stack for the
563 /// specified declaration.
564 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
565 /// Returns data-sharing attributes for the specified declaration.
566 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
567 /// Returns data-sharing attributes for the specified declaration.
568 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
569 /// Checks if the specified variables has data-sharing attributes which
570 /// match specified \a CPred predicate in any directive which matches \a DPred
571 /// predicate.
572 const DSAVarData
573 hasDSA(ValueDecl *D,
574 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
575 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
576 bool FromParent) const;
577 /// Checks if the specified variables has data-sharing attributes which
578 /// match specified \a CPred predicate in any innermost directive which
579 /// matches \a DPred predicate.
580 const DSAVarData
581 hasInnermostDSA(ValueDecl *D,
582 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
583 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
584 bool FromParent) const;
585 /// Checks if the specified variables has explicit data-sharing
586 /// attributes which match specified \a CPred predicate at the specified
587 /// OpenMP region.
588 bool
589 hasExplicitDSA(const ValueDecl *D,
590 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
591 unsigned Level, bool NotLastprivate = false) const;
592
593 /// Returns true if the directive at level \Level matches in the
594 /// specified \a DPred predicate.
595 bool hasExplicitDirective(
596 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
597 unsigned Level) const;
598
599 /// Finds a directive which matches specified \a DPred predicate.
600 bool hasDirective(
601 const llvm::function_ref<bool(
602 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
603 DPred,
604 bool FromParent) const;
605
606 /// Returns currently analyzed directive.
607 OpenMPDirectiveKind getCurrentDirective() const {
608 const SharingMapTy *Top = getTopOfStackOrNull();
609 return Top ? Top->Directive : OMPD_unknown;
610 }
611 /// Returns directive kind at specified level.
612 OpenMPDirectiveKind getDirective(unsigned Level) const {
613 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 613, __PRETTY_FUNCTION__))
;
614 return getStackElemAtLevel(Level).Directive;
615 }
616 /// Returns the capture region at the specified level.
617 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
618 unsigned OpenMPCaptureLevel) const {
619 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
620 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
621 return CaptureRegions[OpenMPCaptureLevel];
622 }
623 /// Returns parent directive.
624 OpenMPDirectiveKind getParentDirective() const {
625 const SharingMapTy *Parent = getSecondOnStackOrNull();
626 return Parent ? Parent->Directive : OMPD_unknown;
627 }
628
629 /// Add requires decl to internal vector
630 void addRequiresDecl(OMPRequiresDecl *RD) {
631 RequiresDecls.push_back(RD);
632 }
633
634 /// Checks if the defined 'requires' directive has specified type of clause.
635 template <typename ClauseType>
636 bool hasRequiresDeclWithClause() const {
637 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
638 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
639 return isa<ClauseType>(C);
640 });
641 });
642 }
643
644 /// Checks for a duplicate clause amongst previously declared requires
645 /// directives
646 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
647 bool IsDuplicate = false;
648 for (OMPClause *CNew : ClauseList) {
649 for (const OMPRequiresDecl *D : RequiresDecls) {
650 for (const OMPClause *CPrev : D->clauselists()) {
651 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
652 SemaRef.Diag(CNew->getBeginLoc(),
653 diag::err_omp_requires_clause_redeclaration)
654 << getOpenMPClauseName(CNew->getClauseKind());
655 SemaRef.Diag(CPrev->getBeginLoc(),
656 diag::note_omp_requires_previous_clause)
657 << getOpenMPClauseName(CPrev->getClauseKind());
658 IsDuplicate = true;
659 }
660 }
661 }
662 }
663 return IsDuplicate;
664 }
665
666 /// Add location of previously encountered target to internal vector
667 void addTargetDirLocation(SourceLocation LocStart) {
668 TargetLocations.push_back(LocStart);
669 }
670
671 /// Add location for the first encountered atomicc directive.
672 void addAtomicDirectiveLoc(SourceLocation Loc) {
673 if (AtomicLocation.isInvalid())
674 AtomicLocation = Loc;
675 }
676
677 /// Returns the location of the first encountered atomic directive in the
678 /// module.
679 SourceLocation getAtomicDirectiveLoc() const {
680 return AtomicLocation;
681 }
682
683 // Return previously encountered target region locations.
684 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
685 return TargetLocations;
686 }
687
688 /// Set default data sharing attribute to none.
689 void setDefaultDSANone(SourceLocation Loc) {
690 getTopOfStack().DefaultAttr = DSA_none;
691 getTopOfStack().DefaultAttrLoc = Loc;
692 }
693 /// Set default data sharing attribute to shared.
694 void setDefaultDSAShared(SourceLocation Loc) {
695 getTopOfStack().DefaultAttr = DSA_shared;
696 getTopOfStack().DefaultAttrLoc = Loc;
697 }
698 /// Set default data sharing attribute to firstprivate.
699 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
700 getTopOfStack().DefaultAttr = DSA_firstprivate;
701 getTopOfStack().DefaultAttrLoc = Loc;
702 }
703 /// Set default data mapping attribute to Modifier:Kind
704 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
705 OpenMPDefaultmapClauseKind Kind,
706 SourceLocation Loc) {
707 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
708 DMI.ImplicitBehavior = M;
709 DMI.SLoc = Loc;
710 }
711 /// Check whether the implicit-behavior has been set in defaultmap
712 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
713 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
714 return getTopOfStack()
715 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
716 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
717 getTopOfStack()
718 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
719 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
720 getTopOfStack()
721 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
722 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
723 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
724 OMPC_DEFAULTMAP_MODIFIER_unknown;
725 }
726
727 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
728 return getStackSize() <= Level ? DSA_unspecified
729 : getStackElemAtLevel(Level).DefaultAttr;
730 }
731 DefaultDataSharingAttributes getDefaultDSA() const {
732 return isStackEmpty() ? DSA_unspecified
733 : getTopOfStack().DefaultAttr;
734 }
735 SourceLocation getDefaultDSALocation() const {
736 return isStackEmpty() ? SourceLocation()
737 : getTopOfStack().DefaultAttrLoc;
738 }
739 OpenMPDefaultmapClauseModifier
740 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
741 return isStackEmpty()
742 ? OMPC_DEFAULTMAP_MODIFIER_unknown
743 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
744 }
745 OpenMPDefaultmapClauseModifier
746 getDefaultmapModifierAtLevel(unsigned Level,
747 OpenMPDefaultmapClauseKind Kind) const {
748 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
749 }
750 bool isDefaultmapCapturedByRef(unsigned Level,
751 OpenMPDefaultmapClauseKind Kind) const {
752 OpenMPDefaultmapClauseModifier M =
753 getDefaultmapModifierAtLevel(Level, Kind);
754 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
755 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
756 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
757 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
759 }
760 return true;
761 }
762 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
763 OpenMPDefaultmapClauseKind Kind) {
764 switch (Kind) {
765 case OMPC_DEFAULTMAP_scalar:
766 case OMPC_DEFAULTMAP_pointer:
767 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
768 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
769 (M == OMPC_DEFAULTMAP_MODIFIER_default);
770 case OMPC_DEFAULTMAP_aggregate:
771 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
772 default:
773 break;
774 }
775 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 775)
;
776 }
777 bool mustBeFirstprivateAtLevel(unsigned Level,
778 OpenMPDefaultmapClauseKind Kind) const {
779 OpenMPDefaultmapClauseModifier M =
780 getDefaultmapModifierAtLevel(Level, Kind);
781 return mustBeFirstprivateBase(M, Kind);
782 }
783 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
784 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
785 return mustBeFirstprivateBase(M, Kind);
786 }
787
788 /// Checks if the specified variable is a threadprivate.
789 bool isThreadPrivate(VarDecl *D) {
790 const DSAVarData DVar = getTopDSA(D, false);
791 return isOpenMPThreadPrivate(DVar.CKind);
792 }
793
794 /// Marks current region as ordered (it has an 'ordered' clause).
795 void setOrderedRegion(bool IsOrdered, const Expr *Param,
796 OMPOrderedClause *Clause) {
797 if (IsOrdered)
798 getTopOfStack().OrderedRegion.emplace(Param, Clause);
799 else
800 getTopOfStack().OrderedRegion.reset();
801 }
802 /// Returns true, if region is ordered (has associated 'ordered' clause),
803 /// false - otherwise.
804 bool isOrderedRegion() const {
805 if (const SharingMapTy *Top = getTopOfStackOrNull())
806 return Top->OrderedRegion.hasValue();
807 return false;
808 }
809 /// Returns optional parameter for the ordered region.
810 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
811 if (const SharingMapTy *Top = getTopOfStackOrNull())
812 if (Top->OrderedRegion.hasValue())
813 return Top->OrderedRegion.getValue();
814 return std::make_pair(nullptr, nullptr);
815 }
816 /// Returns true, if parent region is ordered (has associated
817 /// 'ordered' clause), false - otherwise.
818 bool isParentOrderedRegion() const {
819 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
820 return Parent->OrderedRegion.hasValue();
821 return false;
822 }
823 /// Returns optional parameter for the ordered region.
824 std::pair<const Expr *, OMPOrderedClause *>
825 getParentOrderedRegionParam() const {
826 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
827 if (Parent->OrderedRegion.hasValue())
828 return Parent->OrderedRegion.getValue();
829 return std::make_pair(nullptr, nullptr);
830 }
831 /// Marks current region as nowait (it has a 'nowait' clause).
832 void setNowaitRegion(bool IsNowait = true) {
833 getTopOfStack().NowaitRegion = IsNowait;
834 }
835 /// Returns true, if parent region is nowait (has associated
836 /// 'nowait' clause), false - otherwise.
837 bool isParentNowaitRegion() const {
838 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
839 return Parent->NowaitRegion;
840 return false;
841 }
842 /// Marks parent region as cancel region.
843 void setParentCancelRegion(bool Cancel = true) {
844 if (SharingMapTy *Parent = getSecondOnStackOrNull())
845 Parent->CancelRegion |= Cancel;
846 }
847 /// Return true if current region has inner cancel construct.
848 bool isCancelRegion() const {
849 const SharingMapTy *Top = getTopOfStackOrNull();
850 return Top ? Top->CancelRegion : false;
851 }
852
853 /// Mark that parent region already has scan directive.
854 void setParentHasScanDirective(SourceLocation Loc) {
855 if (SharingMapTy *Parent = getSecondOnStackOrNull())
856 Parent->PrevScanLocation = Loc;
857 }
858 /// Return true if current region has inner cancel construct.
859 bool doesParentHasScanDirective() const {
860 const SharingMapTy *Top = getSecondOnStackOrNull();
861 return Top ? Top->PrevScanLocation.isValid() : false;
862 }
863 /// Return true if current region has inner cancel construct.
864 SourceLocation getParentScanDirectiveLoc() const {
865 const SharingMapTy *Top = getSecondOnStackOrNull();
866 return Top ? Top->PrevScanLocation : SourceLocation();
867 }
868 /// Mark that parent region already has ordered directive.
869 void setParentHasOrderedDirective(SourceLocation Loc) {
870 if (SharingMapTy *Parent = getSecondOnStackOrNull())
871 Parent->PrevOrderedLocation = Loc;
872 }
873 /// Return true if current region has inner ordered construct.
874 bool doesParentHasOrderedDirective() const {
875 const SharingMapTy *Top = getSecondOnStackOrNull();
876 return Top ? Top->PrevOrderedLocation.isValid() : false;
877 }
878 /// Returns the location of the previously specified ordered directive.
879 SourceLocation getParentOrderedDirectiveLoc() const {
880 const SharingMapTy *Top = getSecondOnStackOrNull();
881 return Top ? Top->PrevOrderedLocation : SourceLocation();
882 }
883
884 /// Set collapse value for the region.
885 void setAssociatedLoops(unsigned Val) {
886 getTopOfStack().AssociatedLoops = Val;
887 if (Val > 1)
888 getTopOfStack().HasMutipleLoops = true;
889 }
890 /// Return collapse value for region.
891 unsigned getAssociatedLoops() const {
892 const SharingMapTy *Top = getTopOfStackOrNull();
893 return Top ? Top->AssociatedLoops : 0;
894 }
895 /// Returns true if the construct is associated with multiple loops.
896 bool hasMutipleLoops() const {
897 const SharingMapTy *Top = getTopOfStackOrNull();
898 return Top ? Top->HasMutipleLoops : false;
899 }
900
901 /// Marks current target region as one with closely nested teams
902 /// region.
903 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
904 if (SharingMapTy *Parent = getSecondOnStackOrNull())
905 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
906 }
907 /// Returns true, if current region has closely nested teams region.
908 bool hasInnerTeamsRegion() const {
909 return getInnerTeamsRegionLoc().isValid();
910 }
911 /// Returns location of the nested teams region (if any).
912 SourceLocation getInnerTeamsRegionLoc() const {
913 const SharingMapTy *Top = getTopOfStackOrNull();
914 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
915 }
916
917 Scope *getCurScope() const {
918 const SharingMapTy *Top = getTopOfStackOrNull();
919 return Top ? Top->CurScope : nullptr;
920 }
921 SourceLocation getConstructLoc() const {
922 const SharingMapTy *Top = getTopOfStackOrNull();
923 return Top ? Top->ConstructLoc : SourceLocation();
924 }
925
926 /// Do the check specified in \a Check to all component lists and return true
927 /// if any issue is found.
928 bool checkMappableExprComponentListsForDecl(
929 const ValueDecl *VD, bool CurrentRegionOnly,
930 const llvm::function_ref<
931 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
932 OpenMPClauseKind)>
933 Check) const {
934 if (isStackEmpty())
935 return false;
936 auto SI = begin();
937 auto SE = end();
938
939 if (SI == SE)
940 return false;
941
942 if (CurrentRegionOnly)
943 SE = std::next(SI);
944 else
945 std::advance(SI, 1);
946
947 for (; SI != SE; ++SI) {
948 auto MI = SI->MappedExprComponents.find(VD);
949 if (MI != SI->MappedExprComponents.end())
950 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
951 MI->second.Components)
952 if (Check(L, MI->second.Kind))
953 return true;
954 }
955 return false;
956 }
957
958 /// Do the check specified in \a Check to all component lists at a given level
959 /// and return true if any issue is found.
960 bool checkMappableExprComponentListsForDeclAtLevel(
961 const ValueDecl *VD, unsigned Level,
962 const llvm::function_ref<
963 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
964 OpenMPClauseKind)>
965 Check) const {
966 if (getStackSize() <= Level)
967 return false;
968
969 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
970 auto MI = StackElem.MappedExprComponents.find(VD);
971 if (MI != StackElem.MappedExprComponents.end())
972 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
973 MI->second.Components)
974 if (Check(L, MI->second.Kind))
975 return true;
976 return false;
977 }
978
979 /// Create a new mappable expression component list associated with a given
980 /// declaration and initialize it with the provided list of components.
981 void addMappableExpressionComponents(
982 const ValueDecl *VD,
983 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
984 OpenMPClauseKind WhereFoundClauseKind) {
985 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
986 // Create new entry and append the new components there.
987 MEC.Components.resize(MEC.Components.size() + 1);
988 MEC.Components.back().append(Components.begin(), Components.end());
989 MEC.Kind = WhereFoundClauseKind;
990 }
991
992 unsigned getNestingLevel() const {
993 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 993, __PRETTY_FUNCTION__))
;
994 return getStackSize() - 1;
995 }
996 void addDoacrossDependClause(OMPDependClause *C,
997 const OperatorOffsetTy &OpsOffs) {
998 SharingMapTy *Parent = getSecondOnStackOrNull();
999 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive
)) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 999, __PRETTY_FUNCTION__))
;
1000 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1001 }
1002 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1003 getDoacrossDependClauses() const {
1004 const SharingMapTy &StackElem = getTopOfStack();
1005 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1006 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1007 return llvm::make_range(Ref.begin(), Ref.end());
1008 }
1009 return llvm::make_range(StackElem.DoacrossDepends.end(),
1010 StackElem.DoacrossDepends.end());
1011 }
1012
1013 // Store types of classes which have been explicitly mapped
1014 void addMappedClassesQualTypes(QualType QT) {
1015 SharingMapTy &StackElem = getTopOfStack();
1016 StackElem.MappedClassesQualTypes.insert(QT);
1017 }
1018
1019 // Return set of mapped classes types
1020 bool isClassPreviouslyMapped(QualType QT) const {
1021 const SharingMapTy &StackElem = getTopOfStack();
1022 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1023 }
1024
1025 /// Adds global declare target to the parent target region.
1026 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1027 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1029, __PRETTY_FUNCTION__))
1028 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1029, __PRETTY_FUNCTION__))
1029 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1029, __PRETTY_FUNCTION__))
;
1030 for (auto &Elem : *this) {
1031 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1032 Elem.DeclareTargetLinkVarDecls.push_back(E);
1033 return;
1034 }
1035 }
1036 }
1037
1038 /// Returns the list of globals with declare target link if current directive
1039 /// is target.
1040 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1041 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1042, __PRETTY_FUNCTION__))
1042 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1042, __PRETTY_FUNCTION__))
;
1043 return getTopOfStack().DeclareTargetLinkVarDecls;
1044 }
1045
1046 /// Adds list of allocators expressions.
1047 void addInnerAllocatorExpr(Expr *E) {
1048 getTopOfStack().InnerUsedAllocators.push_back(E);
1049 }
1050 /// Return list of used allocators.
1051 ArrayRef<Expr *> getInnerAllocators() const {
1052 return getTopOfStack().InnerUsedAllocators;
1053 }
1054 /// Marks the declaration as implicitly firstprivate nin the task-based
1055 /// regions.
1056 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1057 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1058 }
1059 /// Checks if the decl is implicitly firstprivate in the task-based region.
1060 bool isImplicitTaskFirstprivate(Decl *D) const {
1061 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1062 }
1063
1064 /// Marks decl as used in uses_allocators clause as the allocator.
1065 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1066 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1067 }
1068 /// Checks if specified decl is used in uses allocator clause as the
1069 /// allocator.
1070 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1071 const Decl *D) const {
1072 const SharingMapTy &StackElem = getTopOfStack();
1073 auto I = StackElem.UsesAllocatorsDecls.find(D);
1074 if (I == StackElem.UsesAllocatorsDecls.end())
1075 return None;
1076 return I->getSecond();
1077 }
1078 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1079 const SharingMapTy &StackElem = getTopOfStack();
1080 auto I = StackElem.UsesAllocatorsDecls.find(D);
1081 if (I == StackElem.UsesAllocatorsDecls.end())
1082 return None;
1083 return I->getSecond();
1084 }
1085
1086 void addDeclareMapperVarRef(Expr *Ref) {
1087 SharingMapTy &StackElem = getTopOfStack();
1088 StackElem.DeclareMapperVar = Ref;
1089 }
1090 const Expr *getDeclareMapperVarRef() const {
1091 const SharingMapTy *Top = getTopOfStackOrNull();
1092 return Top ? Top->DeclareMapperVar : nullptr;
1093 }
1094};
1095
1096bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1097 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1098}
1099
1100bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1101 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1102 DKind == OMPD_unknown;
1103}
1104
1105} // namespace
1106
1107static const Expr *getExprAsWritten(const Expr *E) {
1108 if (const auto *FE = dyn_cast<FullExpr>(E))
1109 E = FE->getSubExpr();
1110
1111 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1112 E = MTE->getSubExpr();
1113
1114 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1115 E = Binder->getSubExpr();
1116
1117 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1118 E = ICE->getSubExprAsWritten();
1119 return E->IgnoreParens();
1120}
1121
1122static Expr *getExprAsWritten(Expr *E) {
1123 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1124}
1125
1126static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1127 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1128 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1129 D = ME->getMemberDecl();
1130 const auto *VD = dyn_cast<VarDecl>(D);
1131 const auto *FD = dyn_cast<FieldDecl>(D);
1132 if (VD != nullptr) {
1133 VD = VD->getCanonicalDecl();
1134 D = VD;
1135 } else {
1136 assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1136, __PRETTY_FUNCTION__))
;
1137 FD = FD->getCanonicalDecl();
1138 D = FD;
1139 }
1140 return D;
1141}
1142
1143static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1144 return const_cast<ValueDecl *>(
1145 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1146}
1147
1148DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1149 ValueDecl *D) const {
1150 D = getCanonicalDecl(D);
1151 auto *VD = dyn_cast<VarDecl>(D);
1152 const auto *FD = dyn_cast<FieldDecl>(D);
1153 DSAVarData DVar;
1154 if (Iter == end()) {
1155 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1156 // in a region but not in construct]
1157 // File-scope or namespace-scope variables referenced in called routines
1158 // in the region are shared unless they appear in a threadprivate
1159 // directive.
1160 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1161 DVar.CKind = OMPC_shared;
1162
1163 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1164 // in a region but not in construct]
1165 // Variables with static storage duration that are declared in called
1166 // routines in the region are shared.
1167 if (VD && VD->hasGlobalStorage())
1168 DVar.CKind = OMPC_shared;
1169
1170 // Non-static data members are shared by default.
1171 if (FD)
1172 DVar.CKind = OMPC_shared;
1173
1174 return DVar;
1175 }
1176
1177 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1178 // in a Construct, C/C++, predetermined, p.1]
1179 // Variables with automatic storage duration that are declared in a scope
1180 // inside the construct are private.
1181 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1182 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1183 DVar.CKind = OMPC_private;
1184 return DVar;
1185 }
1186
1187 DVar.DKind = Iter->Directive;
1188 // Explicitly specified attributes and local variables with predetermined
1189 // attributes.
1190 if (Iter->SharingMap.count(D)) {
1191 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1192 DVar.RefExpr = Data.RefExpr.getPointer();
1193 DVar.PrivateCopy = Data.PrivateCopy;
1194 DVar.CKind = Data.Attributes;
1195 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1196 DVar.Modifier = Data.Modifier;
1197 DVar.AppliedToPointee = Data.AppliedToPointee;
1198 return DVar;
1199 }
1200
1201 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1202 // in a Construct, C/C++, implicitly determined, p.1]
1203 // In a parallel or task construct, the data-sharing attributes of these
1204 // variables are determined by the default clause, if present.
1205 switch (Iter->DefaultAttr) {
1206 case DSA_shared:
1207 DVar.CKind = OMPC_shared;
1208 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1209 return DVar;
1210 case DSA_none:
1211 return DVar;
1212 case DSA_firstprivate:
1213 if (VD->getStorageDuration() == SD_Static &&
1214 VD->getDeclContext()->isFileContext()) {
1215 DVar.CKind = OMPC_unknown;
1216 } else {
1217 DVar.CKind = OMPC_firstprivate;
1218 }
1219 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1220 return DVar;
1221 case DSA_unspecified:
1222 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1223 // in a Construct, implicitly determined, p.2]
1224 // In a parallel construct, if no default clause is present, these
1225 // variables are shared.
1226 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1227 if ((isOpenMPParallelDirective(DVar.DKind) &&
1228 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1229 isOpenMPTeamsDirective(DVar.DKind)) {
1230 DVar.CKind = OMPC_shared;
1231 return DVar;
1232 }
1233
1234 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1235 // in a Construct, implicitly determined, p.4]
1236 // In a task construct, if no default clause is present, a variable that in
1237 // the enclosing context is determined to be shared by all implicit tasks
1238 // bound to the current team is shared.
1239 if (isOpenMPTaskingDirective(DVar.DKind)) {
1240 DSAVarData DVarTemp;
1241 const_iterator I = Iter, E = end();
1242 do {
1243 ++I;
1244 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1245 // Referenced in a Construct, implicitly determined, p.6]
1246 // In a task construct, if no default clause is present, a variable
1247 // whose data-sharing attribute is not determined by the rules above is
1248 // firstprivate.
1249 DVarTemp = getDSA(I, D);
1250 if (DVarTemp.CKind != OMPC_shared) {
1251 DVar.RefExpr = nullptr;
1252 DVar.CKind = OMPC_firstprivate;
1253 return DVar;
1254 }
1255 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1256 DVar.CKind =
1257 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1258 return DVar;
1259 }
1260 }
1261 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1262 // in a Construct, implicitly determined, p.3]
1263 // For constructs other than task, if no default clause is present, these
1264 // variables inherit their data-sharing attributes from the enclosing
1265 // context.
1266 return getDSA(++Iter, D);
1267}
1268
1269const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1270 const Expr *NewDE) {
1271 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1271, __PRETTY_FUNCTION__))
;
1272 D = getCanonicalDecl(D);
1273 SharingMapTy &StackElem = getTopOfStack();
1274 auto It = StackElem.AlignedMap.find(D);
1275 if (It == StackElem.AlignedMap.end()) {
1276 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1276, __PRETTY_FUNCTION__))
;
1277 StackElem.AlignedMap[D] = NewDE;
1278 return nullptr;
1279 }
1280 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1280, __PRETTY_FUNCTION__))
;
1281 return It->second;
1282}
1283
1284const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1285 const Expr *NewDE) {
1286 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1286, __PRETTY_FUNCTION__))
;
1287 D = getCanonicalDecl(D);
1288 SharingMapTy &StackElem = getTopOfStack();
1289 auto It = StackElem.NontemporalMap.find(D);
1290 if (It == StackElem.NontemporalMap.end()) {
1291 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1291, __PRETTY_FUNCTION__))
;
1292 StackElem.NontemporalMap[D] = NewDE;
1293 return nullptr;
1294 }
1295 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1295, __PRETTY_FUNCTION__))
;
1296 return It->second;
1297}
1298
1299void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1300, __PRETTY_FUNCTION__))
;
1301 D = getCanonicalDecl(D);
1302 SharingMapTy &StackElem = getTopOfStack();
1303 StackElem.LCVMap.try_emplace(
1304 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1305}
1306
1307const DSAStackTy::LCDeclInfo
1308DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1309 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1309, __PRETTY_FUNCTION__))
;
1310 D = getCanonicalDecl(D);
1311 const SharingMapTy &StackElem = getTopOfStack();
1312 auto It = StackElem.LCVMap.find(D);
1313 if (It != StackElem.LCVMap.end())
1314 return It->second;
1315 return {0, nullptr};
1316}
1317
1318const DSAStackTy::LCDeclInfo
1319DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1320 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1320, __PRETTY_FUNCTION__))
;
1321 D = getCanonicalDecl(D);
1322 for (unsigned I = Level + 1; I > 0; --I) {
1323 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1324 auto It = StackElem.LCVMap.find(D);
1325 if (It != StackElem.LCVMap.end())
1326 return It->second;
1327 }
1328 return {0, nullptr};
1329}
1330
1331const DSAStackTy::LCDeclInfo
1332DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1333 const SharingMapTy *Parent = getSecondOnStackOrNull();
1334 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1334, __PRETTY_FUNCTION__))
;
1335 D = getCanonicalDecl(D);
1336 auto It = Parent->LCVMap.find(D);
1337 if (It != Parent->LCVMap.end())
1338 return It->second;
1339 return {0, nullptr};
1340}
1341
1342const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1343 const SharingMapTy *Parent = getSecondOnStackOrNull();
1344 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1344, __PRETTY_FUNCTION__))
;
1345 if (Parent->LCVMap.size() < I)
1346 return nullptr;
1347 for (const auto &Pair : Parent->LCVMap)
1348 if (Pair.second.first == I)
1349 return Pair.first;
1350 return nullptr;
1351}
1352
1353void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1354 DeclRefExpr *PrivateCopy, unsigned Modifier,
1355 bool AppliedToPointee) {
1356 D = getCanonicalDecl(D);
1357 if (A == OMPC_threadprivate) {
1358 DSAInfo &Data = Threadprivates[D];
1359 Data.Attributes = A;
1360 Data.RefExpr.setPointer(E);
1361 Data.PrivateCopy = nullptr;
1362 Data.Modifier = Modifier;
1363 } else {
1364 DSAInfo &Data = getTopOfStack().SharingMap[D];
1365 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1368, __PRETTY_FUNCTION__))
1366 (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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1368, __PRETTY_FUNCTION__))
1367 (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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1368, __PRETTY_FUNCTION__))
1368 (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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1368, __PRETTY_FUNCTION__))
;
1369 Data.Modifier = Modifier;
1370 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1371 Data.RefExpr.setInt(/*IntVal=*/true);
1372 return;
1373 }
1374 const bool IsLastprivate =
1375 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1376 Data.Attributes = A;
1377 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1378 Data.PrivateCopy = PrivateCopy;
1379 Data.AppliedToPointee = AppliedToPointee;
1380 if (PrivateCopy) {
1381 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1382 Data.Modifier = Modifier;
1383 Data.Attributes = A;
1384 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1385 Data.PrivateCopy = nullptr;
1386 Data.AppliedToPointee = AppliedToPointee;
1387 }
1388 }
1389}
1390
1391/// Build a variable declaration for OpenMP loop iteration variable.
1392static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1393 StringRef Name, const AttrVec *Attrs = nullptr,
1394 DeclRefExpr *OrigRef = nullptr) {
1395 DeclContext *DC = SemaRef.CurContext;
1396 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1397 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1398 auto *Decl =
1399 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1400 if (Attrs) {
1401 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1402 I != E; ++I)
1403 Decl->addAttr(*I);
1404 }
1405 Decl->setImplicit();
1406 if (OrigRef) {
1407 Decl->addAttr(
1408 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1409 }
1410 return Decl;
1411}
1412
1413static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1414 SourceLocation Loc,
1415 bool RefersToCapture = false) {
1416 D->setReferenced();
1417 D->markUsed(S.Context);
1418 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1419 SourceLocation(), D, RefersToCapture, Loc, Ty,
1420 VK_LValue);
1421}
1422
1423void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1424 BinaryOperatorKind BOK) {
1425 D = getCanonicalDecl(D);
1426 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1426, __PRETTY_FUNCTION__))
;
1427 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1429, __PRETTY_FUNCTION__))
1428 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1429, __PRETTY_FUNCTION__))
1429 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1429, __PRETTY_FUNCTION__))
;
1430 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1431 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1437, __PRETTY_FUNCTION__))
1432 (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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1437, __PRETTY_FUNCTION__))
1433 ((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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1437, __PRETTY_FUNCTION__))
1434 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1437, __PRETTY_FUNCTION__))
1435 !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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1437, __PRETTY_FUNCTION__))
1436 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1437, __PRETTY_FUNCTION__))
1437 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1437, __PRETTY_FUNCTION__))
;
1438 ReductionData.set(BOK, SR);
1439 Expr *&TaskgroupReductionRef =
1440 getTopOfStack().TaskgroupReductionRef;
1441 if (!TaskgroupReductionRef) {
1442 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1443 SemaRef.Context.VoidPtrTy, ".task_red.");
1444 TaskgroupReductionRef =
1445 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1446 }
1447}
1448
1449void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1450 const Expr *ReductionRef) {
1451 D = getCanonicalDecl(D);
1452 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1452, __PRETTY_FUNCTION__))
;
1453 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1455, __PRETTY_FUNCTION__))
1454 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1455, __PRETTY_FUNCTION__))
1455 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1455, __PRETTY_FUNCTION__))
;
1456 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1457 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1463, __PRETTY_FUNCTION__))
1458 (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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1463, __PRETTY_FUNCTION__))
1459 ((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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1463, __PRETTY_FUNCTION__))
1460 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1463, __PRETTY_FUNCTION__))
1461 !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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1463, __PRETTY_FUNCTION__))
1462 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1463, __PRETTY_FUNCTION__))
1463 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1463, __PRETTY_FUNCTION__))
;
1464 ReductionData.set(ReductionRef, SR);
1465 Expr *&TaskgroupReductionRef =
1466 getTopOfStack().TaskgroupReductionRef;
1467 if (!TaskgroupReductionRef) {
1468 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1469 SemaRef.Context.VoidPtrTy, ".task_red.");
1470 TaskgroupReductionRef =
1471 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1472 }
1473}
1474
1475const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1476 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1477 Expr *&TaskgroupDescriptor) const {
1478 D = getCanonicalDecl(D);
1479 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1479, __PRETTY_FUNCTION__))
;
1480 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1481 const DSAInfo &Data = I->SharingMap.lookup(D);
1482 if (Data.Attributes != OMPC_reduction ||
1483 Data.Modifier != OMPC_REDUCTION_task)
1484 continue;
1485 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1486 if (!ReductionData.ReductionOp ||
1487 ReductionData.ReductionOp.is<const Expr *>())
1488 return DSAVarData();
1489 SR = ReductionData.ReductionRange;
1490 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1491 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1493, __PRETTY_FUNCTION__))
1492 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1493, __PRETTY_FUNCTION__))
1493 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1493, __PRETTY_FUNCTION__))
;
1494 TaskgroupDescriptor = I->TaskgroupReductionRef;
1495 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1496 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1497 /*AppliedToPointee=*/false);
1498 }
1499 return DSAVarData();
1500}
1501
1502const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1503 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1504 Expr *&TaskgroupDescriptor) const {
1505 D = getCanonicalDecl(D);
1506 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1506, __PRETTY_FUNCTION__))
;
1507 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1508 const DSAInfo &Data = I->SharingMap.lookup(D);
1509 if (Data.Attributes != OMPC_reduction ||
1510 Data.Modifier != OMPC_REDUCTION_task)
1511 continue;
1512 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1513 if (!ReductionData.ReductionOp ||
1514 !ReductionData.ReductionOp.is<const Expr *>())
1515 return DSAVarData();
1516 SR = ReductionData.ReductionRange;
1517 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1518 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1520, __PRETTY_FUNCTION__))
1519 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1520, __PRETTY_FUNCTION__))
1520 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1520, __PRETTY_FUNCTION__))
;
1521 TaskgroupDescriptor = I->TaskgroupReductionRef;
1522 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1523 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1524 /*AppliedToPointee=*/false);
1525 }
1526 return DSAVarData();
1527}
1528
1529bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1530 D = D->getCanonicalDecl();
1531 for (const_iterator E = end(); I != E; ++I) {
1532 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1533 isOpenMPTargetExecutionDirective(I->Directive)) {
1534 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1535 Scope *CurScope = getCurScope();
1536 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1537 CurScope = CurScope->getParent();
1538 return CurScope != TopScope;
1539 }
1540 }
1541 return false;
1542}
1543
1544static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1545 bool AcceptIfMutable = true,
1546 bool *IsClassType = nullptr) {
1547 ASTContext &Context = SemaRef.getASTContext();
1548 Type = Type.getNonReferenceType().getCanonicalType();
1549 bool IsConstant = Type.isConstant(Context);
1550 Type = Context.getBaseElementType(Type);
1551 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1552 ? Type->getAsCXXRecordDecl()
1553 : nullptr;
1554 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1555 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1556 RD = CTD->getTemplatedDecl();
1557 if (IsClassType)
1558 *IsClassType = RD;
1559 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1560 RD->hasDefinition() && RD->hasMutableFields());
1561}
1562
1563static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1564 QualType Type, OpenMPClauseKind CKind,
1565 SourceLocation ELoc,
1566 bool AcceptIfMutable = true,
1567 bool ListItemNotVar = false) {
1568 ASTContext &Context = SemaRef.getASTContext();
1569 bool IsClassType;
1570 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1571 unsigned Diag = ListItemNotVar
1572 ? diag::err_omp_const_list_item
1573 : IsClassType ? diag::err_omp_const_not_mutable_variable
1574 : diag::err_omp_const_variable;
1575 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1576 if (!ListItemNotVar && D) {
1577 const VarDecl *VD = dyn_cast<VarDecl>(D);
1578 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1579 VarDecl::DeclarationOnly;
1580 SemaRef.Diag(D->getLocation(),
1581 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1582 << D;
1583 }
1584 return true;
1585 }
1586 return false;
1587}
1588
1589const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1590 bool FromParent) {
1591 D = getCanonicalDecl(D);
1592 DSAVarData DVar;
1593
1594 auto *VD = dyn_cast<VarDecl>(D);
1595 auto TI = Threadprivates.find(D);
1596 if (TI != Threadprivates.end()) {
1597 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1598 DVar.CKind = OMPC_threadprivate;
1599 DVar.Modifier = TI->getSecond().Modifier;
1600 return DVar;
1601 }
1602 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1603 DVar.RefExpr = buildDeclRefExpr(
1604 SemaRef, VD, D->getType().getNonReferenceType(),
1605 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1606 DVar.CKind = OMPC_threadprivate;
1607 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1608 return DVar;
1609 }
1610 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1611 // in a Construct, C/C++, predetermined, p.1]
1612 // Variables appearing in threadprivate directives are threadprivate.
1613 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1614 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1615 SemaRef.getLangOpts().OpenMPUseTLS &&
1616 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1617 (VD && VD->getStorageClass() == SC_Register &&
1618 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1619 DVar.RefExpr = buildDeclRefExpr(
1620 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1621 DVar.CKind = OMPC_threadprivate;
1622 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1623 return DVar;
1624 }
1625 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1626 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1627 !isLoopControlVariable(D).first) {
1628 const_iterator IterTarget =
1629 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1630 return isOpenMPTargetExecutionDirective(Data.Directive);
1631 });
1632 if (IterTarget != end()) {
1633 const_iterator ParentIterTarget = IterTarget + 1;
1634 for (const_iterator Iter = begin();
1635 Iter != ParentIterTarget; ++Iter) {
1636 if (isOpenMPLocal(VD, Iter)) {
1637 DVar.RefExpr =
1638 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1639 D->getLocation());
1640 DVar.CKind = OMPC_threadprivate;
1641 return DVar;
1642 }
1643 }
1644 if (!isClauseParsingMode() || IterTarget != begin()) {
1645 auto DSAIter = IterTarget->SharingMap.find(D);
1646 if (DSAIter != IterTarget->SharingMap.end() &&
1647 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1648 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1649 DVar.CKind = OMPC_threadprivate;
1650 return DVar;
1651 }
1652 const_iterator End = end();
1653 if (!SemaRef.isOpenMPCapturedByRef(
1654 D, std::distance(ParentIterTarget, End),
1655 /*OpenMPCaptureLevel=*/0)) {
1656 DVar.RefExpr =
1657 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1658 IterTarget->ConstructLoc);
1659 DVar.CKind = OMPC_threadprivate;
1660 return DVar;
1661 }
1662 }
1663 }
1664 }
1665
1666 if (isStackEmpty())
1667 // Not in OpenMP execution region and top scope was already checked.
1668 return DVar;
1669
1670 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1671 // in a Construct, C/C++, predetermined, p.4]
1672 // Static data members are shared.
1673 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1674 // in a Construct, C/C++, predetermined, p.7]
1675 // Variables with static storage duration that are declared in a scope
1676 // inside the construct are shared.
1677 if (VD && VD->isStaticDataMember()) {
1678 // Check for explicitly specified attributes.
1679 const_iterator I = begin();
1680 const_iterator EndI = end();
1681 if (FromParent && I != EndI)
1682 ++I;
1683 if (I != EndI) {
1684 auto It = I->SharingMap.find(D);
1685 if (It != I->SharingMap.end()) {
1686 const DSAInfo &Data = It->getSecond();
1687 DVar.RefExpr = Data.RefExpr.getPointer();
1688 DVar.PrivateCopy = Data.PrivateCopy;
1689 DVar.CKind = Data.Attributes;
1690 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1691 DVar.DKind = I->Directive;
1692 DVar.Modifier = Data.Modifier;
1693 DVar.AppliedToPointee = Data.AppliedToPointee;
1694 return DVar;
1695 }
1696 }
1697
1698 DVar.CKind = OMPC_shared;
1699 return DVar;
1700 }
1701
1702 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1703 // The predetermined shared attribute for const-qualified types having no
1704 // mutable members was removed after OpenMP 3.1.
1705 if (SemaRef.LangOpts.OpenMP <= 31) {
1706 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1707 // in a Construct, C/C++, predetermined, p.6]
1708 // Variables with const qualified type having no mutable member are
1709 // shared.
1710 if (isConstNotMutableType(SemaRef, D->getType())) {
1711 // Variables with const-qualified type having no mutable member may be
1712 // listed in a firstprivate clause, even if they are static data members.
1713 DSAVarData DVarTemp = hasInnermostDSA(
1714 D,
1715 [](OpenMPClauseKind C, bool) {
1716 return C == OMPC_firstprivate || C == OMPC_shared;
1717 },
1718 MatchesAlways, FromParent);
1719 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1720 return DVarTemp;
1721
1722 DVar.CKind = OMPC_shared;
1723 return DVar;
1724 }
1725 }
1726
1727 // Explicitly specified attributes and local variables with predetermined
1728 // attributes.
1729 const_iterator I = begin();
1730 const_iterator EndI = end();
1731 if (FromParent && I != EndI)
1732 ++I;
1733 if (I == EndI)
1734 return DVar;
1735 auto It = I->SharingMap.find(D);
1736 if (It != I->SharingMap.end()) {
1737 const DSAInfo &Data = It->getSecond();
1738 DVar.RefExpr = Data.RefExpr.getPointer();
1739 DVar.PrivateCopy = Data.PrivateCopy;
1740 DVar.CKind = Data.Attributes;
1741 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1742 DVar.DKind = I->Directive;
1743 DVar.Modifier = Data.Modifier;
1744 DVar.AppliedToPointee = Data.AppliedToPointee;
1745 }
1746
1747 return DVar;
1748}
1749
1750const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1751 bool FromParent) const {
1752 if (isStackEmpty()) {
1753 const_iterator I;
1754 return getDSA(I, D);
1755 }
1756 D = getCanonicalDecl(D);
1757 const_iterator StartI = begin();
1758 const_iterator EndI = end();
1759 if (FromParent && StartI != EndI)
1760 ++StartI;
1761 return getDSA(StartI, D);
1762}
1763
1764const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1765 unsigned Level) const {
1766 if (getStackSize() <= Level)
1767 return DSAVarData();
1768 D = getCanonicalDecl(D);
1769 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1770 return getDSA(StartI, D);
1771}
1772
1773const DSAStackTy::DSAVarData
1774DSAStackTy::hasDSA(ValueDecl *D,
1775 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1776 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1777 bool FromParent) const {
1778 if (isStackEmpty())
1779 return {};
1780 D = getCanonicalDecl(D);
1781 const_iterator I = begin();
1782 const_iterator EndI = end();
1783 if (FromParent && I != EndI)
1784 ++I;
1785 for (; I != EndI; ++I) {
1786 if (!DPred(I->Directive) &&
1787 !isImplicitOrExplicitTaskingRegion(I->Directive))
1788 continue;
1789 const_iterator NewI = I;
1790 DSAVarData DVar = getDSA(NewI, D);
1791 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1792 return DVar;
1793 }
1794 return {};
1795}
1796
1797const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1798 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1799 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1800 bool FromParent) const {
1801 if (isStackEmpty())
1802 return {};
1803 D = getCanonicalDecl(D);
1804 const_iterator StartI = begin();
1805 const_iterator EndI = end();
1806 if (FromParent && StartI != EndI)
1807 ++StartI;
1808 if (StartI == EndI || !DPred(StartI->Directive))
1809 return {};
1810 const_iterator NewI = StartI;
1811 DSAVarData DVar = getDSA(NewI, D);
1812 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1813 ? DVar
1814 : DSAVarData();
1815}
1816
1817bool DSAStackTy::hasExplicitDSA(
1818 const ValueDecl *D,
1819 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1820 unsigned Level, bool NotLastprivate) const {
1821 if (getStackSize() <= Level)
1822 return false;
1823 D = getCanonicalDecl(D);
1824 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1825 auto I = StackElem.SharingMap.find(D);
1826 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1827 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1828 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1829 return true;
1830 // Check predetermined rules for the loop control variables.
1831 auto LI = StackElem.LCVMap.find(D);
1832 if (LI != StackElem.LCVMap.end())
1833 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1834 return false;
1835}
1836
1837bool DSAStackTy::hasExplicitDirective(
1838 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1839 unsigned Level) const {
1840 if (getStackSize() <= Level)
1841 return false;
1842 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1843 return DPred(StackElem.Directive);
1844}
1845
1846bool DSAStackTy::hasDirective(
1847 const llvm::function_ref<bool(OpenMPDirectiveKind,
1848 const DeclarationNameInfo &, SourceLocation)>
1849 DPred,
1850 bool FromParent) const {
1851 // We look only in the enclosing region.
1852 size_t Skip = FromParent ? 2 : 1;
1853 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1854 I != E; ++I) {
1855 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1856 return true;
1857 }
1858 return false;
1859}
1860
1861void Sema::InitDataSharingAttributesStack() {
1862 VarDataSharingAttributesStack = new DSAStackTy(*this);
1863}
1864
1865#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1866
1867void Sema::pushOpenMPFunctionRegion() {
1868 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1869}
1870
1871void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1872 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1873}
1874
1875static bool isOpenMPDeviceDelayedContext(Sema &S) {
1876 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1877, __PRETTY_FUNCTION__))
1877 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1877, __PRETTY_FUNCTION__))
;
1878 return !S.isInOpenMPTargetExecutionDirective() &&
1879 !S.isInOpenMPDeclareTargetContext();
1880}
1881
1882namespace {
1883/// Status of the function emission on the host/device.
1884enum class FunctionEmissionStatus {
1885 Emitted,
1886 Discarded,
1887 Unknown,
1888};
1889} // anonymous namespace
1890
1891Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1892 unsigned DiagID) {
1893 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1894, __PRETTY_FUNCTION__))
1894 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1894, __PRETTY_FUNCTION__))
;
1895
1896 FunctionDecl *FD = getCurFunctionDecl();
1897 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1898 if (FD) {
1899 FunctionEmissionStatus FES = getEmissionStatus(FD);
1900 switch (FES) {
1901 case FunctionEmissionStatus::Emitted:
1902 Kind = DeviceDiagBuilder::K_Immediate;
1903 break;
1904 case FunctionEmissionStatus::Unknown:
1905 Kind = isOpenMPDeviceDelayedContext(*this)
1906 ? DeviceDiagBuilder::K_Deferred
1907 : DeviceDiagBuilder::K_Immediate;
1908 break;
1909 case FunctionEmissionStatus::TemplateDiscarded:
1910 case FunctionEmissionStatus::OMPDiscarded:
1911 Kind = DeviceDiagBuilder::K_Nop;
1912 break;
1913 case FunctionEmissionStatus::CUDADiscarded:
1914 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1914)
;
1915 break;
1916 }
1917 }
1918
1919 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1920}
1921
1922Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1923 unsigned DiagID) {
1924 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1925, __PRETTY_FUNCTION__))
1925 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1925, __PRETTY_FUNCTION__))
;
1926 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1927 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1928 switch (FES) {
1929 case FunctionEmissionStatus::Emitted:
1930 Kind = DeviceDiagBuilder::K_Immediate;
1931 break;
1932 case FunctionEmissionStatus::Unknown:
1933 Kind = DeviceDiagBuilder::K_Deferred;
1934 break;
1935 case FunctionEmissionStatus::TemplateDiscarded:
1936 case FunctionEmissionStatus::OMPDiscarded:
1937 case FunctionEmissionStatus::CUDADiscarded:
1938 Kind = DeviceDiagBuilder::K_Nop;
1939 break;
1940 }
1941
1942 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1943}
1944
1945static OpenMPDefaultmapClauseKind
1946getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1947 if (LO.OpenMP <= 45) {
1948 if (VD->getType().getNonReferenceType()->isScalarType())
1949 return OMPC_DEFAULTMAP_scalar;
1950 return OMPC_DEFAULTMAP_aggregate;
1951 }
1952 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1953 return OMPC_DEFAULTMAP_pointer;
1954 if (VD->getType().getNonReferenceType()->isScalarType())
1955 return OMPC_DEFAULTMAP_scalar;
1956 return OMPC_DEFAULTMAP_aggregate;
1957}
1958
1959bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1960 unsigned OpenMPCaptureLevel) const {
1961 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 1961, __PRETTY_FUNCTION__))
;
1962
1963 ASTContext &Ctx = getASTContext();
1964 bool IsByRef = true;
1965
1966 // Find the directive that is associated with the provided scope.
1967 D = cast<ValueDecl>(D->getCanonicalDecl());
1968 QualType Ty = D->getType();
1969
1970 bool IsVariableUsedInMapClause = false;
1971 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1972 // This table summarizes how a given variable should be passed to the device
1973 // given its type and the clauses where it appears. This table is based on
1974 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1975 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1976 //
1977 // =========================================================================
1978 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1979 // | |(tofrom:scalar)| | pvt | | | |
1980 // =========================================================================
1981 // | scl | | | | - | | bycopy|
1982 // | scl | | - | x | - | - | bycopy|
1983 // | scl | | x | - | - | - | null |
1984 // | scl | x | | | - | | byref |
1985 // | scl | x | - | x | - | - | bycopy|
1986 // | scl | x | x | - | - | - | null |
1987 // | scl | | - | - | - | x | byref |
1988 // | scl | x | - | - | - | x | byref |
1989 //
1990 // | agg | n.a. | | | - | | byref |
1991 // | agg | n.a. | - | x | - | - | byref |
1992 // | agg | n.a. | x | - | - | - | null |
1993 // | agg | n.a. | - | - | - | x | byref |
1994 // | agg | n.a. | - | - | - | x[] | byref |
1995 //
1996 // | ptr | n.a. | | | - | | bycopy|
1997 // | ptr | n.a. | - | x | - | - | bycopy|
1998 // | ptr | n.a. | x | - | - | - | null |
1999 // | ptr | n.a. | - | - | - | x | byref |
2000 // | ptr | n.a. | - | - | - | x[] | bycopy|
2001 // | ptr | n.a. | - | - | x | | bycopy|
2002 // | ptr | n.a. | - | - | x | x | bycopy|
2003 // | ptr | n.a. | - | - | x | x[] | bycopy|
2004 // =========================================================================
2005 // Legend:
2006 // scl - scalar
2007 // ptr - pointer
2008 // agg - aggregate
2009 // x - applies
2010 // - - invalid in this combination
2011 // [] - mapped with an array section
2012 // byref - should be mapped by reference
2013 // byval - should be mapped by value
2014 // null - initialize a local variable to null on the device
2015 //
2016 // Observations:
2017 // - All scalar declarations that show up in a map clause have to be passed
2018 // by reference, because they may have been mapped in the enclosing data
2019 // environment.
2020 // - If the scalar value does not fit the size of uintptr, it has to be
2021 // passed by reference, regardless the result in the table above.
2022 // - For pointers mapped by value that have either an implicit map or an
2023 // array section, the runtime library may pass the NULL value to the
2024 // device instead of the value passed to it by the compiler.
2025
2026 if (Ty->isReferenceType())
2027 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2028
2029 // Locate map clauses and see if the variable being captured is referred to
2030 // in any of those clauses. Here we only care about variables, not fields,
2031 // because fields are part of aggregates.
2032 bool IsVariableAssociatedWithSection = false;
2033
2034 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2035 D, Level,
2036 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2037 OMPClauseMappableExprCommon::MappableExprComponentListRef
2038 MapExprComponents,
2039 OpenMPClauseKind WhereFoundClauseKind) {
2040 // Only the map clause information influences how a variable is
2041 // captured. E.g. is_device_ptr does not require changing the default
2042 // behavior.
2043 if (WhereFoundClauseKind != OMPC_map)
2044 return false;
2045
2046 auto EI = MapExprComponents.rbegin();
2047 auto EE = MapExprComponents.rend();
2048
2049 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2049, __PRETTY_FUNCTION__))
;
2050
2051 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2052 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2053
2054 ++EI;
2055 if (EI == EE)
2056 return false;
2057
2058 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2059 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2060 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2061 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2062 IsVariableAssociatedWithSection = true;
2063 // There is nothing more we need to know about this variable.
2064 return true;
2065 }
2066
2067 // Keep looking for more map info.
2068 return false;
2069 });
2070
2071 if (IsVariableUsedInMapClause) {
2072 // If variable is identified in a map clause it is always captured by
2073 // reference except if it is a pointer that is dereferenced somehow.
2074 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2075 } else {
2076 // By default, all the data that has a scalar type is mapped by copy
2077 // (except for reduction variables).
2078 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2079 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2080 !Ty->isAnyPointerType()) ||
2081 !Ty->isScalarType() ||
2082 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2083 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2084 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2085 D,
2086 [](OpenMPClauseKind K, bool AppliedToPointee) {
2087 return K == OMPC_reduction && !AppliedToPointee;
2088 },
2089 Level);
2090 }
2091 }
2092
2093 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2094 IsByRef =
2095 ((IsVariableUsedInMapClause &&
2096 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2097 OMPD_target) ||
2098 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2099 D,
2100 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2101 return K == OMPC_firstprivate ||
2102 (K == OMPC_reduction && AppliedToPointee);
2103 },
2104 Level, /*NotLastprivate=*/true) ||
2105 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2106 // If the variable is artificial and must be captured by value - try to
2107 // capture by value.
2108 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2109 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2110 // If the variable is implicitly firstprivate and scalar - capture by
2111 // copy
2112 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2113 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2114 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2115 Level) &&
2116 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2117 }
2118
2119 // When passing data by copy, we need to make sure it fits the uintptr size
2120 // and alignment, because the runtime library only deals with uintptr types.
2121 // If it does not fit the uintptr size, we need to pass the data by reference
2122 // instead.
2123 if (!IsByRef &&
2124 (Ctx.getTypeSizeInChars(Ty) >
2125 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2126 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2127 IsByRef = true;
2128 }
2129
2130 return IsByRef;
2131}
2132
2133unsigned Sema::getOpenMPNestingLevel() const {
2134 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2134, __PRETTY_FUNCTION__))
;
2135 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2136}
2137
2138bool Sema::isInOpenMPTargetExecutionDirective() const {
2139 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2140 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2141 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2142 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2143 SourceLocation) -> bool {
2144 return isOpenMPTargetExecutionDirective(K);
2145 },
2146 false);
2147}
2148
2149VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2150 unsigned StopAt) {
2151 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2151, __PRETTY_FUNCTION__))
;
2152 D = getCanonicalDecl(D);
2153
2154 auto *VD = dyn_cast<VarDecl>(D);
2155 // Do not capture constexpr variables.
2156 if (VD && VD->isConstexpr())
2157 return nullptr;
2158
2159 // If we want to determine whether the variable should be captured from the
2160 // perspective of the current capturing scope, and we've already left all the
2161 // capturing scopes of the top directive on the stack, check from the
2162 // perspective of its parent directive (if any) instead.
2163 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2164 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2165
2166 // If we are attempting to capture a global variable in a directive with
2167 // 'target' we return true so that this global is also mapped to the device.
2168 //
2169 if (VD && !VD->hasLocalStorage() &&
2170 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2171 if (isInOpenMPDeclareTargetContext()) {
2172 // Try to mark variable as declare target if it is used in capturing
2173 // regions.
2174 if (LangOpts.OpenMP <= 45 &&
2175 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2176 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2177 return nullptr;
2178 }
2179 if (isInOpenMPTargetExecutionDirective()) {
2180 // If the declaration is enclosed in a 'declare target' directive,
2181 // then it should not be captured.
2182 //
2183 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2184 return nullptr;
2185 CapturedRegionScopeInfo *CSI = nullptr;
2186 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2187 llvm::reverse(FunctionScopes),
2188 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2189 if (!isa<CapturingScopeInfo>(FSI))
2190 return nullptr;
2191 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2192 if (RSI->CapRegionKind == CR_OpenMP) {
2193 CSI = RSI;
2194 break;
2195 }
2196 }
2197 assert(CSI && "Failed to find CapturedRegionScopeInfo")((CSI && "Failed to find CapturedRegionScopeInfo") ? static_cast
<void> (0) : __assert_fail ("CSI && \"Failed to find CapturedRegionScopeInfo\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2197, __PRETTY_FUNCTION__))
;
2198 SmallVector<OpenMPDirectiveKind, 4> Regions;
2199 getOpenMPCaptureRegions(Regions,
2200 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2201 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2202 return VD;
2203 }
2204 }
2205
2206 if (CheckScopeInfo) {
2207 bool OpenMPFound = false;
2208 for (unsigned I = StopAt + 1; I > 0; --I) {
2209 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2210 if(!isa<CapturingScopeInfo>(FSI))
2211 return nullptr;
2212 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2213 if (RSI->CapRegionKind == CR_OpenMP) {
2214 OpenMPFound = true;
2215 break;
2216 }
2217 }
2218 if (!OpenMPFound)
2219 return nullptr;
2220 }
2221
2222 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2223 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2224 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2225 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2226 if (Info.first ||
2227 (VD && VD->hasLocalStorage() &&
2228 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2229 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2230 return VD ? VD : Info.second;
2231 DSAStackTy::DSAVarData DVarTop =
2232 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2233 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2234 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2235 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2236 // Threadprivate variables must not be captured.
2237 if (isOpenMPThreadPrivate(DVarTop.CKind))
2238 return nullptr;
2239 // The variable is not private or it is the variable in the directive with
2240 // default(none) clause and not used in any clause.
2241 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2242 D,
2243 [](OpenMPClauseKind C, bool AppliedToPointee) {
2244 return isOpenMPPrivate(C) && !AppliedToPointee;
2245 },
2246 [](OpenMPDirectiveKind) { return true; },
2247 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2248 // Global shared must not be captured.
2249 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2250 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2251 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2252 DVarTop.CKind == OMPC_shared))
2253 return nullptr;
2254 if (DVarPrivate.CKind != OMPC_unknown ||
2255 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2256 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2257 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2258 }
2259 return nullptr;
2260}
2261
2262void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2263 unsigned Level) const {
2264 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2265}
2266
2267void Sema::startOpenMPLoop() {
2268 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2268, __PRETTY_FUNCTION__))
;
2269 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2271}
2272
2273void Sema::startOpenMPCXXRangeFor() {
2274 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2274, __PRETTY_FUNCTION__))
;
2275 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2276 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2277 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2278 }
2279}
2280
2281OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2282 unsigned CapLevel) const {
2283 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2283, __PRETTY_FUNCTION__))
;
2284 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2285 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2286 Level)) {
2287 bool IsTriviallyCopyable =
2288 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2289 !D->getType()
2290 .getNonReferenceType()
2291 .getCanonicalType()
2292 ->getAsCXXRecordDecl();
2293 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2294 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2295 getOpenMPCaptureRegions(CaptureRegions, DKind);
2296 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2297 (IsTriviallyCopyable ||
2298 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2299 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2300 D,
2301 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2302 Level, /*NotLastprivate=*/true))
2303 return OMPC_firstprivate;
2304 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2305 if (DVar.CKind != OMPC_shared &&
2306 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2307 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2308 return OMPC_firstprivate;
2309 }
2310 }
2311 }
2312 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2313 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2314 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2315 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2316 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2317 return OMPC_private;
2318 }
2319 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2320 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2321 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2322 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2323 Level) &&
2324 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2325 return OMPC_private;
2326 }
2327 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2328 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2329 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2330 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2331 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2332 Level))
2333 return OMPC_private;
2334 }
2335 // User-defined allocators are private since they must be defined in the
2336 // context of target region.
2337 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2338 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2339 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2340 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2341 return OMPC_private;
2342 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2343 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2344 Level) ||
2345 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2346 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2347 // Consider taskgroup reduction descriptor variable a private
2348 // to avoid possible capture in the region.
2349 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2350 [](OpenMPDirectiveKind K) {
2351 return K == OMPD_taskgroup ||
2352 ((isOpenMPParallelDirective(K) ||
2353 isOpenMPWorksharingDirective(K)) &&
2354 !isOpenMPSimdDirective(K));
2355 },
2356 Level) &&
2357 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2358 ? OMPC_private
2359 : OMPC_unknown;
2360}
2361
2362void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2363 unsigned Level) {
2364 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2364, __PRETTY_FUNCTION__))
;
2365 D = getCanonicalDecl(D);
2366 OpenMPClauseKind OMPC = OMPC_unknown;
2367 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2368 const unsigned NewLevel = I - 1;
2369 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2370 D,
2371 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2372 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2373 OMPC = K;
2374 return true;
2375 }
2376 return false;
2377 },
2378 NewLevel))
2379 break;
2380 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2381 D, NewLevel,
2382 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2383 OpenMPClauseKind) { return true; })) {
2384 OMPC = OMPC_map;
2385 break;
2386 }
2387 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2388 NewLevel)) {
2389 OMPC = OMPC_map;
2390 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2391 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2392 OMPC = OMPC_firstprivate;
2393 break;
2394 }
2395 }
2396 if (OMPC != OMPC_unknown)
2397 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2398}
2399
2400bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2401 unsigned CaptureLevel) const {
2402 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2402, __PRETTY_FUNCTION__))
;
2403 // Return true if the current level is no longer enclosed in a target region.
2404
2405 SmallVector<OpenMPDirectiveKind, 4> Regions;
2406 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2407 const auto *VD = dyn_cast<VarDecl>(D);
2408 return VD && !VD->hasLocalStorage() &&
2409 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2410 Level) &&
2411 Regions[CaptureLevel] != OMPD_task;
2412}
2413
2414bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2415 unsigned CaptureLevel) const {
2416 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2416, __PRETTY_FUNCTION__))
;
2417 // Return true if the current level is no longer enclosed in a target region.
2418
2419 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2420 if (!VD->hasLocalStorage()) {
2421 if (isInOpenMPTargetExecutionDirective())
2422 return true;
2423 DSAStackTy::DSAVarData TopDVar =
2424 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2425 unsigned NumLevels =
2426 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2427 if (Level == 0)
2428 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2429 do {
2430 --Level;
2431 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2432 if (DVar.CKind != OMPC_shared)
2433 return true;
2434 } while (Level > 0);
2435 }
2436 }
2437 return true;
2438}
2439
2440void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2441
2442void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2443 OMPTraitInfo &TI) {
2444 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2445}
2446
2447void Sema::ActOnOpenMPEndDeclareVariant() {
2448 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2449, __PRETTY_FUNCTION__))
2449 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2449, __PRETTY_FUNCTION__))
;
2450
2451 OMPDeclareVariantScopes.pop_back();
2452}
2453
2454void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2455 const FunctionDecl *Callee,
2456 SourceLocation Loc) {
2457 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2457, __PRETTY_FUNCTION__))
;
2458 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2459 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2460 // Ignore host functions during device analyzis.
2461 if (LangOpts.OpenMPIsDevice && DevTy &&
2462 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2463 return;
2464 // Ignore nohost functions during host analyzis.
2465 if (!LangOpts.OpenMPIsDevice && DevTy &&
2466 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2467 return;
2468 const FunctionDecl *FD = Callee->getMostRecentDecl();
2469 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2470 if (LangOpts.OpenMPIsDevice && DevTy &&
2471 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2472 // Diagnose host function called during device codegen.
2473 StringRef HostDevTy =
2474 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2475 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2476 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2477 diag::note_omp_marked_device_type_here)
2478 << HostDevTy;
2479 return;
2480 }
2481 if (!LangOpts.OpenMPIsDevice && DevTy &&
2482 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2483 // Diagnose nohost function called during host codegen.
2484 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2485 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2486 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2487 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2488 diag::note_omp_marked_device_type_here)
2489 << NoHostDevTy;
2490 }
2491}
2492
2493void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2494 const DeclarationNameInfo &DirName,
2495 Scope *CurScope, SourceLocation Loc) {
2496 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2497 PushExpressionEvaluationContext(
2498 ExpressionEvaluationContext::PotentiallyEvaluated);
2499}
2500
2501void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2502 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2503}
2504
2505void Sema::EndOpenMPClause() {
2506 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2507}
2508
2509static std::pair<ValueDecl *, bool>
2510getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2511 SourceRange &ERange, bool AllowArraySection = false);
2512
2513/// Check consistency of the reduction clauses.
2514static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2515 ArrayRef<OMPClause *> Clauses) {
2516 bool InscanFound = false;
2517 SourceLocation InscanLoc;
2518 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2519 // A reduction clause without the inscan reduction-modifier may not appear on
2520 // a construct on which a reduction clause with the inscan reduction-modifier
2521 // appears.
2522 for (OMPClause *C : Clauses) {
2523 if (C->getClauseKind() != OMPC_reduction)
2524 continue;
2525 auto *RC = cast<OMPReductionClause>(C);
2526 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2527 InscanFound = true;
2528 InscanLoc = RC->getModifierLoc();
2529 continue;
2530 }
2531 if (RC->getModifier() == OMPC_REDUCTION_task) {
2532 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2533 // A reduction clause with the task reduction-modifier may only appear on
2534 // a parallel construct, a worksharing construct or a combined or
2535 // composite construct for which any of the aforementioned constructs is a
2536 // constituent construct and simd or loop are not constituent constructs.
2537 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2538 if (!(isOpenMPParallelDirective(CurDir) ||
2539 isOpenMPWorksharingDirective(CurDir)) ||
2540 isOpenMPSimdDirective(CurDir))
2541 S.Diag(RC->getModifierLoc(),
2542 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2543 continue;
2544 }
2545 }
2546 if (InscanFound) {
2547 for (OMPClause *C : Clauses) {
2548 if (C->getClauseKind() != OMPC_reduction)
2549 continue;
2550 auto *RC = cast<OMPReductionClause>(C);
2551 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2552 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2553 ? RC->getBeginLoc()
2554 : RC->getModifierLoc(),
2555 diag::err_omp_inscan_reduction_expected);
2556 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2557 continue;
2558 }
2559 for (Expr *Ref : RC->varlists()) {
2560 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2560, __PRETTY_FUNCTION__))
;
2561 SourceLocation ELoc;
2562 SourceRange ERange;
2563 Expr *SimpleRefExpr = Ref;
2564 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2565 /*AllowArraySection=*/true);
2566 ValueDecl *D = Res.first;
2567 if (!D)
2568 continue;
2569 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2570 S.Diag(Ref->getExprLoc(),
2571 diag::err_omp_reduction_not_inclusive_exclusive)
2572 << Ref->getSourceRange();
2573 }
2574 }
2575 }
2576 }
2577}
2578
2579static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2580 ArrayRef<OMPClause *> Clauses);
2581static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2582 bool WithInit);
2583
2584static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2585 const ValueDecl *D,
2586 const DSAStackTy::DSAVarData &DVar,
2587 bool IsLoopIterVar = false);
2588
2589void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2590 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2591 // A variable of class type (or array thereof) that appears in a lastprivate
2592 // clause requires an accessible, unambiguous default constructor for the
2593 // class type, unless the list item is also specified in a firstprivate
2594 // clause.
2595 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2596 for (OMPClause *C : D->clauses()) {
2597 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2598 SmallVector<Expr *, 8> PrivateCopies;
2599 for (Expr *DE : Clause->varlists()) {
2600 if (DE->isValueDependent() || DE->isTypeDependent()) {
2601 PrivateCopies.push_back(nullptr);
2602 continue;
2603 }
2604 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2605 auto *VD = cast<VarDecl>(DRE->getDecl());
2606 QualType Type = VD->getType().getNonReferenceType();
2607 const DSAStackTy::DSAVarData DVar =
2608 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2609 if (DVar.CKind == OMPC_lastprivate) {
2610 // Generate helper private variable and initialize it with the
2611 // default value. The address of the original variable is replaced
2612 // by the address of the new private variable in CodeGen. This new
2613 // variable is not added to IdResolver, so the code in the OpenMP
2614 // region uses original variable for proper diagnostics.
2615 VarDecl *VDPrivate = buildVarDecl(
2616 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2617 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2618 ActOnUninitializedDecl(VDPrivate);
2619 if (VDPrivate->isInvalidDecl()) {
2620 PrivateCopies.push_back(nullptr);
2621 continue;
2622 }
2623 PrivateCopies.push_back(buildDeclRefExpr(
2624 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2625 } else {
2626 // The variable is also a firstprivate, so initialization sequence
2627 // for private copy is generated already.
2628 PrivateCopies.push_back(nullptr);
2629 }
2630 }
2631 Clause->setPrivateCopies(PrivateCopies);
2632 continue;
2633 }
2634 // Finalize nontemporal clause by handling private copies, if any.
2635 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2636 SmallVector<Expr *, 8> PrivateRefs;
2637 for (Expr *RefExpr : Clause->varlists()) {
2638 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 2638, __PRETTY_FUNCTION__))
;
2639 SourceLocation ELoc;
2640 SourceRange ERange;
2641 Expr *SimpleRefExpr = RefExpr;
2642 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2643 if (Res.second)
2644 // It will be analyzed later.
2645 PrivateRefs.push_back(RefExpr);
2646 ValueDecl *D = Res.first;
2647 if (!D)
2648 continue;
2649
2650 const DSAStackTy::DSAVarData DVar =
2651 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2652 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2653 : SimpleRefExpr);
2654 }
2655 Clause->setPrivateRefs(PrivateRefs);
2656 continue;
2657 }
2658 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2659 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2660 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2661 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2662 if (!DRE)
2663 continue;
2664 ValueDecl *VD = DRE->getDecl();
2665 if (!VD || !isa<VarDecl>(VD))
2666 continue;
2667 DSAStackTy::DSAVarData DVar =
2668 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2669 // OpenMP [2.12.5, target Construct]
2670 // Memory allocators that appear in a uses_allocators clause cannot
2671 // appear in other data-sharing attribute clauses or data-mapping
2672 // attribute clauses in the same construct.
2673 Expr *MapExpr = nullptr;
2674 if (DVar.RefExpr ||
2675 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2676 VD, /*CurrentRegionOnly=*/true,
2677 [VD, &MapExpr](
2678 OMPClauseMappableExprCommon::MappableExprComponentListRef
2679 MapExprComponents,
2680 OpenMPClauseKind C) {
2681 auto MI = MapExprComponents.rbegin();
2682 auto ME = MapExprComponents.rend();
2683 if (MI != ME &&
2684 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2685 VD->getCanonicalDecl()) {
2686 MapExpr = MI->getAssociatedExpression();
2687 return true;
2688 }
2689 return false;
2690 })) {
2691 Diag(D.Allocator->getExprLoc(),
2692 diag::err_omp_allocator_used_in_clauses)
2693 << D.Allocator->getSourceRange();
2694 if (DVar.RefExpr)
2695 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2696 else
2697 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2698 << MapExpr->getSourceRange();
2699 }
2700 }
2701 continue;
2702 }
2703 }
2704 // Check allocate clauses.
2705 if (!CurContext->isDependentContext())
2706 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2707 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2708 }
2709
2710 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2711 DiscardCleanupsInEvaluationContext();
2712 PopExpressionEvaluationContext();
2713}
2714
2715static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2716 Expr *NumIterations, Sema &SemaRef,
2717 Scope *S, DSAStackTy *Stack);
2718
2719namespace {
2720
2721class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2722private:
2723 Sema &SemaRef;
2724
2725public:
2726 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2727 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2728 NamedDecl *ND = Candidate.getCorrectionDecl();
2729 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2730 return VD->hasGlobalStorage() &&
2731 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2732 SemaRef.getCurScope());
2733 }
2734 return false;
2735 }
2736
2737 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2738 return std::make_unique<VarDeclFilterCCC>(*this);
2739 }
2740
2741};
2742
2743class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2744private:
2745 Sema &SemaRef;
2746
2747public:
2748 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2749 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2750 NamedDecl *ND = Candidate.getCorrectionDecl();
2751 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2752 isa<FunctionDecl>(ND))) {
2753 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2754 SemaRef.getCurScope());
2755 }
2756 return false;
2757 }
2758
2759 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2760 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2761 }
2762};
2763
2764} // namespace
2765
2766ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2767 CXXScopeSpec &ScopeSpec,
2768 const DeclarationNameInfo &Id,
2769 OpenMPDirectiveKind Kind) {
2770 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2771 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2772
2773 if (Lookup.isAmbiguous())
2774 return ExprError();
2775
2776 VarDecl *VD;
2777 if (!Lookup.isSingleResult()) {
2778 VarDeclFilterCCC CCC(*this);
2779 if (TypoCorrection Corrected =
2780 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2781 CTK_ErrorRecovery)) {
2782 diagnoseTypo(Corrected,
2783 PDiag(Lookup.empty()
2784 ? diag::err_undeclared_var_use_suggest
2785 : diag::err_omp_expected_var_arg_suggest)
2786 << Id.getName());
2787 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2788 } else {
2789 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2790 : diag::err_omp_expected_var_arg)
2791 << Id.getName();
2792 return ExprError();
2793 }
2794 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2795 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2796 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2797 return ExprError();
2798 }
2799 Lookup.suppressDiagnostics();
2800
2801 // OpenMP [2.9.2, Syntax, C/C++]
2802 // Variables must be file-scope, namespace-scope, or static block-scope.
2803 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2804 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2805 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2806 bool IsDecl =
2807 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2808 Diag(VD->getLocation(),
2809 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2810 << VD;
2811 return ExprError();
2812 }
2813
2814 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2815 NamedDecl *ND = CanonicalVD;
2816 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2817 // A threadprivate directive for file-scope variables must appear outside
2818 // any definition or declaration.
2819 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2820 !getCurLexicalContext()->isTranslationUnit()) {
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 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2831 // A threadprivate directive for static class member variables must appear
2832 // in the class definition, in the same scope in which the member
2833 // variables are declared.
2834 if (CanonicalVD->isStaticDataMember() &&
2835 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2836 Diag(Id.getLoc(), diag::err_omp_var_scope)
2837 << getOpenMPDirectiveName(Kind) << VD;
2838 bool IsDecl =
2839 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2840 Diag(VD->getLocation(),
2841 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2842 << VD;
2843 return ExprError();
2844 }
2845 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2846 // A threadprivate directive for namespace-scope variables must appear
2847 // outside any definition or declaration other than the namespace
2848 // definition itself.
2849 if (CanonicalVD->getDeclContext()->isNamespace() &&
2850 (!getCurLexicalContext()->isFileContext() ||
2851 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2852 Diag(Id.getLoc(), diag::err_omp_var_scope)
2853 << getOpenMPDirectiveName(Kind) << VD;
2854 bool IsDecl =
2855 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2856 Diag(VD->getLocation(),
2857 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2858 << VD;
2859 return ExprError();
2860 }
2861 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2862 // A threadprivate directive for static block-scope variables must appear
2863 // in the scope of the variable and not in a nested scope.
2864 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2865 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2866 Diag(Id.getLoc(), diag::err_omp_var_scope)
2867 << getOpenMPDirectiveName(Kind) << VD;
2868 bool IsDecl =
2869 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2870 Diag(VD->getLocation(),
2871 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2872 << VD;
2873 return ExprError();
2874 }
2875
2876 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2877 // A threadprivate directive must lexically precede all references to any
2878 // of the variables in its list.
2879 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2880 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2881 Diag(Id.getLoc(), diag::err_omp_var_used)
2882 << getOpenMPDirectiveName(Kind) << VD;
2883 return ExprError();
2884 }
2885
2886 QualType ExprType = VD->getType().getNonReferenceType();
2887 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2888 SourceLocation(), VD,
2889 /*RefersToEnclosingVariableOrCapture=*/false,
2890 Id.getLoc(), ExprType, VK_LValue);
2891}
2892
2893Sema::DeclGroupPtrTy
2894Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2895 ArrayRef<Expr *> VarList) {
2896 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2897 CurContext->addDecl(D);
2898 return DeclGroupPtrTy::make(DeclGroupRef(D));
2899 }
2900 return nullptr;
2901}
2902
2903namespace {
2904class LocalVarRefChecker final
2905 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2906 Sema &SemaRef;
2907
2908public:
2909 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2910 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2911 if (VD->hasLocalStorage()) {
2912 SemaRef.Diag(E->getBeginLoc(),
2913 diag::err_omp_local_var_in_threadprivate_init)
2914 << E->getSourceRange();
2915 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2916 << VD << VD->getSourceRange();
2917 return true;
2918 }
2919 }
2920 return false;
2921 }
2922 bool VisitStmt(const Stmt *S) {
2923 for (const Stmt *Child : S->children()) {
2924 if (Child && Visit(Child))
2925 return true;
2926 }
2927 return false;
2928 }
2929 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2930};
2931} // namespace
2932
2933OMPThreadPrivateDecl *
2934Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2935 SmallVector<Expr *, 8> Vars;
2936 for (Expr *RefExpr : VarList) {
2937 auto *DE = cast<DeclRefExpr>(RefExpr);
2938 auto *VD = cast<VarDecl>(DE->getDecl());
2939 SourceLocation ILoc = DE->getExprLoc();
2940
2941 // Mark variable as used.
2942 VD->setReferenced();
2943 VD->markUsed(Context);
2944
2945 QualType QType = VD->getType();
2946 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2947 // It will be analyzed later.
2948 Vars.push_back(DE);
2949 continue;
2950 }
2951
2952 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2953 // A threadprivate variable must not have an incomplete type.
2954 if (RequireCompleteType(ILoc, VD->getType(),
2955 diag::err_omp_threadprivate_incomplete_type)) {
2956 continue;
2957 }
2958
2959 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2960 // A threadprivate variable must not have a reference type.
2961 if (VD->getType()->isReferenceType()) {
2962 Diag(ILoc, diag::err_omp_ref_type_arg)
2963 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2964 bool IsDecl =
2965 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2966 Diag(VD->getLocation(),
2967 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2968 << VD;
2969 continue;
2970 }
2971
2972 // Check if this is a TLS variable. If TLS is not being supported, produce
2973 // the corresponding diagnostic.
2974 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2975 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2976 getLangOpts().OpenMPUseTLS &&
2977 getASTContext().getTargetInfo().isTLSSupported())) ||
2978 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2979 !VD->isLocalVarDecl())) {
2980 Diag(ILoc, diag::err_omp_var_thread_local)
2981 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2982 bool IsDecl =
2983 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2984 Diag(VD->getLocation(),
2985 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2986 << VD;
2987 continue;
2988 }
2989
2990 // Check if initial value of threadprivate variable reference variable with
2991 // local storage (it is not supported by runtime).
2992 if (const Expr *Init = VD->getAnyInitializer()) {
2993 LocalVarRefChecker Checker(*this);
2994 if (Checker.Visit(Init))
2995 continue;
2996 }
2997
2998 Vars.push_back(RefExpr);
2999 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3000 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3001 Context, SourceRange(Loc, Loc)));
3002 if (ASTMutationListener *ML = Context.getASTMutationListener())
3003 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3004 }
3005 OMPThreadPrivateDecl *D = nullptr;
3006 if (!Vars.empty()) {
3007 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3008 Vars);
3009 D->setAccess(AS_public);
3010 }
3011 return D;
3012}
3013
3014static OMPAllocateDeclAttr::AllocatorTypeTy
3015getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3016 if (!Allocator)
3017 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3018 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3019 Allocator->isInstantiationDependent() ||
3020 Allocator->containsUnexpandedParameterPack())
3021 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3022 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3023 const Expr *AE = Allocator->IgnoreParenImpCasts();
3024 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3025 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3026 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3027 llvm::FoldingSetNodeID AEId, DAEId;
3028 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3029 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3030 if (AEId == DAEId) {
3031 AllocatorKindRes = AllocatorKind;
3032 break;
3033 }
3034 }
3035 return AllocatorKindRes;
3036}
3037
3038static bool checkPreviousOMPAllocateAttribute(
3039 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3040 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3041 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3042 return false;
3043 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3044 Expr *PrevAllocator = A->getAllocator();
3045 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3046 getAllocatorKind(S, Stack, PrevAllocator);
3047 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3048 if (AllocatorsMatch &&
3049 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3050 Allocator && PrevAllocator) {
3051 const Expr *AE = Allocator->IgnoreParenImpCasts();
3052 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3053 llvm::FoldingSetNodeID AEId, PAEId;
3054 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3055 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3056 AllocatorsMatch = AEId == PAEId;
3057 }
3058 if (!AllocatorsMatch) {
3059 SmallString<256> AllocatorBuffer;
3060 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3061 if (Allocator)
3062 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3063 SmallString<256> PrevAllocatorBuffer;
3064 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3065 if (PrevAllocator)
3066 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3067 S.getPrintingPolicy());
3068
3069 SourceLocation AllocatorLoc =
3070 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3071 SourceRange AllocatorRange =
3072 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3073 SourceLocation PrevAllocatorLoc =
3074 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3075 SourceRange PrevAllocatorRange =
3076 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3077 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3078 << (Allocator ? 1 : 0) << AllocatorStream.str()
3079 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3080 << AllocatorRange;
3081 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3082 << PrevAllocatorRange;
3083 return true;
3084 }
3085 return false;
3086}
3087
3088static void
3089applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3090 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3091 Expr *Allocator, SourceRange SR) {
3092 if (VD->hasAttr<OMPAllocateDeclAttr>())
3093 return;
3094 if (Allocator &&
3095 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3096 Allocator->isInstantiationDependent() ||
3097 Allocator->containsUnexpandedParameterPack()))
3098 return;
3099 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3100 Allocator, SR);
3101 VD->addAttr(A);
3102 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3103 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3104}
3105
3106Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3107 SourceLocation Loc, ArrayRef<Expr *> VarList,
3108 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3109 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 3109, __PRETTY_FUNCTION__))
;
3110 Expr *Allocator = nullptr;
3111 if (Clauses.empty()) {
3112 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3113 // allocate directives that appear in a target region must specify an
3114 // allocator clause unless a requires directive with the dynamic_allocators
3115 // clause is present in the same compilation unit.
3116 if (LangOpts.OpenMPIsDevice &&
3117 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3118 targetDiag(Loc, diag::err_expected_allocator_clause);
3119 } else {
3120 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3121 }
3122 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3123 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3124 SmallVector<Expr *, 8> Vars;
3125 for (Expr *RefExpr : VarList) {
3126 auto *DE = cast<DeclRefExpr>(RefExpr);
3127 auto *VD = cast<VarDecl>(DE->getDecl());
3128
3129 // Check if this is a TLS variable or global register.
3130 if (VD->getTLSKind() != VarDecl::TLS_None ||
3131 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3132 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3133 !VD->isLocalVarDecl()))
3134 continue;
3135
3136 // If the used several times in the allocate directive, the same allocator
3137 // must be used.
3138 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3139 AllocatorKind, Allocator))
3140 continue;
3141
3142 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3143 // If a list item has a static storage type, the allocator expression in the
3144 // allocator clause must be a constant expression that evaluates to one of
3145 // the predefined memory allocator values.
3146 if (Allocator && VD->hasGlobalStorage()) {
3147 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3148 Diag(Allocator->getExprLoc(),
3149 diag::err_omp_expected_predefined_allocator)
3150 << Allocator->getSourceRange();
3151 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3152 VarDecl::DeclarationOnly;
3153 Diag(VD->getLocation(),
3154 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3155 << VD;
3156 continue;
3157 }
3158 }
3159
3160 Vars.push_back(RefExpr);
3161 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3162 DE->getSourceRange());
3163 }
3164 if (Vars.empty())
3165 return nullptr;
3166 if (!Owner)
3167 Owner = getCurLexicalContext();
3168 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3169 D->setAccess(AS_public);
3170 Owner->addDecl(D);
3171 return DeclGroupPtrTy::make(DeclGroupRef(D));
3172}
3173
3174Sema::DeclGroupPtrTy
3175Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3176 ArrayRef<OMPClause *> ClauseList) {
3177 OMPRequiresDecl *D = nullptr;
3178 if (!CurContext->isFileContext()) {
3179 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3180 } else {
3181 D = CheckOMPRequiresDecl(Loc, ClauseList);
3182 if (D) {
3183 CurContext->addDecl(D);
3184 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3185 }
3186 }
3187 return DeclGroupPtrTy::make(DeclGroupRef(D));
3188}
3189
3190OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3191 ArrayRef<OMPClause *> ClauseList) {
3192 /// For target specific clauses, the requires directive cannot be
3193 /// specified after the handling of any of the target regions in the
3194 /// current compilation unit.
3195 ArrayRef<SourceLocation> TargetLocations =
3196 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3197 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3198 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3199 for (const OMPClause *CNew : ClauseList) {
3200 // Check if any of the requires clauses affect target regions.
3201 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3202 isa<OMPUnifiedAddressClause>(CNew) ||
3203 isa<OMPReverseOffloadClause>(CNew) ||
3204 isa<OMPDynamicAllocatorsClause>(CNew)) {
3205 Diag(Loc, diag::err_omp_directive_before_requires)
3206 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3207 for (SourceLocation TargetLoc : TargetLocations) {
3208 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3209 << "target";
3210 }
3211 } else if (!AtomicLoc.isInvalid() &&
3212 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3213 Diag(Loc, diag::err_omp_directive_before_requires)
3214 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3215 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3216 << "atomic";
3217 }
3218 }
3219 }
3220
3221 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3222 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3223 ClauseList);
3224 return nullptr;
3225}
3226
3227static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3228 const ValueDecl *D,
3229 const DSAStackTy::DSAVarData &DVar,
3230 bool IsLoopIterVar) {
3231 if (DVar.RefExpr) {
3232 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3233 << getOpenMPClauseName(DVar.CKind);
3234 return;
3235 }
3236 enum {
3237 PDSA_StaticMemberShared,
3238 PDSA_StaticLocalVarShared,
3239 PDSA_LoopIterVarPrivate,
3240 PDSA_LoopIterVarLinear,
3241 PDSA_LoopIterVarLastprivate,
3242 PDSA_ConstVarShared,
3243 PDSA_GlobalVarShared,
3244 PDSA_TaskVarFirstprivate,
3245 PDSA_LocalVarPrivate,
3246 PDSA_Implicit
3247 } Reason = PDSA_Implicit;
3248 bool ReportHint = false;
3249 auto ReportLoc = D->getLocation();
3250 auto *VD = dyn_cast<VarDecl>(D);
3251 if (IsLoopIterVar) {
3252 if (DVar.CKind == OMPC_private)
3253 Reason = PDSA_LoopIterVarPrivate;
3254 else if (DVar.CKind == OMPC_lastprivate)
3255 Reason = PDSA_LoopIterVarLastprivate;
3256 else
3257 Reason = PDSA_LoopIterVarLinear;
3258 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3259 DVar.CKind == OMPC_firstprivate) {
3260 Reason = PDSA_TaskVarFirstprivate;
3261 ReportLoc = DVar.ImplicitDSALoc;
3262 } else if (VD && VD->isStaticLocal())
3263 Reason = PDSA_StaticLocalVarShared;
3264 else if (VD && VD->isStaticDataMember())
3265 Reason = PDSA_StaticMemberShared;
3266 else if (VD && VD->isFileVarDecl())
3267 Reason = PDSA_GlobalVarShared;
3268 else if (D->getType().isConstant(SemaRef.getASTContext()))
3269 Reason = PDSA_ConstVarShared;
3270 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3271 ReportHint = true;
3272 Reason = PDSA_LocalVarPrivate;
3273 }
3274 if (Reason != PDSA_Implicit) {
3275 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3276 << Reason << ReportHint
3277 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3278 } else if (DVar.ImplicitDSALoc.isValid()) {
3279 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3280 << getOpenMPClauseName(DVar.CKind);
3281 }
3282}
3283
3284static OpenMPMapClauseKind
3285getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3286 bool IsAggregateOrDeclareTarget) {
3287 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3288 switch (M) {
3289 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3290 Kind = OMPC_MAP_alloc;
3291 break;
3292 case OMPC_DEFAULTMAP_MODIFIER_to:
3293 Kind = OMPC_MAP_to;
3294 break;
3295 case OMPC_DEFAULTMAP_MODIFIER_from:
3296 Kind = OMPC_MAP_from;
3297 break;
3298 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3299 Kind = OMPC_MAP_tofrom;
3300 break;
3301 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3302 case OMPC_DEFAULTMAP_MODIFIER_last:
3303 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 3303)
;
3304 case OMPC_DEFAULTMAP_MODIFIER_none:
3305 case OMPC_DEFAULTMAP_MODIFIER_default:
3306 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3307 // IsAggregateOrDeclareTarget could be true if:
3308 // 1. the implicit behavior for aggregate is tofrom
3309 // 2. it's a declare target link
3310 if (IsAggregateOrDeclareTarget) {
3311 Kind = OMPC_MAP_tofrom;
3312 break;
3313 }
3314 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 3314)
;
3315 }
3316 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 3316, __PRETTY_FUNCTION__))
;
3317 return Kind;
3318}
3319
3320namespace {
3321class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3322 DSAStackTy *Stack;
3323 Sema &SemaRef;
3324 bool ErrorFound = false;
3325 bool TryCaptureCXXThisMembers = false;
3326 CapturedStmt *CS = nullptr;
3327 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3328 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3329 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3330 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3331
3332 void VisitSubCaptures(OMPExecutableDirective *S) {
3333 // Check implicitly captured variables.
3334 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt() ||
3335 S->getDirectiveKind() == OMPD_atomic ||
3336 S->getDirectiveKind() == OMPD_critical ||
3337 S->getDirectiveKind() == OMPD_section ||
3338 S->getDirectiveKind() == OMPD_master)
3339 return;
3340 visitSubCaptures(S->getInnermostCapturedStmt());
3341 // Try to capture inner this->member references to generate correct mappings
3342 // and diagnostics.
3343 if (TryCaptureCXXThisMembers ||
3344 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3345 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3346 [](const CapturedStmt::Capture &C) {
3347 return C.capturesThis();
3348 }))) {
3349 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3350 TryCaptureCXXThisMembers = true;
3351 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3352 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3353 }
3354 // In tasks firstprivates are not captured anymore, need to analyze them
3355 // explicitly.
3356 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3357 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3358 for (OMPClause *C : S->clauses())
3359 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3360 for (Expr *Ref : FC->varlists())
3361 Visit(Ref);
3362 }
3363 }
3364 }
3365
3366public:
3367 void VisitDeclRefExpr(DeclRefExpr *E) {
3368 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3369 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3370 E->isInstantiationDependent())
3371 return;
3372 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3373 // Check the datasharing rules for the expressions in the clauses.
3374 if (!CS) {
3375 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3376 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3377 Visit(CED->getInit());
3378 return;
3379 }
3380 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3381 // Do not analyze internal variables and do not enclose them into
3382 // implicit clauses.
3383 return;
3384 VD = VD->getCanonicalDecl();
3385 // Skip internally declared variables.
3386 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3387 !Stack->isImplicitTaskFirstprivate(VD))
3388 return;
3389 // Skip allocators in uses_allocators clauses.
3390 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3391 return;
3392
3393 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3394 // Check if the variable has explicit DSA set and stop analysis if it so.
3395 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3396 return;
3397
3398 // Skip internally declared static variables.
3399 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3400 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3401 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3402 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3403 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3404 !Stack->isImplicitTaskFirstprivate(VD))
3405 return;
3406
3407 SourceLocation ELoc = E->getExprLoc();
3408 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3409 // The default(none) clause requires that each variable that is referenced
3410 // in the construct, and does not have a predetermined data-sharing
3411 // attribute, must have its data-sharing attribute explicitly determined
3412 // by being listed in a data-sharing attribute clause.
3413 if (DVar.CKind == OMPC_unknown &&
3414 (Stack->getDefaultDSA() == DSA_none ||
3415 Stack->getDefaultDSA() == DSA_firstprivate) &&
3416 isImplicitOrExplicitTaskingRegion(DKind) &&
3417 VarsWithInheritedDSA.count(VD) == 0) {
3418 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3419 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3420 DSAStackTy::DSAVarData DVar =
3421 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3422 InheritedDSA = DVar.CKind == OMPC_unknown;
3423 }
3424 if (InheritedDSA)
3425 VarsWithInheritedDSA[VD] = E;
3426 return;
3427 }
3428
3429 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3430 // If implicit-behavior is none, each variable referenced in the
3431 // construct that does not have a predetermined data-sharing attribute
3432 // and does not appear in a to or link clause on a declare target
3433 // directive must be listed in a data-mapping attribute clause, a
3434 // data-haring attribute clause (including a data-sharing attribute
3435 // clause on a combined construct where target. is one of the
3436 // constituent constructs), or an is_device_ptr clause.
3437 OpenMPDefaultmapClauseKind ClauseKind =
3438 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3439 if (SemaRef.getLangOpts().OpenMP >= 50) {
3440 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3441 OMPC_DEFAULTMAP_MODIFIER_none;
3442 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3443 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3444 // Only check for data-mapping attribute and is_device_ptr here
3445 // since we have already make sure that the declaration does not
3446 // have a data-sharing attribute above
3447 if (!Stack->checkMappableExprComponentListsForDecl(
3448 VD, /*CurrentRegionOnly=*/true,
3449 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3450 MapExprComponents,
3451 OpenMPClauseKind) {
3452 auto MI = MapExprComponents.rbegin();
3453 auto ME = MapExprComponents.rend();
3454 return MI != ME && MI->getAssociatedDeclaration() == VD;
3455 })) {
3456 VarsWithInheritedDSA[VD] = E;
3457 return;
3458 }
3459 }
3460 }
3461
3462 if (isOpenMPTargetExecutionDirective(DKind) &&
3463 !Stack->isLoopControlVariable(VD).first) {
3464 if (!Stack->checkMappableExprComponentListsForDecl(
3465 VD, /*CurrentRegionOnly=*/true,
3466 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3467 StackComponents,
3468 OpenMPClauseKind) {
3469 // Variable is used if it has been marked as an array, array
3470 // section, array shaping or the variable iself.
3471 return StackComponents.size() == 1 ||
3472 std::all_of(
3473 std::next(StackComponents.rbegin()),
3474 StackComponents.rend(),
3475 [](const OMPClauseMappableExprCommon::
3476 MappableComponent &MC) {
3477 return MC.getAssociatedDeclaration() ==
3478 nullptr &&
3479 (isa<OMPArraySectionExpr>(
3480 MC.getAssociatedExpression()) ||
3481 isa<OMPArrayShapingExpr>(
3482 MC.getAssociatedExpression()) ||
3483 isa<ArraySubscriptExpr>(
3484 MC.getAssociatedExpression()));
3485 });
3486 })) {
3487 bool IsFirstprivate = false;
3488 // By default lambdas are captured as firstprivates.
3489 if (const auto *RD =
3490 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3491 IsFirstprivate = RD->isLambda();
3492 IsFirstprivate =
3493 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3494 if (IsFirstprivate) {
3495 ImplicitFirstprivate.emplace_back(E);
3496 } else {
3497 OpenMPDefaultmapClauseModifier M =
3498 Stack->getDefaultmapModifier(ClauseKind);
3499 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3500 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3501 ImplicitMap[Kind].emplace_back(E);
3502 }
3503 return;
3504 }
3505 }
3506
3507 // OpenMP [2.9.3.6, Restrictions, p.2]
3508 // A list item that appears in a reduction clause of the innermost
3509 // enclosing worksharing or parallel construct may not be accessed in an
3510 // explicit task.
3511 DVar = Stack->hasInnermostDSA(
3512 VD,
3513 [](OpenMPClauseKind C, bool AppliedToPointee) {
3514 return C == OMPC_reduction && !AppliedToPointee;
3515 },
3516 [](OpenMPDirectiveKind K) {
3517 return isOpenMPParallelDirective(K) ||
3518 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3519 },
3520 /*FromParent=*/true);
3521 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3522 ErrorFound = true;
3523 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3524 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3525 return;
3526 }
3527
3528 // Define implicit data-sharing attributes for task.
3529 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3530 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3531 (Stack->getDefaultDSA() == DSA_firstprivate &&
3532 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3533 !Stack->isLoopControlVariable(VD).first) {
3534 ImplicitFirstprivate.push_back(E);
3535 return;
3536 }
3537
3538 // Store implicitly used globals with declare target link for parent
3539 // target.
3540 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3541 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3542 Stack->addToParentTargetRegionLinkGlobals(E);
3543 return;
3544 }
3545 }
3546 }
3547 void VisitMemberExpr(MemberExpr *E) {
3548 if (E->isTypeDependent() || E->isValueDependent() ||
3549 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3550 return;
3551 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3552 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3553 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3554 if (!FD)
3555 return;
3556 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3557 // Check if the variable has explicit DSA set and stop analysis if it
3558 // so.
3559 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3560 return;
3561
3562 if (isOpenMPTargetExecutionDirective(DKind) &&
3563 !Stack->isLoopControlVariable(FD).first &&
3564 !Stack->checkMappableExprComponentListsForDecl(
3565 FD, /*CurrentRegionOnly=*/true,
3566 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3567 StackComponents,
3568 OpenMPClauseKind) {
3569 return isa<CXXThisExpr>(
3570 cast<MemberExpr>(
3571 StackComponents.back().getAssociatedExpression())
3572 ->getBase()
3573 ->IgnoreParens());
3574 })) {
3575 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3576 // A bit-field cannot appear in a map clause.
3577 //
3578 if (FD->isBitField())
3579 return;
3580
3581 // Check to see if the member expression is referencing a class that
3582 // has already been explicitly mapped
3583 if (Stack->isClassPreviouslyMapped(TE->getType()))
3584 return;
3585
3586 OpenMPDefaultmapClauseModifier Modifier =
3587 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3588 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3589 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3590 ImplicitMap[Kind].emplace_back(E);
3591 return;
3592 }
3593
3594 SourceLocation ELoc = E->getExprLoc();
3595 // OpenMP [2.9.3.6, Restrictions, p.2]
3596 // A list item that appears in a reduction clause of the innermost
3597 // enclosing worksharing or parallel construct may not be accessed in
3598 // an explicit task.
3599 DVar = Stack->hasInnermostDSA(
3600 FD,
3601 [](OpenMPClauseKind C, bool AppliedToPointee) {
3602 return C == OMPC_reduction && !AppliedToPointee;
3603 },
3604 [](OpenMPDirectiveKind K) {
3605 return isOpenMPParallelDirective(K) ||
3606 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3607 },
3608 /*FromParent=*/true);
3609 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3610 ErrorFound = true;
3611 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3612 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3613 return;
3614 }
3615
3616 // Define implicit data-sharing attributes for task.
3617 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3618 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3619 !Stack->isLoopControlVariable(FD).first) {
3620 // Check if there is a captured expression for the current field in the
3621 // region. Do not mark it as firstprivate unless there is no captured
3622 // expression.
3623 // TODO: try to make it firstprivate.
3624 if (DVar.CKind != OMPC_unknown)
3625 ImplicitFirstprivate.push_back(E);
3626 }
3627 return;
3628 }
3629 if (isOpenMPTargetExecutionDirective(DKind)) {
3630 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3631 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3632 /*NoDiagnose=*/true))
3633 return;
3634 const auto *VD = cast<ValueDecl>(
3635 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3636 if (!Stack->checkMappableExprComponentListsForDecl(
3637 VD, /*CurrentRegionOnly=*/true,
3638 [&CurComponents](
3639 OMPClauseMappableExprCommon::MappableExprComponentListRef
3640 StackComponents,
3641 OpenMPClauseKind) {
3642 auto CCI = CurComponents.rbegin();
3643 auto CCE = CurComponents.rend();
3644 for (const auto &SC : llvm::reverse(StackComponents)) {
3645 // Do both expressions have the same kind?
3646 if (CCI->getAssociatedExpression()->getStmtClass() !=
3647 SC.getAssociatedExpression()->getStmtClass())
3648 if (!((isa<OMPArraySectionExpr>(
3649 SC.getAssociatedExpression()) ||
3650 isa<OMPArrayShapingExpr>(
3651 SC.getAssociatedExpression())) &&
3652 isa<ArraySubscriptExpr>(
3653 CCI->getAssociatedExpression())))
3654 return false;
3655
3656 const Decl *CCD = CCI->getAssociatedDeclaration();
3657 const Decl *SCD = SC.getAssociatedDeclaration();
3658 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3659 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3660 if (SCD != CCD)
3661 return false;
3662 std::advance(CCI, 1);
3663 if (CCI == CCE)
3664 break;
3665 }
3666 return true;
3667 })) {
3668 Visit(E->getBase());
3669 }
3670 } else if (!TryCaptureCXXThisMembers) {
3671 Visit(E->getBase());
3672 }
3673 }
3674 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3675 for (OMPClause *C : S->clauses()) {
3676 // Skip analysis of arguments of implicitly defined firstprivate clause
3677 // for task|target directives.
3678 // Skip analysis of arguments of implicitly defined map clause for target
3679 // directives.
3680 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3681 C->isImplicit())) {
3682 for (Stmt *CC : C->children()) {
3683 if (CC)
3684 Visit(CC);
3685 }
3686 }
3687 }
3688 // Check implicitly captured variables.
3689 VisitSubCaptures(S);
3690 }
3691 void VisitStmt(Stmt *S) {
3692 for (Stmt *C : S->children()) {
3693 if (C) {
3694 // Check implicitly captured variables in the task-based directives to
3695 // check if they must be firstprivatized.
3696 Visit(C);
3697 }
3698 }
3699 }
3700
3701 void visitSubCaptures(CapturedStmt *S) {
3702 for (const CapturedStmt::Capture &Cap : S->captures()) {
3703 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3704 continue;
3705 VarDecl *VD = Cap.getCapturedVar();
3706 // Do not try to map the variable if it or its sub-component was mapped
3707 // already.
3708 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3709 Stack->checkMappableExprComponentListsForDecl(
3710 VD, /*CurrentRegionOnly=*/true,
3711 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3712 OpenMPClauseKind) { return true; }))
3713 continue;
3714 DeclRefExpr *DRE = buildDeclRefExpr(
3715 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3716 Cap.getLocation(), /*RefersToCapture=*/true);
3717 Visit(DRE);
3718 }
3719 }
3720 bool isErrorFound() const { return ErrorFound; }
3721 ArrayRef<Expr *> getImplicitFirstprivate() const {
3722 return ImplicitFirstprivate;
3723 }
3724 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3725 return ImplicitMap[Kind];
3726 }
3727 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3728 return VarsWithInheritedDSA;
3729 }
3730
3731 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3732 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3733 // Process declare target link variables for the target directives.
3734 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3735 for (DeclRefExpr *E : Stack->getLinkGlobals())
3736 Visit(E);
3737 }
3738 }
3739};
3740} // namespace
3741
3742void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3743 switch (DKind) {
3744 case OMPD_parallel:
3745 case OMPD_parallel_for:
3746 case OMPD_parallel_for_simd:
3747 case OMPD_parallel_sections:
3748 case OMPD_parallel_master:
3749 case OMPD_teams:
3750 case OMPD_teams_distribute:
3751 case OMPD_teams_distribute_simd: {
3752 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3753 QualType KmpInt32PtrTy =
3754 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3755 Sema::CapturedParamNameType Params[] = {
3756 std::make_pair(".global_tid.", KmpInt32PtrTy),
3757 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3758 std::make_pair(StringRef(), QualType()) // __context with shared vars
3759 };
3760 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3761 Params);
3762 break;
3763 }
3764 case OMPD_target_teams:
3765 case OMPD_target_parallel:
3766 case OMPD_target_parallel_for:
3767 case OMPD_target_parallel_for_simd:
3768 case OMPD_target_teams_distribute:
3769 case OMPD_target_teams_distribute_simd: {
3770 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3771 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3772 QualType KmpInt32PtrTy =
3773 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3774 QualType Args[] = {VoidPtrTy};
3775 FunctionProtoType::ExtProtoInfo EPI;
3776 EPI.Variadic = true;
3777 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3778 Sema::CapturedParamNameType Params[] = {
3779 std::make_pair(".global_tid.", KmpInt32Ty),
3780 std::make_pair(".part_id.", KmpInt32PtrTy),
3781 std::make_pair(".privates.", VoidPtrTy),
3782 std::make_pair(
3783 ".copy_fn.",
3784 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3785 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3786 std::make_pair(StringRef(), QualType()) // __context with shared vars
3787 };
3788 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3789 Params, /*OpenMPCaptureLevel=*/0);
3790 // Mark this captured region as inlined, because we don't use outlined
3791 // function directly.
3792 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3793 AlwaysInlineAttr::CreateImplicit(
3794 Context, {}, AttributeCommonInfo::AS_Keyword,
3795 AlwaysInlineAttr::Keyword_forceinline));
3796 Sema::CapturedParamNameType ParamsTarget[] = {
3797 std::make_pair(StringRef(), QualType()) // __context with shared vars
3798 };
3799 // Start a captured region for 'target' with no implicit parameters.
3800 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3801 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3802 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3803 std::make_pair(".global_tid.", KmpInt32PtrTy),
3804 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3805 std::make_pair(StringRef(), QualType()) // __context with shared vars
3806 };
3807 // Start a captured region for 'teams' or 'parallel'. Both regions have
3808 // the same implicit parameters.
3809 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3810 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3811 break;
3812 }
3813 case OMPD_target:
3814 case OMPD_target_simd: {
3815 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3816 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3817 QualType KmpInt32PtrTy =
3818 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3819 QualType Args[] = {VoidPtrTy};
3820 FunctionProtoType::ExtProtoInfo EPI;
3821 EPI.Variadic = true;
3822 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3823 Sema::CapturedParamNameType Params[] = {
3824 std::make_pair(".global_tid.", KmpInt32Ty),
3825 std::make_pair(".part_id.", KmpInt32PtrTy),
3826 std::make_pair(".privates.", VoidPtrTy),
3827 std::make_pair(
3828 ".copy_fn.",
3829 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3830 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3831 std::make_pair(StringRef(), QualType()) // __context with shared vars
3832 };
3833 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3834 Params, /*OpenMPCaptureLevel=*/0);
3835 // Mark this captured region as inlined, because we don't use outlined
3836 // function directly.
3837 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3838 AlwaysInlineAttr::CreateImplicit(
3839 Context, {}, AttributeCommonInfo::AS_Keyword,
3840 AlwaysInlineAttr::Keyword_forceinline));
3841 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3842 std::make_pair(StringRef(), QualType()),
3843 /*OpenMPCaptureLevel=*/1);
3844 break;
3845 }
3846 case OMPD_atomic:
3847 case OMPD_critical:
3848 case OMPD_section:
3849 case OMPD_master:
3850 break;
3851 case OMPD_simd:
3852 case OMPD_for:
3853 case OMPD_for_simd:
3854 case OMPD_sections:
3855 case OMPD_single:
3856 case OMPD_taskgroup:
3857 case OMPD_distribute:
3858 case OMPD_distribute_simd:
3859 case OMPD_ordered:
3860 case OMPD_target_data: {
3861 Sema::CapturedParamNameType Params[] = {
3862 std::make_pair(StringRef(), QualType()) // __context with shared vars
3863 };
3864 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3865 Params);
3866 break;
3867 }
3868 case OMPD_task: {
3869 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3870 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3871 QualType KmpInt32PtrTy =
3872 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3873 QualType Args[] = {VoidPtrTy};
3874 FunctionProtoType::ExtProtoInfo EPI;
3875 EPI.Variadic = true;
3876 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3877 Sema::CapturedParamNameType Params[] = {
3878 std::make_pair(".global_tid.", KmpInt32Ty),
3879 std::make_pair(".part_id.", KmpInt32PtrTy),
3880 std::make_pair(".privates.", VoidPtrTy),
3881 std::make_pair(
3882 ".copy_fn.",
3883 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3884 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3885 std::make_pair(StringRef(), QualType()) // __context with shared vars
3886 };
3887 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3888 Params);
3889 // Mark this captured region as inlined, because we don't use outlined
3890 // function directly.
3891 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3892 AlwaysInlineAttr::CreateImplicit(
3893 Context, {}, AttributeCommonInfo::AS_Keyword,
3894 AlwaysInlineAttr::Keyword_forceinline));
3895 break;
3896 }
3897 case OMPD_taskloop:
3898 case OMPD_taskloop_simd:
3899 case OMPD_master_taskloop:
3900 case OMPD_master_taskloop_simd: {
3901 QualType KmpInt32Ty =
3902 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3903 .withConst();
3904 QualType KmpUInt64Ty =
3905 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3906 .withConst();
3907 QualType KmpInt64Ty =
3908 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3909 .withConst();
3910 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3911 QualType KmpInt32PtrTy =
3912 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3913 QualType Args[] = {VoidPtrTy};
3914 FunctionProtoType::ExtProtoInfo EPI;
3915 EPI.Variadic = true;
3916 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3917 Sema::CapturedParamNameType Params[] = {
3918 std::make_pair(".global_tid.", KmpInt32Ty),
3919 std::make_pair(".part_id.", KmpInt32PtrTy),
3920 std::make_pair(".privates.", VoidPtrTy),
3921 std::make_pair(
3922 ".copy_fn.",
3923 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3924 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3925 std::make_pair(".lb.", KmpUInt64Ty),
3926 std::make_pair(".ub.", KmpUInt64Ty),
3927 std::make_pair(".st.", KmpInt64Ty),
3928 std::make_pair(".liter.", KmpInt32Ty),
3929 std::make_pair(".reductions.", VoidPtrTy),
3930 std::make_pair(StringRef(), QualType()) // __context with shared vars
3931 };
3932 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3933 Params);
3934 // Mark this captured region as inlined, because we don't use outlined
3935 // function directly.
3936 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3937 AlwaysInlineAttr::CreateImplicit(
3938 Context, {}, AttributeCommonInfo::AS_Keyword,
3939 AlwaysInlineAttr::Keyword_forceinline));
3940 break;
3941 }
3942 case OMPD_parallel_master_taskloop:
3943 case OMPD_parallel_master_taskloop_simd: {
3944 QualType KmpInt32Ty =
3945 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3946 .withConst();
3947 QualType KmpUInt64Ty =
3948 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3949 .withConst();
3950 QualType KmpInt64Ty =
3951 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3952 .withConst();
3953 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3954 QualType KmpInt32PtrTy =
3955 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3956 Sema::CapturedParamNameType ParamsParallel[] = {
3957 std::make_pair(".global_tid.", KmpInt32PtrTy),
3958 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3959 std::make_pair(StringRef(), QualType()) // __context with shared vars
3960 };
3961 // Start a captured region for 'parallel'.
3962 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3963 ParamsParallel, /*OpenMPCaptureLevel=*/0);
3964 QualType Args[] = {VoidPtrTy};
3965 FunctionProtoType::ExtProtoInfo EPI;
3966 EPI.Variadic = true;
3967 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3968 Sema::CapturedParamNameType Params[] = {
3969 std::make_pair(".global_tid.", KmpInt32Ty),
3970 std::make_pair(".part_id.", KmpInt32PtrTy),
3971 std::make_pair(".privates.", VoidPtrTy),
3972 std::make_pair(
3973 ".copy_fn.",
3974 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3975 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3976 std::make_pair(".lb.", KmpUInt64Ty),
3977 std::make_pair(".ub.", KmpUInt64Ty),
3978 std::make_pair(".st.", KmpInt64Ty),
3979 std::make_pair(".liter.", KmpInt32Ty),
3980 std::make_pair(".reductions.", VoidPtrTy),
3981 std::make_pair(StringRef(), QualType()) // __context with shared vars
3982 };
3983 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3984 Params, /*OpenMPCaptureLevel=*/1);
3985 // Mark this captured region as inlined, because we don't use outlined
3986 // function directly.
3987 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3988 AlwaysInlineAttr::CreateImplicit(
3989 Context, {}, AttributeCommonInfo::AS_Keyword,
3990 AlwaysInlineAttr::Keyword_forceinline));
3991 break;
3992 }
3993 case OMPD_distribute_parallel_for_simd:
3994 case OMPD_distribute_parallel_for: {
3995 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3996 QualType KmpInt32PtrTy =
3997 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3998 Sema::CapturedParamNameType Params[] = {
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 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4006 Params);
4007 break;
4008 }
4009 case OMPD_target_teams_distribute_parallel_for:
4010 case OMPD_target_teams_distribute_parallel_for_simd: {
4011 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4012 QualType KmpInt32PtrTy =
4013 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4014 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4015
4016 QualType Args[] = {VoidPtrTy};
4017 FunctionProtoType::ExtProtoInfo EPI;
4018 EPI.Variadic = true;
4019 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4020 Sema::CapturedParamNameType Params[] = {
4021 std::make_pair(".global_tid.", KmpInt32Ty),
4022 std::make_pair(".part_id.", KmpInt32PtrTy),
4023 std::make_pair(".privates.", VoidPtrTy),
4024 std::make_pair(
4025 ".copy_fn.",
4026 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4027 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4028 std::make_pair(StringRef(), QualType()) // __context with shared vars
4029 };
4030 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4031 Params, /*OpenMPCaptureLevel=*/0);
4032 // Mark this captured region as inlined, because we don't use outlined
4033 // function directly.
4034 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4035 AlwaysInlineAttr::CreateImplicit(
4036 Context, {}, AttributeCommonInfo::AS_Keyword,
4037 AlwaysInlineAttr::Keyword_forceinline));
4038 Sema::CapturedParamNameType ParamsTarget[] = {
4039 std::make_pair(StringRef(), QualType()) // __context with shared vars
4040 };
4041 // Start a captured region for 'target' with no implicit parameters.
4042 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4043 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4044
4045 Sema::CapturedParamNameType ParamsTeams[] = {
4046 std::make_pair(".global_tid.", KmpInt32PtrTy),
4047 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4048 std::make_pair(StringRef(), QualType()) // __context with shared vars
4049 };
4050 // Start a captured region for 'target' with no implicit parameters.
4051 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4052 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4053
4054 Sema::CapturedParamNameType ParamsParallel[] = {
4055 std::make_pair(".global_tid.", KmpInt32PtrTy),
4056 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4057 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4058 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4059 std::make_pair(StringRef(), QualType()) // __context with shared vars
4060 };
4061 // Start a captured region for 'teams' or 'parallel'. Both regions have
4062 // the same implicit parameters.
4063 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4064 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4065 break;
4066 }
4067
4068 case OMPD_teams_distribute_parallel_for:
4069 case OMPD_teams_distribute_parallel_for_simd: {
4070 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4071 QualType KmpInt32PtrTy =
4072 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4073
4074 Sema::CapturedParamNameType ParamsTeams[] = {
4075 std::make_pair(".global_tid.", KmpInt32PtrTy),
4076 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4077 std::make_pair(StringRef(), QualType()) // __context with shared vars
4078 };
4079 // Start a captured region for 'target' with no implicit parameters.
4080 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4081 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4082
4083 Sema::CapturedParamNameType ParamsParallel[] = {
4084 std::make_pair(".global_tid.", KmpInt32PtrTy),
4085 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4086 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4087 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4088 std::make_pair(StringRef(), QualType()) // __context with shared vars
4089 };
4090 // Start a captured region for 'teams' or 'parallel'. Both regions have
4091 // the same implicit parameters.
4092 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4093 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4094 break;
4095 }
4096 case OMPD_target_update:
4097 case OMPD_target_enter_data:
4098 case OMPD_target_exit_data: {
4099 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4100 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4101 QualType KmpInt32PtrTy =
4102 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4103 QualType Args[] = {VoidPtrTy};
4104 FunctionProtoType::ExtProtoInfo EPI;
4105 EPI.Variadic = true;
4106 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4107 Sema::CapturedParamNameType Params[] = {
4108 std::make_pair(".global_tid.", KmpInt32Ty),
4109 std::make_pair(".part_id.", KmpInt32PtrTy),
4110 std::make_pair(".privates.", VoidPtrTy),
4111 std::make_pair(
4112 ".copy_fn.",
4113 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4114 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4115 std::make_pair(StringRef(), QualType()) // __context with shared vars
4116 };
4117 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4118 Params);
4119 // Mark this captured region as inlined, because we don't use outlined
4120 // function directly.
4121 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4122 AlwaysInlineAttr::CreateImplicit(
4123 Context, {}, AttributeCommonInfo::AS_Keyword,
4124 AlwaysInlineAttr::Keyword_forceinline));
4125 break;
4126 }
4127 case OMPD_threadprivate:
4128 case OMPD_allocate:
4129 case OMPD_taskyield:
4130 case OMPD_barrier:
4131 case OMPD_taskwait:
4132 case OMPD_cancellation_point:
4133 case OMPD_cancel:
4134 case OMPD_flush:
4135 case OMPD_depobj:
4136 case OMPD_scan:
4137 case OMPD_declare_reduction:
4138 case OMPD_declare_mapper:
4139 case OMPD_declare_simd:
4140 case OMPD_declare_target:
4141 case OMPD_end_declare_target:
4142 case OMPD_requires:
4143 case OMPD_declare_variant:
4144 case OMPD_begin_declare_variant:
4145 case OMPD_end_declare_variant:
4146 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 4146)
;
4147 case OMPD_unknown:
4148 default:
4149 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 4149)
;
4150 }
4151}
4152
4153int Sema::getNumberOfConstructScopes(unsigned Level) const {
4154 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4155}
4156
4157int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4158 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4159 getOpenMPCaptureRegions(CaptureRegions, DKind);
4160 return CaptureRegions.size();
4161}
4162
4163static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4164 Expr *CaptureExpr, bool WithInit,
4165 bool AsExpression) {
4166 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 4166, __PRETTY_FUNCTION__))
;
4167 ASTContext &C = S.getASTContext();
4168 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4169 QualType Ty = Init->getType();
4170 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4171 if (S.getLangOpts().CPlusPlus) {
4172 Ty = C.getLValueReferenceType(Ty);
4173 } else {
4174 Ty = C.getPointerType(Ty);
4175 ExprResult Res =
4176 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4177 if (!Res.isUsable())
4178 return nullptr;
4179 Init = Res.get();
4180 }
4181 WithInit = true;
4182 }
4183 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4184 CaptureExpr->getBeginLoc());
4185 if (!WithInit)
4186 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4187 S.CurContext->addHiddenDecl(CED);
4188 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4189 return CED;
4190}
4191
4192static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4193 bool WithInit) {
4194 OMPCapturedExprDecl *CD;
4195 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4196 CD = cast<OMPCapturedExprDecl>(VD);
4197 else
4198 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4199 /*AsExpression=*/false);
4200 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4201 CaptureExpr->getExprLoc());
4202}
4203
4204static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4205 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4206 if (!Ref) {
4207 OMPCapturedExprDecl *CD = buildCaptureDecl(
4208 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4209 /*WithInit=*/true, /*AsExpression=*/true);
4210 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4211 CaptureExpr->getExprLoc());
4212 }
4213 ExprResult Res = Ref;
4214 if (!S.getLangOpts().CPlusPlus &&
4215 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4216 Ref->getType()->isPointerType()) {
4217 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4218 if (!Res.isUsable())
4219 return ExprError();
4220 }
4221 return S.DefaultLvalueConversion(Res.get());
4222}
4223
4224namespace {
4225// OpenMP directives parsed in this section are represented as a
4226// CapturedStatement with an associated statement. If a syntax error
4227// is detected during the parsing of the associated statement, the
4228// compiler must abort processing and close the CapturedStatement.
4229//
4230// Combined directives such as 'target parallel' have more than one
4231// nested CapturedStatements. This RAII ensures that we unwind out
4232// of all the nested CapturedStatements when an error is found.
4233class CaptureRegionUnwinderRAII {
4234private:
4235 Sema &S;
4236 bool &ErrorFound;
4237 OpenMPDirectiveKind DKind = OMPD_unknown;
4238
4239public:
4240 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4241 OpenMPDirectiveKind DKind)
4242 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4243 ~CaptureRegionUnwinderRAII() {
4244 if (ErrorFound) {
4245 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4246 while (--ThisCaptureLevel >= 0)
4247 S.ActOnCapturedRegionError();
4248 }
4249 }
4250};
4251} // namespace
4252
4253void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4254 // Capture variables captured by reference in lambdas for target-based
4255 // directives.
4256 if (!CurContext->isDependentContext() &&
4257 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4258 isOpenMPTargetDataManagementDirective(
4259 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4260 QualType Type = V->getType();
4261 if (const auto *RD = Type.getCanonicalType()
4262 .getNonReferenceType()
4263 ->getAsCXXRecordDecl()) {
4264 bool SavedForceCaptureByReferenceInTargetExecutable =
4265 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4266 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4267 /*V=*/true);
4268 if (RD->isLambda()) {
4269 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4270 FieldDecl *ThisCapture;
4271 RD->getCaptureFields(Captures, ThisCapture);
4272 for (const LambdaCapture &LC : RD->captures()) {
4273 if (LC.getCaptureKind() == LCK_ByRef) {
4274 VarDecl *VD = LC.getCapturedVar();
4275 DeclContext *VDC = VD->getDeclContext();
4276 if (!VDC->Encloses(CurContext))
4277 continue;
4278 MarkVariableReferenced(LC.getLocation(), VD);
4279 } else if (LC.getCaptureKind() == LCK_This) {
4280 QualType ThisTy = getCurrentThisType();
4281 if (!ThisTy.isNull() &&
4282 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4283 CheckCXXThisCapture(LC.getLocation());
4284 }
4285 }
4286 }
4287 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4288 SavedForceCaptureByReferenceInTargetExecutable);
4289 }
4290 }
4291}
4292
4293static bool checkOrderedOrderSpecified(Sema &S,
4294 const ArrayRef<OMPClause *> Clauses) {
4295 const OMPOrderedClause *Ordered = nullptr;
4296 const OMPOrderClause *Order = nullptr;
4297
4298 for (const OMPClause *Clause : Clauses) {
4299 if (Clause->getClauseKind() == OMPC_ordered)
4300 Ordered = cast<OMPOrderedClause>(Clause);
4301 else if (Clause->getClauseKind() == OMPC_order) {
4302 Order = cast<OMPOrderClause>(Clause);
4303 if (Order->getKind() != OMPC_ORDER_concurrent)
4304 Order = nullptr;
4305 }
4306 if (Ordered && Order)
4307 break;
4308 }
4309
4310 if (Ordered && Order) {
4311 S.Diag(Order->getKindKwLoc(),
4312 diag::err_omp_simple_clause_incompatible_with_ordered)
4313 << getOpenMPClauseName(OMPC_order)
4314 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4315 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4316 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4317 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4318 return true;
4319 }
4320 return false;
4321}
4322
4323StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4324 ArrayRef<OMPClause *> Clauses) {
4325 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4326 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4327 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4328 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master)
4329 return S;
4330
4331 bool ErrorFound = false;
4332 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4333 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4334 if (!S.isUsable()) {
4335 ErrorFound = true;
Value stored to 'ErrorFound' is never read
4336 return StmtError();
4337 }
4338
4339 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4340 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4341 OMPOrderedClause *OC = nullptr;
4342 OMPScheduleClause *SC = nullptr;
4343 SmallVector<const OMPLinearClause *, 4> LCs;
4344 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4345 // This is required for proper codegen.
4346 for (OMPClause *Clause : Clauses) {
4347 if (!LangOpts.OpenMPSimd &&
4348 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4349 Clause->getClauseKind() == OMPC_in_reduction) {
4350 // Capture taskgroup task_reduction descriptors inside the tasking regions
4351 // with the corresponding in_reduction items.
4352 auto *IRC = cast<OMPInReductionClause>(Clause);
4353 for (Expr *E : IRC->taskgroup_descriptors())
4354 if (E)
4355 MarkDeclarationsReferencedInExpr(E);
4356 }
4357 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4358 Clause->getClauseKind() == OMPC_copyprivate ||
4359 (getLangOpts().OpenMPUseTLS &&
4360 getASTContext().getTargetInfo().isTLSSupported() &&
4361 Clause->getClauseKind() == OMPC_copyin)) {
4362 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4363 // Mark all variables in private list clauses as used in inner region.
4364 for (Stmt *VarRef : Clause->children()) {
4365 if (auto *E = cast_or_null<Expr>(VarRef)) {
4366 MarkDeclarationsReferencedInExpr(E);
4367 }
4368 }
4369 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4370 } else if (CaptureRegions.size() > 1 ||
4371 CaptureRegions.back() != OMPD_unknown) {
4372 if (auto *C = OMPClauseWithPreInit::get(Clause))
4373 PICs.push_back(C);
4374 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4375 if (Expr *E = C->getPostUpdateExpr())
4376 MarkDeclarationsReferencedInExpr(E);
4377 }
4378 }
4379 if (Clause->getClauseKind() == OMPC_schedule)
4380 SC = cast<OMPScheduleClause>(Clause);
4381 else if (Clause->getClauseKind() == OMPC_ordered)
4382 OC = cast<OMPOrderedClause>(Clause);
4383 else if (Clause->getClauseKind() == OMPC_linear)
4384 LCs.push_back(cast<OMPLinearClause>(Clause));
4385 }
4386 // Capture allocator expressions if used.
4387 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4388 MarkDeclarationsReferencedInExpr(E);
4389 // OpenMP, 2.7.1 Loop Construct, Restrictions
4390 // The nonmonotonic modifier cannot be specified if an ordered clause is
4391 // specified.
4392 if (SC &&
4393 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4394 SC->getSecondScheduleModifier() ==
4395 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4396 OC) {
4397 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4398 ? SC->getFirstScheduleModifierLoc()
4399 : SC->getSecondScheduleModifierLoc(),
4400 diag::err_omp_simple_clause_incompatible_with_ordered)
4401 << getOpenMPClauseName(OMPC_schedule)
4402 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4403 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4404 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4405 ErrorFound = true;
4406 }
4407 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4408 // If an order(concurrent) clause is present, an ordered clause may not appear
4409 // on the same directive.
4410 if (checkOrderedOrderSpecified(*this, Clauses))
4411 ErrorFound = true;
4412 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4413 for (const OMPLinearClause *C : LCs) {
4414 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4415 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4416 }
4417 ErrorFound = true;
4418 }
4419 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4420 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4421 OC->getNumForLoops()) {
4422 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4423 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4424 ErrorFound = true;
4425 }
4426 if (ErrorFound) {
4427 return StmtError();
4428 }
4429 StmtResult SR = S;
4430 unsigned CompletedRegions = 0;
4431 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4432 // Mark all variables in private list clauses as used in inner region.
4433 // Required for proper codegen of combined directives.
4434 // TODO: add processing for other clauses.
4435 if (ThisCaptureRegion != OMPD_unknown) {
4436 for (const clang::OMPClauseWithPreInit *C : PICs) {
4437 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4438 // Find the particular capture region for the clause if the
4439 // directive is a combined one with multiple capture regions.
4440 // If the directive is not a combined one, the capture region
4441 // associated with the clause is OMPD_unknown and is generated
4442 // only once.
4443 if (CaptureRegion == ThisCaptureRegion ||
4444 CaptureRegion == OMPD_unknown) {
4445 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4446 for (Decl *D : DS->decls())
4447 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4448 }
4449 }
4450 }
4451 }
4452 if (ThisCaptureRegion == OMPD_target) {
4453 // Capture allocator traits in the target region. They are used implicitly
4454 // and, thus, are not captured by default.
4455 for (OMPClause *C : Clauses) {
4456 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4457 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4458 ++I) {
4459 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4460 if (Expr *E = D.AllocatorTraits)
4461 MarkDeclarationsReferencedInExpr(E);
4462 }
4463 continue;
4464 }
4465 }
4466 }
4467 if (++CompletedRegions == CaptureRegions.size())
4468 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4469 SR = ActOnCapturedRegionEnd(SR.get());
4470 }
4471 return SR;
4472}
4473
4474static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4475 OpenMPDirectiveKind CancelRegion,
4476 SourceLocation StartLoc) {
4477 // CancelRegion is only needed for cancel and cancellation_point.
4478 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4479 return false;
4480
4481 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4482 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4483 return false;
4484
4485 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4486 << getOpenMPDirectiveName(CancelRegion);
4487 return true;
4488}
4489
4490static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4491 OpenMPDirectiveKind CurrentRegion,
4492 const DeclarationNameInfo &CurrentName,
4493 OpenMPDirectiveKind CancelRegion,
4494 SourceLocation StartLoc) {
4495 if (Stack->getCurScope()) {
4496 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4497 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4498 bool NestingProhibited = false;
4499 bool CloseNesting = true;
4500 bool OrphanSeen = false;
4501 enum {
4502 NoRecommend,
4503 ShouldBeInParallelRegion,
4504 ShouldBeInOrderedRegion,
4505 ShouldBeInTargetRegion,
4506 ShouldBeInTeamsRegion,
4507 ShouldBeInLoopSimdRegion,
4508 } Recommend = NoRecommend;
4509 if (isOpenMPSimdDirective(ParentRegion) &&
4510 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4511 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4512 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4513 CurrentRegion != OMPD_scan))) {
4514 // OpenMP [2.16, Nesting of Regions]
4515 // OpenMP constructs may not be nested inside a simd region.
4516 // OpenMP [2.8.1,simd Construct, Restrictions]
4517 // An ordered construct with the simd clause is the only OpenMP
4518 // construct that can appear in the simd region.
4519 // Allowing a SIMD construct nested in another SIMD construct is an
4520 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4521 // message.
4522 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4523 // The only OpenMP constructs that can be encountered during execution of
4524 // a simd region are the atomic construct, the loop construct, the simd
4525 // construct and the ordered construct with the simd clause.
4526 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4527 ? diag::err_omp_prohibited_region_simd
4528 : diag::warn_omp_nesting_simd)
4529 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4530 return CurrentRegion != OMPD_simd;
4531 }
4532 if (ParentRegion == OMPD_atomic) {
4533 // OpenMP [2.16, Nesting of Regions]
4534 // OpenMP constructs may not be nested inside an atomic region.
4535 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4536 return true;
4537 }
4538 if (CurrentRegion == OMPD_section) {
4539 // OpenMP [2.7.2, sections Construct, Restrictions]
4540 // Orphaned section directives are prohibited. That is, the section
4541 // directives must appear within the sections construct and must not be
4542 // encountered elsewhere in the sections region.
4543 if (ParentRegion != OMPD_sections &&
4544 ParentRegion != OMPD_parallel_sections) {
4545 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4546 << (ParentRegion != OMPD_unknown)
4547 << getOpenMPDirectiveName(ParentRegion);
4548 return true;
4549 }
4550 return false;
4551 }
4552 // Allow some constructs (except teams and cancellation constructs) to be
4553 // orphaned (they could be used in functions, called from OpenMP regions
4554 // with the required preconditions).
4555 if (ParentRegion == OMPD_unknown &&
4556 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4557 CurrentRegion != OMPD_cancellation_point &&
4558 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4559 return false;
4560 if (CurrentRegion == OMPD_cancellation_point ||
4561 CurrentRegion == OMPD_cancel) {
4562 // OpenMP [2.16, Nesting of Regions]
4563 // A cancellation point construct for which construct-type-clause is
4564 // taskgroup must be nested inside a task construct. A cancellation
4565 // point construct for which construct-type-clause is not taskgroup must
4566 // be closely nested inside an OpenMP construct that matches the type
4567 // specified in construct-type-clause.
4568 // A cancel construct for which construct-type-clause is taskgroup must be
4569 // nested inside a task construct. A cancel construct for which
4570 // construct-type-clause is not taskgroup must be closely nested inside an
4571 // OpenMP construct that matches the type specified in
4572 // construct-type-clause.
4573 NestingProhibited =
4574 !((CancelRegion == OMPD_parallel &&
4575 (ParentRegion == OMPD_parallel ||
4576 ParentRegion == OMPD_target_parallel)) ||
4577 (CancelRegion == OMPD_for &&
4578 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4579 ParentRegion == OMPD_target_parallel_for ||
4580 ParentRegion == OMPD_distribute_parallel_for ||
4581 ParentRegion == OMPD_teams_distribute_parallel_for ||
4582 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4583 (CancelRegion == OMPD_taskgroup &&
4584 (ParentRegion == OMPD_task ||
4585 (SemaRef.getLangOpts().OpenMP >= 50 &&
4586 (ParentRegion == OMPD_taskloop ||
4587 ParentRegion == OMPD_master_taskloop ||
4588 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4589 (CancelRegion == OMPD_sections &&
4590 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4591 ParentRegion == OMPD_parallel_sections)));
4592 OrphanSeen = ParentRegion == OMPD_unknown;
4593 } else if (CurrentRegion == OMPD_master) {
4594 // OpenMP [2.16, Nesting of Regions]
4595 // A master region may not be closely nested inside a worksharing,
4596 // atomic, or explicit task region.
4597 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4598 isOpenMPTaskingDirective(ParentRegion);
4599 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4600 // OpenMP [2.16, Nesting of Regions]
4601 // A critical region may not be nested (closely or otherwise) inside a
4602 // critical region with the same name. Note that this restriction is not
4603 // sufficient to prevent deadlock.
4604 SourceLocation PreviousCriticalLoc;
4605 bool DeadLock = Stack->hasDirective(
4606 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4607 const DeclarationNameInfo &DNI,
4608 SourceLocation Loc) {
4609 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4610 PreviousCriticalLoc = Loc;
4611 return true;
4612 }
4613 return false;
4614 },
4615 false /* skip top directive */);
4616 if (DeadLock) {
4617 SemaRef.Diag(StartLoc,
4618 diag::err_omp_prohibited_region_critical_same_name)
4619 << CurrentName.getName();
4620 if (PreviousCriticalLoc.isValid())
4621 SemaRef.Diag(PreviousCriticalLoc,
4622 diag::note_omp_previous_critical_region);
4623 return true;
4624 }
4625 } else if (CurrentRegion == OMPD_barrier) {
4626 // OpenMP [2.16, Nesting of Regions]
4627 // A barrier region may not be closely nested inside a worksharing,
4628 // explicit task, critical, ordered, atomic, or master region.
4629 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4630 isOpenMPTaskingDirective(ParentRegion) ||
4631 ParentRegion == OMPD_master ||
4632 ParentRegion == OMPD_parallel_master ||
4633 ParentRegion == OMPD_critical ||
4634 ParentRegion == OMPD_ordered;
4635 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4636 !isOpenMPParallelDirective(CurrentRegion) &&
4637 !isOpenMPTeamsDirective(CurrentRegion)) {
4638 // OpenMP [2.16, Nesting of Regions]
4639 // A worksharing region may not be closely nested inside a worksharing,
4640 // explicit task, critical, ordered, atomic, or master region.
4641 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4642 isOpenMPTaskingDirective(ParentRegion) ||
4643 ParentRegion == OMPD_master ||
4644 ParentRegion == OMPD_parallel_master ||
4645 ParentRegion == OMPD_critical ||
4646 ParentRegion == OMPD_ordered;
4647 Recommend = ShouldBeInParallelRegion;
4648 } else if (CurrentRegion == OMPD_ordered) {
4649 // OpenMP [2.16, Nesting of Regions]
4650 // An ordered region may not be closely nested inside a critical,
4651 // atomic, or explicit task region.
4652 // An ordered region must be closely nested inside a loop region (or
4653 // parallel loop region) with an ordered clause.
4654 // OpenMP [2.8.1,simd Construct, Restrictions]
4655 // An ordered construct with the simd clause is the only OpenMP construct
4656 // that can appear in the simd region.
4657 NestingProhibited = ParentRegion == OMPD_critical ||
4658 isOpenMPTaskingDirective(ParentRegion) ||
4659 !(isOpenMPSimdDirective(ParentRegion) ||
4660 Stack->isParentOrderedRegion());
4661 Recommend = ShouldBeInOrderedRegion;
4662 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4663 // OpenMP [2.16, Nesting of Regions]
4664 // If specified, a teams construct must be contained within a target
4665 // construct.
4666 NestingProhibited =
4667 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4668 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4669 ParentRegion != OMPD_target);
4670 OrphanSeen = ParentRegion == OMPD_unknown;
4671 Recommend = ShouldBeInTargetRegion;
4672 } else if (CurrentRegion == OMPD_scan) {
4673 // OpenMP [2.16, Nesting of Regions]
4674 // If specified, a teams construct must be contained within a target
4675 // construct.
4676 NestingProhibited =
4677 SemaRef.LangOpts.OpenMP < 50 ||
4678 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4679 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4680 ParentRegion != OMPD_parallel_for_simd);
4681 OrphanSeen = ParentRegion == OMPD_unknown;
4682 Recommend = ShouldBeInLoopSimdRegion;
4683 }
4684 if (!NestingProhibited &&
4685 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4686 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4687 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4688 // OpenMP [2.16, Nesting of Regions]
4689 // distribute, parallel, parallel sections, parallel workshare, and the
4690 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4691 // constructs that can be closely nested in the teams region.
4692 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4693 !isOpenMPDistributeDirective(CurrentRegion);
4694 Recommend = ShouldBeInParallelRegion;
4695 }
4696 if (!NestingProhibited &&
4697 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4698 // OpenMP 4.5 [2.17 Nesting of Regions]
4699 // The region associated with the distribute construct must be strictly
4700 // nested inside a teams region
4701 NestingProhibited =
4702 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4703 Recommend = ShouldBeInTeamsRegion;
4704 }
4705 if (!NestingProhibited &&
4706 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4707 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4708 // OpenMP 4.5 [2.17 Nesting of Regions]
4709 // If a target, target update, target data, target enter data, or
4710 // target exit data construct is encountered during execution of a
4711 // target region, the behavior is unspecified.
4712 NestingProhibited = Stack->hasDirective(
4713 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4714 SourceLocation) {
4715 if (isOpenMPTargetExecutionDirective(K)) {
4716 OffendingRegion = K;
4717 return true;
4718 }
4719 return false;
4720 },
4721 false /* don't skip top directive */);
4722 CloseNesting = false;
4723 }
4724 if (NestingProhibited) {
4725 if (OrphanSeen) {
4726 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4727 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4728 } else {
4729 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4730 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4731 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4732 }
4733 return true;
4734 }
4735 }
4736 return false;
4737}
4738
4739struct Kind2Unsigned {
4740 using argument_type = OpenMPDirectiveKind;
4741 unsigned operator()(argument_type DK) { return unsigned(DK); }
4742};
4743static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4744 ArrayRef<OMPClause *> Clauses,
4745 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4746 bool ErrorFound = false;
4747 unsigned NamedModifiersNumber = 0;
4748 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4749 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4750 SmallVector<SourceLocation, 4> NameModifierLoc;
4751 for (const OMPClause *C : Clauses) {
4752 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4753 // At most one if clause without a directive-name-modifier can appear on
4754 // the directive.
4755 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4756 if (FoundNameModifiers[CurNM]) {
4757 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4758 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4759 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4760 ErrorFound = true;
4761 } else if (CurNM != OMPD_unknown) {
4762 NameModifierLoc.push_back(IC->getNameModifierLoc());
4763 ++NamedModifiersNumber;
4764 }
4765 FoundNameModifiers[CurNM] = IC;
4766 if (CurNM == OMPD_unknown)
4767 continue;
4768 // Check if the specified name modifier is allowed for the current
4769 // directive.
4770 // At most one if clause with the particular directive-name-modifier can
4771 // appear on the directive.
4772 bool MatchFound = false;
4773 for (auto NM : AllowedNameModifiers) {
4774 if (CurNM == NM) {
4775 MatchFound = true;
4776 break;
4777 }
4778 }
4779 if (!MatchFound) {
4780 S.Diag(IC->getNameModifierLoc(),
4781 diag::err_omp_wrong_if_directive_name_modifier)
4782 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4783 ErrorFound = true;
4784 }
4785 }
4786 }
4787 // If any if clause on the directive includes a directive-name-modifier then
4788 // all if clauses on the directive must include a directive-name-modifier.
4789 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4790 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4791 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4792 diag::err_omp_no_more_if_clause);
4793 } else {
4794 std::string Values;
4795 std::string Sep(", ");
4796 unsigned AllowedCnt = 0;
4797 unsigned TotalAllowedNum =
4798 AllowedNameModifiers.size() - NamedModifiersNumber;
4799 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4800 ++Cnt) {
4801 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4802 if (!FoundNameModifiers[NM]) {
4803 Values += "'";
4804 Values += getOpenMPDirectiveName(NM);
4805 Values += "'";
4806 if (AllowedCnt + 2 == TotalAllowedNum)
4807 Values += " or ";
4808 else if (AllowedCnt + 1 != TotalAllowedNum)
4809 Values += Sep;
4810 ++AllowedCnt;
4811 }
4812 }
4813 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4814 diag::err_omp_unnamed_if_clause)
4815 << (TotalAllowedNum > 1) << Values;
4816 }
4817 for (SourceLocation Loc : NameModifierLoc) {
4818 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4819 }
4820 ErrorFound = true;
4821 }
4822 return ErrorFound;
4823}
4824
4825static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4826 SourceLocation &ELoc,
4827 SourceRange &ERange,
4828 bool AllowArraySection) {
4829 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4830 RefExpr->containsUnexpandedParameterPack())
4831 return std::make_pair(nullptr, true);
4832
4833 // OpenMP [3.1, C/C++]
4834 // A list item is a variable name.
4835 // OpenMP [2.9.3.3, Restrictions, p.1]
4836 // A variable that is part of another variable (as an array or
4837 // structure element) cannot appear in a private clause.
4838 RefExpr = RefExpr->IgnoreParens();
4839 enum {
4840 NoArrayExpr = -1,
4841 ArraySubscript = 0,
4842 OMPArraySection = 1
4843 } IsArrayExpr = NoArrayExpr;
4844 if (AllowArraySection) {
4845 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4846 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4847 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4848 Base = TempASE->getBase()->IgnoreParenImpCasts();
4849 RefExpr = Base;
4850 IsArrayExpr = ArraySubscript;
4851 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4852 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4853 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4854 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4855 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4856 Base = TempASE->getBase()->IgnoreParenImpCasts();
4857 RefExpr = Base;
4858 IsArrayExpr = OMPArraySection;
4859 }
4860 }
4861 ELoc = RefExpr->getExprLoc();
4862 ERange = RefExpr->getSourceRange();
4863 RefExpr = RefExpr->IgnoreParenImpCasts();
4864 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4865 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4866 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4867 (S.getCurrentThisType().isNull() || !ME ||
4868 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4869 !isa<FieldDecl>(ME->getMemberDecl()))) {
4870 if (IsArrayExpr != NoArrayExpr) {
4871 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4872 << ERange;
4873 } else {
4874 S.Diag(ELoc,
4875 AllowArraySection
4876 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4877 : diag::err_omp_expected_var_name_member_expr)
4878 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4879 }
4880 return std::make_pair(nullptr, false);
4881 }
4882 return std::make_pair(
4883 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4884}
4885
4886namespace {
4887/// Checks if the allocator is used in uses_allocators clause to be allowed in
4888/// target regions.
4889class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4890 DSAStackTy *S = nullptr;
4891
4892public:
4893 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4894 return S->isUsesAllocatorsDecl(E->getDecl())
4895 .getValueOr(
4896 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4897 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4898 }
4899 bool VisitStmt(const Stmt *S) {
4900 for (const Stmt *Child : S->children()) {
4901 if (Child && Visit(Child))
4902 return true;
4903 }
4904 return false;
4905 }
4906 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4907};
4908} // namespace
4909
4910static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4911 ArrayRef<OMPClause *> Clauses) {
4912 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 4913, __PRETTY_FUNCTION__))
4913 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 4913, __PRETTY_FUNCTION__))
;
4914 auto AllocateRange =
4915 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4916 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4917 DeclToCopy;
4918 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4919 return isOpenMPPrivate(C->getClauseKind());
4920 });
4921 for (OMPClause *Cl : PrivateRange) {
4922 MutableArrayRef<Expr *>::iterator I, It, Et;
4923 if (Cl->getClauseKind() == OMPC_private) {
4924 auto *PC = cast<OMPPrivateClause>(Cl);
4925 I = PC->private_copies().begin();
4926 It = PC->varlist_begin();
4927 Et = PC->varlist_end();
4928 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4929 auto *PC = cast<OMPFirstprivateClause>(Cl);
4930 I = PC->private_copies().begin();
4931 It = PC->varlist_begin();
4932 Et = PC->varlist_end();
4933 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4934 auto *PC = cast<OMPLastprivateClause>(Cl);
4935 I = PC->private_copies().begin();
4936 It = PC->varlist_begin();
4937 Et = PC->varlist_end();
4938 } else if (Cl->getClauseKind() == OMPC_linear) {
4939 auto *PC = cast<OMPLinearClause>(Cl);
4940 I = PC->privates().begin();
4941 It = PC->varlist_begin();
4942 Et = PC->varlist_end();
4943 } else if (Cl->getClauseKind() == OMPC_reduction) {
4944 auto *PC = cast<OMPReductionClause>(Cl);
4945 I = PC->privates().begin();
4946 It = PC->varlist_begin();
4947 Et = PC->varlist_end();
4948 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4949 auto *PC = cast<OMPTaskReductionClause>(Cl);
4950 I = PC->privates().begin();
4951 It = PC->varlist_begin();
4952 Et = PC->varlist_end();
4953 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4954 auto *PC = cast<OMPInReductionClause>(Cl);
4955 I = PC->privates().begin();
4956 It = PC->varlist_begin();
4957 Et = PC->varlist_end();
4958 } else {
4959 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 4959)
;
4960 }
4961 for (Expr *E : llvm::make_range(It, Et)) {
4962 if (!*I) {
4963 ++I;
4964 continue;
4965 }
4966 SourceLocation ELoc;
4967 SourceRange ERange;
4968 Expr *SimpleRefExpr = E;
4969 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4970 /*AllowArraySection=*/true);
4971 DeclToCopy.try_emplace(Res.first,
4972 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4973 ++I;
4974 }
4975 }
4976 for (OMPClause *C : AllocateRange) {
4977 auto *AC = cast<OMPAllocateClause>(C);
4978 if (S.getLangOpts().OpenMP >= 50 &&
4979 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4980 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4981 AC->getAllocator()) {
4982 Expr *Allocator = AC->getAllocator();
4983 // OpenMP, 2.12.5 target Construct
4984 // Memory allocators that do not appear in a uses_allocators clause cannot
4985 // appear as an allocator in an allocate clause or be used in the target
4986 // region unless a requires directive with the dynamic_allocators clause
4987 // is present in the same compilation unit.
4988 AllocatorChecker Checker(Stack);
4989 if (Checker.Visit(Allocator))
4990 S.Diag(Allocator->getExprLoc(),
4991 diag::err_omp_allocator_not_in_uses_allocators)
4992 << Allocator->getSourceRange();
4993 }
4994 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4995 getAllocatorKind(S, Stack, AC->getAllocator());
4996 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4997 // For task, taskloop or target directives, allocation requests to memory
4998 // allocators with the trait access set to thread result in unspecified
4999 // behavior.
5000 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5001 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5002 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5003 S.Diag(AC->getAllocator()->getExprLoc(),
5004 diag::warn_omp_allocate_thread_on_task_target_directive)
5005 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5006 }
5007 for (Expr *E : AC->varlists()) {
5008 SourceLocation ELoc;
5009 SourceRange ERange;
5010 Expr *SimpleRefExpr = E;
5011 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5012 ValueDecl *VD = Res.first;
5013 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5014 if (!isOpenMPPrivate(Data.CKind)) {
5015 S.Diag(E->getExprLoc(),
5016 diag::err_omp_expected_private_copy_for_allocate);
5017 continue;
5018 }
5019 VarDecl *PrivateVD = DeclToCopy[VD];
5020 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5021 AllocatorKind, AC->getAllocator()))
5022 continue;
5023 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5024 E->getSourceRange());
5025 }
5026 }
5027}
5028
5029StmtResult Sema::ActOnOpenMPExecutableDirective(
5030 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5031 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5032 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5033 StmtResult Res = StmtError();
5034 // First check CancelRegion which is then used in checkNestingOfRegions.
5035 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5036 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5037 StartLoc))
5038 return StmtError();
5039
5040 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5041 VarsWithInheritedDSAType VarsWithInheritedDSA;
5042 bool ErrorFound = false;
5043 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5044 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5045 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5046 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5046, __PRETTY_FUNCTION__))
;
5047
5048 // Check default data sharing attributes for referenced variables.
5049 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5050 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5051 Stmt *S = AStmt;
5052 while (--ThisCaptureLevel >= 0)
5053 S = cast<CapturedStmt>(S)->getCapturedStmt();
5054 DSAChecker.Visit(S);
5055 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5056 !isOpenMPTaskingDirective(Kind)) {
5057 // Visit subcaptures to generate implicit clauses for captured vars.
5058 auto *CS = cast<CapturedStmt>(AStmt);
5059 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5060 getOpenMPCaptureRegions(CaptureRegions, Kind);
5061 // Ignore outer tasking regions for target directives.
5062 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5063 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5064 DSAChecker.visitSubCaptures(CS);
5065 }
5066 if (DSAChecker.isErrorFound())
5067 return StmtError();
5068 // Generate list of implicitly defined firstprivate variables.
5069 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5070
5071 SmallVector<Expr *, 4> ImplicitFirstprivates(
5072 DSAChecker.getImplicitFirstprivate().begin(),
5073 DSAChecker.getImplicitFirstprivate().end());
5074 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5075 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5076 ArrayRef<Expr *> ImplicitMap =
5077 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5078 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5079 }
5080 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5081 for (OMPClause *C : Clauses) {
5082 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5083 for (Expr *E : IRC->taskgroup_descriptors())
5084 if (E)
5085 ImplicitFirstprivates.emplace_back(E);
5086 }
5087 // OpenMP 5.0, 2.10.1 task Construct
5088 // [detach clause]... The event-handle will be considered as if it was
5089 // specified on a firstprivate clause.
5090 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5091 ImplicitFirstprivates.push_back(DC->getEventHandler());
5092 }
5093 if (!ImplicitFirstprivates.empty()) {
5094 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5095 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5096 SourceLocation())) {
5097 ClausesWithImplicit.push_back(Implicit);
5098 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5099 ImplicitFirstprivates.size();
5100 } else {
5101 ErrorFound = true;
5102 }
5103 }
5104 int ClauseKindCnt = -1;
5105 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5106 ++ClauseKindCnt;
5107 if (ImplicitMap.empty())
5108 continue;
5109 CXXScopeSpec MapperIdScopeSpec;
5110 DeclarationNameInfo MapperId;
5111 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5112 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5113 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5114 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5115 ImplicitMap, OMPVarListLocTy())) {
5116 ClausesWithImplicit.emplace_back(Implicit);
5117 ErrorFound |=
5118 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5119 } else {
5120 ErrorFound = true;
5121 }
5122 }
5123 }
5124
5125 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5126 switch (Kind) {
5127 case OMPD_parallel:
5128 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5129 EndLoc);
5130 AllowedNameModifiers.push_back(OMPD_parallel);
5131 break;
5132 case OMPD_simd:
5133 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5134 VarsWithInheritedDSA);
5135 if (LangOpts.OpenMP >= 50)
5136 AllowedNameModifiers.push_back(OMPD_simd);
5137 break;
5138 case OMPD_for:
5139 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5140 VarsWithInheritedDSA);
5141 break;
5142 case OMPD_for_simd:
5143 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5144 EndLoc, VarsWithInheritedDSA);
5145 if (LangOpts.OpenMP >= 50)
5146 AllowedNameModifiers.push_back(OMPD_simd);
5147 break;
5148 case OMPD_sections:
5149 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5150 EndLoc);
5151 break;
5152 case OMPD_section:
5153 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5154, __PRETTY_FUNCTION__))
5154 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5154, __PRETTY_FUNCTION__))
;
5155 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5156 break;
5157 case OMPD_single:
5158 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5159 EndLoc);
5160 break;
5161 case OMPD_master:
5162 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5163, __PRETTY_FUNCTION__))
5163 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5163, __PRETTY_FUNCTION__))
;
5164 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5165 break;
5166 case OMPD_critical:
5167 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5168 StartLoc, EndLoc);
5169 break;
5170 case OMPD_parallel_for:
5171 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5172 EndLoc, VarsWithInheritedDSA);
5173 AllowedNameModifiers.push_back(OMPD_parallel);
5174 break;
5175 case OMPD_parallel_for_simd:
5176 Res = ActOnOpenMPParallelForSimdDirective(
5177 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5178 AllowedNameModifiers.push_back(OMPD_parallel);
5179 if (LangOpts.OpenMP >= 50)
5180 AllowedNameModifiers.push_back(OMPD_simd);
5181 break;
5182 case OMPD_parallel_master:
5183 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5184 StartLoc, EndLoc);
5185 AllowedNameModifiers.push_back(OMPD_parallel);
5186 break;
5187 case OMPD_parallel_sections:
5188 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5189 StartLoc, EndLoc);
5190 AllowedNameModifiers.push_back(OMPD_parallel);
5191 break;
5192 case OMPD_task:
5193 Res =
5194 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5195 AllowedNameModifiers.push_back(OMPD_task);
5196 break;
5197 case OMPD_taskyield:
5198 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5199, __PRETTY_FUNCTION__))
5199 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5199, __PRETTY_FUNCTION__))
;
5200 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5201, __PRETTY_FUNCTION__))
5201 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5201, __PRETTY_FUNCTION__))
;
5202 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5203 break;
5204 case OMPD_barrier:
5205 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5206, __PRETTY_FUNCTION__))
5206 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5206, __PRETTY_FUNCTION__))
;
5207 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5208, __PRETTY_FUNCTION__))
5208 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5208, __PRETTY_FUNCTION__))
;
5209 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5210 break;
5211 case OMPD_taskwait:
5212 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5213, __PRETTY_FUNCTION__))
5213 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5213, __PRETTY_FUNCTION__))
;
5214 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5215, __PRETTY_FUNCTION__))
5215 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5215, __PRETTY_FUNCTION__))
;
5216 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5217 break;
5218 case OMPD_taskgroup:
5219 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5220 EndLoc);
5221 break;
5222 case OMPD_flush:
5223 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5224, __PRETTY_FUNCTION__))
5224 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5224, __PRETTY_FUNCTION__))
;
5225 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5226 break;
5227 case OMPD_depobj:
5228 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5229, __PRETTY_FUNCTION__))
5229 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5229, __PRETTY_FUNCTION__))
;
5230 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5231 break;
5232 case OMPD_scan:
5233 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5234, __PRETTY_FUNCTION__))
5234 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5234, __PRETTY_FUNCTION__))
;
5235 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5236 break;
5237 case OMPD_ordered:
5238 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5239 EndLoc);
5240 break;
5241 case OMPD_atomic:
5242 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5243 EndLoc);
5244 break;
5245 case OMPD_teams:
5246 Res =
5247 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5248 break;
5249 case OMPD_target:
5250 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5251 EndLoc);
5252 AllowedNameModifiers.push_back(OMPD_target);
5253 break;
5254 case OMPD_target_parallel:
5255 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5256 StartLoc, EndLoc);
5257 AllowedNameModifiers.push_back(OMPD_target);
5258 AllowedNameModifiers.push_back(OMPD_parallel);
5259 break;
5260 case OMPD_target_parallel_for:
5261 Res = ActOnOpenMPTargetParallelForDirective(
5262 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5263 AllowedNameModifiers.push_back(OMPD_target);
5264 AllowedNameModifiers.push_back(OMPD_parallel);
5265 break;
5266 case OMPD_cancellation_point:
5267 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5268, __PRETTY_FUNCTION__))
5268 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5268, __PRETTY_FUNCTION__))
;
5269 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5270, __PRETTY_FUNCTION__))
5270 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5270, __PRETTY_FUNCTION__))
;
5271 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5272 break;
5273 case OMPD_cancel:
5274 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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5275, __PRETTY_FUNCTION__))
5275 "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~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5275, __PRETTY_FUNCTION__))
;
5276 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5277 CancelRegion);
5278 AllowedNameModifiers.push_back(OMPD_cancel);
5279 break;
5280 case OMPD_target_data:
5281 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5282 EndLoc);
5283 AllowedNameModifiers.push_back(OMPD_target_data);
5284 break;
5285 case OMPD_target_enter_data:
5286 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5287 EndLoc, AStmt);
5288 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5289 break;
5290 case OMPD_target_exit_data:
5291 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5292 EndLoc, AStmt);
5293 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5294 break;
5295 case OMPD_taskloop:
5296 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5297 EndLoc, VarsWithInheritedDSA);
5298 AllowedNameModifiers.push_back(OMPD_taskloop);
5299 break;
5300 case OMPD_taskloop_simd:
5301 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5302 EndLoc, VarsWithInheritedDSA);
5303 AllowedNameModifiers.push_back(OMPD_taskloop);
5304 if (LangOpts.OpenMP >= 50)
5305 AllowedNameModifiers.push_back(OMPD_simd);
5306 break;
5307 case OMPD_master_taskloop:
5308 Res = ActOnOpenMPMasterTaskLoopDirective(
5309 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5310 AllowedNameModifiers.push_back(OMPD_taskloop);
5311 break;
5312 case OMPD_master_taskloop_simd:
5313 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5315 AllowedNameModifiers.push_back(OMPD_taskloop);
5316 if (LangOpts.OpenMP >= 50)
5317 AllowedNameModifiers.push_back(OMPD_simd);
5318 break;
5319 case OMPD_parallel_master_taskloop:
5320 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5321 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5322 AllowedNameModifiers.push_back(OMPD_taskloop);
5323 AllowedNameModifiers.push_back(OMPD_parallel);
5324 break;
5325 case OMPD_parallel_master_taskloop_simd:
5326 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5327 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5328 AllowedNameModifiers.push_back(OMPD_taskloop);
5329 AllowedNameModifiers.push_back(OMPD_parallel);
5330 if (LangOpts.OpenMP >= 50)
5331 AllowedNameModifiers.push_back(OMPD_simd);
5332 break;
5333 case OMPD_distribute:
5334 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5335 EndLoc, VarsWithInheritedDSA);
5336 break;
5337 case OMPD_target_update:
5338 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5339 EndLoc, AStmt);
5340 AllowedNameModifiers.push_back(OMPD_target_update);
5341 break;
5342 case OMPD_distribute_parallel_for:
5343 Res = ActOnOpenMPDistributeParallelForDirective(
5344 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5345 AllowedNameModifiers.push_back(OMPD_parallel);
5346 break;
5347 case OMPD_distribute_parallel_for_simd:
5348 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5349 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5350 AllowedNameModifiers.push_back(OMPD_parallel);
5351 if (LangOpts.OpenMP >= 50)
5352 AllowedNameModifiers.push_back(OMPD_simd);
5353 break;
5354 case OMPD_distribute_simd:
5355 Res = ActOnOpenMPDistributeSimdDirective(
5356 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5357 if (LangOpts.OpenMP >= 50)
5358 AllowedNameModifiers.push_back(OMPD_simd);
5359 break;
5360 case OMPD_target_parallel_for_simd:
5361 Res = ActOnOpenMPTargetParallelForSimdDirective(
5362 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5363 AllowedNameModifiers.push_back(OMPD_target);
5364 AllowedNameModifiers.push_back(OMPD_parallel);
5365 if (LangOpts.OpenMP >= 50)
5366 AllowedNameModifiers.push_back(OMPD_simd);
5367 break;
5368 case OMPD_target_simd:
5369 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5370 EndLoc, VarsWithInheritedDSA);
5371 AllowedNameModifiers.push_back(OMPD_target);
5372 if (LangOpts.OpenMP >= 50)
5373 AllowedNameModifiers.push_back(OMPD_simd);
5374 break;
5375 case OMPD_teams_distribute:
5376 Res = ActOnOpenMPTeamsDistributeDirective(
5377 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5378 break;
5379 case OMPD_teams_distribute_simd:
5380 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5381 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5382 if (LangOpts.OpenMP >= 50)
5383 AllowedNameModifiers.push_back(OMPD_simd);
5384 break;
5385 case OMPD_teams_distribute_parallel_for_simd:
5386 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5387 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5388 AllowedNameModifiers.push_back(OMPD_parallel);
5389 if (LangOpts.OpenMP >= 50)
5390 AllowedNameModifiers.push_back(OMPD_simd);
5391 break;
5392 case OMPD_teams_distribute_parallel_for:
5393 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5394 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5395 AllowedNameModifiers.push_back(OMPD_parallel);
5396 break;
5397 case OMPD_target_teams:
5398 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5399 EndLoc);
5400 AllowedNameModifiers.push_back(OMPD_target);
5401 break;
5402 case OMPD_target_teams_distribute:
5403 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5404 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5405 AllowedNameModifiers.push_back(OMPD_target);
5406 break;
5407 case OMPD_target_teams_distribute_parallel_for:
5408 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5409 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5410 AllowedNameModifiers.push_back(OMPD_target);
5411 AllowedNameModifiers.push_back(OMPD_parallel);
5412 break;
5413 case OMPD_target_teams_distribute_parallel_for_simd:
5414 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5415 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5416 AllowedNameModifiers.push_back(OMPD_target);
5417 AllowedNameModifiers.push_back(OMPD_parallel);
5418 if (LangOpts.OpenMP >= 50)
5419 AllowedNameModifiers.push_back(OMPD_simd);
5420 break;
5421 case OMPD_target_teams_distribute_simd:
5422 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5423 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5424 AllowedNameModifiers.push_back(OMPD_target);
5425 if (LangOpts.OpenMP >= 50)
5426 AllowedNameModifiers.push_back(OMPD_simd);
5427 break;
5428 case OMPD_declare_target:
5429 case OMPD_end_declare_target:
5430 case OMPD_threadprivate:
5431 case OMPD_allocate:
5432 case OMPD_declare_reduction:
5433 case OMPD_declare_mapper:
5434 case OMPD_declare_simd:
5435 case OMPD_requires:
5436 case OMPD_declare_variant:
5437 case OMPD_begin_declare_variant:
5438 case OMPD_end_declare_variant:
5439 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5439)
;
5440 case OMPD_unknown:
5441 default:
5442 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5442)
;
5443 }
5444
5445 ErrorFound = Res.isInvalid() || ErrorFound;
5446
5447 // Check variables in the clauses if default(none) or
5448 // default(firstprivate) was specified.
5449 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5450 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5451 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
5452 for (OMPClause *C : Clauses) {
5453 switch (C->getClauseKind()) {
5454 case OMPC_num_threads:
5455 case OMPC_dist_schedule:
5456 // Do not analyse if no parent teams directive.
5457 if (isOpenMPTeamsDirective(Kind))
5458 break;
5459 continue;
5460 case OMPC_if:
5461 if (isOpenMPTeamsDirective(Kind) &&
5462 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5463 break;
5464 if (isOpenMPParallelDirective(Kind) &&
5465 isOpenMPTaskLoopDirective(Kind) &&
5466 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5467 break;
5468 continue;
5469 case OMPC_schedule:
5470 case OMPC_detach:
5471 break;
5472 case OMPC_grainsize:
5473 case OMPC_num_tasks:
5474 case OMPC_final:
5475 case OMPC_priority:
5476 // Do not analyze if no parent parallel directive.
5477 if (isOpenMPParallelDirective(Kind))
5478 break;
5479 continue;
5480 case OMPC_ordered:
5481 case OMPC_device:
5482 case OMPC_num_teams:
5483 case OMPC_thread_limit:
5484 case OMPC_hint:
5485 case OMPC_collapse:
5486 case OMPC_safelen:
5487 case OMPC_simdlen:
5488 case OMPC_default:
5489 case OMPC_proc_bind:
5490 case OMPC_private:
5491 case OMPC_firstprivate:
5492 case OMPC_lastprivate:
5493 case OMPC_shared:
5494 case OMPC_reduction:
5495 case OMPC_task_reduction:
5496 case OMPC_in_reduction:
5497 case OMPC_linear:
5498 case OMPC_aligned:
5499 case OMPC_copyin:
5500 case OMPC_copyprivate:
5501 case OMPC_nowait:
5502 case OMPC_untied:
5503 case OMPC_mergeable:
5504 case OMPC_allocate:
5505 case OMPC_read:
5506 case OMPC_write:
5507 case OMPC_update:
5508 case OMPC_capture:
5509 case OMPC_seq_cst:
5510 case OMPC_acq_rel:
5511 case OMPC_acquire:
5512 case OMPC_release:
5513 case OMPC_relaxed:
5514 case OMPC_depend:
5515 case OMPC_threads:
5516 case OMPC_simd:
5517 case OMPC_map:
5518 case OMPC_nogroup:
5519 case OMPC_defaultmap:
5520 case OMPC_to:
5521 case OMPC_from:
5522 case OMPC_use_device_ptr:
5523 case OMPC_use_device_addr:
5524 case OMPC_is_device_ptr:
5525 case OMPC_nontemporal:
5526 case OMPC_order:
5527 case OMPC_destroy:
5528 case OMPC_inclusive:
5529 case OMPC_exclusive:
5530 case OMPC_uses_allocators:
5531 case OMPC_affinity:
5532 continue;
5533 case OMPC_allocator:
5534 case OMPC_flush:
5535 case OMPC_depobj:
5536 case OMPC_threadprivate:
5537 case OMPC_uniform:
5538 case OMPC_unknown:
5539 case OMPC_unified_address:
5540 case OMPC_unified_shared_memory:
5541 case OMPC_reverse_offload:
5542 case OMPC_dynamic_allocators:
5543 case OMPC_atomic_default_mem_order:
5544 case OMPC_device_type:
5545 case OMPC_match:
5546 default:
5547 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaOpenMP.cpp"
, 5547)
;
5548 }
5549 for (Stmt *CC : C->children()) {
5550 if (CC)
5551 DSAChecker.Visit(CC);
5552 }
5553 }
5554 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5555 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5556 }
5557 for (const auto &P : VarsWithInheritedDSA) {
5558 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5559 continue;
5560 ErrorFound = true;
5561 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5562 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5563 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5564 << P.first << P.second->getSourceRange();
5565 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5566 } else if (getLangOpts().OpenMP >= 50) {
5567 Diag(P.second->getExprLoc(),
5568 diag::err_omp_defaultmap_no_attr_for_variable)
5569 << P.first << P.second->getSourceRange();
5570 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
5571 diag::note_omp_defaultmap_attr_none);
5572 }
5573 }
5574
5575 if (!AllowedNameModifiers.empty())
5576 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5577 ErrorFound;
5578
5579 if (ErrorFound)
5580 return StmtError();
5581
5582 if (!CurContext->isDependentContext() &&
5583 isOpenMPTargetExecutionDirective(Kind) &&
5584 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5585 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5586 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5587 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5588 // Register target to DSA Stack.
5589 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
5590 }
5591
5592 return Res;
5593}
5594
5595