Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/clang/include -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-11-29-190409-37574-1 -x c++ /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/clang/lib/Sema/SemaOpenMP.cpp

/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/clang/lib/Sema/SemaOpenMP.cpp

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