Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/include -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/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~++20200806111125+5446ec85070/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-08-06-171148-17323-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp

/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp

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