Bug Summary

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