Bug Summary

File:clang/lib/Sema/SemaOpenMP.cpp
Warning:line 2199, column 54
Access to field 'OpenMPLevel' results in a dereference of a null pointer (loaded from variable 'CSI')

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~++20200915100651+00ba1a3de7f/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/include -I /build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f=. -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-15-222444-33637-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp

/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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~++20200915100651+00ba1a3de7f/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())
&&
34
Assuming the condition is true
35
Returning the value 1, which participates in a condition later
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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2151, __PRETTY_FUNCTION__))
;
6
Assuming field 'OpenMP' is not equal to 0
7
'?' condition is true
2152 D = getCanonicalDecl(D);
2153
2154 auto *VD = dyn_cast<VarDecl>(D);
8
Assuming 'D' is a 'VarDecl'
2155 // Do not capture constexpr variables.
2156 if (VD
8.1
'VD' is non-null
8.1
'VD' is non-null
8.1
'VD' is non-null
8.1
'VD' is non-null
&& VD->isConstexpr())
9
Calling 'VarDecl::isConstexpr'
13
Returning from 'VarDecl::isConstexpr'
14
Assuming the condition is false
15
Taking false branch
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
15.1
'CheckScopeInfo' is false
15.1
'CheckScopeInfo' is false
15.1
'CheckScopeInfo' is false
15.1
'CheckScopeInfo' is false
&& 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
15.2
'VD' is non-null
15.2
'VD' is non-null
15.2
'VD' is non-null
15.2
'VD' is non-null
&& !VD->hasLocalStorage() &&
16
Calling 'VarDecl::hasLocalStorage'
22
Returning from 'VarDecl::hasLocalStorage'
2170 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
23
Assuming the condition is false
24
Assuming the condition is true
2171 if (isInOpenMPDeclareTargetContext()) {
25
Calling 'Sema::isInOpenMPDeclareTargetContext'
31
Returning from 'Sema::isInOpenMPDeclareTargetContext'
32
Taking false branch
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()) {
33
Calling 'Sema::isInOpenMPTargetExecutionDirective'
36
Returning from 'Sema::isInOpenMPTargetExecutionDirective'
37
Taking true branch
2180 // If the declaration is enclosed in a 'declare target' directive,
2181 // then it should not be captured.
2182 //
2183 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
38
Assuming the condition is false
39
Taking false branch
2184 return nullptr;
2185 CapturedRegionScopeInfo *CSI = nullptr;
40
'CSI' initialized to a null pointer value
2186 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2187 llvm::reverse(FunctionScopes),
2188 CheckScopeInfo
40.1
'CheckScopeInfo' is false
40.1
'CheckScopeInfo' is false
40.1
'CheckScopeInfo' is false
40.1
'CheckScopeInfo' is false
? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
41
'?' condition is false
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 SmallVector<OpenMPDirectiveKind, 4> Regions;
2198 getOpenMPCaptureRegions(Regions,
2199 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
42
Access to field 'OpenMPLevel' results in a dereference of a null pointer (loaded from variable 'CSI')
2200 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2201 return VD;
2202 }
2203 }
2204
2205 if (CheckScopeInfo) {
2206 bool OpenMPFound = false;
2207 for (unsigned I = StopAt + 1; I > 0; --I) {
2208 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2209 if(!isa<CapturingScopeInfo>(FSI))
2210 return nullptr;
2211 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2212 if (RSI->CapRegionKind == CR_OpenMP) {
2213 OpenMPFound = true;
2214 break;
2215 }
2216 }
2217 if (!OpenMPFound)
2218 return nullptr;
2219 }
2220
2221 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2222 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2223 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2224 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2225 if (Info.first ||
2226 (VD && VD->hasLocalStorage() &&
2227 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2228 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2229 return VD ? VD : Info.second;
2230 DSAStackTy::DSAVarData DVarTop =
2231 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2232 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2233 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2234 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2235 // Threadprivate variables must not be captured.
2236 if (isOpenMPThreadPrivate(DVarTop.CKind))
2237 return nullptr;
2238 // The variable is not private or it is the variable in the directive with
2239 // default(none) clause and not used in any clause.
2240 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2241 D,
2242 [](OpenMPClauseKind C, bool AppliedToPointee) {
2243 return isOpenMPPrivate(C) && !AppliedToPointee;
2244 },
2245 [](OpenMPDirectiveKind) { return true; },
2246 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2247 // Global shared must not be captured.
2248 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2249 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2250 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2251 DVarTop.CKind == OMPC_shared))
2252 return nullptr;
2253 if (DVarPrivate.CKind != OMPC_unknown ||
2254 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2255 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2256 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2257 }
2258 return nullptr;
2259}
2260
2261void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2262 unsigned Level) const {
2263 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2264}
2265
2266void Sema::startOpenMPLoop() {
2267 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2267, __PRETTY_FUNCTION__))
;
2268 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2269 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2270}
2271
2272void Sema::startOpenMPCXXRangeFor() {
2273 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2273, __PRETTY_FUNCTION__))
;
2274 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2275 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2276 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2277 }
2278}
2279
2280OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2281 unsigned CapLevel) const {
2282 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2282, __PRETTY_FUNCTION__))
;
2283 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2284 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2285 Level)) {
2286 bool IsTriviallyCopyable =
2287 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2288 !D->getType()
2289 .getNonReferenceType()
2290 .getCanonicalType()
2291 ->getAsCXXRecordDecl();
2292 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2293 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2294 getOpenMPCaptureRegions(CaptureRegions, DKind);
2295 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2296 (IsTriviallyCopyable ||
2297 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2298 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2299 D,
2300 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2301 Level, /*NotLastprivate=*/true))
2302 return OMPC_firstprivate;
2303 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2304 if (DVar.CKind != OMPC_shared &&
2305 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2306 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2307 return OMPC_firstprivate;
2308 }
2309 }
2310 }
2311 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2312 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2313 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2314 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2315 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2316 return OMPC_private;
2317 }
2318 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2319 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2320 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2321 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2322 Level) &&
2323 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2324 return OMPC_private;
2325 }
2326 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2327 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2328 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2329 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2330 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2331 Level))
2332 return OMPC_private;
2333 }
2334 // User-defined allocators are private since they must be defined in the
2335 // context of target region.
2336 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2337 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2338 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2339 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2340 return OMPC_private;
2341 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2342 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2343 Level) ||
2344 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2345 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2346 // Consider taskgroup reduction descriptor variable a private
2347 // to avoid possible capture in the region.
2348 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2349 [](OpenMPDirectiveKind K) {
2350 return K == OMPD_taskgroup ||
2351 ((isOpenMPParallelDirective(K) ||
2352 isOpenMPWorksharingDirective(K)) &&
2353 !isOpenMPSimdDirective(K));
2354 },
2355 Level) &&
2356 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2357 ? OMPC_private
2358 : OMPC_unknown;
2359}
2360
2361void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2362 unsigned Level) {
2363 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2363, __PRETTY_FUNCTION__))
;
2364 D = getCanonicalDecl(D);
2365 OpenMPClauseKind OMPC = OMPC_unknown;
2366 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2367 const unsigned NewLevel = I - 1;
2368 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2369 D,
2370 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2371 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2372 OMPC = K;
2373 return true;
2374 }
2375 return false;
2376 },
2377 NewLevel))
2378 break;
2379 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2380 D, NewLevel,
2381 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2382 OpenMPClauseKind) { return true; })) {
2383 OMPC = OMPC_map;
2384 break;
2385 }
2386 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2387 NewLevel)) {
2388 OMPC = OMPC_map;
2389 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2390 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2391 OMPC = OMPC_firstprivate;
2392 break;
2393 }
2394 }
2395 if (OMPC != OMPC_unknown)
2396 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2397}
2398
2399bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2400 unsigned CaptureLevel) const {
2401 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2401, __PRETTY_FUNCTION__))
;
2402 // Return true if the current level is no longer enclosed in a target region.
2403
2404 SmallVector<OpenMPDirectiveKind, 4> Regions;
2405 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2406 const auto *VD = dyn_cast<VarDecl>(D);
2407 return VD && !VD->hasLocalStorage() &&
2408 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2409 Level) &&
2410 Regions[CaptureLevel] != OMPD_task;
2411}
2412
2413bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2414 unsigned CaptureLevel) const {
2415 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2415, __PRETTY_FUNCTION__))
;
2416 // Return true if the current level is no longer enclosed in a target region.
2417
2418 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2419 if (!VD->hasLocalStorage()) {
2420 if (isInOpenMPTargetExecutionDirective())
2421 return true;
2422 DSAStackTy::DSAVarData TopDVar =
2423 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2424 unsigned NumLevels =
2425 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2426 if (Level == 0)
2427 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2428 do {
2429 --Level;
2430 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2431 if (DVar.CKind != OMPC_shared)
2432 return true;
2433 } while (Level > 0);
2434 }
2435 }
2436 return true;
2437}
2438
2439void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2440
2441void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2442 OMPTraitInfo &TI) {
2443 if (!OMPDeclareVariantScopes.empty()) {
2444 Diag(Loc, diag::warn_nested_declare_variant);
2445 return;
2446 }
2447 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2448}
2449
2450void Sema::ActOnOpenMPEndDeclareVariant() {
2451 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2452, __PRETTY_FUNCTION__))
2452 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2452, __PRETTY_FUNCTION__))
;
2453
2454 OMPDeclareVariantScopes.pop_back();
2455}
2456
2457void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2458 const FunctionDecl *Callee,
2459 SourceLocation Loc) {
2460 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2460, __PRETTY_FUNCTION__))
;
2461 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2462 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2463 // Ignore host functions during device analyzis.
2464 if (LangOpts.OpenMPIsDevice && DevTy &&
2465 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2466 return;
2467 // Ignore nohost functions during host analyzis.
2468 if (!LangOpts.OpenMPIsDevice && DevTy &&
2469 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2470 return;
2471 const FunctionDecl *FD = Callee->getMostRecentDecl();
2472 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2473 if (LangOpts.OpenMPIsDevice && DevTy &&
2474 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2475 // Diagnose host function called during device codegen.
2476 StringRef HostDevTy =
2477 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2478 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2479 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2480 diag::note_omp_marked_device_type_here)
2481 << HostDevTy;
2482 return;
2483 }
2484 if (!LangOpts.OpenMPIsDevice && DevTy &&
2485 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2486 // Diagnose nohost function called during host codegen.
2487 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2488 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2489 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2490 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2491 diag::note_omp_marked_device_type_here)
2492 << NoHostDevTy;
2493 }
2494}
2495
2496void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2497 const DeclarationNameInfo &DirName,
2498 Scope *CurScope, SourceLocation Loc) {
2499 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2500 PushExpressionEvaluationContext(
2501 ExpressionEvaluationContext::PotentiallyEvaluated);
2502}
2503
2504void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2505 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2506}
2507
2508void Sema::EndOpenMPClause() {
2509 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2510}
2511
2512static std::pair<ValueDecl *, bool>
2513getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2514 SourceRange &ERange, bool AllowArraySection = false);
2515
2516/// Check consistency of the reduction clauses.
2517static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2518 ArrayRef<OMPClause *> Clauses) {
2519 bool InscanFound = false;
2520 SourceLocation InscanLoc;
2521 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2522 // A reduction clause without the inscan reduction-modifier may not appear on
2523 // a construct on which a reduction clause with the inscan reduction-modifier
2524 // appears.
2525 for (OMPClause *C : Clauses) {
2526 if (C->getClauseKind() != OMPC_reduction)
2527 continue;
2528 auto *RC = cast<OMPReductionClause>(C);
2529 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2530 InscanFound = true;
2531 InscanLoc = RC->getModifierLoc();
2532 continue;
2533 }
2534 if (RC->getModifier() == OMPC_REDUCTION_task) {
2535 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2536 // A reduction clause with the task reduction-modifier may only appear on
2537 // a parallel construct, a worksharing construct or a combined or
2538 // composite construct for which any of the aforementioned constructs is a
2539 // constituent construct and simd or loop are not constituent constructs.
2540 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2541 if (!(isOpenMPParallelDirective(CurDir) ||
2542 isOpenMPWorksharingDirective(CurDir)) ||
2543 isOpenMPSimdDirective(CurDir))
2544 S.Diag(RC->getModifierLoc(),
2545 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2546 continue;
2547 }
2548 }
2549 if (InscanFound) {
2550 for (OMPClause *C : Clauses) {
2551 if (C->getClauseKind() != OMPC_reduction)
2552 continue;
2553 auto *RC = cast<OMPReductionClause>(C);
2554 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2555 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2556 ? RC->getBeginLoc()
2557 : RC->getModifierLoc(),
2558 diag::err_omp_inscan_reduction_expected);
2559 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2560 continue;
2561 }
2562 for (Expr *Ref : RC->varlists()) {
2563 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2563, __PRETTY_FUNCTION__))
;
2564 SourceLocation ELoc;
2565 SourceRange ERange;
2566 Expr *SimpleRefExpr = Ref;
2567 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2568 /*AllowArraySection=*/true);
2569 ValueDecl *D = Res.first;
2570 if (!D)
2571 continue;
2572 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2573 S.Diag(Ref->getExprLoc(),
2574 diag::err_omp_reduction_not_inclusive_exclusive)
2575 << Ref->getSourceRange();
2576 }
2577 }
2578 }
2579 }
2580}
2581
2582static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2583 ArrayRef<OMPClause *> Clauses);
2584static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2585 bool WithInit);
2586
2587static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2588 const ValueDecl *D,
2589 const DSAStackTy::DSAVarData &DVar,
2590 bool IsLoopIterVar = false);
2591
2592void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2593 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2594 // A variable of class type (or array thereof) that appears in a lastprivate
2595 // clause requires an accessible, unambiguous default constructor for the
2596 // class type, unless the list item is also specified in a firstprivate
2597 // clause.
2598 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2599 for (OMPClause *C : D->clauses()) {
2600 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2601 SmallVector<Expr *, 8> PrivateCopies;
2602 for (Expr *DE : Clause->varlists()) {
2603 if (DE->isValueDependent() || DE->isTypeDependent()) {
2604 PrivateCopies.push_back(nullptr);
2605 continue;
2606 }
2607 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2608 auto *VD = cast<VarDecl>(DRE->getDecl());
2609 QualType Type = VD->getType().getNonReferenceType();
2610 const DSAStackTy::DSAVarData DVar =
2611 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2612 if (DVar.CKind == OMPC_lastprivate) {
2613 // Generate helper private variable and initialize it with the
2614 // default value. The address of the original variable is replaced
2615 // by the address of the new private variable in CodeGen. This new
2616 // variable is not added to IdResolver, so the code in the OpenMP
2617 // region uses original variable for proper diagnostics.
2618 VarDecl *VDPrivate = buildVarDecl(
2619 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2620 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2621 ActOnUninitializedDecl(VDPrivate);
2622 if (VDPrivate->isInvalidDecl()) {
2623 PrivateCopies.push_back(nullptr);
2624 continue;
2625 }
2626 PrivateCopies.push_back(buildDeclRefExpr(
2627 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2628 } else {
2629 // The variable is also a firstprivate, so initialization sequence
2630 // for private copy is generated already.
2631 PrivateCopies.push_back(nullptr);
2632 }
2633 }
2634 Clause->setPrivateCopies(PrivateCopies);
2635 continue;
2636 }
2637 // Finalize nontemporal clause by handling private copies, if any.
2638 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2639 SmallVector<Expr *, 8> PrivateRefs;
2640 for (Expr *RefExpr : Clause->varlists()) {
2641 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 2641, __PRETTY_FUNCTION__))
;
2642 SourceLocation ELoc;
2643 SourceRange ERange;
2644 Expr *SimpleRefExpr = RefExpr;
2645 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2646 if (Res.second)
2647 // It will be analyzed later.
2648 PrivateRefs.push_back(RefExpr);
2649 ValueDecl *D = Res.first;
2650 if (!D)
2651 continue;
2652
2653 const DSAStackTy::DSAVarData DVar =
2654 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2655 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2656 : SimpleRefExpr);
2657 }
2658 Clause->setPrivateRefs(PrivateRefs);
2659 continue;
2660 }
2661 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2662 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2663 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2664 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2665 if (!DRE)
2666 continue;
2667 ValueDecl *VD = DRE->getDecl();
2668 if (!VD || !isa<VarDecl>(VD))
2669 continue;
2670 DSAStackTy::DSAVarData DVar =
2671 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2672 // OpenMP [2.12.5, target Construct]
2673 // Memory allocators that appear in a uses_allocators clause cannot
2674 // appear in other data-sharing attribute clauses or data-mapping
2675 // attribute clauses in the same construct.
2676 Expr *MapExpr = nullptr;
2677 if (DVar.RefExpr ||
2678 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2679 VD, /*CurrentRegionOnly=*/true,
2680 [VD, &MapExpr](
2681 OMPClauseMappableExprCommon::MappableExprComponentListRef
2682 MapExprComponents,
2683 OpenMPClauseKind C) {
2684 auto MI = MapExprComponents.rbegin();
2685 auto ME = MapExprComponents.rend();
2686 if (MI != ME &&
2687 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2688 VD->getCanonicalDecl()) {
2689 MapExpr = MI->getAssociatedExpression();
2690 return true;
2691 }
2692 return false;
2693 })) {
2694 Diag(D.Allocator->getExprLoc(),
2695 diag::err_omp_allocator_used_in_clauses)
2696 << D.Allocator->getSourceRange();
2697 if (DVar.RefExpr)
2698 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2699 else
2700 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2701 << MapExpr->getSourceRange();
2702 }
2703 }
2704 continue;
2705 }
2706 }
2707 // Check allocate clauses.
2708 if (!CurContext->isDependentContext())
2709 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2710 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2711 }
2712
2713 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2714 DiscardCleanupsInEvaluationContext();
2715 PopExpressionEvaluationContext();
2716}
2717
2718static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2719 Expr *NumIterations, Sema &SemaRef,
2720 Scope *S, DSAStackTy *Stack);
2721
2722namespace {
2723
2724class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2725private:
2726 Sema &SemaRef;
2727
2728public:
2729 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2730 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2731 NamedDecl *ND = Candidate.getCorrectionDecl();
2732 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2733 return VD->hasGlobalStorage() &&
2734 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2735 SemaRef.getCurScope());
2736 }
2737 return false;
2738 }
2739
2740 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2741 return std::make_unique<VarDeclFilterCCC>(*this);
2742 }
2743
2744};
2745
2746class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2747private:
2748 Sema &SemaRef;
2749
2750public:
2751 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2752 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2753 NamedDecl *ND = Candidate.getCorrectionDecl();
2754 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2755 isa<FunctionDecl>(ND))) {
2756 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2757 SemaRef.getCurScope());
2758 }
2759 return false;
2760 }
2761
2762 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2763 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2764 }
2765};
2766
2767} // namespace
2768
2769ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2770 CXXScopeSpec &ScopeSpec,
2771 const DeclarationNameInfo &Id,
2772 OpenMPDirectiveKind Kind) {
2773 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2774 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2775
2776 if (Lookup.isAmbiguous())
2777 return ExprError();
2778
2779 VarDecl *VD;
2780 if (!Lookup.isSingleResult()) {
2781 VarDeclFilterCCC CCC(*this);
2782 if (TypoCorrection Corrected =
2783 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2784 CTK_ErrorRecovery)) {
2785 diagnoseTypo(Corrected,
2786 PDiag(Lookup.empty()
2787 ? diag::err_undeclared_var_use_suggest
2788 : diag::err_omp_expected_var_arg_suggest)
2789 << Id.getName());
2790 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2791 } else {
2792 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2793 : diag::err_omp_expected_var_arg)
2794 << Id.getName();
2795 return ExprError();
2796 }
2797 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2798 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2799 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2800 return ExprError();
2801 }
2802 Lookup.suppressDiagnostics();
2803
2804 // OpenMP [2.9.2, Syntax, C/C++]
2805 // Variables must be file-scope, namespace-scope, or static block-scope.
2806 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2807 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2808 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2809 bool IsDecl =
2810 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2811 Diag(VD->getLocation(),
2812 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2813 << VD;
2814 return ExprError();
2815 }
2816
2817 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2818 NamedDecl *ND = CanonicalVD;
2819 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2820 // A threadprivate directive for file-scope variables must appear outside
2821 // any definition or declaration.
2822 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2823 !getCurLexicalContext()->isTranslationUnit()) {
2824 Diag(Id.getLoc(), diag::err_omp_var_scope)
2825 << getOpenMPDirectiveName(Kind) << VD;
2826 bool IsDecl =
2827 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2828 Diag(VD->getLocation(),
2829 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2830 << VD;
2831 return ExprError();
2832 }
2833 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2834 // A threadprivate directive for static class member variables must appear
2835 // in the class definition, in the same scope in which the member
2836 // variables are declared.
2837 if (CanonicalVD->isStaticDataMember() &&
2838 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2839 Diag(Id.getLoc(), diag::err_omp_var_scope)
2840 << getOpenMPDirectiveName(Kind) << VD;
2841 bool IsDecl =
2842 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2843 Diag(VD->getLocation(),
2844 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2845 << VD;
2846 return ExprError();
2847 }
2848 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2849 // A threadprivate directive for namespace-scope variables must appear
2850 // outside any definition or declaration other than the namespace
2851 // definition itself.
2852 if (CanonicalVD->getDeclContext()->isNamespace() &&
2853 (!getCurLexicalContext()->isFileContext() ||
2854 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2855 Diag(Id.getLoc(), diag::err_omp_var_scope)
2856 << getOpenMPDirectiveName(Kind) << VD;
2857 bool IsDecl =
2858 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2859 Diag(VD->getLocation(),
2860 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2861 << VD;
2862 return ExprError();
2863 }
2864 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2865 // A threadprivate directive for static block-scope variables must appear
2866 // in the scope of the variable and not in a nested scope.
2867 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2868 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2869 Diag(Id.getLoc(), diag::err_omp_var_scope)
2870 << getOpenMPDirectiveName(Kind) << VD;
2871 bool IsDecl =
2872 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2873 Diag(VD->getLocation(),
2874 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2875 << VD;
2876 return ExprError();
2877 }
2878
2879 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2880 // A threadprivate directive must lexically precede all references to any
2881 // of the variables in its list.
2882 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2883 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2884 Diag(Id.getLoc(), diag::err_omp_var_used)
2885 << getOpenMPDirectiveName(Kind) << VD;
2886 return ExprError();
2887 }
2888
2889 QualType ExprType = VD->getType().getNonReferenceType();
2890 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2891 SourceLocation(), VD,
2892 /*RefersToEnclosingVariableOrCapture=*/false,
2893 Id.getLoc(), ExprType, VK_LValue);
2894}
2895
2896Sema::DeclGroupPtrTy
2897Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2898 ArrayRef<Expr *> VarList) {
2899 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2900 CurContext->addDecl(D);
2901 return DeclGroupPtrTy::make(DeclGroupRef(D));
2902 }
2903 return nullptr;
2904}
2905
2906namespace {
2907class LocalVarRefChecker final
2908 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2909 Sema &SemaRef;
2910
2911public:
2912 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2913 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2914 if (VD->hasLocalStorage()) {
2915 SemaRef.Diag(E->getBeginLoc(),
2916 diag::err_omp_local_var_in_threadprivate_init)
2917 << E->getSourceRange();
2918 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2919 << VD << VD->getSourceRange();
2920 return true;
2921 }
2922 }
2923 return false;
2924 }
2925 bool VisitStmt(const Stmt *S) {
2926 for (const Stmt *Child : S->children()) {
2927 if (Child && Visit(Child))
2928 return true;
2929 }
2930 return false;
2931 }
2932 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2933};
2934} // namespace
2935
2936OMPThreadPrivateDecl *
2937Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2938 SmallVector<Expr *, 8> Vars;
2939 for (Expr *RefExpr : VarList) {
2940 auto *DE = cast<DeclRefExpr>(RefExpr);
2941 auto *VD = cast<VarDecl>(DE->getDecl());
2942 SourceLocation ILoc = DE->getExprLoc();
2943
2944 // Mark variable as used.
2945 VD->setReferenced();
2946 VD->markUsed(Context);
2947
2948 QualType QType = VD->getType();
2949 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2950 // It will be analyzed later.
2951 Vars.push_back(DE);
2952 continue;
2953 }
2954
2955 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2956 // A threadprivate variable must not have an incomplete type.
2957 if (RequireCompleteType(ILoc, VD->getType(),
2958 diag::err_omp_threadprivate_incomplete_type)) {
2959 continue;
2960 }
2961
2962 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2963 // A threadprivate variable must not have a reference type.
2964 if (VD->getType()->isReferenceType()) {
2965 Diag(ILoc, diag::err_omp_ref_type_arg)
2966 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2967 bool IsDecl =
2968 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2969 Diag(VD->getLocation(),
2970 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2971 << VD;
2972 continue;
2973 }
2974
2975 // Check if this is a TLS variable. If TLS is not being supported, produce
2976 // the corresponding diagnostic.
2977 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2978 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2979 getLangOpts().OpenMPUseTLS &&
2980 getASTContext().getTargetInfo().isTLSSupported())) ||
2981 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2982 !VD->isLocalVarDecl())) {
2983 Diag(ILoc, diag::err_omp_var_thread_local)
2984 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2985 bool IsDecl =
2986 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2987 Diag(VD->getLocation(),
2988 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2989 << VD;
2990 continue;
2991 }
2992
2993 // Check if initial value of threadprivate variable reference variable with
2994 // local storage (it is not supported by runtime).
2995 if (const Expr *Init = VD->getAnyInitializer()) {
2996 LocalVarRefChecker Checker(*this);
2997 if (Checker.Visit(Init))
2998 continue;
2999 }
3000
3001 Vars.push_back(RefExpr);
3002 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3003 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3004 Context, SourceRange(Loc, Loc)));
3005 if (ASTMutationListener *ML = Context.getASTMutationListener())
3006 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3007 }
3008 OMPThreadPrivateDecl *D = nullptr;
3009 if (!Vars.empty()) {
3010 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3011 Vars);
3012 D->setAccess(AS_public);
3013 }
3014 return D;
3015}
3016
3017static OMPAllocateDeclAttr::AllocatorTypeTy
3018getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3019 if (!Allocator)
3020 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3021 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3022 Allocator->isInstantiationDependent() ||
3023 Allocator->containsUnexpandedParameterPack())
3024 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3025 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3026 const Expr *AE = Allocator->IgnoreParenImpCasts();
3027 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3028 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3029 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3030 llvm::FoldingSetNodeID AEId, DAEId;
3031 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3032 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3033 if (AEId == DAEId) {
3034 AllocatorKindRes = AllocatorKind;
3035 break;
3036 }
3037 }
3038 return AllocatorKindRes;
3039}
3040
3041static bool checkPreviousOMPAllocateAttribute(
3042 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3043 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3044 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3045 return false;
3046 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3047 Expr *PrevAllocator = A->getAllocator();
3048 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3049 getAllocatorKind(S, Stack, PrevAllocator);
3050 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3051 if (AllocatorsMatch &&
3052 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3053 Allocator && PrevAllocator) {
3054 const Expr *AE = Allocator->IgnoreParenImpCasts();
3055 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3056 llvm::FoldingSetNodeID AEId, PAEId;
3057 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3058 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3059 AllocatorsMatch = AEId == PAEId;
3060 }
3061 if (!AllocatorsMatch) {
3062 SmallString<256> AllocatorBuffer;
3063 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3064 if (Allocator)
3065 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3066 SmallString<256> PrevAllocatorBuffer;
3067 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3068 if (PrevAllocator)
3069 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3070 S.getPrintingPolicy());
3071
3072 SourceLocation AllocatorLoc =
3073 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3074 SourceRange AllocatorRange =
3075 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3076 SourceLocation PrevAllocatorLoc =
3077 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3078 SourceRange PrevAllocatorRange =
3079 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3080 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3081 << (Allocator ? 1 : 0) << AllocatorStream.str()
3082 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3083 << AllocatorRange;
3084 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3085 << PrevAllocatorRange;
3086 return true;
3087 }
3088 return false;
3089}
3090
3091static void
3092applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3093 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3094 Expr *Allocator, SourceRange SR) {
3095 if (VD->hasAttr<OMPAllocateDeclAttr>())
3096 return;
3097 if (Allocator &&
3098 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3099 Allocator->isInstantiationDependent() ||
3100 Allocator->containsUnexpandedParameterPack()))
3101 return;
3102 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3103 Allocator, SR);
3104 VD->addAttr(A);
3105 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3106 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3107}
3108
3109Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3110 SourceLocation Loc, ArrayRef<Expr *> VarList,
3111 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3112 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 3112, __PRETTY_FUNCTION__))
;
3113 Expr *Allocator = nullptr;
3114 if (Clauses.empty()) {
3115 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3116 // allocate directives that appear in a target region must specify an
3117 // allocator clause unless a requires directive with the dynamic_allocators
3118 // clause is present in the same compilation unit.
3119 if (LangOpts.OpenMPIsDevice &&
3120 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3121 targetDiag(Loc, diag::err_expected_allocator_clause);
3122 } else {
3123 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3124 }
3125 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3126 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3127 SmallVector<Expr *, 8> Vars;
3128 for (Expr *RefExpr : VarList) {
3129 auto *DE = cast<DeclRefExpr>(RefExpr);
3130 auto *VD = cast<VarDecl>(DE->getDecl());
3131
3132 // Check if this is a TLS variable or global register.
3133 if (VD->getTLSKind() != VarDecl::TLS_None ||
3134 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3135 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3136 !VD->isLocalVarDecl()))
3137 continue;
3138
3139 // If the used several times in the allocate directive, the same allocator
3140 // must be used.
3141 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3142 AllocatorKind, Allocator))
3143 continue;
3144
3145 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3146 // If a list item has a static storage type, the allocator expression in the
3147 // allocator clause must be a constant expression that evaluates to one of
3148 // the predefined memory allocator values.
3149 if (Allocator && VD->hasGlobalStorage()) {
3150 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3151 Diag(Allocator->getExprLoc(),
3152 diag::err_omp_expected_predefined_allocator)
3153 << Allocator->getSourceRange();
3154 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3155 VarDecl::DeclarationOnly;
3156 Diag(VD->getLocation(),
3157 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3158 << VD;
3159 continue;
3160 }
3161 }
3162
3163 Vars.push_back(RefExpr);
3164 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3165 DE->getSourceRange());
3166 }
3167 if (Vars.empty())
3168 return nullptr;
3169 if (!Owner)
3170 Owner = getCurLexicalContext();
3171 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3172 D->setAccess(AS_public);
3173 Owner->addDecl(D);
3174 return DeclGroupPtrTy::make(DeclGroupRef(D));
3175}
3176
3177Sema::DeclGroupPtrTy
3178Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3179 ArrayRef<OMPClause *> ClauseList) {
3180 OMPRequiresDecl *D = nullptr;
3181 if (!CurContext->isFileContext()) {
3182 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3183 } else {
3184 D = CheckOMPRequiresDecl(Loc, ClauseList);
3185 if (D) {
3186 CurContext->addDecl(D);
3187 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3188 }
3189 }
3190 return DeclGroupPtrTy::make(DeclGroupRef(D));
3191}
3192
3193OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3194 ArrayRef<OMPClause *> ClauseList) {
3195 /// For target specific clauses, the requires directive cannot be
3196 /// specified after the handling of any of the target regions in the
3197 /// current compilation unit.
3198 ArrayRef<SourceLocation> TargetLocations =
3199 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3200 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3201 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3202 for (const OMPClause *CNew : ClauseList) {
3203 // Check if any of the requires clauses affect target regions.
3204 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3205 isa<OMPUnifiedAddressClause>(CNew) ||
3206 isa<OMPReverseOffloadClause>(CNew) ||
3207 isa<OMPDynamicAllocatorsClause>(CNew)) {
3208 Diag(Loc, diag::err_omp_directive_before_requires)
3209 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3210 for (SourceLocation TargetLoc : TargetLocations) {
3211 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3212 << "target";
3213 }
3214 } else if (!AtomicLoc.isInvalid() &&
3215 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3216 Diag(Loc, diag::err_omp_directive_before_requires)
3217 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3218 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3219 << "atomic";
3220 }
3221 }
3222 }
3223
3224 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3225 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3226 ClauseList);
3227 return nullptr;
3228}
3229
3230static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3231 const ValueDecl *D,
3232 const DSAStackTy::DSAVarData &DVar,
3233 bool IsLoopIterVar) {
3234 if (DVar.RefExpr) {
3235 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3236 << getOpenMPClauseName(DVar.CKind);
3237 return;
3238 }
3239 enum {
3240 PDSA_StaticMemberShared,
3241 PDSA_StaticLocalVarShared,
3242 PDSA_LoopIterVarPrivate,
3243 PDSA_LoopIterVarLinear,
3244 PDSA_LoopIterVarLastprivate,
3245 PDSA_ConstVarShared,
3246 PDSA_GlobalVarShared,
3247 PDSA_TaskVarFirstprivate,
3248 PDSA_LocalVarPrivate,
3249 PDSA_Implicit
3250 } Reason = PDSA_Implicit;
3251 bool ReportHint = false;
3252 auto ReportLoc = D->getLocation();
3253 auto *VD = dyn_cast<VarDecl>(D);
3254 if (IsLoopIterVar) {
3255 if (DVar.CKind == OMPC_private)
3256 Reason = PDSA_LoopIterVarPrivate;
3257 else if (DVar.CKind == OMPC_lastprivate)
3258 Reason = PDSA_LoopIterVarLastprivate;
3259 else
3260 Reason = PDSA_LoopIterVarLinear;
3261 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3262 DVar.CKind == OMPC_firstprivate) {
3263 Reason = PDSA_TaskVarFirstprivate;
3264 ReportLoc = DVar.ImplicitDSALoc;
3265 } else if (VD && VD->isStaticLocal())
3266 Reason = PDSA_StaticLocalVarShared;
3267 else if (VD && VD->isStaticDataMember())
3268 Reason = PDSA_StaticMemberShared;
3269 else if (VD && VD->isFileVarDecl())
3270 Reason = PDSA_GlobalVarShared;
3271 else if (D->getType().isConstant(SemaRef.getASTContext()))
3272 Reason = PDSA_ConstVarShared;
3273 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3274 ReportHint = true;
3275 Reason = PDSA_LocalVarPrivate;
3276 }
3277 if (Reason != PDSA_Implicit) {
3278 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3279 << Reason << ReportHint
3280 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3281 } else if (DVar.ImplicitDSALoc.isValid()) {
3282 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3283 << getOpenMPClauseName(DVar.CKind);
3284 }
3285}
3286
3287static OpenMPMapClauseKind
3288getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3289 bool IsAggregateOrDeclareTarget) {
3290 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3291 switch (M) {
3292 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3293 Kind = OMPC_MAP_alloc;
3294 break;
3295 case OMPC_DEFAULTMAP_MODIFIER_to:
3296 Kind = OMPC_MAP_to;
3297 break;
3298 case OMPC_DEFAULTMAP_MODIFIER_from:
3299 Kind = OMPC_MAP_from;
3300 break;
3301 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3302 Kind = OMPC_MAP_tofrom;
3303 break;
3304 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3305 case OMPC_DEFAULTMAP_MODIFIER_last:
3306 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 3306)
;
3307 case OMPC_DEFAULTMAP_MODIFIER_none:
3308 case OMPC_DEFAULTMAP_MODIFIER_default:
3309 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3310 // IsAggregateOrDeclareTarget could be true if:
3311 // 1. the implicit behavior for aggregate is tofrom
3312 // 2. it's a declare target link
3313 if (IsAggregateOrDeclareTarget) {
3314 Kind = OMPC_MAP_tofrom;
3315 break;
3316 }
3317 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 3317)
;
3318 }
3319 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 3319, __PRETTY_FUNCTION__))
;
3320 return Kind;
3321}
3322
3323namespace {
3324class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3325 DSAStackTy *Stack;
3326 Sema &SemaRef;
3327 bool ErrorFound = false;
3328 bool TryCaptureCXXThisMembers = false;
3329 CapturedStmt *CS = nullptr;
3330 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3331 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3332 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3333 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3334
3335 void VisitSubCaptures(OMPExecutableDirective *S) {
3336 // Check implicitly captured variables.
3337 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt() ||
3338 S->getDirectiveKind() == OMPD_atomic ||
3339 S->getDirectiveKind() == OMPD_critical ||
3340 S->getDirectiveKind() == OMPD_section ||
3341 S->getDirectiveKind() == OMPD_master)
3342 return;
3343 visitSubCaptures(S->getInnermostCapturedStmt());
3344 // Try to capture inner this->member references to generate correct mappings
3345 // and diagnostics.
3346 if (TryCaptureCXXThisMembers ||
3347 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3348 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3349 [](const CapturedStmt::Capture &C) {
3350 return C.capturesThis();
3351 }))) {
3352 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3353 TryCaptureCXXThisMembers = true;
3354 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3355 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3356 }
3357 // In tasks firstprivates are not captured anymore, need to analyze them
3358 // explicitly.
3359 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3360 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3361 for (OMPClause *C : S->clauses())
3362 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3363 for (Expr *Ref : FC->varlists())
3364 Visit(Ref);
3365 }
3366 }
3367 }
3368
3369public:
3370 void VisitDeclRefExpr(DeclRefExpr *E) {
3371 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3372 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3373 E->isInstantiationDependent())
3374 return;
3375 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3376 // Check the datasharing rules for the expressions in the clauses.
3377 if (!CS) {
3378 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3379 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3380 Visit(CED->getInit());
3381 return;
3382 }
3383 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3384 // Do not analyze internal variables and do not enclose them into
3385 // implicit clauses.
3386 return;
3387 VD = VD->getCanonicalDecl();
3388 // Skip internally declared variables.
3389 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3390 !Stack->isImplicitTaskFirstprivate(VD))
3391 return;
3392 // Skip allocators in uses_allocators clauses.
3393 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3394 return;
3395
3396 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3397 // Check if the variable has explicit DSA set and stop analysis if it so.
3398 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3399 return;
3400
3401 // Skip internally declared static variables.
3402 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3403 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3404 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3405 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3406 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3407 !Stack->isImplicitTaskFirstprivate(VD))
3408 return;
3409
3410 SourceLocation ELoc = E->getExprLoc();
3411 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3412 // The default(none) clause requires that each variable that is referenced
3413 // in the construct, and does not have a predetermined data-sharing
3414 // attribute, must have its data-sharing attribute explicitly determined
3415 // by being listed in a data-sharing attribute clause.
3416 if (DVar.CKind == OMPC_unknown &&
3417 (Stack->getDefaultDSA() == DSA_none ||
3418 Stack->getDefaultDSA() == DSA_firstprivate) &&
3419 isImplicitOrExplicitTaskingRegion(DKind) &&
3420 VarsWithInheritedDSA.count(VD) == 0) {
3421 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3422 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3423 DSAStackTy::DSAVarData DVar =
3424 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3425 InheritedDSA = DVar.CKind == OMPC_unknown;
3426 }
3427 if (InheritedDSA)
3428 VarsWithInheritedDSA[VD] = E;
3429 return;
3430 }
3431
3432 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3433 // If implicit-behavior is none, each variable referenced in the
3434 // construct that does not have a predetermined data-sharing attribute
3435 // and does not appear in a to or link clause on a declare target
3436 // directive must be listed in a data-mapping attribute clause, a
3437 // data-haring attribute clause (including a data-sharing attribute
3438 // clause on a combined construct where target. is one of the
3439 // constituent constructs), or an is_device_ptr clause.
3440 OpenMPDefaultmapClauseKind ClauseKind =
3441 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3442 if (SemaRef.getLangOpts().OpenMP >= 50) {
3443 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3444 OMPC_DEFAULTMAP_MODIFIER_none;
3445 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3446 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3447 // Only check for data-mapping attribute and is_device_ptr here
3448 // since we have already make sure that the declaration does not
3449 // have a data-sharing attribute above
3450 if (!Stack->checkMappableExprComponentListsForDecl(
3451 VD, /*CurrentRegionOnly=*/true,
3452 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3453 MapExprComponents,
3454 OpenMPClauseKind) {
3455 auto MI = MapExprComponents.rbegin();
3456 auto ME = MapExprComponents.rend();
3457 return MI != ME && MI->getAssociatedDeclaration() == VD;
3458 })) {
3459 VarsWithInheritedDSA[VD] = E;
3460 return;
3461 }
3462 }
3463 }
3464
3465 if (isOpenMPTargetExecutionDirective(DKind) &&
3466 !Stack->isLoopControlVariable(VD).first) {
3467 if (!Stack->checkMappableExprComponentListsForDecl(
3468 VD, /*CurrentRegionOnly=*/true,
3469 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3470 StackComponents,
3471 OpenMPClauseKind) {
3472 // Variable is used if it has been marked as an array, array
3473 // section, array shaping or the variable iself.
3474 return StackComponents.size() == 1 ||
3475 std::all_of(
3476 std::next(StackComponents.rbegin()),
3477 StackComponents.rend(),
3478 [](const OMPClauseMappableExprCommon::
3479 MappableComponent &MC) {
3480 return MC.getAssociatedDeclaration() ==
3481 nullptr &&
3482 (isa<OMPArraySectionExpr>(
3483 MC.getAssociatedExpression()) ||
3484 isa<OMPArrayShapingExpr>(
3485 MC.getAssociatedExpression()) ||
3486 isa<ArraySubscriptExpr>(
3487 MC.getAssociatedExpression()));
3488 });
3489 })) {
3490 bool IsFirstprivate = false;
3491 // By default lambdas are captured as firstprivates.
3492 if (const auto *RD =
3493 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3494 IsFirstprivate = RD->isLambda();
3495 IsFirstprivate =
3496 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3497 if (IsFirstprivate) {
3498 ImplicitFirstprivate.emplace_back(E);
3499 } else {
3500 OpenMPDefaultmapClauseModifier M =
3501 Stack->getDefaultmapModifier(ClauseKind);
3502 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3503 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3504 ImplicitMap[Kind].emplace_back(E);
3505 }
3506 return;
3507 }
3508 }
3509
3510 // OpenMP [2.9.3.6, Restrictions, p.2]
3511 // A list item that appears in a reduction clause of the innermost
3512 // enclosing worksharing or parallel construct may not be accessed in an
3513 // explicit task.
3514 DVar = Stack->hasInnermostDSA(
3515 VD,
3516 [](OpenMPClauseKind C, bool AppliedToPointee) {
3517 return C == OMPC_reduction && !AppliedToPointee;
3518 },
3519 [](OpenMPDirectiveKind K) {
3520 return isOpenMPParallelDirective(K) ||
3521 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3522 },
3523 /*FromParent=*/true);
3524 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3525 ErrorFound = true;
3526 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3527 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3528 return;
3529 }
3530
3531 // Define implicit data-sharing attributes for task.
3532 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3533 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3534 (Stack->getDefaultDSA() == DSA_firstprivate &&
3535 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3536 !Stack->isLoopControlVariable(VD).first) {
3537 ImplicitFirstprivate.push_back(E);
3538 return;
3539 }
3540
3541 // Store implicitly used globals with declare target link for parent
3542 // target.
3543 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3544 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3545 Stack->addToParentTargetRegionLinkGlobals(E);
3546 return;
3547 }
3548 }
3549 }
3550 void VisitMemberExpr(MemberExpr *E) {
3551 if (E->isTypeDependent() || E->isValueDependent() ||
3552 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3553 return;
3554 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3555 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3556 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3557 if (!FD)
3558 return;
3559 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3560 // Check if the variable has explicit DSA set and stop analysis if it
3561 // so.
3562 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3563 return;
3564
3565 if (isOpenMPTargetExecutionDirective(DKind) &&
3566 !Stack->isLoopControlVariable(FD).first &&
3567 !Stack->checkMappableExprComponentListsForDecl(
3568 FD, /*CurrentRegionOnly=*/true,
3569 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3570 StackComponents,
3571 OpenMPClauseKind) {
3572 return isa<CXXThisExpr>(
3573 cast<MemberExpr>(
3574 StackComponents.back().getAssociatedExpression())
3575 ->getBase()
3576 ->IgnoreParens());
3577 })) {
3578 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3579 // A bit-field cannot appear in a map clause.
3580 //
3581 if (FD->isBitField())
3582 return;
3583
3584 // Check to see if the member expression is referencing a class that
3585 // has already been explicitly mapped
3586 if (Stack->isClassPreviouslyMapped(TE->getType()))
3587 return;
3588
3589 OpenMPDefaultmapClauseModifier Modifier =
3590 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3591 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3592 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3593 ImplicitMap[Kind].emplace_back(E);
3594 return;
3595 }
3596
3597 SourceLocation ELoc = E->getExprLoc();
3598 // OpenMP [2.9.3.6, Restrictions, p.2]
3599 // A list item that appears in a reduction clause of the innermost
3600 // enclosing worksharing or parallel construct may not be accessed in
3601 // an explicit task.
3602 DVar = Stack->hasInnermostDSA(
3603 FD,
3604 [](OpenMPClauseKind C, bool AppliedToPointee) {
3605 return C == OMPC_reduction && !AppliedToPointee;
3606 },
3607 [](OpenMPDirectiveKind K) {
3608 return isOpenMPParallelDirective(K) ||
3609 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3610 },
3611 /*FromParent=*/true);
3612 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3613 ErrorFound = true;
3614 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3615 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3616 return;
3617 }
3618
3619 // Define implicit data-sharing attributes for task.
3620 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3621 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3622 !Stack->isLoopControlVariable(FD).first) {
3623 // Check if there is a captured expression for the current field in the
3624 // region. Do not mark it as firstprivate unless there is no captured
3625 // expression.
3626 // TODO: try to make it firstprivate.
3627 if (DVar.CKind != OMPC_unknown)
3628 ImplicitFirstprivate.push_back(E);
3629 }
3630 return;
3631 }
3632 if (isOpenMPTargetExecutionDirective(DKind)) {
3633 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3634 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3635 /*NoDiagnose=*/true))
3636 return;
3637 const auto *VD = cast<ValueDecl>(
3638 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3639 if (!Stack->checkMappableExprComponentListsForDecl(
3640 VD, /*CurrentRegionOnly=*/true,
3641 [&CurComponents](
3642 OMPClauseMappableExprCommon::MappableExprComponentListRef
3643 StackComponents,
3644 OpenMPClauseKind) {
3645 auto CCI = CurComponents.rbegin();
3646 auto CCE = CurComponents.rend();
3647 for (const auto &SC : llvm::reverse(StackComponents)) {
3648 // Do both expressions have the same kind?
3649 if (CCI->getAssociatedExpression()->getStmtClass() !=
3650 SC.getAssociatedExpression()->getStmtClass())
3651 if (!((isa<OMPArraySectionExpr>(
3652 SC.getAssociatedExpression()) ||
3653 isa<OMPArrayShapingExpr>(
3654 SC.getAssociatedExpression())) &&
3655 isa<ArraySubscriptExpr>(
3656 CCI->getAssociatedExpression())))
3657 return false;
3658
3659 const Decl *CCD = CCI->getAssociatedDeclaration();
3660 const Decl *SCD = SC.getAssociatedDeclaration();
3661 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3662 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3663 if (SCD != CCD)
3664 return false;
3665 std::advance(CCI, 1);
3666 if (CCI == CCE)
3667 break;
3668 }
3669 return true;
3670 })) {
3671 Visit(E->getBase());
3672 }
3673 } else if (!TryCaptureCXXThisMembers) {
3674 Visit(E->getBase());
3675 }
3676 }
3677 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3678 for (OMPClause *C : S->clauses()) {
3679 // Skip analysis of arguments of implicitly defined firstprivate clause
3680 // for task|target directives.
3681 // Skip analysis of arguments of implicitly defined map clause for target
3682 // directives.
3683 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3684 C->isImplicit())) {
3685 for (Stmt *CC : C->children()) {
3686 if (CC)
3687 Visit(CC);
3688 }
3689 }
3690 }
3691 // Check implicitly captured variables.
3692 VisitSubCaptures(S);
3693 }
3694 void VisitStmt(Stmt *S) {
3695 for (Stmt *C : S->children()) {
3696 if (C) {
3697 // Check implicitly captured variables in the task-based directives to
3698 // check if they must be firstprivatized.
3699 Visit(C);
3700 }
3701 }
3702 }
3703
3704 void visitSubCaptures(CapturedStmt *S) {
3705 for (const CapturedStmt::Capture &Cap : S->captures()) {
3706 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3707 continue;
3708 VarDecl *VD = Cap.getCapturedVar();
3709 // Do not try to map the variable if it or its sub-component was mapped
3710 // already.
3711 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3712 Stack->checkMappableExprComponentListsForDecl(
3713 VD, /*CurrentRegionOnly=*/true,
3714 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3715 OpenMPClauseKind) { return true; }))
3716 continue;
3717 DeclRefExpr *DRE = buildDeclRefExpr(
3718 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3719 Cap.getLocation(), /*RefersToCapture=*/true);
3720 Visit(DRE);
3721 }
3722 }
3723 bool isErrorFound() const { return ErrorFound; }
3724 ArrayRef<Expr *> getImplicitFirstprivate() const {
3725 return ImplicitFirstprivate;
3726 }
3727 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3728 return ImplicitMap[Kind];
3729 }
3730 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3731 return VarsWithInheritedDSA;
3732 }
3733
3734 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3735 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3736 // Process declare target link variables for the target directives.
3737 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3738 for (DeclRefExpr *E : Stack->getLinkGlobals())
3739 Visit(E);
3740 }
3741 }
3742};
3743} // namespace
3744
3745void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3746 switch (DKind) {
3747 case OMPD_parallel:
3748 case OMPD_parallel_for:
3749 case OMPD_parallel_for_simd:
3750 case OMPD_parallel_sections:
3751 case OMPD_parallel_master:
3752 case OMPD_teams:
3753 case OMPD_teams_distribute:
3754 case OMPD_teams_distribute_simd: {
3755 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3756 QualType KmpInt32PtrTy =
3757 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3758 Sema::CapturedParamNameType Params[] = {
3759 std::make_pair(".global_tid.", KmpInt32PtrTy),
3760 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3761 std::make_pair(StringRef(), QualType()) // __context with shared vars
3762 };
3763 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3764 Params);
3765 break;
3766 }
3767 case OMPD_target_teams:
3768 case OMPD_target_parallel:
3769 case OMPD_target_parallel_for:
3770 case OMPD_target_parallel_for_simd:
3771 case OMPD_target_teams_distribute:
3772 case OMPD_target_teams_distribute_simd: {
3773 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3774 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3775 QualType KmpInt32PtrTy =
3776 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3777 QualType Args[] = {VoidPtrTy};
3778 FunctionProtoType::ExtProtoInfo EPI;
3779 EPI.Variadic = true;
3780 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3781 Sema::CapturedParamNameType Params[] = {
3782 std::make_pair(".global_tid.", KmpInt32Ty),
3783 std::make_pair(".part_id.", KmpInt32PtrTy),
3784 std::make_pair(".privates.", VoidPtrTy),
3785 std::make_pair(
3786 ".copy_fn.",
3787 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3788 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3789 std::make_pair(StringRef(), QualType()) // __context with shared vars
3790 };
3791 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3792 Params, /*OpenMPCaptureLevel=*/0);
3793 // Mark this captured region as inlined, because we don't use outlined
3794 // function directly.
3795 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3796 AlwaysInlineAttr::CreateImplicit(
3797 Context, {}, AttributeCommonInfo::AS_Keyword,
3798 AlwaysInlineAttr::Keyword_forceinline));
3799 Sema::CapturedParamNameType ParamsTarget[] = {
3800 std::make_pair(StringRef(), QualType()) // __context with shared vars
3801 };
3802 // Start a captured region for 'target' with no implicit parameters.
3803 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3804 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3805 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3806 std::make_pair(".global_tid.", KmpInt32PtrTy),
3807 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3808 std::make_pair(StringRef(), QualType()) // __context with shared vars
3809 };
3810 // Start a captured region for 'teams' or 'parallel'. Both regions have
3811 // the same implicit parameters.
3812 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3813 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3814 break;
3815 }
3816 case OMPD_target:
3817 case OMPD_target_simd: {
3818 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3819 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3820 QualType KmpInt32PtrTy =
3821 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3822 QualType Args[] = {VoidPtrTy};
3823 FunctionProtoType::ExtProtoInfo EPI;
3824 EPI.Variadic = true;
3825 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3826 Sema::CapturedParamNameType Params[] = {
3827 std::make_pair(".global_tid.", KmpInt32Ty),
3828 std::make_pair(".part_id.", KmpInt32PtrTy),
3829 std::make_pair(".privates.", VoidPtrTy),
3830 std::make_pair(
3831 ".copy_fn.",
3832 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3833 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3834 std::make_pair(StringRef(), QualType()) // __context with shared vars
3835 };
3836 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3837 Params, /*OpenMPCaptureLevel=*/0);
3838 // Mark this captured region as inlined, because we don't use outlined
3839 // function directly.
3840 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3841 AlwaysInlineAttr::CreateImplicit(
3842 Context, {}, AttributeCommonInfo::AS_Keyword,
3843 AlwaysInlineAttr::Keyword_forceinline));
3844 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3845 std::make_pair(StringRef(), QualType()),
3846 /*OpenMPCaptureLevel=*/1);
3847 break;
3848 }
3849 case OMPD_atomic:
3850 case OMPD_critical:
3851 case OMPD_section:
3852 case OMPD_master:
3853 break;
3854 case OMPD_simd:
3855 case OMPD_for:
3856 case OMPD_for_simd:
3857 case OMPD_sections:
3858 case OMPD_single:
3859 case OMPD_taskgroup:
3860 case OMPD_distribute:
3861 case OMPD_distribute_simd:
3862 case OMPD_ordered:
3863 case OMPD_target_data: {
3864 Sema::CapturedParamNameType Params[] = {
3865 std::make_pair(StringRef(), QualType()) // __context with shared vars
3866 };
3867 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3868 Params);
3869 break;
3870 }
3871 case OMPD_task: {
3872 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3873 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3874 QualType KmpInt32PtrTy =
3875 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3876 QualType Args[] = {VoidPtrTy};
3877 FunctionProtoType::ExtProtoInfo EPI;
3878 EPI.Variadic = true;
3879 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3880 Sema::CapturedParamNameType Params[] = {
3881 std::make_pair(".global_tid.", KmpInt32Ty),
3882 std::make_pair(".part_id.", KmpInt32PtrTy),
3883 std::make_pair(".privates.", VoidPtrTy),
3884 std::make_pair(
3885 ".copy_fn.",
3886 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3887 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3888 std::make_pair(StringRef(), QualType()) // __context with shared vars
3889 };
3890 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3891 Params);
3892 // Mark this captured region as inlined, because we don't use outlined
3893 // function directly.
3894 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3895 AlwaysInlineAttr::CreateImplicit(
3896 Context, {}, AttributeCommonInfo::AS_Keyword,
3897 AlwaysInlineAttr::Keyword_forceinline));
3898 break;
3899 }
3900 case OMPD_taskloop:
3901 case OMPD_taskloop_simd:
3902 case OMPD_master_taskloop:
3903 case OMPD_master_taskloop_simd: {
3904 QualType KmpInt32Ty =
3905 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3906 .withConst();
3907 QualType KmpUInt64Ty =
3908 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3909 .withConst();
3910 QualType KmpInt64Ty =
3911 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3912 .withConst();
3913 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3914 QualType KmpInt32PtrTy =
3915 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3916 QualType Args[] = {VoidPtrTy};
3917 FunctionProtoType::ExtProtoInfo EPI;
3918 EPI.Variadic = true;
3919 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3920 Sema::CapturedParamNameType Params[] = {
3921 std::make_pair(".global_tid.", KmpInt32Ty),
3922 std::make_pair(".part_id.", KmpInt32PtrTy),
3923 std::make_pair(".privates.", VoidPtrTy),
3924 std::make_pair(
3925 ".copy_fn.",
3926 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3927 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3928 std::make_pair(".lb.", KmpUInt64Ty),
3929 std::make_pair(".ub.", KmpUInt64Ty),
3930 std::make_pair(".st.", KmpInt64Ty),
3931 std::make_pair(".liter.", KmpInt32Ty),
3932 std::make_pair(".reductions.", VoidPtrTy),
3933 std::make_pair(StringRef(), QualType()) // __context with shared vars
3934 };
3935 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3936 Params);
3937 // Mark this captured region as inlined, because we don't use outlined
3938 // function directly.
3939 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3940 AlwaysInlineAttr::CreateImplicit(
3941 Context, {}, AttributeCommonInfo::AS_Keyword,
3942 AlwaysInlineAttr::Keyword_forceinline));
3943 break;
3944 }
3945 case OMPD_parallel_master_taskloop:
3946 case OMPD_parallel_master_taskloop_simd: {
3947 QualType KmpInt32Ty =
3948 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3949 .withConst();
3950 QualType KmpUInt64Ty =
3951 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3952 .withConst();
3953 QualType KmpInt64Ty =
3954 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3955 .withConst();
3956 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3957 QualType KmpInt32PtrTy =
3958 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3959 Sema::CapturedParamNameType ParamsParallel[] = {
3960 std::make_pair(".global_tid.", KmpInt32PtrTy),
3961 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3962 std::make_pair(StringRef(), QualType()) // __context with shared vars
3963 };
3964 // Start a captured region for 'parallel'.
3965 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3966 ParamsParallel, /*OpenMPCaptureLevel=*/0);
3967 QualType Args[] = {VoidPtrTy};
3968 FunctionProtoType::ExtProtoInfo EPI;
3969 EPI.Variadic = true;
3970 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3971 Sema::CapturedParamNameType Params[] = {
3972 std::make_pair(".global_tid.", KmpInt32Ty),
3973 std::make_pair(".part_id.", KmpInt32PtrTy),
3974 std::make_pair(".privates.", VoidPtrTy),
3975 std::make_pair(
3976 ".copy_fn.",
3977 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3978 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3979 std::make_pair(".lb.", KmpUInt64Ty),
3980 std::make_pair(".ub.", KmpUInt64Ty),
3981 std::make_pair(".st.", KmpInt64Ty),
3982 std::make_pair(".liter.", KmpInt32Ty),
3983 std::make_pair(".reductions.", VoidPtrTy),
3984 std::make_pair(StringRef(), QualType()) // __context with shared vars
3985 };
3986 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3987 Params, /*OpenMPCaptureLevel=*/1);
3988 // Mark this captured region as inlined, because we don't use outlined
3989 // function directly.
3990 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3991 AlwaysInlineAttr::CreateImplicit(
3992 Context, {}, AttributeCommonInfo::AS_Keyword,
3993 AlwaysInlineAttr::Keyword_forceinline));
3994 break;
3995 }
3996 case OMPD_distribute_parallel_for_simd:
3997 case OMPD_distribute_parallel_for: {
3998 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3999 QualType KmpInt32PtrTy =
4000 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4001 Sema::CapturedParamNameType Params[] = {
4002 std::make_pair(".global_tid.", KmpInt32PtrTy),
4003 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4004 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4005 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4006 std::make_pair(StringRef(), QualType()) // __context with shared vars
4007 };
4008 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4009 Params);
4010 break;
4011 }
4012 case OMPD_target_teams_distribute_parallel_for:
4013 case OMPD_target_teams_distribute_parallel_for_simd: {
4014 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4015 QualType KmpInt32PtrTy =
4016 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4017 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4018
4019 QualType Args[] = {VoidPtrTy};
4020 FunctionProtoType::ExtProtoInfo EPI;
4021 EPI.Variadic = true;
4022 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4023 Sema::CapturedParamNameType Params[] = {
4024 std::make_pair(".global_tid.", KmpInt32Ty),
4025 std::make_pair(".part_id.", KmpInt32PtrTy),
4026 std::make_pair(".privates.", VoidPtrTy),
4027 std::make_pair(
4028 ".copy_fn.",
4029 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4030 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4031 std::make_pair(StringRef(), QualType()) // __context with shared vars
4032 };
4033 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4034 Params, /*OpenMPCaptureLevel=*/0);
4035 // Mark this captured region as inlined, because we don't use outlined
4036 // function directly.
4037 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4038 AlwaysInlineAttr::CreateImplicit(
4039 Context, {}, AttributeCommonInfo::AS_Keyword,
4040 AlwaysInlineAttr::Keyword_forceinline));
4041 Sema::CapturedParamNameType ParamsTarget[] = {
4042 std::make_pair(StringRef(), QualType()) // __context with shared vars
4043 };
4044 // Start a captured region for 'target' with no implicit parameters.
4045 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4046 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4047
4048 Sema::CapturedParamNameType ParamsTeams[] = {
4049 std::make_pair(".global_tid.", KmpInt32PtrTy),
4050 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4051 std::make_pair(StringRef(), QualType()) // __context with shared vars
4052 };
4053 // Start a captured region for 'target' with no implicit parameters.
4054 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4055 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4056
4057 Sema::CapturedParamNameType ParamsParallel[] = {
4058 std::make_pair(".global_tid.", KmpInt32PtrTy),
4059 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4060 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4061 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4062 std::make_pair(StringRef(), QualType()) // __context with shared vars
4063 };
4064 // Start a captured region for 'teams' or 'parallel'. Both regions have
4065 // the same implicit parameters.
4066 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4067 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4068 break;
4069 }
4070
4071 case OMPD_teams_distribute_parallel_for:
4072 case OMPD_teams_distribute_parallel_for_simd: {
4073 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4074 QualType KmpInt32PtrTy =
4075 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4076
4077 Sema::CapturedParamNameType ParamsTeams[] = {
4078 std::make_pair(".global_tid.", KmpInt32PtrTy),
4079 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4080 std::make_pair(StringRef(), QualType()) // __context with shared vars
4081 };
4082 // Start a captured region for 'target' with no implicit parameters.
4083 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4084 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4085
4086 Sema::CapturedParamNameType ParamsParallel[] = {
4087 std::make_pair(".global_tid.", KmpInt32PtrTy),
4088 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4089 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4090 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4091 std::make_pair(StringRef(), QualType()) // __context with shared vars
4092 };
4093 // Start a captured region for 'teams' or 'parallel'. Both regions have
4094 // the same implicit parameters.
4095 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4096 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4097 break;
4098 }
4099 case OMPD_target_update:
4100 case OMPD_target_enter_data:
4101 case OMPD_target_exit_data: {
4102 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4103 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4104 QualType KmpInt32PtrTy =
4105 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4106 QualType Args[] = {VoidPtrTy};
4107 FunctionProtoType::ExtProtoInfo EPI;
4108 EPI.Variadic = true;
4109 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4110 Sema::CapturedParamNameType Params[] = {
4111 std::make_pair(".global_tid.", KmpInt32Ty),
4112 std::make_pair(".part_id.", KmpInt32PtrTy),
4113 std::make_pair(".privates.", VoidPtrTy),
4114 std::make_pair(
4115 ".copy_fn.",
4116 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4117 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4118 std::make_pair(StringRef(), QualType()) // __context with shared vars
4119 };
4120 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4121 Params);
4122 // Mark this captured region as inlined, because we don't use outlined
4123 // function directly.
4124 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4125 AlwaysInlineAttr::CreateImplicit(
4126 Context, {}, AttributeCommonInfo::AS_Keyword,
4127 AlwaysInlineAttr::Keyword_forceinline));
4128 break;
4129 }
4130 case OMPD_threadprivate:
4131 case OMPD_allocate:
4132 case OMPD_taskyield:
4133 case OMPD_barrier:
4134 case OMPD_taskwait:
4135 case OMPD_cancellation_point:
4136 case OMPD_cancel:
4137 case OMPD_flush:
4138 case OMPD_depobj:
4139 case OMPD_scan:
4140 case OMPD_declare_reduction:
4141 case OMPD_declare_mapper:
4142 case OMPD_declare_simd:
4143 case OMPD_declare_target:
4144 case OMPD_end_declare_target:
4145 case OMPD_requires:
4146 case OMPD_declare_variant:
4147 case OMPD_begin_declare_variant:
4148 case OMPD_end_declare_variant:
4149 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 4149)
;
4150 case OMPD_unknown:
4151 default:
4152 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 4152)
;
4153 }
4154}
4155
4156int Sema::getNumberOfConstructScopes(unsigned Level) const {
4157 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4158}
4159
4160int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4161 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4162 getOpenMPCaptureRegions(CaptureRegions, DKind);
4163 return CaptureRegions.size();
4164}
4165
4166static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4167 Expr *CaptureExpr, bool WithInit,
4168 bool AsExpression) {
4169 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 4169, __PRETTY_FUNCTION__))
;
4170 ASTContext &C = S.getASTContext();
4171 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4172 QualType Ty = Init->getType();
4173 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4174 if (S.getLangOpts().CPlusPlus) {
4175 Ty = C.getLValueReferenceType(Ty);
4176 } else {
4177 Ty = C.getPointerType(Ty);
4178 ExprResult Res =
4179 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4180 if (!Res.isUsable())
4181 return nullptr;
4182 Init = Res.get();
4183 }
4184 WithInit = true;
4185 }
4186 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4187 CaptureExpr->getBeginLoc());
4188 if (!WithInit)
4189 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4190 S.CurContext->addHiddenDecl(CED);
4191 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4192 return CED;
4193}
4194
4195static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4196 bool WithInit) {
4197 OMPCapturedExprDecl *CD;
4198 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
5
Calling 'Sema::isOpenMPCapturedDecl'
4199 CD = cast<OMPCapturedExprDecl>(VD);
4200 else
4201 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4202 /*AsExpression=*/false);
4203 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4204 CaptureExpr->getExprLoc());
4205}
4206
4207static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4208 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4209 if (!Ref) {
4210 OMPCapturedExprDecl *CD = buildCaptureDecl(
4211 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4212 /*WithInit=*/true, /*AsExpression=*/true);
4213 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4214 CaptureExpr->getExprLoc());
4215 }
4216 ExprResult Res = Ref;
4217 if (!S.getLangOpts().CPlusPlus &&
4218 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4219 Ref->getType()->isPointerType()) {
4220 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4221 if (!Res.isUsable())
4222 return ExprError();
4223 }
4224 return S.DefaultLvalueConversion(Res.get());
4225}
4226
4227namespace {
4228// OpenMP directives parsed in this section are represented as a
4229// CapturedStatement with an associated statement. If a syntax error
4230// is detected during the parsing of the associated statement, the
4231// compiler must abort processing and close the CapturedStatement.
4232//
4233// Combined directives such as 'target parallel' have more than one
4234// nested CapturedStatements. This RAII ensures that we unwind out
4235// of all the nested CapturedStatements when an error is found.
4236class CaptureRegionUnwinderRAII {
4237private:
4238 Sema &S;
4239 bool &ErrorFound;
4240 OpenMPDirectiveKind DKind = OMPD_unknown;
4241
4242public:
4243 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4244 OpenMPDirectiveKind DKind)
4245 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4246 ~CaptureRegionUnwinderRAII() {
4247 if (ErrorFound) {
4248 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4249 while (--ThisCaptureLevel >= 0)
4250 S.ActOnCapturedRegionError();
4251 }
4252 }
4253};
4254} // namespace
4255
4256void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4257 // Capture variables captured by reference in lambdas for target-based
4258 // directives.
4259 if (!CurContext->isDependentContext() &&
4260 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4261 isOpenMPTargetDataManagementDirective(
4262 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4263 QualType Type = V->getType();
4264 if (const auto *RD = Type.getCanonicalType()
4265 .getNonReferenceType()
4266 ->getAsCXXRecordDecl()) {
4267 bool SavedForceCaptureByReferenceInTargetExecutable =
4268 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4269 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4270 /*V=*/true);
4271 if (RD->isLambda()) {
4272 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4273 FieldDecl *ThisCapture;
4274 RD->getCaptureFields(Captures, ThisCapture);
4275 for (const LambdaCapture &LC : RD->captures()) {
4276 if (LC.getCaptureKind() == LCK_ByRef) {
4277 VarDecl *VD = LC.getCapturedVar();
4278 DeclContext *VDC = VD->getDeclContext();
4279 if (!VDC->Encloses(CurContext))
4280 continue;
4281 MarkVariableReferenced(LC.getLocation(), VD);
4282 } else if (LC.getCaptureKind() == LCK_This) {
4283 QualType ThisTy = getCurrentThisType();
4284 if (!ThisTy.isNull() &&
4285 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4286 CheckCXXThisCapture(LC.getLocation());
4287 }
4288 }
4289 }
4290 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4291 SavedForceCaptureByReferenceInTargetExecutable);
4292 }
4293 }
4294}
4295
4296static bool checkOrderedOrderSpecified(Sema &S,
4297 const ArrayRef<OMPClause *> Clauses) {
4298 const OMPOrderedClause *Ordered = nullptr;
4299 const OMPOrderClause *Order = nullptr;
4300
4301 for (const OMPClause *Clause : Clauses) {
4302 if (Clause->getClauseKind() == OMPC_ordered)
4303 Ordered = cast<OMPOrderedClause>(Clause);
4304 else if (Clause->getClauseKind() == OMPC_order) {
4305 Order = cast<OMPOrderClause>(Clause);
4306 if (Order->getKind() != OMPC_ORDER_concurrent)
4307 Order = nullptr;
4308 }
4309 if (Ordered && Order)
4310 break;
4311 }
4312
4313 if (Ordered && Order) {
4314 S.Diag(Order->getKindKwLoc(),
4315 diag::err_omp_simple_clause_incompatible_with_ordered)
4316 << getOpenMPClauseName(OMPC_order)
4317 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4318 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4319 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4320 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4321 return true;
4322 }
4323 return false;
4324}
4325
4326StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4327 ArrayRef<OMPClause *> Clauses) {
4328 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4329 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4330 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4331 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master)
4332 return S;
4333
4334 bool ErrorFound = false;
4335 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4336 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4337 if (!S.isUsable()) {
4338 ErrorFound = true;
4339 return StmtError();
4340 }
4341
4342 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4343 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4344 OMPOrderedClause *OC = nullptr;
4345 OMPScheduleClause *SC = nullptr;
4346 SmallVector<const OMPLinearClause *, 4> LCs;
4347 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4348 // This is required for proper codegen.
4349 for (OMPClause *Clause : Clauses) {
4350 if (!LangOpts.OpenMPSimd &&
4351 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4352 Clause->getClauseKind() == OMPC_in_reduction) {
4353 // Capture taskgroup task_reduction descriptors inside the tasking regions
4354 // with the corresponding in_reduction items.
4355 auto *IRC = cast<OMPInReductionClause>(Clause);
4356 for (Expr *E : IRC->taskgroup_descriptors())
4357 if (E)
4358 MarkDeclarationsReferencedInExpr(E);
4359 }
4360 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4361 Clause->getClauseKind() == OMPC_copyprivate ||
4362 (getLangOpts().OpenMPUseTLS &&
4363 getASTContext().getTargetInfo().isTLSSupported() &&
4364 Clause->getClauseKind() == OMPC_copyin)) {
4365 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4366 // Mark all variables in private list clauses as used in inner region.
4367 for (Stmt *VarRef : Clause->children()) {
4368 if (auto *E = cast_or_null<Expr>(VarRef)) {
4369 MarkDeclarationsReferencedInExpr(E);
4370 }
4371 }
4372 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4373 } else if (CaptureRegions.size() > 1 ||
4374 CaptureRegions.back() != OMPD_unknown) {
4375 if (auto *C = OMPClauseWithPreInit::get(Clause))
4376 PICs.push_back(C);
4377 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4378 if (Expr *E = C->getPostUpdateExpr())
4379 MarkDeclarationsReferencedInExpr(E);
4380 }
4381 }
4382 if (Clause->getClauseKind() == OMPC_schedule)
4383 SC = cast<OMPScheduleClause>(Clause);
4384 else if (Clause->getClauseKind() == OMPC_ordered)
4385 OC = cast<OMPOrderedClause>(Clause);
4386 else if (Clause->getClauseKind() == OMPC_linear)
4387 LCs.push_back(cast<OMPLinearClause>(Clause));
4388 }
4389 // Capture allocator expressions if used.
4390 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4391 MarkDeclarationsReferencedInExpr(E);
4392 // OpenMP, 2.7.1 Loop Construct, Restrictions
4393 // The nonmonotonic modifier cannot be specified if an ordered clause is
4394 // specified.
4395 if (SC &&
4396 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4397 SC->getSecondScheduleModifier() ==
4398 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4399 OC) {
4400 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4401 ? SC->getFirstScheduleModifierLoc()
4402 : SC->getSecondScheduleModifierLoc(),
4403 diag::err_omp_simple_clause_incompatible_with_ordered)
4404 << getOpenMPClauseName(OMPC_schedule)
4405 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4406 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4407 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4408 ErrorFound = true;
4409 }
4410 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4411 // If an order(concurrent) clause is present, an ordered clause may not appear
4412 // on the same directive.
4413 if (checkOrderedOrderSpecified(*this, Clauses))
4414 ErrorFound = true;
4415 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4416 for (const OMPLinearClause *C : LCs) {
4417 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4418 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4419 }
4420 ErrorFound = true;
4421 }
4422 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4423 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4424 OC->getNumForLoops()) {
4425 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4426 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4427 ErrorFound = true;
4428 }
4429 if (ErrorFound) {
4430 return StmtError();
4431 }
4432 StmtResult SR = S;
4433 unsigned CompletedRegions = 0;
4434 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4435 // Mark all variables in private list clauses as used in inner region.
4436 // Required for proper codegen of combined directives.
4437 // TODO: add processing for other clauses.
4438 if (ThisCaptureRegion != OMPD_unknown) {
4439 for (const clang::OMPClauseWithPreInit *C : PICs) {
4440 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4441 // Find the particular capture region for the clause if the
4442 // directive is a combined one with multiple capture regions.
4443 // If the directive is not a combined one, the capture region
4444 // associated with the clause is OMPD_unknown and is generated
4445 // only once.
4446 if (CaptureRegion == ThisCaptureRegion ||
4447 CaptureRegion == OMPD_unknown) {
4448 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4449 for (Decl *D : DS->decls())
4450 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4451 }
4452 }
4453 }
4454 }
4455 if (ThisCaptureRegion == OMPD_target) {
4456 // Capture allocator traits in the target region. They are used implicitly
4457 // and, thus, are not captured by default.
4458 for (OMPClause *C : Clauses) {
4459 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4460 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4461 ++I) {
4462 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4463 if (Expr *E = D.AllocatorTraits)
4464 MarkDeclarationsReferencedInExpr(E);
4465 }
4466 continue;
4467 }
4468 }
4469 }
4470 if (++CompletedRegions == CaptureRegions.size())
4471 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4472 SR = ActOnCapturedRegionEnd(SR.get());
4473 }
4474 return SR;
4475}
4476
4477static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4478 OpenMPDirectiveKind CancelRegion,
4479 SourceLocation StartLoc) {
4480 // CancelRegion is only needed for cancel and cancellation_point.
4481 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4482 return false;
4483
4484 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4485 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4486 return false;
4487
4488 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4489 << getOpenMPDirectiveName(CancelRegion);
4490 return true;
4491}
4492
4493static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4494 OpenMPDirectiveKind CurrentRegion,
4495 const DeclarationNameInfo &CurrentName,
4496 OpenMPDirectiveKind CancelRegion,
4497 SourceLocation StartLoc) {
4498 if (Stack->getCurScope()) {
4499 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4500 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4501 bool NestingProhibited = false;
4502 bool CloseNesting = true;
4503 bool OrphanSeen = false;
4504 enum {
4505 NoRecommend,
4506 ShouldBeInParallelRegion,
4507 ShouldBeInOrderedRegion,
4508 ShouldBeInTargetRegion,
4509 ShouldBeInTeamsRegion,
4510 ShouldBeInLoopSimdRegion,
4511 } Recommend = NoRecommend;
4512 if (isOpenMPSimdDirective(ParentRegion) &&
4513 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4514 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4515 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4516 CurrentRegion != OMPD_scan))) {
4517 // OpenMP [2.16, Nesting of Regions]
4518 // OpenMP constructs may not be nested inside a simd region.
4519 // OpenMP [2.8.1,simd Construct, Restrictions]
4520 // An ordered construct with the simd clause is the only OpenMP
4521 // construct that can appear in the simd region.
4522 // Allowing a SIMD construct nested in another SIMD construct is an
4523 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4524 // message.
4525 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4526 // The only OpenMP constructs that can be encountered during execution of
4527 // a simd region are the atomic construct, the loop construct, the simd
4528 // construct and the ordered construct with the simd clause.
4529 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4530 ? diag::err_omp_prohibited_region_simd
4531 : diag::warn_omp_nesting_simd)
4532 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4533 return CurrentRegion != OMPD_simd;
4534 }
4535 if (ParentRegion == OMPD_atomic) {
4536 // OpenMP [2.16, Nesting of Regions]
4537 // OpenMP constructs may not be nested inside an atomic region.
4538 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4539 return true;
4540 }
4541 if (CurrentRegion == OMPD_section) {
4542 // OpenMP [2.7.2, sections Construct, Restrictions]
4543 // Orphaned section directives are prohibited. That is, the section
4544 // directives must appear within the sections construct and must not be
4545 // encountered elsewhere in the sections region.
4546 if (ParentRegion != OMPD_sections &&
4547 ParentRegion != OMPD_parallel_sections) {
4548 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4549 << (ParentRegion != OMPD_unknown)
4550 << getOpenMPDirectiveName(ParentRegion);
4551 return true;
4552 }
4553 return false;
4554 }
4555 // Allow some constructs (except teams and cancellation constructs) to be
4556 // orphaned (they could be used in functions, called from OpenMP regions
4557 // with the required preconditions).
4558 if (ParentRegion == OMPD_unknown &&
4559 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4560 CurrentRegion != OMPD_cancellation_point &&
4561 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4562 return false;
4563 if (CurrentRegion == OMPD_cancellation_point ||
4564 CurrentRegion == OMPD_cancel) {
4565 // OpenMP [2.16, Nesting of Regions]
4566 // A cancellation point construct for which construct-type-clause is
4567 // taskgroup must be nested inside a task construct. A cancellation
4568 // point construct for which construct-type-clause is not taskgroup must
4569 // be closely nested inside an OpenMP construct that matches the type
4570 // specified in construct-type-clause.
4571 // A cancel construct for which construct-type-clause is taskgroup must be
4572 // nested inside a task construct. A cancel construct for which
4573 // construct-type-clause is not taskgroup must be closely nested inside an
4574 // OpenMP construct that matches the type specified in
4575 // construct-type-clause.
4576 NestingProhibited =
4577 !((CancelRegion == OMPD_parallel &&
4578 (ParentRegion == OMPD_parallel ||
4579 ParentRegion == OMPD_target_parallel)) ||
4580 (CancelRegion == OMPD_for &&
4581 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4582 ParentRegion == OMPD_target_parallel_for ||
4583 ParentRegion == OMPD_distribute_parallel_for ||
4584 ParentRegion == OMPD_teams_distribute_parallel_for ||
4585 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4586 (CancelRegion == OMPD_taskgroup &&
4587 (ParentRegion == OMPD_task ||
4588 (SemaRef.getLangOpts().OpenMP >= 50 &&
4589 (ParentRegion == OMPD_taskloop ||
4590 ParentRegion == OMPD_master_taskloop ||
4591 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4592 (CancelRegion == OMPD_sections &&
4593 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4594 ParentRegion == OMPD_parallel_sections)));
4595 OrphanSeen = ParentRegion == OMPD_unknown;
4596 } else if (CurrentRegion == OMPD_master) {
4597 // OpenMP [2.16, Nesting of Regions]
4598 // A master region may not be closely nested inside a worksharing,
4599 // atomic, or explicit task region.
4600 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4601 isOpenMPTaskingDirective(ParentRegion);
4602 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4603 // OpenMP [2.16, Nesting of Regions]
4604 // A critical region may not be nested (closely or otherwise) inside a
4605 // critical region with the same name. Note that this restriction is not
4606 // sufficient to prevent deadlock.
4607 SourceLocation PreviousCriticalLoc;
4608 bool DeadLock = Stack->hasDirective(
4609 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4610 const DeclarationNameInfo &DNI,
4611 SourceLocation Loc) {
4612 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4613 PreviousCriticalLoc = Loc;
4614 return true;
4615 }
4616 return false;
4617 },
4618 false /* skip top directive */);
4619 if (DeadLock) {
4620 SemaRef.Diag(StartLoc,
4621 diag::err_omp_prohibited_region_critical_same_name)
4622 << CurrentName.getName();
4623 if (PreviousCriticalLoc.isValid())
4624 SemaRef.Diag(PreviousCriticalLoc,
4625 diag::note_omp_previous_critical_region);
4626 return true;
4627 }
4628 } else if (CurrentRegion == OMPD_barrier) {
4629 // OpenMP [2.16, Nesting of Regions]
4630 // A barrier region may not be closely nested inside a worksharing,
4631 // explicit task, critical, ordered, atomic, or master region.
4632 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4633 isOpenMPTaskingDirective(ParentRegion) ||
4634 ParentRegion == OMPD_master ||
4635 ParentRegion == OMPD_parallel_master ||
4636 ParentRegion == OMPD_critical ||
4637 ParentRegion == OMPD_ordered;
4638 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4639 !isOpenMPParallelDirective(CurrentRegion) &&
4640 !isOpenMPTeamsDirective(CurrentRegion)) {
4641 // OpenMP [2.16, Nesting of Regions]
4642 // A worksharing region may not be closely nested inside a worksharing,
4643 // explicit task, critical, ordered, atomic, or master region.
4644 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4645 isOpenMPTaskingDirective(ParentRegion) ||
4646 ParentRegion == OMPD_master ||
4647 ParentRegion == OMPD_parallel_master ||
4648 ParentRegion == OMPD_critical ||
4649 ParentRegion == OMPD_ordered;
4650 Recommend = ShouldBeInParallelRegion;
4651 } else if (CurrentRegion == OMPD_ordered) {
4652 // OpenMP [2.16, Nesting of Regions]
4653 // An ordered region may not be closely nested inside a critical,
4654 // atomic, or explicit task region.
4655 // An ordered region must be closely nested inside a loop region (or
4656 // parallel loop region) with an ordered clause.
4657 // OpenMP [2.8.1,simd Construct, Restrictions]
4658 // An ordered construct with the simd clause is the only OpenMP construct
4659 // that can appear in the simd region.
4660 NestingProhibited = ParentRegion == OMPD_critical ||
4661 isOpenMPTaskingDirective(ParentRegion) ||
4662 !(isOpenMPSimdDirective(ParentRegion) ||
4663 Stack->isParentOrderedRegion());
4664 Recommend = ShouldBeInOrderedRegion;
4665 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4666 // OpenMP [2.16, Nesting of Regions]
4667 // If specified, a teams construct must be contained within a target
4668 // construct.
4669 NestingProhibited =
4670 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4671 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4672 ParentRegion != OMPD_target);
4673 OrphanSeen = ParentRegion == OMPD_unknown;
4674 Recommend = ShouldBeInTargetRegion;
4675 } else if (CurrentRegion == OMPD_scan) {
4676 // OpenMP [2.16, Nesting of Regions]
4677 // If specified, a teams construct must be contained within a target
4678 // construct.
4679 NestingProhibited =
4680 SemaRef.LangOpts.OpenMP < 50 ||
4681 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4682 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4683 ParentRegion != OMPD_parallel_for_simd);
4684 OrphanSeen = ParentRegion == OMPD_unknown;
4685 Recommend = ShouldBeInLoopSimdRegion;
4686 }
4687 if (!NestingProhibited &&
4688 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4689 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4690 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4691 // OpenMP [2.16, Nesting of Regions]
4692 // distribute, parallel, parallel sections, parallel workshare, and the
4693 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4694 // constructs that can be closely nested in the teams region.
4695 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4696 !isOpenMPDistributeDirective(CurrentRegion);
4697 Recommend = ShouldBeInParallelRegion;
4698 }
4699 if (!NestingProhibited &&
4700 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4701 // OpenMP 4.5 [2.17 Nesting of Regions]
4702 // The region associated with the distribute construct must be strictly
4703 // nested inside a teams region
4704 NestingProhibited =
4705 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4706 Recommend = ShouldBeInTeamsRegion;
4707 }
4708 if (!NestingProhibited &&
4709 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4710 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4711 // OpenMP 4.5 [2.17 Nesting of Regions]
4712 // If a target, target update, target data, target enter data, or
4713 // target exit data construct is encountered during execution of a
4714 // target region, the behavior is unspecified.
4715 NestingProhibited = Stack->hasDirective(
4716 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4717 SourceLocation) {
4718 if (isOpenMPTargetExecutionDirective(K)) {
4719 OffendingRegion = K;
4720 return true;
4721 }
4722 return false;
4723 },
4724 false /* don't skip top directive */);
4725 CloseNesting = false;
4726 }
4727 if (NestingProhibited) {
4728 if (OrphanSeen) {
4729 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4730 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4731 } else {
4732 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4733 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4734 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4735 }
4736 return true;
4737 }
4738 }
4739 return false;
4740}
4741
4742struct Kind2Unsigned {
4743 using argument_type = OpenMPDirectiveKind;
4744 unsigned operator()(argument_type DK) { return unsigned(DK); }
4745};
4746static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4747 ArrayRef<OMPClause *> Clauses,
4748 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4749 bool ErrorFound = false;
4750 unsigned NamedModifiersNumber = 0;
4751 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4752 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4753 SmallVector<SourceLocation, 4> NameModifierLoc;
4754 for (const OMPClause *C : Clauses) {
4755 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4756 // At most one if clause without a directive-name-modifier can appear on
4757 // the directive.
4758 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4759 if (FoundNameModifiers[CurNM]) {
4760 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4761 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4762 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4763 ErrorFound = true;
4764 } else if (CurNM != OMPD_unknown) {
4765 NameModifierLoc.push_back(IC->getNameModifierLoc());
4766 ++NamedModifiersNumber;
4767 }
4768 FoundNameModifiers[CurNM] = IC;
4769 if (CurNM == OMPD_unknown)
4770 continue;
4771 // Check if the specified name modifier is allowed for the current
4772 // directive.
4773 // At most one if clause with the particular directive-name-modifier can
4774 // appear on the directive.
4775 bool MatchFound = false;
4776 for (auto NM : AllowedNameModifiers) {
4777 if (CurNM == NM) {
4778 MatchFound = true;
4779 break;
4780 }
4781 }
4782 if (!MatchFound) {
4783 S.Diag(IC->getNameModifierLoc(),
4784 diag::err_omp_wrong_if_directive_name_modifier)
4785 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4786 ErrorFound = true;
4787 }
4788 }
4789 }
4790 // If any if clause on the directive includes a directive-name-modifier then
4791 // all if clauses on the directive must include a directive-name-modifier.
4792 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4793 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4794 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4795 diag::err_omp_no_more_if_clause);
4796 } else {
4797 std::string Values;
4798 std::string Sep(", ");
4799 unsigned AllowedCnt = 0;
4800 unsigned TotalAllowedNum =
4801 AllowedNameModifiers.size() - NamedModifiersNumber;
4802 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4803 ++Cnt) {
4804 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4805 if (!FoundNameModifiers[NM]) {
4806 Values += "'";
4807 Values += getOpenMPDirectiveName(NM);
4808 Values += "'";
4809 if (AllowedCnt + 2 == TotalAllowedNum)
4810 Values += " or ";
4811 else if (AllowedCnt + 1 != TotalAllowedNum)
4812 Values += Sep;
4813 ++AllowedCnt;
4814 }
4815 }
4816 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4817 diag::err_omp_unnamed_if_clause)
4818 << (TotalAllowedNum > 1) << Values;
4819 }
4820 for (SourceLocation Loc : NameModifierLoc) {
4821 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4822 }
4823 ErrorFound = true;
4824 }
4825 return ErrorFound;
4826}
4827
4828static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4829 SourceLocation &ELoc,
4830 SourceRange &ERange,
4831 bool AllowArraySection) {
4832 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4833 RefExpr->containsUnexpandedParameterPack())
4834 return std::make_pair(nullptr, true);
4835
4836 // OpenMP [3.1, C/C++]
4837 // A list item is a variable name.
4838 // OpenMP [2.9.3.3, Restrictions, p.1]
4839 // A variable that is part of another variable (as an array or
4840 // structure element) cannot appear in a private clause.
4841 RefExpr = RefExpr->IgnoreParens();
4842 enum {
4843 NoArrayExpr = -1,
4844 ArraySubscript = 0,
4845 OMPArraySection = 1
4846 } IsArrayExpr = NoArrayExpr;
4847 if (AllowArraySection) {
4848 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4849 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4850 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4851 Base = TempASE->getBase()->IgnoreParenImpCasts();
4852 RefExpr = Base;
4853 IsArrayExpr = ArraySubscript;
4854 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4855 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4856 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4857 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4858 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4859 Base = TempASE->getBase()->IgnoreParenImpCasts();
4860 RefExpr = Base;
4861 IsArrayExpr = OMPArraySection;
4862 }
4863 }
4864 ELoc = RefExpr->getExprLoc();
4865 ERange = RefExpr->getSourceRange();
4866 RefExpr = RefExpr->IgnoreParenImpCasts();
4867 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4868 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4869 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4870 (S.getCurrentThisType().isNull() || !ME ||
4871 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4872 !isa<FieldDecl>(ME->getMemberDecl()))) {
4873 if (IsArrayExpr != NoArrayExpr) {
4874 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4875 << ERange;
4876 } else {
4877 S.Diag(ELoc,
4878 AllowArraySection
4879 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4880 : diag::err_omp_expected_var_name_member_expr)
4881 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4882 }
4883 return std::make_pair(nullptr, false);
4884 }
4885 return std::make_pair(
4886 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4887}
4888
4889namespace {
4890/// Checks if the allocator is used in uses_allocators clause to be allowed in
4891/// target regions.
4892class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4893 DSAStackTy *S = nullptr;
4894
4895public:
4896 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4897 return S->isUsesAllocatorsDecl(E->getDecl())
4898 .getValueOr(
4899 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4900 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4901 }
4902 bool VisitStmt(const Stmt *S) {
4903 for (const Stmt *Child : S->children()) {
4904 if (Child && Visit(Child))
4905 return true;
4906 }
4907 return false;
4908 }
4909 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4910};
4911} // namespace
4912
4913static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4914 ArrayRef<OMPClause *> Clauses) {
4915 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 4916, __PRETTY_FUNCTION__))
4916 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 4916, __PRETTY_FUNCTION__))
;
4917 auto AllocateRange =
4918 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4919 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4920 DeclToCopy;
4921 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4922 return isOpenMPPrivate(C->getClauseKind());
4923 });
4924 for (OMPClause *Cl : PrivateRange) {
4925 MutableArrayRef<Expr *>::iterator I, It, Et;
4926 if (Cl->getClauseKind() == OMPC_private) {
4927 auto *PC = cast<OMPPrivateClause>(Cl);
4928 I = PC->private_copies().begin();
4929 It = PC->varlist_begin();
4930 Et = PC->varlist_end();
4931 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4932 auto *PC = cast<OMPFirstprivateClause>(Cl);
4933 I = PC->private_copies().begin();
4934 It = PC->varlist_begin();
4935 Et = PC->varlist_end();
4936 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4937 auto *PC = cast<OMPLastprivateClause>(Cl);
4938 I = PC->private_copies().begin();
4939 It = PC->varlist_begin();
4940 Et = PC->varlist_end();
4941 } else if (Cl->getClauseKind() == OMPC_linear) {
4942 auto *PC = cast<OMPLinearClause>(Cl);
4943 I = PC->privates().begin();
4944 It = PC->varlist_begin();
4945 Et = PC->varlist_end();
4946 } else if (Cl->getClauseKind() == OMPC_reduction) {
4947 auto *PC = cast<OMPReductionClause>(Cl);
4948 I = PC->privates().begin();
4949 It = PC->varlist_begin();
4950 Et = PC->varlist_end();
4951 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4952 auto *PC = cast<OMPTaskReductionClause>(Cl);
4953 I = PC->privates().begin();
4954 It = PC->varlist_begin();
4955 Et = PC->varlist_end();
4956 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4957 auto *PC = cast<OMPInReductionClause>(Cl);
4958 I = PC->privates().begin();
4959 It = PC->varlist_begin();
4960 Et = PC->varlist_end();
4961 } else {
4962 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 4962)
;
4963 }
4964 for (Expr *E : llvm::make_range(It, Et)) {
4965 if (!*I) {
4966 ++I;
4967 continue;
4968 }
4969 SourceLocation ELoc;
4970 SourceRange ERange;
4971 Expr *SimpleRefExpr = E;
4972 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4973 /*AllowArraySection=*/true);
4974 DeclToCopy.try_emplace(Res.first,
4975 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4976 ++I;
4977 }
4978 }
4979 for (OMPClause *C : AllocateRange) {
4980 auto *AC = cast<OMPAllocateClause>(C);
4981 if (S.getLangOpts().OpenMP >= 50 &&
4982 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4983 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4984 AC->getAllocator()) {
4985 Expr *Allocator = AC->getAllocator();
4986 // OpenMP, 2.12.5 target Construct
4987 // Memory allocators that do not appear in a uses_allocators clause cannot
4988 // appear as an allocator in an allocate clause or be used in the target
4989 // region unless a requires directive with the dynamic_allocators clause
4990 // is present in the same compilation unit.
4991 AllocatorChecker Checker(Stack);
4992 if (Checker.Visit(Allocator))
4993 S.Diag(Allocator->getExprLoc(),
4994 diag::err_omp_allocator_not_in_uses_allocators)
4995 << Allocator->getSourceRange();
4996 }
4997 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4998 getAllocatorKind(S, Stack, AC->getAllocator());
4999 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5000 // For task, taskloop or target directives, allocation requests to memory
5001 // allocators with the trait access set to thread result in unspecified
5002 // behavior.
5003 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5004 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5005 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5006 S.Diag(AC->getAllocator()->getExprLoc(),
5007 diag::warn_omp_allocate_thread_on_task_target_directive)
5008 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5009 }
5010 for (Expr *E : AC->varlists()) {
5011 SourceLocation ELoc;
5012 SourceRange ERange;
5013 Expr *SimpleRefExpr = E;
5014 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5015 ValueDecl *VD = Res.first;
5016 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5017 if (!isOpenMPPrivate(Data.CKind)) {
5018 S.Diag(E->getExprLoc(),
5019 diag::err_omp_expected_private_copy_for_allocate);
5020 continue;
5021 }
5022 VarDecl *PrivateVD = DeclToCopy[VD];
5023 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5024 AllocatorKind, AC->getAllocator()))
5025 continue;
5026 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5027 E->getSourceRange());
5028 }
5029 }
5030}
5031
5032StmtResult Sema::ActOnOpenMPExecutableDirective(
5033 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5034 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5035 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5036 StmtResult Res = StmtError();
5037 // First check CancelRegion which is then used in checkNestingOfRegions.
5038 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5039 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5040 StartLoc))
5041 return StmtError();
5042
5043 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5044 VarsWithInheritedDSAType VarsWithInheritedDSA;
5045 bool ErrorFound = false;
5046 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5047 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5048 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5049 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5049, __PRETTY_FUNCTION__))
;
5050
5051 // Check default data sharing attributes for referenced variables.
5052 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5053 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5054 Stmt *S = AStmt;
5055 while (--ThisCaptureLevel >= 0)
5056 S = cast<CapturedStmt>(S)->getCapturedStmt();
5057 DSAChecker.Visit(S);
5058 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5059 !isOpenMPTaskingDirective(Kind)) {
5060 // Visit subcaptures to generate implicit clauses for captured vars.
5061 auto *CS = cast<CapturedStmt>(AStmt);
5062 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5063 getOpenMPCaptureRegions(CaptureRegions, Kind);
5064 // Ignore outer tasking regions for target directives.
5065 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5066 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5067 DSAChecker.visitSubCaptures(CS);
5068 }
5069 if (DSAChecker.isErrorFound())
5070 return StmtError();
5071 // Generate list of implicitly defined firstprivate variables.
5072 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5073
5074 SmallVector<Expr *, 4> ImplicitFirstprivates(
5075 DSAChecker.getImplicitFirstprivate().begin(),
5076 DSAChecker.getImplicitFirstprivate().end());
5077 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5078 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5079 ArrayRef<Expr *> ImplicitMap =
5080 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5081 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5082 }
5083 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5084 for (OMPClause *C : Clauses) {
5085 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5086 for (Expr *E : IRC->taskgroup_descriptors())
5087 if (E)
5088 ImplicitFirstprivates.emplace_back(E);
5089 }
5090 // OpenMP 5.0, 2.10.1 task Construct
5091 // [detach clause]... The event-handle will be considered as if it was
5092 // specified on a firstprivate clause.
5093 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5094 ImplicitFirstprivates.push_back(DC->getEventHandler());
5095 }
5096 if (!ImplicitFirstprivates.empty()) {
5097 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5098 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5099 SourceLocation())) {
5100 ClausesWithImplicit.push_back(Implicit);
5101 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5102 ImplicitFirstprivates.size();
5103 } else {
5104 ErrorFound = true;
5105 }
5106 }
5107 int ClauseKindCnt = -1;
5108 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5109 ++ClauseKindCnt;
5110 if (ImplicitMap.empty())
5111 continue;
5112 CXXScopeSpec MapperIdScopeSpec;
5113 DeclarationNameInfo MapperId;
5114 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5115 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5116 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5117 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5118 ImplicitMap, OMPVarListLocTy())) {
5119 ClausesWithImplicit.emplace_back(Implicit);
5120 ErrorFound |=
5121 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5122 } else {
5123 ErrorFound = true;
5124 }
5125 }
5126 }
5127
5128 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5129 switch (Kind) {
5130 case OMPD_parallel:
5131 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5132 EndLoc);
5133 AllowedNameModifiers.push_back(OMPD_parallel);
5134 break;
5135 case OMPD_simd:
5136 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5137 VarsWithInheritedDSA);
5138 if (LangOpts.OpenMP >= 50)
5139 AllowedNameModifiers.push_back(OMPD_simd);
5140 break;
5141 case OMPD_for:
5142 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5143 VarsWithInheritedDSA);
5144 break;
5145 case OMPD_for_simd:
5146 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5147 EndLoc, VarsWithInheritedDSA);
5148 if (LangOpts.OpenMP >= 50)
5149 AllowedNameModifiers.push_back(OMPD_simd);
5150 break;
5151 case OMPD_sections:
5152 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5153 EndLoc);
5154 break;
5155 case OMPD_section:
5156 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5157, __PRETTY_FUNCTION__))
5157 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5157, __PRETTY_FUNCTION__))
;
5158 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5159 break;
5160 case OMPD_single:
5161 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5162 EndLoc);
5163 break;
5164 case OMPD_master:
5165 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5166, __PRETTY_FUNCTION__))
5166 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5166, __PRETTY_FUNCTION__))
;
5167 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5168 break;
5169 case OMPD_critical:
5170 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5171 StartLoc, EndLoc);
5172 break;
5173 case OMPD_parallel_for:
5174 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5175 EndLoc, VarsWithInheritedDSA);
5176 AllowedNameModifiers.push_back(OMPD_parallel);
5177 break;
5178 case OMPD_parallel_for_simd:
5179 Res = ActOnOpenMPParallelForSimdDirective(
5180 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5181 AllowedNameModifiers.push_back(OMPD_parallel);
5182 if (LangOpts.OpenMP >= 50)
5183 AllowedNameModifiers.push_back(OMPD_simd);
5184 break;
5185 case OMPD_parallel_master:
5186 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5187 StartLoc, EndLoc);
5188 AllowedNameModifiers.push_back(OMPD_parallel);
5189 break;
5190 case OMPD_parallel_sections:
5191 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5192 StartLoc, EndLoc);
5193 AllowedNameModifiers.push_back(OMPD_parallel);
5194 break;
5195 case OMPD_task:
5196 Res =
5197 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5198 AllowedNameModifiers.push_back(OMPD_task);
5199 break;
5200 case OMPD_taskyield:
5201 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5202, __PRETTY_FUNCTION__))
5202 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5202, __PRETTY_FUNCTION__))
;
5203 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5204, __PRETTY_FUNCTION__))
5204 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5204, __PRETTY_FUNCTION__))
;
5205 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5206 break;
5207 case OMPD_barrier:
5208 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5209, __PRETTY_FUNCTION__))
5209 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5209, __PRETTY_FUNCTION__))
;
5210 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5211, __PRETTY_FUNCTION__))
5211 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5211, __PRETTY_FUNCTION__))
;
5212 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5213 break;
5214 case OMPD_taskwait:
5215 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5216, __PRETTY_FUNCTION__))
5216 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5216, __PRETTY_FUNCTION__))
;
5217 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5218, __PRETTY_FUNCTION__))
5218 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5218, __PRETTY_FUNCTION__))
;
5219 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5220 break;
5221 case OMPD_taskgroup:
5222 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5223 EndLoc);
5224 break;
5225 case OMPD_flush:
5226 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5227, __PRETTY_FUNCTION__))
5227 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5227, __PRETTY_FUNCTION__))
;
5228 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5229 break;
5230 case OMPD_depobj:
5231 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5232, __PRETTY_FUNCTION__))
5232 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5232, __PRETTY_FUNCTION__))
;
5233 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5234 break;
5235 case OMPD_scan:
5236 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5237, __PRETTY_FUNCTION__))
5237 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5237, __PRETTY_FUNCTION__))
;
5238 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5239 break;
5240 case OMPD_ordered:
5241 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5242 EndLoc);
5243 break;
5244 case OMPD_atomic:
5245 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5246 EndLoc);
5247 break;
5248 case OMPD_teams:
5249 Res =
5250 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5251 break;
5252 case OMPD_target:
5253 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5254 EndLoc);
5255 AllowedNameModifiers.push_back(OMPD_target);
5256 break;
5257 case OMPD_target_parallel:
5258 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5259 StartLoc, EndLoc);
5260 AllowedNameModifiers.push_back(OMPD_target);
5261 AllowedNameModifiers.push_back(OMPD_parallel);
5262 break;
5263 case OMPD_target_parallel_for:
5264 Res = ActOnOpenMPTargetParallelForDirective(
5265 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5266 AllowedNameModifiers.push_back(OMPD_target);
5267 AllowedNameModifiers.push_back(OMPD_parallel);
5268 break;
5269 case OMPD_cancellation_point:
5270 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5271, __PRETTY_FUNCTION__))
5271 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5271, __PRETTY_FUNCTION__))
;
5272 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5273, __PRETTY_FUNCTION__))
5273 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5273, __PRETTY_FUNCTION__))
;
5274 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5275 break;
5276 case OMPD_cancel:
5277 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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5278, __PRETTY_FUNCTION__))
5278 "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~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5278, __PRETTY_FUNCTION__))
;
5279 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5280 CancelRegion);
5281 AllowedNameModifiers.push_back(OMPD_cancel);
5282 break;
5283 case OMPD_target_data:
5284 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5285 EndLoc);
5286 AllowedNameModifiers.push_back(OMPD_target_data);
5287 break;
5288 case OMPD_target_enter_data:
5289 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5290 EndLoc, AStmt);
5291 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5292 break;
5293 case OMPD_target_exit_data:
5294 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5295 EndLoc, AStmt);
5296 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5297 break;
5298 case OMPD_taskloop:
5299 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5300 EndLoc, VarsWithInheritedDSA);
5301 AllowedNameModifiers.push_back(OMPD_taskloop);
5302 break;
5303 case OMPD_taskloop_simd:
5304 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5305 EndLoc, VarsWithInheritedDSA);
5306 AllowedNameModifiers.push_back(OMPD_taskloop);
5307 if (LangOpts.OpenMP >= 50)
5308 AllowedNameModifiers.push_back(OMPD_simd);
5309 break;
5310 case OMPD_master_taskloop:
5311 Res = ActOnOpenMPMasterTaskLoopDirective(
5312 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5313 AllowedNameModifiers.push_back(OMPD_taskloop);
5314 break;
5315 case OMPD_master_taskloop_simd:
5316 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5317 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5318 AllowedNameModifiers.push_back(OMPD_taskloop);
5319 if (LangOpts.OpenMP >= 50)
5320 AllowedNameModifiers.push_back(OMPD_simd);
5321 break;
5322 case OMPD_parallel_master_taskloop:
5323 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5325 AllowedNameModifiers.push_back(OMPD_taskloop);
5326 AllowedNameModifiers.push_back(OMPD_parallel);
5327 break;
5328 case OMPD_parallel_master_taskloop_simd:
5329 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5330 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5331 AllowedNameModifiers.push_back(OMPD_taskloop);
5332 AllowedNameModifiers.push_back(OMPD_parallel);
5333 if (LangOpts.OpenMP >= 50)
5334 AllowedNameModifiers.push_back(OMPD_simd);
5335 break;
5336 case OMPD_distribute:
5337 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5338 EndLoc, VarsWithInheritedDSA);
5339 break;
5340 case OMPD_target_update:
5341 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5342 EndLoc, AStmt);
5343 AllowedNameModifiers.push_back(OMPD_target_update);
5344 break;
5345 case OMPD_distribute_parallel_for:
5346 Res = ActOnOpenMPDistributeParallelForDirective(
5347 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5348 AllowedNameModifiers.push_back(OMPD_parallel);
5349 break;
5350 case OMPD_distribute_parallel_for_simd:
5351 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5352 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5353 AllowedNameModifiers.push_back(OMPD_parallel);
5354 if (LangOpts.OpenMP >= 50)
5355 AllowedNameModifiers.push_back(OMPD_simd);
5356 break;
5357 case OMPD_distribute_simd:
5358 Res = ActOnOpenMPDistributeSimdDirective(
5359 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5360 if (LangOpts.OpenMP >= 50)
5361 AllowedNameModifiers.push_back(OMPD_simd);
5362 break;
5363 case OMPD_target_parallel_for_simd:
5364 Res = ActOnOpenMPTargetParallelForSimdDirective(
5365 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5366 AllowedNameModifiers.push_back(OMPD_target);
5367 AllowedNameModifiers.push_back(OMPD_parallel);
5368 if (LangOpts.OpenMP >= 50)
5369 AllowedNameModifiers.push_back(OMPD_simd);
5370 break;
5371 case OMPD_target_simd:
5372 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5373 EndLoc, VarsWithInheritedDSA);
5374 AllowedNameModifiers.push_back(OMPD_target);
5375 if (LangOpts.OpenMP >= 50)
5376 AllowedNameModifiers.push_back(OMPD_simd);
5377 break;
5378 case OMPD_teams_distribute:
5379 Res = ActOnOpenMPTeamsDistributeDirective(
5380 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5381 break;
5382 case OMPD_teams_distribute_simd:
5383 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5384 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5385 if (LangOpts.OpenMP >= 50)
5386 AllowedNameModifiers.push_back(OMPD_simd);
5387 break;
5388 case OMPD_teams_distribute_parallel_for_simd:
5389 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5390 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5391 AllowedNameModifiers.push_back(OMPD_parallel);
5392 if (LangOpts.OpenMP >= 50)
5393 AllowedNameModifiers.push_back(OMPD_simd);
5394 break;
5395 case OMPD_teams_distribute_parallel_for:
5396 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5397 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5398 AllowedNameModifiers.push_back(OMPD_parallel);
5399 break;
5400 case OMPD_target_teams:
5401 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5402 EndLoc);
5403 AllowedNameModifiers.push_back(OMPD_target);
5404 break;
5405 case OMPD_target_teams_distribute:
5406 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5407 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5408 AllowedNameModifiers.push_back(OMPD_target);
5409 break;
5410 case OMPD_target_teams_distribute_parallel_for:
5411 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5412 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5413 AllowedNameModifiers.push_back(OMPD_target);
5414 AllowedNameModifiers.push_back(OMPD_parallel);
5415 break;
5416 case OMPD_target_teams_distribute_parallel_for_simd:
5417 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5418 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5419 AllowedNameModifiers.push_back(OMPD_target);
5420 AllowedNameModifiers.push_back(OMPD_parallel);
5421 if (LangOpts.OpenMP >= 50)
5422 AllowedNameModifiers.push_back(OMPD_simd);
5423 break;
5424 case OMPD_target_teams_distribute_simd:
5425 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5426 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5427 AllowedNameModifiers.push_back(OMPD_target);
5428 if (LangOpts.OpenMP >= 50)
5429 AllowedNameModifiers.push_back(OMPD_simd);
5430 break;
5431 case OMPD_declare_target:
5432 case OMPD_end_declare_target:
5433 case OMPD_threadprivate:
5434 case OMPD_allocate:
5435 case OMPD_declare_reduction:
5436 case OMPD_declare_mapper:
5437 case OMPD_declare_simd:
5438 case OMPD_requires:
5439 case OMPD_declare_variant:
5440 case OMPD_begin_declare_variant:
5441 case OMPD_end_declare_variant:
5442 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5442)
;
5443 case OMPD_unknown:
5444 default:
5445 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200915100651+00ba1a3de7f/clang/lib/Sema/SemaOpenMP.cpp"
, 5445)
;
5446 }
5447
5448 ErrorFound = Res.isInvalid() || ErrorFound;
5449
5450 // Check variables in the clauses if default(none) or
5451 // default(firstprivate) was specified.
5452 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5453 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5454 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
5455 for (OMPClause *C : Clauses) {
5456 switch (C->getClauseKind()) {
5457 case OMPC_num_threads:
5458 case OMPC_dist_schedule:
5459 // Do not analyse if no parent teams directive.
5460 if (isOpenMPTeamsDirective(Kind))
5461 break;
5462 continue;
5463 case OMPC_if:
5464 if (isOpenMPTeamsDirective(Kind) &&
5465 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5466 break;
5467 if (isOpenMPParallelDirective(Kind) &&
5468 isOpenMPTaskLoopDirective(Kind) &&
5469 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5470 break;
5471 continue;
5472 case OMPC_schedule:
5473 case OMPC_detach:
5474 break;
5475 case OMPC_grainsize:
5476 case OMPC_num_tasks:
5477 case OMPC_final:
5478 case OMPC_priority:
5479 // Do not analyze if no parent parallel directive.
5480 if (isOpenMPParallelDirective(Kind))
5481 break;
5482 continue;
5483 case OMPC_ordered:
5484 case OMPC_device:
5485 case OMPC_num_teams:
5486 case OMPC_thread_limit:
5487 case OMPC_hint:
5488 case OMPC_collapse:
5489 case OMPC_safelen:
5490 case OMPC_simdlen:
5491 case OMPC_default:
5492 case OMPC_proc_bind:
5493 case OMPC_private:
5494 case OMPC_firstprivate:
5495 case OMPC_lastprivate:
5496 case OMPC_shared:
5497 case OMPC_reduction:
5498 case OMPC_task_reduction:
5499 case OMPC_in_reduction:
5500 case OMPC_linear:
5501 case OMPC_aligned:
5502 case OMPC_copyin:
5503<