Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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