Bug Summary

File:clang/lib/Sema/SemaOpenMP.cpp
Warning:line 9017, column 22
Called C++ object pointer is null

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