Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/build-llvm/tools/clang/lib/Sema -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/include -I /build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/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-13/lib/clang/13.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-13~++20210304100658+2f37cdd5699f/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2021-03-05-015038-47150-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp
1//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements semantic analysis for OpenMP directives and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
14#include "TreeTransform.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/CXXInheritance.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclOpenMP.h"
21#include "clang/AST/OpenMPClause.h"
22#include "clang/AST/StmtCXX.h"
23#include "clang/AST/StmtOpenMP.h"
24#include "clang/AST/StmtVisitor.h"
25#include "clang/AST/TypeOrdering.h"
26#include "clang/Basic/DiagnosticSema.h"
27#include "clang/Basic/OpenMPKinds.h"
28#include "clang/Basic/PartialDiagnostic.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/Sema/Initialization.h"
31#include "clang/Sema/Lookup.h"
32#include "clang/Sema/Scope.h"
33#include "clang/Sema/ScopeInfo.h"
34#include "clang/Sema/SemaInternal.h"
35#include "llvm/ADT/IndexedMap.h"
36#include "llvm/ADT/PointerEmbeddedInt.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringExtras.h"
39#include "llvm/Frontend/OpenMP/OMPConstants.h"
40#include <set>
41
42using namespace clang;
43using namespace llvm::omp;
44
45//===----------------------------------------------------------------------===//
46// Stack of data-sharing attributes for variables
47//===----------------------------------------------------------------------===//
48
49static const Expr *checkMapClauseExpressionBase(
50 Sema &SemaRef, Expr *E,
51 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
52 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
53
54namespace {
55/// Default data sharing attributes, which can be applied to directive.
56enum DefaultDataSharingAttributes {
57 DSA_unspecified = 0, /// Data sharing attribute not specified.
58 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
59 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
60 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
61};
62
63/// Stack for tracking declarations used in OpenMP directives and
64/// clauses and their data-sharing attributes.
65class DSAStackTy {
66public:
67 struct DSAVarData {
68 OpenMPDirectiveKind DKind = OMPD_unknown;
69 OpenMPClauseKind CKind = OMPC_unknown;
70 unsigned Modifier = 0;
71 const Expr *RefExpr = nullptr;
72 DeclRefExpr *PrivateCopy = nullptr;
73 SourceLocation ImplicitDSALoc;
74 bool AppliedToPointee = false;
75 DSAVarData() = default;
76 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
77 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
78 SourceLocation ImplicitDSALoc, unsigned Modifier,
79 bool AppliedToPointee)
80 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
81 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
82 AppliedToPointee(AppliedToPointee) {}
83 };
84 using OperatorOffsetTy =
85 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
86 using DoacrossDependMapTy =
87 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
88 /// Kind of the declaration used in the uses_allocators clauses.
89 enum class UsesAllocatorsDeclKind {
90 /// Predefined allocator
91 PredefinedAllocator,
92 /// User-defined allocator
93 UserDefinedAllocator,
94 /// The declaration that represent allocator trait
95 AllocatorTrait,
96 };
97
98private:
99 struct DSAInfo {
100 OpenMPClauseKind Attributes = OMPC_unknown;
101 unsigned Modifier = 0;
102 /// Pointer to a reference expression and a flag which shows that the
103 /// variable is marked as lastprivate(true) or not (false).
104 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
105 DeclRefExpr *PrivateCopy = nullptr;
106 /// true if the attribute is applied to the pointee, not the variable
107 /// itself.
108 bool AppliedToPointee = false;
109 };
110 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
111 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
112 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
113 using LoopControlVariablesMapTy =
114 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
115 /// Struct that associates a component with the clause kind where they are
116 /// found.
117 struct MappedExprComponentTy {
118 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
119 OpenMPClauseKind Kind = OMPC_unknown;
120 };
121 using MappedExprComponentsTy =
122 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
123 using CriticalsWithHintsTy =
124 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
125 struct ReductionData {
126 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
127 SourceRange ReductionRange;
128 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
129 ReductionData() = default;
130 void set(BinaryOperatorKind BO, SourceRange RR) {
131 ReductionRange = RR;
132 ReductionOp = BO;
133 }
134 void set(const Expr *RefExpr, SourceRange RR) {
135 ReductionRange = RR;
136 ReductionOp = RefExpr;
137 }
138 };
139 using DeclReductionMapTy =
140 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
141 struct DefaultmapInfo {
142 OpenMPDefaultmapClauseModifier ImplicitBehavior =
143 OMPC_DEFAULTMAP_MODIFIER_unknown;
144 SourceLocation SLoc;
145 DefaultmapInfo() = default;
146 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
147 : ImplicitBehavior(M), SLoc(Loc) {}
148 };
149
150 struct SharingMapTy {
151 DeclSAMapTy SharingMap;
152 DeclReductionMapTy ReductionMap;
153 UsedRefMapTy AlignedMap;
154 UsedRefMapTy NontemporalMap;
155 MappedExprComponentsTy MappedExprComponents;
156 LoopControlVariablesMapTy LCVMap;
157 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
158 SourceLocation DefaultAttrLoc;
159 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
160 OpenMPDirectiveKind Directive = OMPD_unknown;
161 DeclarationNameInfo DirectiveName;
162 Scope *CurScope = nullptr;
163 DeclContext *Context = nullptr;
164 SourceLocation ConstructLoc;
165 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
166 /// get the data (loop counters etc.) about enclosing loop-based construct.
167 /// This data is required during codegen.
168 DoacrossDependMapTy DoacrossDepends;
169 /// First argument (Expr *) contains optional argument of the
170 /// 'ordered' clause, the second one is true if the regions has 'ordered'
171 /// clause, false otherwise.
172 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
173 unsigned AssociatedLoops = 1;
174 bool HasMutipleLoops = false;
175 const Decl *PossiblyLoopCounter = nullptr;
176 bool NowaitRegion = false;
177 bool CancelRegion = false;
178 bool LoopStart = false;
179 bool BodyComplete = false;
180 SourceLocation PrevScanLocation;
181 SourceLocation PrevOrderedLocation;
182 SourceLocation InnerTeamsRegionLoc;
183 /// Reference to the taskgroup task_reduction reference expression.
184 Expr *TaskgroupReductionRef = nullptr;
185 llvm::DenseSet<QualType> MappedClassesQualTypes;
186 SmallVector<Expr *, 4> InnerUsedAllocators;
187 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
188 /// List of globals marked as declare target link in this target region
189 /// (isOpenMPTargetExecutionDirective(Directive) == true).
190 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
191 /// List of decls used in inclusive/exclusive clauses of the scan directive.
192 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
193 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
194 UsesAllocatorsDecls;
195 Expr *DeclareMapperVar = nullptr;
196 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
197 Scope *CurScope, SourceLocation Loc)
198 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
199 ConstructLoc(Loc) {}
200 SharingMapTy() = default;
201 };
202
203 using StackTy = SmallVector<SharingMapTy, 4>;
204
205 /// Stack of used declaration and their data-sharing attributes.
206 DeclSAMapTy Threadprivates;
207 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
208 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
209 /// true, if check for DSA must be from parent directive, false, if
210 /// from current directive.
211 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
212 Sema &SemaRef;
213 bool ForceCapturing = false;
214 /// true if all the variables in the target executable directives must be
215 /// captured by reference.
216 bool ForceCaptureByReferenceInTargetExecutable = false;
217 CriticalsWithHintsTy Criticals;
218 unsigned IgnoredStackElements = 0;
219
220 /// Iterators over the stack iterate in order from innermost to outermost
221 /// directive.
222 using const_iterator = StackTy::const_reverse_iterator;
223 const_iterator begin() const {
224 return Stack.empty() ? const_iterator()
225 : Stack.back().first.rbegin() + IgnoredStackElements;
226 }
227 const_iterator end() const {
228 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
229 }
230 using iterator = StackTy::reverse_iterator;
231 iterator begin() {
232 return Stack.empty() ? iterator()
233 : Stack.back().first.rbegin() + IgnoredStackElements;
234 }
235 iterator end() {
236 return Stack.empty() ? iterator() : Stack.back().first.rend();
237 }
238
239 // Convenience operations to get at the elements of the stack.
240
241 bool isStackEmpty() const {
242 return Stack.empty() ||
243 Stack.back().second != CurrentNonCapturingFunctionScope ||
244 Stack.back().first.size() <= IgnoredStackElements;
245 }
246 size_t getStackSize() const {
247 return isStackEmpty() ? 0
248 : Stack.back().first.size() - IgnoredStackElements;
249 }
250
251 SharingMapTy *getTopOfStackOrNull() {
252 size_t Size = getStackSize();
253 if (Size == 0)
254 return nullptr;
255 return &Stack.back().first[Size - 1];
256 }
257 const SharingMapTy *getTopOfStackOrNull() const {
258 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
259 }
260 SharingMapTy &getTopOfStack() {
261 assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 261, __PRETTY_FUNCTION__))
;
262 return *getTopOfStackOrNull();
263 }
264 const SharingMapTy &getTopOfStack() const {
265 return const_cast<DSAStackTy&>(*this).getTopOfStack();
266 }
267
268 SharingMapTy *getSecondOnStackOrNull() {
269 size_t Size = getStackSize();
270 if (Size <= 1)
271 return nullptr;
272 return &Stack.back().first[Size - 2];
273 }
274 const SharingMapTy *getSecondOnStackOrNull() const {
275 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
276 }
277
278 /// Get the stack element at a certain level (previously returned by
279 /// \c getNestingLevel).
280 ///
281 /// Note that nesting levels count from outermost to innermost, and this is
282 /// the reverse of our iteration order where new inner levels are pushed at
283 /// the front of the stack.
284 SharingMapTy &getStackElemAtLevel(unsigned Level) {
285 assert(Level < getStackSize() && "no such stack element")((Level < getStackSize() && "no such stack element"
) ? static_cast<void> (0) : __assert_fail ("Level < getStackSize() && \"no such stack element\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 285, __PRETTY_FUNCTION__))
;
286 return Stack.back().first[Level];
287 }
288 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
289 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
290 }
291
292 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
293
294 /// Checks if the variable is a local for OpenMP region.
295 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
296
297 /// Vector of previously declared requires directives
298 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
299 /// omp_allocator_handle_t type.
300 QualType OMPAllocatorHandleT;
301 /// omp_depend_t type.
302 QualType OMPDependT;
303 /// omp_event_handle_t type.
304 QualType OMPEventHandleT;
305 /// omp_alloctrait_t type.
306 QualType OMPAlloctraitT;
307 /// Expression for the predefined allocators.
308 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
309 nullptr};
310 /// Vector of previously encountered target directives
311 SmallVector<SourceLocation, 2> TargetLocations;
312 SourceLocation AtomicLocation;
313
314public:
315 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
316
317 /// Sets omp_allocator_handle_t type.
318 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
319 /// Gets omp_allocator_handle_t type.
320 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
321 /// Sets omp_alloctrait_t type.
322 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
323 /// Gets omp_alloctrait_t type.
324 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
325 /// Sets the given default allocator.
326 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
327 Expr *Allocator) {
328 OMPPredefinedAllocators[AllocatorKind] = Allocator;
329 }
330 /// Returns the specified default allocator.
331 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
332 return OMPPredefinedAllocators[AllocatorKind];
333 }
334 /// Sets omp_depend_t type.
335 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
336 /// Gets omp_depend_t type.
337 QualType getOMPDependT() const { return OMPDependT; }
338
339 /// Sets omp_event_handle_t type.
340 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
341 /// Gets omp_event_handle_t type.
342 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
343
344 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
345 OpenMPClauseKind getClauseParsingMode() const {
346 assert(isClauseParsingMode() && "Must be in clause parsing mode.")((isClauseParsingMode() && "Must be in clause parsing mode."
) ? static_cast<void> (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 346, __PRETTY_FUNCTION__))
;
347 return ClauseKindMode;
348 }
349 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
350
351 bool isBodyComplete() const {
352 const SharingMapTy *Top = getTopOfStackOrNull();
353 return Top && Top->BodyComplete;
354 }
355 void setBodyComplete() {
356 getTopOfStack().BodyComplete = true;
357 }
358
359 bool isForceVarCapturing() const { return ForceCapturing; }
360 void setForceVarCapturing(bool V) { ForceCapturing = V; }
361
362 void setForceCaptureByReferenceInTargetExecutable(bool V) {
363 ForceCaptureByReferenceInTargetExecutable = V;
364 }
365 bool isForceCaptureByReferenceInTargetExecutable() const {
366 return ForceCaptureByReferenceInTargetExecutable;
367 }
368
369 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
370 Scope *CurScope, SourceLocation Loc) {
371 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 372, __PRETTY_FUNCTION__))
372 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 372, __PRETTY_FUNCTION__))
;
373 if (Stack.empty() ||
374 Stack.back().second != CurrentNonCapturingFunctionScope)
375 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
376 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
377 Stack.back().first.back().DefaultAttrLoc = Loc;
378 }
379
380 void pop() {
381 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 382, __PRETTY_FUNCTION__))
382 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 382, __PRETTY_FUNCTION__))
;
383 assert(!Stack.back().first.empty() &&((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 384, __PRETTY_FUNCTION__))
384 "Data-sharing attributes stack is empty!")((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 384, __PRETTY_FUNCTION__))
;
385 Stack.back().first.pop_back();
386 }
387
388 /// RAII object to temporarily leave the scope of a directive when we want to
389 /// logically operate in its parent.
390 class ParentDirectiveScope {
391 DSAStackTy &Self;
392 bool Active;
393 public:
394 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
395 : Self(Self), Active(false) {
396 if (Activate)
397 enable();
398 }
399 ~ParentDirectiveScope() { disable(); }
400 void disable() {
401 if (Active) {
402 --Self.IgnoredStackElements;
403 Active = false;
404 }
405 }
406 void enable() {
407 if (!Active) {
408 ++Self.IgnoredStackElements;
409 Active = true;
410 }
411 }
412 };
413
414 /// Marks that we're started loop parsing.
415 void loopInit() {
416 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 417, __PRETTY_FUNCTION__))
417 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 417, __PRETTY_FUNCTION__))
;
418 getTopOfStack().LoopStart = true;
419 }
420 /// Start capturing of the variables in the loop context.
421 void loopStart() {
422 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 423, __PRETTY_FUNCTION__))
423 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 423, __PRETTY_FUNCTION__))
;
424 getTopOfStack().LoopStart = false;
425 }
426 /// true, if variables are captured, false otherwise.
427 bool isLoopStarted() const {
428 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 429, __PRETTY_FUNCTION__))
429 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 429, __PRETTY_FUNCTION__))
;
430 return !getTopOfStack().LoopStart;
431 }
432 /// Marks (or clears) declaration as possibly loop counter.
433 void resetPossibleLoopCounter(const Decl *D = nullptr) {
434 getTopOfStack().PossiblyLoopCounter =
435 D ? D->getCanonicalDecl() : D;
436 }
437 /// Gets the possible loop counter decl.
438 const Decl *getPossiblyLoopCunter() const {
439 return getTopOfStack().PossiblyLoopCounter;
440 }
441 /// Start new OpenMP region stack in new non-capturing function.
442 void pushFunction() {
443 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 444, __PRETTY_FUNCTION__))
444 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 444, __PRETTY_FUNCTION__))
;
445 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
446 assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast<
void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 446, __PRETTY_FUNCTION__))
;
447 CurrentNonCapturingFunctionScope = CurFnScope;
448 }
449 /// Pop region stack for non-capturing function.
450 void popFunction(const FunctionScopeInfo *OldFSI) {
451 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 452, __PRETTY_FUNCTION__))
452 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 452, __PRETTY_FUNCTION__))
;
453 if (!Stack.empty() && Stack.back().second == OldFSI) {
454 assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) :
__assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 454, __PRETTY_FUNCTION__))
;
455 Stack.pop_back();
456 }
457 CurrentNonCapturingFunctionScope = nullptr;
458 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
459 if (!isa<CapturingScopeInfo>(FSI)) {
460 CurrentNonCapturingFunctionScope = FSI;
461 break;
462 }
463 }
464 }
465
466 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
467 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
468 }
469 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
470 getCriticalWithHint(const DeclarationNameInfo &Name) const {
471 auto I = Criticals.find(Name.getAsString());
472 if (I != Criticals.end())
473 return I->second;
474 return std::make_pair(nullptr, llvm::APSInt());
475 }
476 /// If 'aligned' declaration for given variable \a D was not seen yet,
477 /// add it and return NULL; otherwise return previous occurrence's expression
478 /// for diagnostics.
479 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
480 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
481 /// add it and return NULL; otherwise return previous occurrence's expression
482 /// for diagnostics.
483 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
484
485 /// Register specified variable as loop control variable.
486 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
487 /// Check if the specified variable is a loop control variable for
488 /// current region.
489 /// \return The index of the loop control variable in the list of associated
490 /// for-loops (from outer to inner).
491 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
492 /// Check if the specified variable is a loop control variable for
493 /// parent region.
494 /// \return The index of the loop control variable in the list of associated
495 /// for-loops (from outer to inner).
496 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
497 /// Check if the specified variable is a loop control variable for
498 /// current region.
499 /// \return The index of the loop control variable in the list of associated
500 /// for-loops (from outer to inner).
501 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
502 unsigned Level) const;
503 /// Get the loop control variable for the I-th loop (or nullptr) in
504 /// parent directive.
505 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
506
507 /// Marks the specified decl \p D as used in scan directive.
508 void markDeclAsUsedInScanDirective(ValueDecl *D) {
509 if (SharingMapTy *Stack = getSecondOnStackOrNull())
510 Stack->UsedInScanDirective.insert(D);
511 }
512
513 /// Checks if the specified declaration was used in the inner scan directive.
514 bool isUsedInScanDirective(ValueDecl *D) const {
515 if (const SharingMapTy *Stack = getTopOfStackOrNull())
516 return Stack->UsedInScanDirective.count(D) > 0;
517 return false;
518 }
519
520 /// Adds explicit data sharing attribute to the specified declaration.
521 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
522 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
523 bool AppliedToPointee = false);
524
525 /// Adds additional information for the reduction items with the reduction id
526 /// represented as an operator.
527 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
528 BinaryOperatorKind BOK);
529 /// Adds additional information for the reduction items with the reduction id
530 /// represented as reduction identifier.
531 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
532 const Expr *ReductionRef);
533 /// Returns the location and reduction operation from the innermost parent
534 /// region for the given \p D.
535 const DSAVarData
536 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
537 BinaryOperatorKind &BOK,
538 Expr *&TaskgroupDescriptor) const;
539 /// Returns the location and reduction operation from the innermost parent
540 /// region for the given \p D.
541 const DSAVarData
542 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
543 const Expr *&ReductionRef,
544 Expr *&TaskgroupDescriptor) const;
545 /// Return reduction reference expression for the current taskgroup or
546 /// parallel/worksharing directives with task reductions.
547 Expr *getTaskgroupReductionRef() const {
548 assert((getTopOfStack().Directive == OMPD_taskgroup ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 553, __PRETTY_FUNCTION__))
549 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 553, __PRETTY_FUNCTION__))
550 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 553, __PRETTY_FUNCTION__))
551 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 553, __PRETTY_FUNCTION__))
552 "taskgroup reference expression requested for non taskgroup or "(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 553, __PRETTY_FUNCTION__))
553 "parallel/worksharing directive.")(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 553, __PRETTY_FUNCTION__))
;
554 return getTopOfStack().TaskgroupReductionRef;
555 }
556 /// Checks if the given \p VD declaration is actually a taskgroup reduction
557 /// descriptor variable at the \p Level of OpenMP regions.
558 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
559 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
560 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
561 ->getDecl() == VD;
562 }
563
564 /// Returns data sharing attributes from top of the stack for the
565 /// specified declaration.
566 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
567 /// Returns data-sharing attributes for the specified declaration.
568 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
569 /// Returns data-sharing attributes for the specified declaration.
570 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
571 /// Checks if the specified variables has data-sharing attributes which
572 /// match specified \a CPred predicate in any directive which matches \a DPred
573 /// predicate.
574 const DSAVarData
575 hasDSA(ValueDecl *D,
576 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
577 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
578 bool FromParent) const;
579 /// Checks if the specified variables has data-sharing attributes which
580 /// match specified \a CPred predicate in any innermost directive which
581 /// matches \a DPred predicate.
582 const DSAVarData
583 hasInnermostDSA(ValueDecl *D,
584 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
585 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
586 bool FromParent) const;
587 /// Checks if the specified variables has explicit data-sharing
588 /// attributes which match specified \a CPred predicate at the specified
589 /// OpenMP region.
590 bool
591 hasExplicitDSA(const ValueDecl *D,
592 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
593 unsigned Level, bool NotLastprivate = false) const;
594
595 /// Returns true if the directive at level \Level matches in the
596 /// specified \a DPred predicate.
597 bool hasExplicitDirective(
598 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
599 unsigned Level) const;
600
601 /// Finds a directive which matches specified \a DPred predicate.
602 bool hasDirective(
603 const llvm::function_ref<bool(
604 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
605 DPred,
606 bool FromParent) const;
607
608 /// Returns currently analyzed directive.
609 OpenMPDirectiveKind getCurrentDirective() const {
610 const SharingMapTy *Top = getTopOfStackOrNull();
611 return Top ? Top->Directive : OMPD_unknown;
612 }
613 /// Returns directive kind at specified level.
614 OpenMPDirectiveKind getDirective(unsigned Level) const {
615 assert(!isStackEmpty() && "No directive at specified level.")((!isStackEmpty() && "No directive at specified level."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 615, __PRETTY_FUNCTION__))
;
616 return getStackElemAtLevel(Level).Directive;
617 }
618 /// Returns the capture region at the specified level.
619 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
620 unsigned OpenMPCaptureLevel) const {
621 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
622 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
623 return CaptureRegions[OpenMPCaptureLevel];
624 }
625 /// Returns parent directive.
626 OpenMPDirectiveKind getParentDirective() const {
627 const SharingMapTy *Parent = getSecondOnStackOrNull();
628 return Parent ? Parent->Directive : OMPD_unknown;
629 }
630
631 /// Add requires decl to internal vector
632 void addRequiresDecl(OMPRequiresDecl *RD) {
633 RequiresDecls.push_back(RD);
634 }
635
636 /// Checks if the defined 'requires' directive has specified type of clause.
637 template <typename ClauseType>
638 bool hasRequiresDeclWithClause() const {
639 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
640 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
641 return isa<ClauseType>(C);
642 });
643 });
644 }
645
646 /// Checks for a duplicate clause amongst previously declared requires
647 /// directives
648 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
649 bool IsDuplicate = false;
650 for (OMPClause *CNew : ClauseList) {
651 for (const OMPRequiresDecl *D : RequiresDecls) {
652 for (const OMPClause *CPrev : D->clauselists()) {
653 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
654 SemaRef.Diag(CNew->getBeginLoc(),
655 diag::err_omp_requires_clause_redeclaration)
656 << getOpenMPClauseName(CNew->getClauseKind());
657 SemaRef.Diag(CPrev->getBeginLoc(),
658 diag::note_omp_requires_previous_clause)
659 << getOpenMPClauseName(CPrev->getClauseKind());
660 IsDuplicate = true;
661 }
662 }
663 }
664 }
665 return IsDuplicate;
666 }
667
668 /// Add location of previously encountered target to internal vector
669 void addTargetDirLocation(SourceLocation LocStart) {
670 TargetLocations.push_back(LocStart);
671 }
672
673 /// Add location for the first encountered atomicc directive.
674 void addAtomicDirectiveLoc(SourceLocation Loc) {
675 if (AtomicLocation.isInvalid())
676 AtomicLocation = Loc;
677 }
678
679 /// Returns the location of the first encountered atomic directive in the
680 /// module.
681 SourceLocation getAtomicDirectiveLoc() const {
682 return AtomicLocation;
683 }
684
685 // Return previously encountered target region locations.
686 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
687 return TargetLocations;
688 }
689
690 /// Set default data sharing attribute to none.
691 void setDefaultDSANone(SourceLocation Loc) {
692 getTopOfStack().DefaultAttr = DSA_none;
693 getTopOfStack().DefaultAttrLoc = Loc;
694 }
695 /// Set default data sharing attribute to shared.
696 void setDefaultDSAShared(SourceLocation Loc) {
697 getTopOfStack().DefaultAttr = DSA_shared;
698 getTopOfStack().DefaultAttrLoc = Loc;
699 }
700 /// Set default data sharing attribute to firstprivate.
701 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
702 getTopOfStack().DefaultAttr = DSA_firstprivate;
703 getTopOfStack().DefaultAttrLoc = Loc;
704 }
705 /// Set default data mapping attribute to Modifier:Kind
706 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
707 OpenMPDefaultmapClauseKind Kind,
708 SourceLocation Loc) {
709 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
710 DMI.ImplicitBehavior = M;
711 DMI.SLoc = Loc;
712 }
713 /// Check whether the implicit-behavior has been set in defaultmap
714 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
715 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
716 return getTopOfStack()
717 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
718 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
719 getTopOfStack()
720 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
721 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
722 getTopOfStack()
723 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
724 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
725 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
726 OMPC_DEFAULTMAP_MODIFIER_unknown;
727 }
728
729 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
730 return getStackSize() <= Level ? DSA_unspecified
731 : getStackElemAtLevel(Level).DefaultAttr;
732 }
733 DefaultDataSharingAttributes getDefaultDSA() const {
734 return isStackEmpty() ? DSA_unspecified
735 : getTopOfStack().DefaultAttr;
736 }
737 SourceLocation getDefaultDSALocation() const {
738 return isStackEmpty() ? SourceLocation()
739 : getTopOfStack().DefaultAttrLoc;
740 }
741 OpenMPDefaultmapClauseModifier
742 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
743 return isStackEmpty()
744 ? OMPC_DEFAULTMAP_MODIFIER_unknown
745 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
746 }
747 OpenMPDefaultmapClauseModifier
748 getDefaultmapModifierAtLevel(unsigned Level,
749 OpenMPDefaultmapClauseKind Kind) const {
750 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
751 }
752 bool isDefaultmapCapturedByRef(unsigned Level,
753 OpenMPDefaultmapClauseKind Kind) const {
754 OpenMPDefaultmapClauseModifier M =
755 getDefaultmapModifierAtLevel(Level, Kind);
756 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
757 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
760 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
761 }
762 return true;
763 }
764 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
765 OpenMPDefaultmapClauseKind Kind) {
766 switch (Kind) {
767 case OMPC_DEFAULTMAP_scalar:
768 case OMPC_DEFAULTMAP_pointer:
769 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
770 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
771 (M == OMPC_DEFAULTMAP_MODIFIER_default);
772 case OMPC_DEFAULTMAP_aggregate:
773 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
774 default:
775 break;
776 }
777 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 777)
;
778 }
779 bool mustBeFirstprivateAtLevel(unsigned Level,
780 OpenMPDefaultmapClauseKind Kind) const {
781 OpenMPDefaultmapClauseModifier M =
782 getDefaultmapModifierAtLevel(Level, Kind);
783 return mustBeFirstprivateBase(M, Kind);
784 }
785 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
786 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
787 return mustBeFirstprivateBase(M, Kind);
788 }
789
790 /// Checks if the specified variable is a threadprivate.
791 bool isThreadPrivate(VarDecl *D) {
792 const DSAVarData DVar = getTopDSA(D, false);
793 return isOpenMPThreadPrivate(DVar.CKind);
794 }
795
796 /// Marks current region as ordered (it has an 'ordered' clause).
797 void setOrderedRegion(bool IsOrdered, const Expr *Param,
798 OMPOrderedClause *Clause) {
799 if (IsOrdered)
800 getTopOfStack().OrderedRegion.emplace(Param, Clause);
801 else
802 getTopOfStack().OrderedRegion.reset();
803 }
804 /// Returns true, if region is ordered (has associated 'ordered' clause),
805 /// false - otherwise.
806 bool isOrderedRegion() const {
807 if (const SharingMapTy *Top = getTopOfStackOrNull())
808 return Top->OrderedRegion.hasValue();
809 return false;
810 }
811 /// Returns optional parameter for the ordered region.
812 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
813 if (const SharingMapTy *Top = getTopOfStackOrNull())
814 if (Top->OrderedRegion.hasValue())
815 return Top->OrderedRegion.getValue();
816 return std::make_pair(nullptr, nullptr);
817 }
818 /// Returns true, if parent region is ordered (has associated
819 /// 'ordered' clause), false - otherwise.
820 bool isParentOrderedRegion() const {
821 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
822 return Parent->OrderedRegion.hasValue();
823 return false;
824 }
825 /// Returns optional parameter for the ordered region.
826 std::pair<const Expr *, OMPOrderedClause *>
827 getParentOrderedRegionParam() const {
828 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
829 if (Parent->OrderedRegion.hasValue())
830 return Parent->OrderedRegion.getValue();
831 return std::make_pair(nullptr, nullptr);
832 }
833 /// Marks current region as nowait (it has a 'nowait' clause).
834 void setNowaitRegion(bool IsNowait = true) {
835 getTopOfStack().NowaitRegion = IsNowait;
836 }
837 /// Returns true, if parent region is nowait (has associated
838 /// 'nowait' clause), false - otherwise.
839 bool isParentNowaitRegion() const {
840 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
841 return Parent->NowaitRegion;
842 return false;
843 }
844 /// Marks parent region as cancel region.
845 void setParentCancelRegion(bool Cancel = true) {
846 if (SharingMapTy *Parent = getSecondOnStackOrNull())
847 Parent->CancelRegion |= Cancel;
848 }
849 /// Return true if current region has inner cancel construct.
850 bool isCancelRegion() const {
851 const SharingMapTy *Top = getTopOfStackOrNull();
852 return Top ? Top->CancelRegion : false;
853 }
854
855 /// Mark that parent region already has scan directive.
856 void setParentHasScanDirective(SourceLocation Loc) {
857 if (SharingMapTy *Parent = getSecondOnStackOrNull())
858 Parent->PrevScanLocation = Loc;
859 }
860 /// Return true if current region has inner cancel construct.
861 bool doesParentHasScanDirective() const {
862 const SharingMapTy *Top = getSecondOnStackOrNull();
863 return Top ? Top->PrevScanLocation.isValid() : false;
864 }
865 /// Return true if current region has inner cancel construct.
866 SourceLocation getParentScanDirectiveLoc() const {
867 const SharingMapTy *Top = getSecondOnStackOrNull();
868 return Top ? Top->PrevScanLocation : SourceLocation();
869 }
870 /// Mark that parent region already has ordered directive.
871 void setParentHasOrderedDirective(SourceLocation Loc) {
872 if (SharingMapTy *Parent = getSecondOnStackOrNull())
873 Parent->PrevOrderedLocation = Loc;
874 }
875 /// Return true if current region has inner ordered construct.
876 bool doesParentHasOrderedDirective() const {
877 const SharingMapTy *Top = getSecondOnStackOrNull();
878 return Top ? Top->PrevOrderedLocation.isValid() : false;
879 }
880 /// Returns the location of the previously specified ordered directive.
881 SourceLocation getParentOrderedDirectiveLoc() const {
882 const SharingMapTy *Top = getSecondOnStackOrNull();
883 return Top ? Top->PrevOrderedLocation : SourceLocation();
884 }
885
886 /// Set collapse value for the region.
887 void setAssociatedLoops(unsigned Val) {
888 getTopOfStack().AssociatedLoops = Val;
889 if (Val > 1)
890 getTopOfStack().HasMutipleLoops = true;
891 }
892 /// Return collapse value for region.
893 unsigned getAssociatedLoops() const {
894 const SharingMapTy *Top = getTopOfStackOrNull();
895 return Top ? Top->AssociatedLoops : 0;
896 }
897 /// Returns true if the construct is associated with multiple loops.
898 bool hasMutipleLoops() const {
899 const SharingMapTy *Top = getTopOfStackOrNull();
900 return Top ? Top->HasMutipleLoops : false;
901 }
902
903 /// Marks current target region as one with closely nested teams
904 /// region.
905 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
906 if (SharingMapTy *Parent = getSecondOnStackOrNull())
907 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
908 }
909 /// Returns true, if current region has closely nested teams region.
910 bool hasInnerTeamsRegion() const {
911 return getInnerTeamsRegionLoc().isValid();
912 }
913 /// Returns location of the nested teams region (if any).
914 SourceLocation getInnerTeamsRegionLoc() const {
915 const SharingMapTy *Top = getTopOfStackOrNull();
916 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
917 }
918
919 Scope *getCurScope() const {
920 const SharingMapTy *Top = getTopOfStackOrNull();
921 return Top ? Top->CurScope : nullptr;
922 }
923 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
924 SourceLocation getConstructLoc() const {
925 const SharingMapTy *Top = getTopOfStackOrNull();
926 return Top ? Top->ConstructLoc : SourceLocation();
927 }
928
929 /// Do the check specified in \a Check to all component lists and return true
930 /// if any issue is found.
931 bool checkMappableExprComponentListsForDecl(
932 const ValueDecl *VD, bool CurrentRegionOnly,
933 const llvm::function_ref<
934 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
935 OpenMPClauseKind)>
936 Check) const {
937 if (isStackEmpty())
938 return false;
939 auto SI = begin();
940 auto SE = end();
941
942 if (SI == SE)
943 return false;
944
945 if (CurrentRegionOnly)
946 SE = std::next(SI);
947 else
948 std::advance(SI, 1);
949
950 for (; SI != SE; ++SI) {
951 auto MI = SI->MappedExprComponents.find(VD);
952 if (MI != SI->MappedExprComponents.end())
953 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
954 MI->second.Components)
955 if (Check(L, MI->second.Kind))
956 return true;
957 }
958 return false;
959 }
960
961 /// Do the check specified in \a Check to all component lists at a given level
962 /// and return true if any issue is found.
963 bool checkMappableExprComponentListsForDeclAtLevel(
964 const ValueDecl *VD, unsigned Level,
965 const llvm::function_ref<
966 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
967 OpenMPClauseKind)>
968 Check) const {
969 if (getStackSize() <= Level)
970 return false;
971
972 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
973 auto MI = StackElem.MappedExprComponents.find(VD);
974 if (MI != StackElem.MappedExprComponents.end())
975 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
976 MI->second.Components)
977 if (Check(L, MI->second.Kind))
978 return true;
979 return false;
980 }
981
982 /// Create a new mappable expression component list associated with a given
983 /// declaration and initialize it with the provided list of components.
984 void addMappableExpressionComponents(
985 const ValueDecl *VD,
986 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
987 OpenMPClauseKind WhereFoundClauseKind) {
988 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
989 // Create new entry and append the new components there.
990 MEC.Components.resize(MEC.Components.size() + 1);
991 MEC.Components.back().append(Components.begin(), Components.end());
992 MEC.Kind = WhereFoundClauseKind;
993 }
994
995 unsigned getNestingLevel() const {
996 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 996, __PRETTY_FUNCTION__))
;
997 return getStackSize() - 1;
998 }
999 void addDoacrossDependClause(OMPDependClause *C,
1000 const OperatorOffsetTy &OpsOffs) {
1001 SharingMapTy *Parent = getSecondOnStackOrNull();
1002 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive
)) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1002, __PRETTY_FUNCTION__))
;
1003 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1004 }
1005 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1006 getDoacrossDependClauses() const {
1007 const SharingMapTy &StackElem = getTopOfStack();
1008 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1009 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1010 return llvm::make_range(Ref.begin(), Ref.end());
1011 }
1012 return llvm::make_range(StackElem.DoacrossDepends.end(),
1013 StackElem.DoacrossDepends.end());
1014 }
1015
1016 // Store types of classes which have been explicitly mapped
1017 void addMappedClassesQualTypes(QualType QT) {
1018 SharingMapTy &StackElem = getTopOfStack();
1019 StackElem.MappedClassesQualTypes.insert(QT);
1020 }
1021
1022 // Return set of mapped classes types
1023 bool isClassPreviouslyMapped(QualType QT) const {
1024 const SharingMapTy &StackElem = getTopOfStack();
1025 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1026 }
1027
1028 /// Adds global declare target to the parent target region.
1029 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1030 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1032, __PRETTY_FUNCTION__))
1031 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1032, __PRETTY_FUNCTION__))
1032 "Expected declare target link global.")((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1032, __PRETTY_FUNCTION__))
;
1033 for (auto &Elem : *this) {
1034 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1035 Elem.DeclareTargetLinkVarDecls.push_back(E);
1036 return;
1037 }
1038 }
1039 }
1040
1041 /// Returns the list of globals with declare target link if current directive
1042 /// is target.
1043 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1044 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&((isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
"Expected target executable directive.") ? static_cast<void
> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1045, __PRETTY_FUNCTION__))
1045 "Expected target executable directive.")((isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
"Expected target executable directive.") ? static_cast<void
> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1045, __PRETTY_FUNCTION__))
;
1046 return getTopOfStack().DeclareTargetLinkVarDecls;
1047 }
1048
1049 /// Adds list of allocators expressions.
1050 void addInnerAllocatorExpr(Expr *E) {
1051 getTopOfStack().InnerUsedAllocators.push_back(E);
1052 }
1053 /// Return list of used allocators.
1054 ArrayRef<Expr *> getInnerAllocators() const {
1055 return getTopOfStack().InnerUsedAllocators;
1056 }
1057 /// Marks the declaration as implicitly firstprivate nin the task-based
1058 /// regions.
1059 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1060 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1061 }
1062 /// Checks if the decl is implicitly firstprivate in the task-based region.
1063 bool isImplicitTaskFirstprivate(Decl *D) const {
1064 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1065 }
1066
1067 /// Marks decl as used in uses_allocators clause as the allocator.
1068 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1069 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1070 }
1071 /// Checks if specified decl is used in uses allocator clause as the
1072 /// allocator.
1073 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1074 const Decl *D) const {
1075 const SharingMapTy &StackElem = getTopOfStack();
1076 auto I = StackElem.UsesAllocatorsDecls.find(D);
1077 if (I == StackElem.UsesAllocatorsDecls.end())
1078 return None;
1079 return I->getSecond();
1080 }
1081 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1082 const SharingMapTy &StackElem = getTopOfStack();
1083 auto I = StackElem.UsesAllocatorsDecls.find(D);
1084 if (I == StackElem.UsesAllocatorsDecls.end())
1085 return None;
1086 return I->getSecond();
1087 }
1088
1089 void addDeclareMapperVarRef(Expr *Ref) {
1090 SharingMapTy &StackElem = getTopOfStack();
1091 StackElem.DeclareMapperVar = Ref;
1092 }
1093 const Expr *getDeclareMapperVarRef() const {
1094 const SharingMapTy *Top = getTopOfStackOrNull();
1095 return Top ? Top->DeclareMapperVar : nullptr;
1096 }
1097};
1098
1099bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1100 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1101}
1102
1103bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1104 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1105 DKind == OMPD_unknown;
1106}
1107
1108} // namespace
1109
1110static const Expr *getExprAsWritten(const Expr *E) {
1111 if (const auto *FE = dyn_cast<FullExpr>(E))
1112 E = FE->getSubExpr();
1113
1114 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1115 E = MTE->getSubExpr();
1116
1117 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1118 E = Binder->getSubExpr();
1119
1120 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1121 E = ICE->getSubExprAsWritten();
1122 return E->IgnoreParens();
1123}
1124
1125static Expr *getExprAsWritten(Expr *E) {
1126 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1127}
1128
1129static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1130 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1131 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1132 D = ME->getMemberDecl();
1133 const auto *VD = dyn_cast<VarDecl>(D);
1134 const auto *FD = dyn_cast<FieldDecl>(D);
1135 if (VD != nullptr) {
1136 VD = VD->getCanonicalDecl();
1137 D = VD;
1138 } else {
1139 assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1139, __PRETTY_FUNCTION__))
;
1140 FD = FD->getCanonicalDecl();
1141 D = FD;
1142 }
1143 return D;
1144}
1145
1146static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1147 return const_cast<ValueDecl *>(
1148 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1149}
1150
1151DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1152 ValueDecl *D) const {
1153 D = getCanonicalDecl(D);
1154 auto *VD = dyn_cast<VarDecl>(D);
1155 const auto *FD = dyn_cast<FieldDecl>(D);
1156 DSAVarData DVar;
1157 if (Iter == end()) {
1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1159 // in a region but not in construct]
1160 // File-scope or namespace-scope variables referenced in called routines
1161 // in the region are shared unless they appear in a threadprivate
1162 // directive.
1163 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1164 DVar.CKind = OMPC_shared;
1165
1166 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1167 // in a region but not in construct]
1168 // Variables with static storage duration that are declared in called
1169 // routines in the region are shared.
1170 if (VD && VD->hasGlobalStorage())
1171 DVar.CKind = OMPC_shared;
1172
1173 // Non-static data members are shared by default.
1174 if (FD)
1175 DVar.CKind = OMPC_shared;
1176
1177 return DVar;
1178 }
1179
1180 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1181 // in a Construct, C/C++, predetermined, p.1]
1182 // Variables with automatic storage duration that are declared in a scope
1183 // inside the construct are private.
1184 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1185 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1186 DVar.CKind = OMPC_private;
1187 return DVar;
1188 }
1189
1190 DVar.DKind = Iter->Directive;
1191 // Explicitly specified attributes and local variables with predetermined
1192 // attributes.
1193 if (Iter->SharingMap.count(D)) {
1194 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1195 DVar.RefExpr = Data.RefExpr.getPointer();
1196 DVar.PrivateCopy = Data.PrivateCopy;
1197 DVar.CKind = Data.Attributes;
1198 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1199 DVar.Modifier = Data.Modifier;
1200 DVar.AppliedToPointee = Data.AppliedToPointee;
1201 return DVar;
1202 }
1203
1204 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1205 // in a Construct, C/C++, implicitly determined, p.1]
1206 // In a parallel or task construct, the data-sharing attributes of these
1207 // variables are determined by the default clause, if present.
1208 switch (Iter->DefaultAttr) {
1209 case DSA_shared:
1210 DVar.CKind = OMPC_shared;
1211 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1212 return DVar;
1213 case DSA_none:
1214 return DVar;
1215 case DSA_firstprivate:
1216 if (VD->getStorageDuration() == SD_Static &&
1217 VD->getDeclContext()->isFileContext()) {
1218 DVar.CKind = OMPC_unknown;
1219 } else {
1220 DVar.CKind = OMPC_firstprivate;
1221 }
1222 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1223 return DVar;
1224 case DSA_unspecified:
1225 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1226 // in a Construct, implicitly determined, p.2]
1227 // In a parallel construct, if no default clause is present, these
1228 // variables are shared.
1229 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1230 if ((isOpenMPParallelDirective(DVar.DKind) &&
1231 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1232 isOpenMPTeamsDirective(DVar.DKind)) {
1233 DVar.CKind = OMPC_shared;
1234 return DVar;
1235 }
1236
1237 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1238 // in a Construct, implicitly determined, p.4]
1239 // In a task construct, if no default clause is present, a variable that in
1240 // the enclosing context is determined to be shared by all implicit tasks
1241 // bound to the current team is shared.
1242 if (isOpenMPTaskingDirective(DVar.DKind)) {
1243 DSAVarData DVarTemp;
1244 const_iterator I = Iter, E = end();
1245 do {
1246 ++I;
1247 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1248 // Referenced in a Construct, implicitly determined, p.6]
1249 // In a task construct, if no default clause is present, a variable
1250 // whose data-sharing attribute is not determined by the rules above is
1251 // firstprivate.
1252 DVarTemp = getDSA(I, D);
1253 if (DVarTemp.CKind != OMPC_shared) {
1254 DVar.RefExpr = nullptr;
1255 DVar.CKind = OMPC_firstprivate;
1256 return DVar;
1257 }
1258 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1259 DVar.CKind =
1260 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1261 return DVar;
1262 }
1263 }
1264 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1265 // in a Construct, implicitly determined, p.3]
1266 // For constructs other than task, if no default clause is present, these
1267 // variables inherit their data-sharing attributes from the enclosing
1268 // context.
1269 return getDSA(++Iter, D);
1270}
1271
1272const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1273 const Expr *NewDE) {
1274 assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1274, __PRETTY_FUNCTION__))
;
1275 D = getCanonicalDecl(D);
1276 SharingMapTy &StackElem = getTopOfStack();
1277 auto It = StackElem.AlignedMap.find(D);
1278 if (It == StackElem.AlignedMap.end()) {
1279 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1279, __PRETTY_FUNCTION__))
;
1280 StackElem.AlignedMap[D] = NewDE;
1281 return nullptr;
1282 }
1283 assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map"
) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1283, __PRETTY_FUNCTION__))
;
1284 return It->second;
1285}
1286
1287const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1288 const Expr *NewDE) {
1289 assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1289, __PRETTY_FUNCTION__))
;
1290 D = getCanonicalDecl(D);
1291 SharingMapTy &StackElem = getTopOfStack();
1292 auto It = StackElem.NontemporalMap.find(D);
1293 if (It == StackElem.NontemporalMap.end()) {
1294 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1294, __PRETTY_FUNCTION__))
;
1295 StackElem.NontemporalMap[D] = NewDE;
1296 return nullptr;
1297 }
1298 assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map"
) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1298, __PRETTY_FUNCTION__))
;
1299 return It->second;
1300}
1301
1302void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1303 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1303, __PRETTY_FUNCTION__))
;
1304 D = getCanonicalDecl(D);
1305 SharingMapTy &StackElem = getTopOfStack();
1306 StackElem.LCVMap.try_emplace(
1307 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1308}
1309
1310const DSAStackTy::LCDeclInfo
1311DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1312 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1312, __PRETTY_FUNCTION__))
;
1313 D = getCanonicalDecl(D);
1314 const SharingMapTy &StackElem = getTopOfStack();
1315 auto It = StackElem.LCVMap.find(D);
1316 if (It != StackElem.LCVMap.end())
1317 return It->second;
1318 return {0, nullptr};
1319}
1320
1321const DSAStackTy::LCDeclInfo
1322DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1323 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1323, __PRETTY_FUNCTION__))
;
1324 D = getCanonicalDecl(D);
1325 for (unsigned I = Level + 1; I > 0; --I) {
1326 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1327 auto It = StackElem.LCVMap.find(D);
1328 if (It != StackElem.LCVMap.end())
1329 return It->second;
1330 }
1331 return {0, nullptr};
1332}
1333
1334const DSAStackTy::LCDeclInfo
1335DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1336 const SharingMapTy *Parent = getSecondOnStackOrNull();
1337 assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty")
? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1337, __PRETTY_FUNCTION__))
;
1338 D = getCanonicalDecl(D);
1339 auto It = Parent->LCVMap.find(D);
1340 if (It != Parent->LCVMap.end())
1341 return It->second;
1342 return {0, nullptr};
1343}
1344
1345const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1346 const SharingMapTy *Parent = getSecondOnStackOrNull();
1347 assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty")
? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1347, __PRETTY_FUNCTION__))
;
1348 if (Parent->LCVMap.size() < I)
1349 return nullptr;
1350 for (const auto &Pair : Parent->LCVMap)
1351 if (Pair.second.first == I)
1352 return Pair.first;
1353 return nullptr;
1354}
1355
1356void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1357 DeclRefExpr *PrivateCopy, unsigned Modifier,
1358 bool AppliedToPointee) {
1359 D = getCanonicalDecl(D);
1360 if (A == OMPC_threadprivate) {
1361 DSAInfo &Data = Threadprivates[D];
1362 Data.Attributes = A;
1363 Data.RefExpr.setPointer(E);
1364 Data.PrivateCopy = nullptr;
1365 Data.Modifier = Modifier;
1366 } else {
1367 DSAInfo &Data = getTopOfStack().SharingMap[D];
1368 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1371, __PRETTY_FUNCTION__))
1369 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1371, __PRETTY_FUNCTION__))
1370 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1371, __PRETTY_FUNCTION__))
1371 (isLoopControlVariable(D).first && A == OMPC_private))((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1371, __PRETTY_FUNCTION__))
;
1372 Data.Modifier = Modifier;
1373 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1374 Data.RefExpr.setInt(/*IntVal=*/true);
1375 return;
1376 }
1377 const bool IsLastprivate =
1378 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1379 Data.Attributes = A;
1380 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1381 Data.PrivateCopy = PrivateCopy;
1382 Data.AppliedToPointee = AppliedToPointee;
1383 if (PrivateCopy) {
1384 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1385 Data.Modifier = Modifier;
1386 Data.Attributes = A;
1387 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1388 Data.PrivateCopy = nullptr;
1389 Data.AppliedToPointee = AppliedToPointee;
1390 }
1391 }
1392}
1393
1394/// Build a variable declaration for OpenMP loop iteration variable.
1395static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1396 StringRef Name, const AttrVec *Attrs = nullptr,
1397 DeclRefExpr *OrigRef = nullptr) {
1398 DeclContext *DC = SemaRef.CurContext;
1399 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1400 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1401 auto *Decl =
1402 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1403 if (Attrs) {
1404 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1405 I != E; ++I)
1406 Decl->addAttr(*I);
1407 }
1408 Decl->setImplicit();
1409 if (OrigRef) {
1410 Decl->addAttr(
1411 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1412 }
1413 return Decl;
1414}
1415
1416static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1417 SourceLocation Loc,
1418 bool RefersToCapture = false) {
1419 D->setReferenced();
1420 D->markUsed(S.Context);
1421 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1422 SourceLocation(), D, RefersToCapture, Loc, Ty,
1423 VK_LValue);
1424}
1425
1426void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1427 BinaryOperatorKind BOK) {
1428 D = getCanonicalDecl(D);
1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
;
1441 ReductionData.set(BOK, SR);
1442 Expr *&TaskgroupReductionRef =
1443 getTopOfStack().TaskgroupReductionRef;
1444 if (!TaskgroupReductionRef) {
1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1446 SemaRef.Context.VoidPtrTy, ".task_red.");
1447 TaskgroupReductionRef =
1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1449 }
1450}
1451
1452void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1453 const Expr *ReductionRef) {
1454 D = getCanonicalDecl(D);
1455 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1455, __PRETTY_FUNCTION__))
;
1456 assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1458, __PRETTY_FUNCTION__))
1457 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1458, __PRETTY_FUNCTION__))
1458 "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1458, __PRETTY_FUNCTION__))
;
1459 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1460 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1466, __PRETTY_FUNCTION__))
1461 (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1466, __PRETTY_FUNCTION__))
1462 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1466, __PRETTY_FUNCTION__))
1463 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1466, __PRETTY_FUNCTION__))
1464 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1466, __PRETTY_FUNCTION__))
1465 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1466, __PRETTY_FUNCTION__))
1466 "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1466, __PRETTY_FUNCTION__))
;
1467 ReductionData.set(ReductionRef, SR);
1468 Expr *&TaskgroupReductionRef =
1469 getTopOfStack().TaskgroupReductionRef;
1470 if (!TaskgroupReductionRef) {
1471 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1472 SemaRef.Context.VoidPtrTy, ".task_red.");
1473 TaskgroupReductionRef =
1474 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1475 }
1476}
1477
1478const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1479 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1480 Expr *&TaskgroupDescriptor) const {
1481 D = getCanonicalDecl(D);
1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1482, __PRETTY_FUNCTION__))
;
1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1484 const DSAInfo &Data = I->SharingMap.lookup(D);
1485 if (Data.Attributes != OMPC_reduction ||
1486 Data.Modifier != OMPC_REDUCTION_task)
1487 continue;
1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1489 if (!ReductionData.ReductionOp ||
1490 ReductionData.ReductionOp.is<const Expr *>())
1491 return DSAVarData();
1492 SR = ReductionData.ReductionRange;
1493 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1496, __PRETTY_FUNCTION__))
;
1497 TaskgroupDescriptor = I->TaskgroupReductionRef;
1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1500 /*AppliedToPointee=*/false);
1501 }
1502 return DSAVarData();
1503}
1504
1505const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1506 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1507 Expr *&TaskgroupDescriptor) const {
1508 D = getCanonicalDecl(D);
1509 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1509, __PRETTY_FUNCTION__))
;
1510 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1511 const DSAInfo &Data = I->SharingMap.lookup(D);
1512 if (Data.Attributes != OMPC_reduction ||
1513 Data.Modifier != OMPC_REDUCTION_task)
1514 continue;
1515 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1516 if (!ReductionData.ReductionOp ||
1517 !ReductionData.ReductionOp.is<const Expr *>())
1518 return DSAVarData();
1519 SR = ReductionData.ReductionRange;
1520 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1521 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1523, __PRETTY_FUNCTION__))
1522 "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1523, __PRETTY_FUNCTION__))
1523 "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1523, __PRETTY_FUNCTION__))
;
1524 TaskgroupDescriptor = I->TaskgroupReductionRef;
1525 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1526 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1527 /*AppliedToPointee=*/false);
1528 }
1529 return DSAVarData();
1530}
1531
1532bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1533 D = D->getCanonicalDecl();
1534 for (const_iterator E = end(); I != E; ++I) {
1535 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1536 isOpenMPTargetExecutionDirective(I->Directive)) {
1537 if (I->CurScope) {
1538 Scope *TopScope = I->CurScope->getParent();
1539 Scope *CurScope = getCurScope();
1540 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1541 CurScope = CurScope->getParent();
1542 return CurScope != TopScope;
1543 }
1544 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1545 if (I->Context == DC)
1546 return true;
1547 return false;
1548 }
1549 }
1550 return false;
1551}
1552
1553static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1554 bool AcceptIfMutable = true,
1555 bool *IsClassType = nullptr) {
1556 ASTContext &Context = SemaRef.getASTContext();
1557 Type = Type.getNonReferenceType().getCanonicalType();
1558 bool IsConstant = Type.isConstant(Context);
1559 Type = Context.getBaseElementType(Type);
1560 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1561 ? Type->getAsCXXRecordDecl()
1562 : nullptr;
1563 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1564 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1565 RD = CTD->getTemplatedDecl();
1566 if (IsClassType)
1567 *IsClassType = RD;
1568 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1569 RD->hasDefinition() && RD->hasMutableFields());
1570}
1571
1572static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1573 QualType Type, OpenMPClauseKind CKind,
1574 SourceLocation ELoc,
1575 bool AcceptIfMutable = true,
1576 bool ListItemNotVar = false) {
1577 ASTContext &Context = SemaRef.getASTContext();
1578 bool IsClassType;
1579 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1580 unsigned Diag = ListItemNotVar
1581 ? diag::err_omp_const_list_item
1582 : IsClassType ? diag::err_omp_const_not_mutable_variable
1583 : diag::err_omp_const_variable;
1584 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1585 if (!ListItemNotVar && D) {
1586 const VarDecl *VD = dyn_cast<VarDecl>(D);
1587 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1588 VarDecl::DeclarationOnly;
1589 SemaRef.Diag(D->getLocation(),
1590 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1591 << D;
1592 }
1593 return true;
1594 }
1595 return false;
1596}
1597
1598const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1599 bool FromParent) {
1600 D = getCanonicalDecl(D);
1601 DSAVarData DVar;
1602
1603 auto *VD = dyn_cast<VarDecl>(D);
1604 auto TI = Threadprivates.find(D);
1605 if (TI != Threadprivates.end()) {
1606 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1607 DVar.CKind = OMPC_threadprivate;
1608 DVar.Modifier = TI->getSecond().Modifier;
1609 return DVar;
1610 }
1611 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1612 DVar.RefExpr = buildDeclRefExpr(
1613 SemaRef, VD, D->getType().getNonReferenceType(),
1614 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1615 DVar.CKind = OMPC_threadprivate;
1616 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1617 return DVar;
1618 }
1619 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1620 // in a Construct, C/C++, predetermined, p.1]
1621 // Variables appearing in threadprivate directives are threadprivate.
1622 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1623 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1624 SemaRef.getLangOpts().OpenMPUseTLS &&
1625 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1626 (VD && VD->getStorageClass() == SC_Register &&
1627 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1628 DVar.RefExpr = buildDeclRefExpr(
1629 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1630 DVar.CKind = OMPC_threadprivate;
1631 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1632 return DVar;
1633 }
1634 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1635 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1636 !isLoopControlVariable(D).first) {
1637 const_iterator IterTarget =
1638 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1639 return isOpenMPTargetExecutionDirective(Data.Directive);
1640 });
1641 if (IterTarget != end()) {
1642 const_iterator ParentIterTarget = IterTarget + 1;
1643 for (const_iterator Iter = begin();
1644 Iter != ParentIterTarget; ++Iter) {
1645 if (isOpenMPLocal(VD, Iter)) {
1646 DVar.RefExpr =
1647 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1648 D->getLocation());
1649 DVar.CKind = OMPC_threadprivate;
1650 return DVar;
1651 }
1652 }
1653 if (!isClauseParsingMode() || IterTarget != begin()) {
1654 auto DSAIter = IterTarget->SharingMap.find(D);
1655 if (DSAIter != IterTarget->SharingMap.end() &&
1656 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1657 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1658 DVar.CKind = OMPC_threadprivate;
1659 return DVar;
1660 }
1661 const_iterator End = end();
1662 if (!SemaRef.isOpenMPCapturedByRef(
1663 D, std::distance(ParentIterTarget, End),
1664 /*OpenMPCaptureLevel=*/0)) {
1665 DVar.RefExpr =
1666 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1667 IterTarget->ConstructLoc);
1668 DVar.CKind = OMPC_threadprivate;
1669 return DVar;
1670 }
1671 }
1672 }
1673 }
1674
1675 if (isStackEmpty())
1676 // Not in OpenMP execution region and top scope was already checked.
1677 return DVar;
1678
1679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1680 // in a Construct, C/C++, predetermined, p.4]
1681 // Static data members are shared.
1682 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1683 // in a Construct, C/C++, predetermined, p.7]
1684 // Variables with static storage duration that are declared in a scope
1685 // inside the construct are shared.
1686 if (VD && VD->isStaticDataMember()) {
1687 // Check for explicitly specified attributes.
1688 const_iterator I = begin();
1689 const_iterator EndI = end();
1690 if (FromParent && I != EndI)
1691 ++I;
1692 if (I != EndI) {
1693 auto It = I->SharingMap.find(D);
1694 if (It != I->SharingMap.end()) {
1695 const DSAInfo &Data = It->getSecond();
1696 DVar.RefExpr = Data.RefExpr.getPointer();
1697 DVar.PrivateCopy = Data.PrivateCopy;
1698 DVar.CKind = Data.Attributes;
1699 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1700 DVar.DKind = I->Directive;
1701 DVar.Modifier = Data.Modifier;
1702 DVar.AppliedToPointee = Data.AppliedToPointee;
1703 return DVar;
1704 }
1705 }
1706
1707 DVar.CKind = OMPC_shared;
1708 return DVar;
1709 }
1710
1711 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1712 // The predetermined shared attribute for const-qualified types having no
1713 // mutable members was removed after OpenMP 3.1.
1714 if (SemaRef.LangOpts.OpenMP <= 31) {
1715 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1716 // in a Construct, C/C++, predetermined, p.6]
1717 // Variables with const qualified type having no mutable member are
1718 // shared.
1719 if (isConstNotMutableType(SemaRef, D->getType())) {
1720 // Variables with const-qualified type having no mutable member may be
1721 // listed in a firstprivate clause, even if they are static data members.
1722 DSAVarData DVarTemp = hasInnermostDSA(
1723 D,
1724 [](OpenMPClauseKind C, bool) {
1725 return C == OMPC_firstprivate || C == OMPC_shared;
1726 },
1727 MatchesAlways, FromParent);
1728 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1729 return DVarTemp;
1730
1731 DVar.CKind = OMPC_shared;
1732 return DVar;
1733 }
1734 }
1735
1736 // Explicitly specified attributes and local variables with predetermined
1737 // attributes.
1738 const_iterator I = begin();
1739 const_iterator EndI = end();
1740 if (FromParent && I != EndI)
1741 ++I;
1742 if (I == EndI)
1743 return DVar;
1744 auto It = I->SharingMap.find(D);
1745 if (It != I->SharingMap.end()) {
1746 const DSAInfo &Data = It->getSecond();
1747 DVar.RefExpr = Data.RefExpr.getPointer();
1748 DVar.PrivateCopy = Data.PrivateCopy;
1749 DVar.CKind = Data.Attributes;
1750 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1751 DVar.DKind = I->Directive;
1752 DVar.Modifier = Data.Modifier;
1753 DVar.AppliedToPointee = Data.AppliedToPointee;
1754 }
1755
1756 return DVar;
1757}
1758
1759const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1760 bool FromParent) const {
1761 if (isStackEmpty()) {
1762 const_iterator I;
1763 return getDSA(I, D);
1764 }
1765 D = getCanonicalDecl(D);
1766 const_iterator StartI = begin();
1767 const_iterator EndI = end();
1768 if (FromParent && StartI != EndI)
1769 ++StartI;
1770 return getDSA(StartI, D);
1771}
1772
1773const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1774 unsigned Level) const {
1775 if (getStackSize() <= Level)
1776 return DSAVarData();
1777 D = getCanonicalDecl(D);
1778 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1779 return getDSA(StartI, D);
1780}
1781
1782const DSAStackTy::DSAVarData
1783DSAStackTy::hasDSA(ValueDecl *D,
1784 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1785 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1786 bool FromParent) const {
1787 if (isStackEmpty())
1788 return {};
1789 D = getCanonicalDecl(D);
1790 const_iterator I = begin();
1791 const_iterator EndI = end();
1792 if (FromParent && I != EndI)
1793 ++I;
1794 for (; I != EndI; ++I) {
1795 if (!DPred(I->Directive) &&
1796 !isImplicitOrExplicitTaskingRegion(I->Directive))
1797 continue;
1798 const_iterator NewI = I;
1799 DSAVarData DVar = getDSA(NewI, D);
1800 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1801 return DVar;
1802 }
1803 return {};
1804}
1805
1806const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1807 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1808 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1809 bool FromParent) const {
1810 if (isStackEmpty())
1811 return {};
1812 D = getCanonicalDecl(D);
1813 const_iterator StartI = begin();
1814 const_iterator EndI = end();
1815 if (FromParent && StartI != EndI)
1816 ++StartI;
1817 if (StartI == EndI || !DPred(StartI->Directive))
1818 return {};
1819 const_iterator NewI = StartI;
1820 DSAVarData DVar = getDSA(NewI, D);
1821 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1822 ? DVar
1823 : DSAVarData();
1824}
1825
1826bool DSAStackTy::hasExplicitDSA(
1827 const ValueDecl *D,
1828 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1829 unsigned Level, bool NotLastprivate) const {
1830 if (getStackSize() <= Level)
1831 return false;
1832 D = getCanonicalDecl(D);
1833 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1834 auto I = StackElem.SharingMap.find(D);
1835 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1836 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1837 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1838 return true;
1839 // Check predetermined rules for the loop control variables.
1840 auto LI = StackElem.LCVMap.find(D);
1841 if (LI != StackElem.LCVMap.end())
1842 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1843 return false;
1844}
1845
1846bool DSAStackTy::hasExplicitDirective(
1847 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1848 unsigned Level) const {
1849 if (getStackSize() <= Level)
1850 return false;
1851 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1852 return DPred(StackElem.Directive);
1853}
1854
1855bool DSAStackTy::hasDirective(
1856 const llvm::function_ref<bool(OpenMPDirectiveKind,
1857 const DeclarationNameInfo &, SourceLocation)>
1858 DPred,
1859 bool FromParent) const {
1860 // We look only in the enclosing region.
1861 size_t Skip = FromParent ? 2 : 1;
1862 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1863 I != E; ++I) {
1864 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1865 return true;
1866 }
1867 return false;
1868}
1869
1870void Sema::InitDataSharingAttributesStack() {
1871 VarDataSharingAttributesStack = new DSAStackTy(*this);
1872}
1873
1874#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1875
1876void Sema::pushOpenMPFunctionRegion() {
1877 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1878}
1879
1880void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1881 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1882}
1883
1884static bool isOpenMPDeviceDelayedContext(Sema &S) {
1885 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1886, __PRETTY_FUNCTION__))
1886 "Expected OpenMP device compilation.")((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1886, __PRETTY_FUNCTION__))
;
1887 return !S.isInOpenMPTargetExecutionDirective();
1888}
1889
1890namespace {
1891/// Status of the function emission on the host/device.
1892enum class FunctionEmissionStatus {
1893 Emitted,
1894 Discarded,
1895 Unknown,
1896};
1897} // anonymous namespace
1898
1899Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1900 unsigned DiagID,
1901 FunctionDecl *FD) {
1902 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1903, __PRETTY_FUNCTION__))
1903 "Expected OpenMP device compilation.")((LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1903, __PRETTY_FUNCTION__))
;
1904
1905 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1906 if (FD) {
1907 FunctionEmissionStatus FES = getEmissionStatus(FD);
1908 switch (FES) {
1909 case FunctionEmissionStatus::Emitted:
1910 Kind = SemaDiagnosticBuilder::K_Immediate;
1911 break;
1912 case FunctionEmissionStatus::Unknown:
1913 // TODO: We should always delay diagnostics here in case a target
1914 // region is in a function we do not emit. However, as the
1915 // current diagnostics are associated with the function containing
1916 // the target region and we do not emit that one, we would miss out
1917 // on diagnostics for the target region itself. We need to anchor
1918 // the diagnostics with the new generated function *or* ensure we
1919 // emit diagnostics associated with the surrounding function.
1920 Kind = isOpenMPDeviceDelayedContext(*this)
1921 ? SemaDiagnosticBuilder::K_Deferred
1922 : SemaDiagnosticBuilder::K_Immediate;
1923 break;
1924 case FunctionEmissionStatus::TemplateDiscarded:
1925 case FunctionEmissionStatus::OMPDiscarded:
1926 Kind = SemaDiagnosticBuilder::K_Nop;
1927 break;
1928 case FunctionEmissionStatus::CUDADiscarded:
1929 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1929)
;
1930 break;
1931 }
1932 }
1933
1934 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1935}
1936
1937Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1938 unsigned DiagID,
1939 FunctionDecl *FD) {
1940 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1941, __PRETTY_FUNCTION__))
1941 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1941, __PRETTY_FUNCTION__))
;
1942 FunctionEmissionStatus FES = getEmissionStatus(FD);
1943 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944 switch (FES) {
1945 case FunctionEmissionStatus::Emitted:
1946 Kind = SemaDiagnosticBuilder::K_Immediate;
1947 break;
1948 case FunctionEmissionStatus::Unknown:
1949 Kind = SemaDiagnosticBuilder::K_Deferred;
1950 break;
1951 case FunctionEmissionStatus::TemplateDiscarded:
1952 case FunctionEmissionStatus::OMPDiscarded:
1953 case FunctionEmissionStatus::CUDADiscarded:
1954 Kind = SemaDiagnosticBuilder::K_Nop;
1955 break;
1956 }
1957
1958 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1959}
1960
1961static OpenMPDefaultmapClauseKind
1962getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1963 if (LO.OpenMP <= 45) {
1964 if (VD->getType().getNonReferenceType()->isScalarType())
1965 return OMPC_DEFAULTMAP_scalar;
1966 return OMPC_DEFAULTMAP_aggregate;
1967 }
1968 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1969 return OMPC_DEFAULTMAP_pointer;
1970 if (VD->getType().getNonReferenceType()->isScalarType())
1971 return OMPC_DEFAULTMAP_scalar;
1972 return OMPC_DEFAULTMAP_aggregate;
1973}
1974
1975bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1976 unsigned OpenMPCaptureLevel) const {
1977 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 1977, __PRETTY_FUNCTION__))
;
1978
1979 ASTContext &Ctx = getASTContext();
1980 bool IsByRef = true;
1981
1982 // Find the directive that is associated with the provided scope.
1983 D = cast<ValueDecl>(D->getCanonicalDecl());
1984 QualType Ty = D->getType();
1985
1986 bool IsVariableUsedInMapClause = false;
1987 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1988 // This table summarizes how a given variable should be passed to the device
1989 // given its type and the clauses where it appears. This table is based on
1990 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1991 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1992 //
1993 // =========================================================================
1994 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1995 // | |(tofrom:scalar)| | pvt | | | |
1996 // =========================================================================
1997 // | scl | | | | - | | bycopy|
1998 // | scl | | - | x | - | - | bycopy|
1999 // | scl | | x | - | - | - | null |
2000 // | scl | x | | | - | | byref |
2001 // | scl | x | - | x | - | - | bycopy|
2002 // | scl | x | x | - | - | - | null |
2003 // | scl | | - | - | - | x | byref |
2004 // | scl | x | - | - | - | x | byref |
2005 //
2006 // | agg | n.a. | | | - | | byref |
2007 // | agg | n.a. | - | x | - | - | byref |
2008 // | agg | n.a. | x | - | - | - | null |
2009 // | agg | n.a. | - | - | - | x | byref |
2010 // | agg | n.a. | - | - | - | x[] | byref |
2011 //
2012 // | ptr | n.a. | | | - | | bycopy|
2013 // | ptr | n.a. | - | x | - | - | bycopy|
2014 // | ptr | n.a. | x | - | - | - | null |
2015 // | ptr | n.a. | - | - | - | x | byref |
2016 // | ptr | n.a. | - | - | - | x[] | bycopy|
2017 // | ptr | n.a. | - | - | x | | bycopy|
2018 // | ptr | n.a. | - | - | x | x | bycopy|
2019 // | ptr | n.a. | - | - | x | x[] | bycopy|
2020 // =========================================================================
2021 // Legend:
2022 // scl - scalar
2023 // ptr - pointer
2024 // agg - aggregate
2025 // x - applies
2026 // - - invalid in this combination
2027 // [] - mapped with an array section
2028 // byref - should be mapped by reference
2029 // byval - should be mapped by value
2030 // null - initialize a local variable to null on the device
2031 //
2032 // Observations:
2033 // - All scalar declarations that show up in a map clause have to be passed
2034 // by reference, because they may have been mapped in the enclosing data
2035 // environment.
2036 // - If the scalar value does not fit the size of uintptr, it has to be
2037 // passed by reference, regardless the result in the table above.
2038 // - For pointers mapped by value that have either an implicit map or an
2039 // array section, the runtime library may pass the NULL value to the
2040 // device instead of the value passed to it by the compiler.
2041
2042 if (Ty->isReferenceType())
2043 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2044
2045 // Locate map clauses and see if the variable being captured is referred to
2046 // in any of those clauses. Here we only care about variables, not fields,
2047 // because fields are part of aggregates.
2048 bool IsVariableAssociatedWithSection = false;
2049
2050 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2051 D, Level,
2052 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2053 OMPClauseMappableExprCommon::MappableExprComponentListRef
2054 MapExprComponents,
2055 OpenMPClauseKind WhereFoundClauseKind) {
2056 // Only the map clause information influences how a variable is
2057 // captured. E.g. is_device_ptr does not require changing the default
2058 // behavior.
2059 if (WhereFoundClauseKind != OMPC_map)
2060 return false;
2061
2062 auto EI = MapExprComponents.rbegin();
2063 auto EE = MapExprComponents.rend();
2064
2065 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2065, __PRETTY_FUNCTION__))
;
2066
2067 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2068 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2069
2070 ++EI;
2071 if (EI == EE)
2072 return false;
2073
2074 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2075 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2076 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2077 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2078 IsVariableAssociatedWithSection = true;
2079 // There is nothing more we need to know about this variable.
2080 return true;
2081 }
2082
2083 // Keep looking for more map info.
2084 return false;
2085 });
2086
2087 if (IsVariableUsedInMapClause) {
2088 // If variable is identified in a map clause it is always captured by
2089 // reference except if it is a pointer that is dereferenced somehow.
2090 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2091 } else {
2092 // By default, all the data that has a scalar type is mapped by copy
2093 // (except for reduction variables).
2094 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2095 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2096 !Ty->isAnyPointerType()) ||
2097 !Ty->isScalarType() ||
2098 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2099 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2100 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2101 D,
2102 [](OpenMPClauseKind K, bool AppliedToPointee) {
2103 return K == OMPC_reduction && !AppliedToPointee;
2104 },
2105 Level);
2106 }
2107 }
2108
2109 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2110 IsByRef =
2111 ((IsVariableUsedInMapClause &&
2112 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2113 OMPD_target) ||
2114 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2115 D,
2116 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2117 return K == OMPC_firstprivate ||
2118 (K == OMPC_reduction && AppliedToPointee);
2119 },
2120 Level, /*NotLastprivate=*/true) ||
2121 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2122 // If the variable is artificial and must be captured by value - try to
2123 // capture by value.
2124 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2125 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2126 // If the variable is implicitly firstprivate and scalar - capture by
2127 // copy
2128 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2129 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2130 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2131 Level) &&
2132 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2133 }
2134
2135 // When passing data by copy, we need to make sure it fits the uintptr size
2136 // and alignment, because the runtime library only deals with uintptr types.
2137 // If it does not fit the uintptr size, we need to pass the data by reference
2138 // instead.
2139 if (!IsByRef &&
2140 (Ctx.getTypeSizeInChars(Ty) >
2141 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2142 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2143 IsByRef = true;
2144 }
2145
2146 return IsByRef;
2147}
2148
2149unsigned Sema::getOpenMPNestingLevel() const {
2150 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2150, __PRETTY_FUNCTION__))
;
2151 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2152}
2153
2154bool Sema::isInOpenMPTargetExecutionDirective() const {
2155 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2156 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2157 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2158 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2159 SourceLocation) -> bool {
2160 return isOpenMPTargetExecutionDirective(K);
2161 },
2162 false);
2163}
2164
2165VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2166 unsigned StopAt) {
2167 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2167, __PRETTY_FUNCTION__))
;
2168 D = getCanonicalDecl(D);
2169
2170 auto *VD = dyn_cast<VarDecl>(D);
2171 // Do not capture constexpr variables.
2172 if (VD && VD->isConstexpr())
2173 return nullptr;
2174
2175 // If we want to determine whether the variable should be captured from the
2176 // perspective of the current capturing scope, and we've already left all the
2177 // capturing scopes of the top directive on the stack, check from the
2178 // perspective of its parent directive (if any) instead.
2179 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2180 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2181
2182 // If we are attempting to capture a global variable in a directive with
2183 // 'target' we return true so that this global is also mapped to the device.
2184 //
2185 if (VD && !VD->hasLocalStorage() &&
2186 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2187 if (isInOpenMPDeclareTargetContext()) {
2188 // Try to mark variable as declare target if it is used in capturing
2189 // regions.
2190 if (LangOpts.OpenMP <= 45 &&
2191 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2192 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2193 return nullptr;
2194 }
2195 if (isInOpenMPTargetExecutionDirective()) {
2196 // If the declaration is enclosed in a 'declare target' directive,
2197 // then it should not be captured.
2198 //
2199 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2200 return nullptr;
2201 CapturedRegionScopeInfo *CSI = nullptr;
2202 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2203 llvm::reverse(FunctionScopes),
2204 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2205 if (!isa<CapturingScopeInfo>(FSI))
2206 return nullptr;
2207 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2208 if (RSI->CapRegionKind == CR_OpenMP) {
2209 CSI = RSI;
2210 break;
2211 }
2212 }
2213 assert(CSI && "Failed to find CapturedRegionScopeInfo")((CSI && "Failed to find CapturedRegionScopeInfo") ? static_cast
<void> (0) : __assert_fail ("CSI && \"Failed to find CapturedRegionScopeInfo\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2213, __PRETTY_FUNCTION__))
;
2214 SmallVector<OpenMPDirectiveKind, 4> Regions;
2215 getOpenMPCaptureRegions(Regions,
2216 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2217 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2218 return VD;
2219 }
2220 }
2221
2222 if (CheckScopeInfo) {
2223 bool OpenMPFound = false;
2224 for (unsigned I = StopAt + 1; I > 0; --I) {
2225 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2226 if(!isa<CapturingScopeInfo>(FSI))
2227 return nullptr;
2228 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2229 if (RSI->CapRegionKind == CR_OpenMP) {
2230 OpenMPFound = true;
2231 break;
2232 }
2233 }
2234 if (!OpenMPFound)
2235 return nullptr;
2236 }
2237
2238 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2239 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2240 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2241 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2242 if (Info.first ||
2243 (VD && VD->hasLocalStorage() &&
2244 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2245 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2246 return VD ? VD : Info.second;
2247 DSAStackTy::DSAVarData DVarTop =
2248 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2249 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2250 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2251 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2252 // Threadprivate variables must not be captured.
2253 if (isOpenMPThreadPrivate(DVarTop.CKind))
2254 return nullptr;
2255 // The variable is not private or it is the variable in the directive with
2256 // default(none) clause and not used in any clause.
2257 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2258 D,
2259 [](OpenMPClauseKind C, bool AppliedToPointee) {
2260 return isOpenMPPrivate(C) && !AppliedToPointee;
2261 },
2262 [](OpenMPDirectiveKind) { return true; },
2263 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2264 // Global shared must not be captured.
2265 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2266 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2267 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2268 DVarTop.CKind == OMPC_shared))
2269 return nullptr;
2270 if (DVarPrivate.CKind != OMPC_unknown ||
2271 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2272 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2273 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2274 }
2275 return nullptr;
2276}
2277
2278void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2279 unsigned Level) const {
2280 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2281}
2282
2283void Sema::startOpenMPLoop() {
2284 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2284, __PRETTY_FUNCTION__))
;
2285 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2286 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2287}
2288
2289void Sema::startOpenMPCXXRangeFor() {
2290 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2290, __PRETTY_FUNCTION__))
;
2291 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2292 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2293 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2294 }
2295}
2296
2297OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2298 unsigned CapLevel) const {
2299 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2299, __PRETTY_FUNCTION__))
;
2300 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2301 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2302 Level)) {
2303 bool IsTriviallyCopyable =
2304 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2305 !D->getType()
2306 .getNonReferenceType()
2307 .getCanonicalType()
2308 ->getAsCXXRecordDecl();
2309 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2310 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2311 getOpenMPCaptureRegions(CaptureRegions, DKind);
2312 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2313 (IsTriviallyCopyable ||
2314 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2315 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2316 D,
2317 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2318 Level, /*NotLastprivate=*/true))
2319 return OMPC_firstprivate;
2320 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2321 if (DVar.CKind != OMPC_shared &&
2322 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2323 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2324 return OMPC_firstprivate;
2325 }
2326 }
2327 }
2328 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2329 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2330 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2331 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2332 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2333 return OMPC_private;
2334 }
2335 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2336 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2337 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2338 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2339 Level) &&
2340 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2341 return OMPC_private;
2342 }
2343 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2344 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2345 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2346 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2347 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2348 Level))
2349 return OMPC_private;
2350 }
2351 // User-defined allocators are private since they must be defined in the
2352 // context of target region.
2353 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2354 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2355 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2356 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2357 return OMPC_private;
2358 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2359 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2360 Level) ||
2361 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2362 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2363 // Consider taskgroup reduction descriptor variable a private
2364 // to avoid possible capture in the region.
2365 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2366 [](OpenMPDirectiveKind K) {
2367 return K == OMPD_taskgroup ||
2368 ((isOpenMPParallelDirective(K) ||
2369 isOpenMPWorksharingDirective(K)) &&
2370 !isOpenMPSimdDirective(K));
2371 },
2372 Level) &&
2373 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2374 ? OMPC_private
2375 : OMPC_unknown;
2376}
2377
2378void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2379 unsigned Level) {
2380 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2380, __PRETTY_FUNCTION__))
;
2381 D = getCanonicalDecl(D);
2382 OpenMPClauseKind OMPC = OMPC_unknown;
2383 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2384 const unsigned NewLevel = I - 1;
2385 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2386 D,
2387 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2388 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2389 OMPC = K;
2390 return true;
2391 }
2392 return false;
2393 },
2394 NewLevel))
2395 break;
2396 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2397 D, NewLevel,
2398 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2399 OpenMPClauseKind) { return true; })) {
2400 OMPC = OMPC_map;
2401 break;
2402 }
2403 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2404 NewLevel)) {
2405 OMPC = OMPC_map;
2406 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2407 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2408 OMPC = OMPC_firstprivate;
2409 break;
2410 }
2411 }
2412 if (OMPC != OMPC_unknown)
2413 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2414}
2415
2416bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2417 unsigned CaptureLevel) const {
2418 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2418, __PRETTY_FUNCTION__))
;
2419 // Return true if the current level is no longer enclosed in a target region.
2420
2421 SmallVector<OpenMPDirectiveKind, 4> Regions;
2422 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2423 const auto *VD = dyn_cast<VarDecl>(D);
2424 return VD && !VD->hasLocalStorage() &&
2425 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2426 Level) &&
2427 Regions[CaptureLevel] != OMPD_task;
2428}
2429
2430bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2431 unsigned CaptureLevel) const {
2432 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2432, __PRETTY_FUNCTION__))
;
2433 // Return true if the current level is no longer enclosed in a target region.
2434
2435 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2436 if (!VD->hasLocalStorage()) {
2437 if (isInOpenMPTargetExecutionDirective())
2438 return true;
2439 DSAStackTy::DSAVarData TopDVar =
2440 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2441 unsigned NumLevels =
2442 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2443 if (Level == 0)
2444 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2445 do {
2446 --Level;
2447 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2448 if (DVar.CKind != OMPC_shared)
2449 return true;
2450 } while (Level > 0);
2451 }
2452 }
2453 return true;
2454}
2455
2456void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2457
2458void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2459 OMPTraitInfo &TI) {
2460 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2461}
2462
2463void Sema::ActOnOpenMPEndDeclareVariant() {
2464 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2465, __PRETTY_FUNCTION__))
2465 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2465, __PRETTY_FUNCTION__))
;
2466
2467 OMPDeclareVariantScopes.pop_back();
2468}
2469
2470void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2471 const FunctionDecl *Callee,
2472 SourceLocation Loc) {
2473 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2473, __PRETTY_FUNCTION__))
;
2474 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2475 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2476 // Ignore host functions during device analyzis.
2477 if (LangOpts.OpenMPIsDevice && DevTy &&
2478 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2479 return;
2480 // Ignore nohost functions during host analyzis.
2481 if (!LangOpts.OpenMPIsDevice && DevTy &&
2482 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2483 return;
2484 const FunctionDecl *FD = Callee->getMostRecentDecl();
2485 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2486 if (LangOpts.OpenMPIsDevice && DevTy &&
2487 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2488 // Diagnose host function called during device codegen.
2489 StringRef HostDevTy =
2490 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2491 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2492 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2493 diag::note_omp_marked_device_type_here)
2494 << HostDevTy;
2495 return;
2496 }
2497 if (!LangOpts.OpenMPIsDevice && DevTy &&
2498 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2499 // Diagnose nohost function called during host codegen.
2500 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2501 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2502 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2503 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2504 diag::note_omp_marked_device_type_here)
2505 << NoHostDevTy;
2506 }
2507}
2508
2509void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2510 const DeclarationNameInfo &DirName,
2511 Scope *CurScope, SourceLocation Loc) {
2512 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2513 PushExpressionEvaluationContext(
2514 ExpressionEvaluationContext::PotentiallyEvaluated);
2515}
2516
2517void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2518 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2519}
2520
2521void Sema::EndOpenMPClause() {
2522 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2523}
2524
2525static std::pair<ValueDecl *, bool>
2526getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2527 SourceRange &ERange, bool AllowArraySection = false);
2528
2529/// Check consistency of the reduction clauses.
2530static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2531 ArrayRef<OMPClause *> Clauses) {
2532 bool InscanFound = false;
2533 SourceLocation InscanLoc;
2534 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2535 // A reduction clause without the inscan reduction-modifier may not appear on
2536 // a construct on which a reduction clause with the inscan reduction-modifier
2537 // appears.
2538 for (OMPClause *C : Clauses) {
2539 if (C->getClauseKind() != OMPC_reduction)
2540 continue;
2541 auto *RC = cast<OMPReductionClause>(C);
2542 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2543 InscanFound = true;
2544 InscanLoc = RC->getModifierLoc();
2545 continue;
2546 }
2547 if (RC->getModifier() == OMPC_REDUCTION_task) {
2548 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2549 // A reduction clause with the task reduction-modifier may only appear on
2550 // a parallel construct, a worksharing construct or a combined or
2551 // composite construct for which any of the aforementioned constructs is a
2552 // constituent construct and simd or loop are not constituent constructs.
2553 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2554 if (!(isOpenMPParallelDirective(CurDir) ||
2555 isOpenMPWorksharingDirective(CurDir)) ||
2556 isOpenMPSimdDirective(CurDir))
2557 S.Diag(RC->getModifierLoc(),
2558 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2559 continue;
2560 }
2561 }
2562 if (InscanFound) {
2563 for (OMPClause *C : Clauses) {
2564 if (C->getClauseKind() != OMPC_reduction)
2565 continue;
2566 auto *RC = cast<OMPReductionClause>(C);
2567 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2568 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2569 ? RC->getBeginLoc()
2570 : RC->getModifierLoc(),
2571 diag::err_omp_inscan_reduction_expected);
2572 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2573 continue;
2574 }
2575 for (Expr *Ref : RC->varlists()) {
2576 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2576, __PRETTY_FUNCTION__))
;
2577 SourceLocation ELoc;
2578 SourceRange ERange;
2579 Expr *SimpleRefExpr = Ref;
2580 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2581 /*AllowArraySection=*/true);
2582 ValueDecl *D = Res.first;
2583 if (!D)
2584 continue;
2585 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2586 S.Diag(Ref->getExprLoc(),
2587 diag::err_omp_reduction_not_inclusive_exclusive)
2588 << Ref->getSourceRange();
2589 }
2590 }
2591 }
2592 }
2593}
2594
2595static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2596 ArrayRef<OMPClause *> Clauses);
2597static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2598 bool WithInit);
2599
2600static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2601 const ValueDecl *D,
2602 const DSAStackTy::DSAVarData &DVar,
2603 bool IsLoopIterVar = false);
2604
2605void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2606 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2607 // A variable of class type (or array thereof) that appears in a lastprivate
2608 // clause requires an accessible, unambiguous default constructor for the
2609 // class type, unless the list item is also specified in a firstprivate
2610 // clause.
2611 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2612 for (OMPClause *C : D->clauses()) {
2613 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2614 SmallVector<Expr *, 8> PrivateCopies;
2615 for (Expr *DE : Clause->varlists()) {
2616 if (DE->isValueDependent() || DE->isTypeDependent()) {
2617 PrivateCopies.push_back(nullptr);
2618 continue;
2619 }
2620 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2621 auto *VD = cast<VarDecl>(DRE->getDecl());
2622 QualType Type = VD->getType().getNonReferenceType();
2623 const DSAStackTy::DSAVarData DVar =
2624 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2625 if (DVar.CKind == OMPC_lastprivate) {
2626 // Generate helper private variable and initialize it with the
2627 // default value. The address of the original variable is replaced
2628 // by the address of the new private variable in CodeGen. This new
2629 // variable is not added to IdResolver, so the code in the OpenMP
2630 // region uses original variable for proper diagnostics.
2631 VarDecl *VDPrivate = buildVarDecl(
2632 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2633 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2634 ActOnUninitializedDecl(VDPrivate);
2635 if (VDPrivate->isInvalidDecl()) {
2636 PrivateCopies.push_back(nullptr);
2637 continue;
2638 }
2639 PrivateCopies.push_back(buildDeclRefExpr(
2640 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2641 } else {
2642 // The variable is also a firstprivate, so initialization sequence
2643 // for private copy is generated already.
2644 PrivateCopies.push_back(nullptr);
2645 }
2646 }
2647 Clause->setPrivateCopies(PrivateCopies);
2648 continue;
2649 }
2650 // Finalize nontemporal clause by handling private copies, if any.
2651 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2652 SmallVector<Expr *, 8> PrivateRefs;
2653 for (Expr *RefExpr : Clause->varlists()) {
2654 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 2654, __PRETTY_FUNCTION__))
;
2655 SourceLocation ELoc;
2656 SourceRange ERange;
2657 Expr *SimpleRefExpr = RefExpr;
2658 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2659 if (Res.second)
2660 // It will be analyzed later.
2661 PrivateRefs.push_back(RefExpr);
2662 ValueDecl *D = Res.first;
2663 if (!D)
2664 continue;
2665
2666 const DSAStackTy::DSAVarData DVar =
2667 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2668 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2669 : SimpleRefExpr);
2670 }
2671 Clause->setPrivateRefs(PrivateRefs);
2672 continue;
2673 }
2674 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2675 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2676 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2677 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2678 if (!DRE)
2679 continue;
2680 ValueDecl *VD = DRE->getDecl();
2681 if (!VD || !isa<VarDecl>(VD))
2682 continue;
2683 DSAStackTy::DSAVarData DVar =
2684 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2685 // OpenMP [2.12.5, target Construct]
2686 // Memory allocators that appear in a uses_allocators clause cannot
2687 // appear in other data-sharing attribute clauses or data-mapping
2688 // attribute clauses in the same construct.
2689 Expr *MapExpr = nullptr;
2690 if (DVar.RefExpr ||
2691 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2692 VD, /*CurrentRegionOnly=*/true,
2693 [VD, &MapExpr](
2694 OMPClauseMappableExprCommon::MappableExprComponentListRef
2695 MapExprComponents,
2696 OpenMPClauseKind C) {
2697 auto MI = MapExprComponents.rbegin();
2698 auto ME = MapExprComponents.rend();
2699 if (MI != ME &&
2700 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2701 VD->getCanonicalDecl()) {
2702 MapExpr = MI->getAssociatedExpression();
2703 return true;
2704 }
2705 return false;
2706 })) {
2707 Diag(D.Allocator->getExprLoc(),
2708 diag::err_omp_allocator_used_in_clauses)
2709 << D.Allocator->getSourceRange();
2710 if (DVar.RefExpr)
2711 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2712 else
2713 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2714 << MapExpr->getSourceRange();
2715 }
2716 }
2717 continue;
2718 }
2719 }
2720 // Check allocate clauses.
2721 if (!CurContext->isDependentContext())
2722 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2723 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2724 }
2725
2726 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2727 DiscardCleanupsInEvaluationContext();
2728 PopExpressionEvaluationContext();
2729}
2730
2731static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2732 Expr *NumIterations, Sema &SemaRef,
2733 Scope *S, DSAStackTy *Stack);
2734
2735namespace {
2736
2737class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2738private:
2739 Sema &SemaRef;
2740
2741public:
2742 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2743 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2744 NamedDecl *ND = Candidate.getCorrectionDecl();
2745 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2746 return VD->hasGlobalStorage() &&
2747 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2748 SemaRef.getCurScope());
2749 }
2750 return false;
2751 }
2752
2753 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2754 return std::make_unique<VarDeclFilterCCC>(*this);
2755 }
2756
2757};
2758
2759class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2760private:
2761 Sema &SemaRef;
2762
2763public:
2764 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2765 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2766 NamedDecl *ND = Candidate.getCorrectionDecl();
2767 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2768 isa<FunctionDecl>(ND))) {
2769 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2770 SemaRef.getCurScope());
2771 }
2772 return false;
2773 }
2774
2775 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2776 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2777 }
2778};
2779
2780} // namespace
2781
2782ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2783 CXXScopeSpec &ScopeSpec,
2784 const DeclarationNameInfo &Id,
2785 OpenMPDirectiveKind Kind) {
2786 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2787 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2788
2789 if (Lookup.isAmbiguous())
2790 return ExprError();
2791
2792 VarDecl *VD;
2793 if (!Lookup.isSingleResult()) {
2794 VarDeclFilterCCC CCC(*this);
2795 if (TypoCorrection Corrected =
2796 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2797 CTK_ErrorRecovery)) {
2798 diagnoseTypo(Corrected,
2799 PDiag(Lookup.empty()
2800 ? diag::err_undeclared_var_use_suggest
2801 : diag::err_omp_expected_var_arg_suggest)
2802 << Id.getName());
2803 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2804 } else {
2805 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2806 : diag::err_omp_expected_var_arg)
2807 << Id.getName();
2808 return ExprError();
2809 }
2810 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2811 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2812 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2813 return ExprError();
2814 }
2815 Lookup.suppressDiagnostics();
2816
2817 // OpenMP [2.9.2, Syntax, C/C++]
2818 // Variables must be file-scope, namespace-scope, or static block-scope.
2819 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2820 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2821 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2822 bool IsDecl =
2823 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2824 Diag(VD->getLocation(),
2825 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2826 << VD;
2827 return ExprError();
2828 }
2829
2830 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2831 NamedDecl *ND = CanonicalVD;
2832 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2833 // A threadprivate directive for file-scope variables must appear outside
2834 // any definition or declaration.
2835 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2836 !getCurLexicalContext()->isTranslationUnit()) {
2837 Diag(Id.getLoc(), diag::err_omp_var_scope)
2838 << getOpenMPDirectiveName(Kind) << VD;
2839 bool IsDecl =
2840 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2841 Diag(VD->getLocation(),
2842 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2843 << VD;
2844 return ExprError();
2845 }
2846 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2847 // A threadprivate directive for static class member variables must appear
2848 // in the class definition, in the same scope in which the member
2849 // variables are declared.
2850 if (CanonicalVD->isStaticDataMember() &&
2851 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2852 Diag(Id.getLoc(), diag::err_omp_var_scope)
2853 << getOpenMPDirectiveName(Kind) << VD;
2854 bool IsDecl =
2855 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2856 Diag(VD->getLocation(),
2857 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2858 << VD;
2859 return ExprError();
2860 }
2861 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2862 // A threadprivate directive for namespace-scope variables must appear
2863 // outside any definition or declaration other than the namespace
2864 // definition itself.
2865 if (CanonicalVD->getDeclContext()->isNamespace() &&
2866 (!getCurLexicalContext()->isFileContext() ||
2867 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2868 Diag(Id.getLoc(), diag::err_omp_var_scope)
2869 << getOpenMPDirectiveName(Kind) << VD;
2870 bool IsDecl =
2871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2872 Diag(VD->getLocation(),
2873 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2874 << VD;
2875 return ExprError();
2876 }
2877 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2878 // A threadprivate directive for static block-scope variables must appear
2879 // in the scope of the variable and not in a nested scope.
2880 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2881 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2882 Diag(Id.getLoc(), diag::err_omp_var_scope)
2883 << getOpenMPDirectiveName(Kind) << VD;
2884 bool IsDecl =
2885 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2886 Diag(VD->getLocation(),
2887 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2888 << VD;
2889 return ExprError();
2890 }
2891
2892 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2893 // A threadprivate directive must lexically precede all references to any
2894 // of the variables in its list.
2895 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2896 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2897 Diag(Id.getLoc(), diag::err_omp_var_used)
2898 << getOpenMPDirectiveName(Kind) << VD;
2899 return ExprError();
2900 }
2901
2902 QualType ExprType = VD->getType().getNonReferenceType();
2903 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2904 SourceLocation(), VD,
2905 /*RefersToEnclosingVariableOrCapture=*/false,
2906 Id.getLoc(), ExprType, VK_LValue);
2907}
2908
2909Sema::DeclGroupPtrTy
2910Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2911 ArrayRef<Expr *> VarList) {
2912 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2913 CurContext->addDecl(D);
2914 return DeclGroupPtrTy::make(DeclGroupRef(D));
2915 }
2916 return nullptr;
2917}
2918
2919namespace {
2920class LocalVarRefChecker final
2921 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2922 Sema &SemaRef;
2923
2924public:
2925 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2926 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2927 if (VD->hasLocalStorage()) {
2928 SemaRef.Diag(E->getBeginLoc(),
2929 diag::err_omp_local_var_in_threadprivate_init)
2930 << E->getSourceRange();
2931 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2932 << VD << VD->getSourceRange();
2933 return true;
2934 }
2935 }
2936 return false;
2937 }
2938 bool VisitStmt(const Stmt *S) {
2939 for (const Stmt *Child : S->children()) {
2940 if (Child && Visit(Child))
2941 return true;
2942 }
2943 return false;
2944 }
2945 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2946};
2947} // namespace
2948
2949OMPThreadPrivateDecl *
2950Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2951 SmallVector<Expr *, 8> Vars;
2952 for (Expr *RefExpr : VarList) {
2953 auto *DE = cast<DeclRefExpr>(RefExpr);
2954 auto *VD = cast<VarDecl>(DE->getDecl());
2955 SourceLocation ILoc = DE->getExprLoc();
2956
2957 // Mark variable as used.
2958 VD->setReferenced();
2959 VD->markUsed(Context);
2960
2961 QualType QType = VD->getType();
2962 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2963 // It will be analyzed later.
2964 Vars.push_back(DE);
2965 continue;
2966 }
2967
2968 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2969 // A threadprivate variable must not have an incomplete type.
2970 if (RequireCompleteType(ILoc, VD->getType(),
2971 diag::err_omp_threadprivate_incomplete_type)) {
2972 continue;
2973 }
2974
2975 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2976 // A threadprivate variable must not have a reference type.
2977 if (VD->getType()->isReferenceType()) {
2978 Diag(ILoc, diag::err_omp_ref_type_arg)
2979 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2980 bool IsDecl =
2981 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2982 Diag(VD->getLocation(),
2983 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2984 << VD;
2985 continue;
2986 }
2987
2988 // Check if this is a TLS variable. If TLS is not being supported, produce
2989 // the corresponding diagnostic.
2990 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2991 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2992 getLangOpts().OpenMPUseTLS &&
2993 getASTContext().getTargetInfo().isTLSSupported())) ||
2994 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2995 !VD->isLocalVarDecl())) {
2996 Diag(ILoc, diag::err_omp_var_thread_local)
2997 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2998 bool IsDecl =
2999 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3000 Diag(VD->getLocation(),
3001 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3002 << VD;
3003 continue;
3004 }
3005
3006 // Check if initial value of threadprivate variable reference variable with
3007 // local storage (it is not supported by runtime).
3008 if (const Expr *Init = VD->getAnyInitializer()) {
3009 LocalVarRefChecker Checker(*this);
3010 if (Checker.Visit(Init))
3011 continue;
3012 }
3013
3014 Vars.push_back(RefExpr);
3015 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3016 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3017 Context, SourceRange(Loc, Loc)));
3018 if (ASTMutationListener *ML = Context.getASTMutationListener())
3019 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3020 }
3021 OMPThreadPrivateDecl *D = nullptr;
3022 if (!Vars.empty()) {
3023 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3024 Vars);
3025 D->setAccess(AS_public);
3026 }
3027 return D;
3028}
3029
3030static OMPAllocateDeclAttr::AllocatorTypeTy
3031getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3032 if (!Allocator)
3033 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3034 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3035 Allocator->isInstantiationDependent() ||
3036 Allocator->containsUnexpandedParameterPack())
3037 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3038 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3039 const Expr *AE = Allocator->IgnoreParenImpCasts();
3040 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3041 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3042 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3043 llvm::FoldingSetNodeID AEId, DAEId;
3044 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3045 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3046 if (AEId == DAEId) {
3047 AllocatorKindRes = AllocatorKind;
3048 break;
3049 }
3050 }
3051 return AllocatorKindRes;
3052}
3053
3054static bool checkPreviousOMPAllocateAttribute(
3055 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3056 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3057 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3058 return false;
3059 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3060 Expr *PrevAllocator = A->getAllocator();
3061 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3062 getAllocatorKind(S, Stack, PrevAllocator);
3063 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3064 if (AllocatorsMatch &&
3065 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3066 Allocator && PrevAllocator) {
3067 const Expr *AE = Allocator->IgnoreParenImpCasts();
3068 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3069 llvm::FoldingSetNodeID AEId, PAEId;
3070 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3071 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3072 AllocatorsMatch = AEId == PAEId;
3073 }
3074 if (!AllocatorsMatch) {
3075 SmallString<256> AllocatorBuffer;
3076 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3077 if (Allocator)
3078 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3079 SmallString<256> PrevAllocatorBuffer;
3080 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3081 if (PrevAllocator)
3082 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3083 S.getPrintingPolicy());
3084
3085 SourceLocation AllocatorLoc =
3086 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3087 SourceRange AllocatorRange =
3088 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3089 SourceLocation PrevAllocatorLoc =
3090 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3091 SourceRange PrevAllocatorRange =
3092 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3093 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3094 << (Allocator ? 1 : 0) << AllocatorStream.str()
3095 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3096 << AllocatorRange;
3097 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3098 << PrevAllocatorRange;
3099 return true;
3100 }
3101 return false;
3102}
3103
3104static void
3105applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3106 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3107 Expr *Allocator, SourceRange SR) {
3108 if (VD->hasAttr<OMPAllocateDeclAttr>())
3109 return;
3110 if (Allocator &&
3111 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3112 Allocator->isInstantiationDependent() ||
3113 Allocator->containsUnexpandedParameterPack()))
3114 return;
3115 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3116 Allocator, SR);
3117 VD->addAttr(A);
3118 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3119 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3120}
3121
3122Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3123 SourceLocation Loc, ArrayRef<Expr *> VarList,
3124 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3125 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 3125, __PRETTY_FUNCTION__))
;
3126 Expr *Allocator = nullptr;
3127 if (Clauses.empty()) {
3128 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3129 // allocate directives that appear in a target region must specify an
3130 // allocator clause unless a requires directive with the dynamic_allocators
3131 // clause is present in the same compilation unit.
3132 if (LangOpts.OpenMPIsDevice &&
3133 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3134 targetDiag(Loc, diag::err_expected_allocator_clause);
3135 } else {
3136 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3137 }
3138 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3139 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3140 SmallVector<Expr *, 8> Vars;
3141 for (Expr *RefExpr : VarList) {
3142 auto *DE = cast<DeclRefExpr>(RefExpr);
3143 auto *VD = cast<VarDecl>(DE->getDecl());
3144
3145 // Check if this is a TLS variable or global register.
3146 if (VD->getTLSKind() != VarDecl::TLS_None ||
3147 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3148 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3149 !VD->isLocalVarDecl()))
3150 continue;
3151
3152 // If the used several times in the allocate directive, the same allocator
3153 // must be used.
3154 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3155 AllocatorKind, Allocator))
3156 continue;
3157
3158 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3159 // If a list item has a static storage type, the allocator expression in the
3160 // allocator clause must be a constant expression that evaluates to one of
3161 // the predefined memory allocator values.
3162 if (Allocator && VD->hasGlobalStorage()) {
3163 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3164 Diag(Allocator->getExprLoc(),
3165 diag::err_omp_expected_predefined_allocator)
3166 << Allocator->getSourceRange();
3167 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3168 VarDecl::DeclarationOnly;
3169 Diag(VD->getLocation(),
3170 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3171 << VD;
3172 continue;
3173 }
3174 }
3175
3176 Vars.push_back(RefExpr);
3177 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3178 DE->getSourceRange());
3179 }
3180 if (Vars.empty())
3181 return nullptr;
3182 if (!Owner)
3183 Owner = getCurLexicalContext();
3184 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3185 D->setAccess(AS_public);
3186 Owner->addDecl(D);
3187 return DeclGroupPtrTy::make(DeclGroupRef(D));
3188}
3189
3190Sema::DeclGroupPtrTy
3191Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3192 ArrayRef<OMPClause *> ClauseList) {
3193 OMPRequiresDecl *D = nullptr;
3194 if (!CurContext->isFileContext()) {
3195 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3196 } else {
3197 D = CheckOMPRequiresDecl(Loc, ClauseList);
3198 if (D) {
3199 CurContext->addDecl(D);
3200 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3201 }
3202 }
3203 return DeclGroupPtrTy::make(DeclGroupRef(D));
3204}
3205
3206void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3207 OpenMPDirectiveKind DKind,
3208 ArrayRef<StringRef> Assumptions,
3209 bool SkippedClauses) {
3210 if (!SkippedClauses && Assumptions.empty())
3211 Diag(Loc, diag::err_omp_no_clause_for_directive)
3212 << llvm::omp::getAllAssumeClauseOptions()
3213 << llvm::omp::getOpenMPDirectiveName(DKind);
3214
3215 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3216 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3217 OMPAssumeScoped.push_back(AA);
3218 return;
3219 }
3220
3221 // Global assumes without assumption clauses are ignored.
3222 if (Assumptions.empty())
3223 return;
3224
3225 assert(DKind == llvm::omp::Directive::OMPD_assumes &&((DKind == llvm::omp::Directive::OMPD_assumes && "Unexpected omp assumption directive!"
) ? static_cast<void> (0) : __assert_fail ("DKind == llvm::omp::Directive::OMPD_assumes && \"Unexpected omp assumption directive!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 3226, __PRETTY_FUNCTION__))
3226 "Unexpected omp assumption directive!")((DKind == llvm::omp::Directive::OMPD_assumes && "Unexpected omp assumption directive!"
) ? static_cast<void> (0) : __assert_fail ("DKind == llvm::omp::Directive::OMPD_assumes && \"Unexpected omp assumption directive!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 3226, __PRETTY_FUNCTION__))
;
3227 OMPAssumeGlobal.push_back(AA);
3228
3229 // The OMPAssumeGlobal scope above will take care of new declarations but
3230 // we also want to apply the assumption to existing ones, e.g., to
3231 // declarations in included headers. To this end, we traverse all existing
3232 // declaration contexts and annotate function declarations here.
3233 SmallVector<DeclContext *, 8> DeclContexts;
3234 auto *Ctx = CurContext;
3235 while (Ctx->getLexicalParent())
3236 Ctx = Ctx->getLexicalParent();
3237 DeclContexts.push_back(Ctx);
3238 while (!DeclContexts.empty()) {
3239 DeclContext *DC = DeclContexts.pop_back_val();
3240 for (auto *SubDC : DC->decls()) {
3241 if (SubDC->isInvalidDecl())
3242 continue;
3243 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3244 DeclContexts.push_back(CTD->getTemplatedDecl());
3245 for (auto *S : CTD->specializations())
3246 DeclContexts.push_back(S);
3247 continue;
3248 }
3249 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3250 DeclContexts.push_back(DC);
3251 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3252 F->addAttr(AA);
3253 continue;
3254 }
3255 }
3256 }
3257}
3258
3259void Sema::ActOnOpenMPEndAssumesDirective() {
3260 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!")((isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPAssumeScope() && \"Not in OpenMP assumes scope!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 3260, __PRETTY_FUNCTION__))
;
3261 OMPAssumeScoped.pop_back();
3262}
3263
3264OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3265 ArrayRef<OMPClause *> ClauseList) {
3266 /// For target specific clauses, the requires directive cannot be
3267 /// specified after the handling of any of the target regions in the
3268 /// current compilation unit.
3269 ArrayRef<SourceLocation> TargetLocations =
3270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3271 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3272 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3273 for (const OMPClause *CNew : ClauseList) {
3274 // Check if any of the requires clauses affect target regions.
3275 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3276 isa<OMPUnifiedAddressClause>(CNew) ||
3277 isa<OMPReverseOffloadClause>(CNew) ||
3278 isa<OMPDynamicAllocatorsClause>(CNew)) {
3279 Diag(Loc, diag::err_omp_directive_before_requires)
3280 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3281 for (SourceLocation TargetLoc : TargetLocations) {
3282 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3283 << "target";
3284 }
3285 } else if (!AtomicLoc.isInvalid() &&
3286 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3287 Diag(Loc, diag::err_omp_directive_before_requires)
3288 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3289 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3290 << "atomic";
3291 }
3292 }
3293 }
3294
3295 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3296 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3297 ClauseList);
3298 return nullptr;
3299}
3300
3301static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3302 const ValueDecl *D,
3303 const DSAStackTy::DSAVarData &DVar,
3304 bool IsLoopIterVar) {
3305 if (DVar.RefExpr) {
3306 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3307 << getOpenMPClauseName(DVar.CKind);
3308 return;
3309 }
3310 enum {
3311 PDSA_StaticMemberShared,
3312 PDSA_StaticLocalVarShared,
3313 PDSA_LoopIterVarPrivate,
3314 PDSA_LoopIterVarLinear,
3315 PDSA_LoopIterVarLastprivate,
3316 PDSA_ConstVarShared,
3317 PDSA_GlobalVarShared,
3318 PDSA_TaskVarFirstprivate,
3319 PDSA_LocalVarPrivate,
3320 PDSA_Implicit
3321 } Reason = PDSA_Implicit;
3322 bool ReportHint = false;
3323 auto ReportLoc = D->getLocation();
3324 auto *VD = dyn_cast<VarDecl>(D);
3325 if (IsLoopIterVar) {
3326 if (DVar.CKind == OMPC_private)
3327 Reason = PDSA_LoopIterVarPrivate;
3328 else if (DVar.CKind == OMPC_lastprivate)
3329 Reason = PDSA_LoopIterVarLastprivate;
3330 else
3331 Reason = PDSA_LoopIterVarLinear;
3332 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3333 DVar.CKind == OMPC_firstprivate) {
3334 Reason = PDSA_TaskVarFirstprivate;
3335 ReportLoc = DVar.ImplicitDSALoc;
3336 } else if (VD && VD->isStaticLocal())
3337 Reason = PDSA_StaticLocalVarShared;
3338 else if (VD && VD->isStaticDataMember())
3339 Reason = PDSA_StaticMemberShared;
3340 else if (VD && VD->isFileVarDecl())
3341 Reason = PDSA_GlobalVarShared;
3342 else if (D->getType().isConstant(SemaRef.getASTContext()))
3343 Reason = PDSA_ConstVarShared;
3344 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3345 ReportHint = true;
3346 Reason = PDSA_LocalVarPrivate;
3347 }
3348 if (Reason != PDSA_Implicit) {
3349 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3350 << Reason << ReportHint
3351 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3352 } else if (DVar.ImplicitDSALoc.isValid()) {
3353 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3354 << getOpenMPClauseName(DVar.CKind);
3355 }
3356}
3357
3358static OpenMPMapClauseKind
3359getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3360 bool IsAggregateOrDeclareTarget) {
3361 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3362 switch (M) {
3363 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3364 Kind = OMPC_MAP_alloc;
3365 break;
3366 case OMPC_DEFAULTMAP_MODIFIER_to:
3367 Kind = OMPC_MAP_to;
3368 break;
3369 case OMPC_DEFAULTMAP_MODIFIER_from:
3370 Kind = OMPC_MAP_from;
3371 break;
3372 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3373 Kind = OMPC_MAP_tofrom;
3374 break;
3375 case OMPC_DEFAULTMAP_MODIFIER_present:
3376 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3377 // If implicit-behavior is present, each variable referenced in the
3378 // construct in the category specified by variable-category is treated as if
3379 // it had been listed in a map clause with the map-type of alloc and
3380 // map-type-modifier of present.
3381 Kind = OMPC_MAP_alloc;
3382 break;
3383 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3384 case OMPC_DEFAULTMAP_MODIFIER_last:
3385 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 3385)
;
3386 case OMPC_DEFAULTMAP_MODIFIER_none:
3387 case OMPC_DEFAULTMAP_MODIFIER_default:
3388 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3389 // IsAggregateOrDeclareTarget could be true if:
3390 // 1. the implicit behavior for aggregate is tofrom
3391 // 2. it's a declare target link
3392 if (IsAggregateOrDeclareTarget) {
3393 Kind = OMPC_MAP_tofrom;
3394 break;
3395 }
3396 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 3396)
;
3397 }
3398 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 3398, __PRETTY_FUNCTION__))
;
3399 return Kind;
3400}
3401
3402namespace {
3403class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3404 DSAStackTy *Stack;
3405 Sema &SemaRef;
3406 bool ErrorFound = false;
3407 bool TryCaptureCXXThisMembers = false;
3408 CapturedStmt *CS = nullptr;
3409 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3410 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3411 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3412 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3413 ImplicitMapModifier[DefaultmapKindNum];
3414 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3415 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3416
3417 void VisitSubCaptures(OMPExecutableDirective *S) {
3418 // Check implicitly captured variables.
3419 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3420 return;
3421 if (S->getDirectiveKind() == OMPD_atomic ||
3422 S->getDirectiveKind() == OMPD_critical ||
3423 S->getDirectiveKind() == OMPD_section ||
3424 S->getDirectiveKind() == OMPD_master ||
3425 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3426 Visit(S->getAssociatedStmt());
3427 return;
3428 }
3429 visitSubCaptures(S->getInnermostCapturedStmt());
3430 // Try to capture inner this->member references to generate correct mappings
3431 // and diagnostics.
3432 if (TryCaptureCXXThisMembers ||
3433 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3434 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3435 [](const CapturedStmt::Capture &C) {
3436 return C.capturesThis();
3437 }))) {
3438 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3439 TryCaptureCXXThisMembers = true;
3440 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3441 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3442 }
3443 // In tasks firstprivates are not captured anymore, need to analyze them
3444 // explicitly.
3445 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3446 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3447 for (OMPClause *C : S->clauses())
3448 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3449 for (Expr *Ref : FC->varlists())
3450 Visit(Ref);
3451 }
3452 }
3453 }
3454
3455public:
3456 void VisitDeclRefExpr(DeclRefExpr *E) {
3457 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3458 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3459 E->isInstantiationDependent())
3460 return;
3461 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3462 // Check the datasharing rules for the expressions in the clauses.
3463 if (!CS) {
3464 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3465 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3466 Visit(CED->getInit());
3467 return;
3468 }
3469 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3470 // Do not analyze internal variables and do not enclose them into
3471 // implicit clauses.
3472 return;
3473 VD = VD->getCanonicalDecl();
3474 // Skip internally declared variables.
3475 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3476 !Stack->isImplicitTaskFirstprivate(VD))
3477 return;
3478 // Skip allocators in uses_allocators clauses.
3479 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3480 return;
3481
3482 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3483 // Check if the variable has explicit DSA set and stop analysis if it so.
3484 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3485 return;
3486
3487 // Skip internally declared static variables.
3488 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3489 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3490 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3491 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3492 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3493 !Stack->isImplicitTaskFirstprivate(VD))
3494 return;
3495
3496 SourceLocation ELoc = E->getExprLoc();
3497 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3498 // The default(none) clause requires that each variable that is referenced
3499 // in the construct, and does not have a predetermined data-sharing
3500 // attribute, must have its data-sharing attribute explicitly determined
3501 // by being listed in a data-sharing attribute clause.
3502 if (DVar.CKind == OMPC_unknown &&
3503 (Stack->getDefaultDSA() == DSA_none ||
3504 Stack->getDefaultDSA() == DSA_firstprivate) &&
3505 isImplicitOrExplicitTaskingRegion(DKind) &&
3506 VarsWithInheritedDSA.count(VD) == 0) {
3507 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3508 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3509 DSAStackTy::DSAVarData DVar =
3510 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3511 InheritedDSA = DVar.CKind == OMPC_unknown;
3512 }
3513 if (InheritedDSA)
3514 VarsWithInheritedDSA[VD] = E;
3515 return;
3516 }
3517
3518 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3519 // If implicit-behavior is none, each variable referenced in the
3520 // construct that does not have a predetermined data-sharing attribute
3521 // and does not appear in a to or link clause on a declare target
3522 // directive must be listed in a data-mapping attribute clause, a
3523 // data-haring attribute clause (including a data-sharing attribute
3524 // clause on a combined construct where target. is one of the
3525 // constituent constructs), or an is_device_ptr clause.
3526 OpenMPDefaultmapClauseKind ClauseKind =
3527 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3528 if (SemaRef.getLangOpts().OpenMP >= 50) {
3529 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3530 OMPC_DEFAULTMAP_MODIFIER_none;
3531 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3532 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3533 // Only check for data-mapping attribute and is_device_ptr here
3534 // since we have already make sure that the declaration does not
3535 // have a data-sharing attribute above
3536 if (!Stack->checkMappableExprComponentListsForDecl(
3537 VD, /*CurrentRegionOnly=*/true,
3538 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3539 MapExprComponents,
3540 OpenMPClauseKind) {
3541 auto MI = MapExprComponents.rbegin();
3542 auto ME = MapExprComponents.rend();
3543 return MI != ME && MI->getAssociatedDeclaration() == VD;
3544 })) {
3545 VarsWithInheritedDSA[VD] = E;
3546 return;
3547 }
3548 }
3549 }
3550 if (SemaRef.getLangOpts().OpenMP > 50) {
3551 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3552 OMPC_DEFAULTMAP_MODIFIER_present;
3553 if (IsModifierPresent) {
3554 if (llvm::find(ImplicitMapModifier[ClauseKind],
3555 OMPC_MAP_MODIFIER_present) ==
3556 std::end(ImplicitMapModifier[ClauseKind])) {
3557 ImplicitMapModifier[ClauseKind].push_back(
3558 OMPC_MAP_MODIFIER_present);
3559 }
3560 }
3561 }
3562
3563 if (isOpenMPTargetExecutionDirective(DKind) &&
3564 !Stack->isLoopControlVariable(VD).first) {
3565 if (!Stack->checkMappableExprComponentListsForDecl(
3566 VD, /*CurrentRegionOnly=*/true,
3567 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3568 StackComponents,
3569 OpenMPClauseKind) {
3570 if (SemaRef.LangOpts.OpenMP >= 50)
3571 return !StackComponents.empty();
3572 // Variable is used if it has been marked as an array, array
3573 // section, array shaping or the variable iself.
3574 return StackComponents.size() == 1 ||
3575 std::all_of(
3576 std::next(StackComponents.rbegin()),
3577 StackComponents.rend(),
3578 [](const OMPClauseMappableExprCommon::
3579 MappableComponent &MC) {
3580 return MC.getAssociatedDeclaration() ==
3581 nullptr &&
3582 (isa<OMPArraySectionExpr>(
3583 MC.getAssociatedExpression()) ||
3584 isa<OMPArrayShapingExpr>(
3585 MC.getAssociatedExpression()) ||
3586 isa<ArraySubscriptExpr>(
3587 MC.getAssociatedExpression()));
3588 });
3589 })) {
3590 bool IsFirstprivate = false;
3591 // By default lambdas are captured as firstprivates.
3592 if (const auto *RD =
3593 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3594 IsFirstprivate = RD->isLambda();
3595 IsFirstprivate =
3596 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3597 if (IsFirstprivate) {
3598 ImplicitFirstprivate.emplace_back(E);
3599 } else {
3600 OpenMPDefaultmapClauseModifier M =
3601 Stack->getDefaultmapModifier(ClauseKind);
3602 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3603 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3604 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3605 }
3606 return;
3607 }
3608 }
3609
3610 // OpenMP [2.9.3.6, Restrictions, p.2]
3611 // A list item that appears in a reduction clause of the innermost
3612 // enclosing worksharing or parallel construct may not be accessed in an
3613 // explicit task.
3614 DVar = Stack->hasInnermostDSA(
3615 VD,
3616 [](OpenMPClauseKind C, bool AppliedToPointee) {
3617 return C == OMPC_reduction && !AppliedToPointee;
3618 },
3619 [](OpenMPDirectiveKind K) {
3620 return isOpenMPParallelDirective(K) ||
3621 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3622 },
3623 /*FromParent=*/true);
3624 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3625 ErrorFound = true;
3626 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3627 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3628 return;
3629 }
3630
3631 // Define implicit data-sharing attributes for task.
3632 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3633 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3634 (Stack->getDefaultDSA() == DSA_firstprivate &&
3635 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3636 !Stack->isLoopControlVariable(VD).first) {
3637 ImplicitFirstprivate.push_back(E);
3638 return;
3639 }
3640
3641 // Store implicitly used globals with declare target link for parent
3642 // target.
3643 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3644 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3645 Stack->addToParentTargetRegionLinkGlobals(E);
3646 return;
3647 }
3648 }
3649 }
3650 void VisitMemberExpr(MemberExpr *E) {
3651 if (E->isTypeDependent() || E->isValueDependent() ||
3652 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3653 return;
3654 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3655 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3656 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3657 if (!FD)
3658 return;
3659 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3660 // Check if the variable has explicit DSA set and stop analysis if it
3661 // so.
3662 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3663 return;
3664
3665 if (isOpenMPTargetExecutionDirective(DKind) &&
3666 !Stack->isLoopControlVariable(FD).first &&
3667 !Stack->checkMappableExprComponentListsForDecl(
3668 FD, /*CurrentRegionOnly=*/true,
3669 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3670 StackComponents,
3671 OpenMPClauseKind) {
3672 return isa<CXXThisExpr>(
3673 cast<MemberExpr>(
3674 StackComponents.back().getAssociatedExpression())
3675 ->getBase()
3676 ->IgnoreParens());
3677 })) {
3678 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3679 // A bit-field cannot appear in a map clause.
3680 //
3681 if (FD->isBitField())
3682 return;
3683
3684 // Check to see if the member expression is referencing a class that
3685 // has already been explicitly mapped
3686 if (Stack->isClassPreviouslyMapped(TE->getType()))
3687 return;
3688
3689 OpenMPDefaultmapClauseModifier Modifier =
3690 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3691 OpenMPDefaultmapClauseKind ClauseKind =
3692 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3693 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3694 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3695 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3696 return;
3697 }
3698
3699 SourceLocation ELoc = E->getExprLoc();
3700 // OpenMP [2.9.3.6, Restrictions, p.2]
3701 // A list item that appears in a reduction clause of the innermost
3702 // enclosing worksharing or parallel construct may not be accessed in
3703 // an explicit task.
3704 DVar = Stack->hasInnermostDSA(
3705 FD,
3706 [](OpenMPClauseKind C, bool AppliedToPointee) {
3707 return C == OMPC_reduction && !AppliedToPointee;
3708 },
3709 [](OpenMPDirectiveKind K) {
3710 return isOpenMPParallelDirective(K) ||
3711 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3712 },
3713 /*FromParent=*/true);
3714 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3715 ErrorFound = true;
3716 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3717 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3718 return;
3719 }
3720
3721 // Define implicit data-sharing attributes for task.
3722 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3723 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3724 !Stack->isLoopControlVariable(FD).first) {
3725 // Check if there is a captured expression for the current field in the
3726 // region. Do not mark it as firstprivate unless there is no captured
3727 // expression.
3728 // TODO: try to make it firstprivate.
3729 if (DVar.CKind != OMPC_unknown)
3730 ImplicitFirstprivate.push_back(E);
3731 }
3732 return;
3733 }
3734 if (isOpenMPTargetExecutionDirective(DKind)) {
3735 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3736 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3737 Stack->getCurrentDirective(),
3738 /*NoDiagnose=*/true))
3739 return;
3740 const auto *VD = cast<ValueDecl>(
3741 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3742 if (!Stack->checkMappableExprComponentListsForDecl(
3743 VD, /*CurrentRegionOnly=*/true,
3744 [&CurComponents](
3745 OMPClauseMappableExprCommon::MappableExprComponentListRef
3746 StackComponents,
3747 OpenMPClauseKind) {
3748 auto CCI = CurComponents.rbegin();
3749 auto CCE = CurComponents.rend();
3750 for (const auto &SC : llvm::reverse(StackComponents)) {
3751 // Do both expressions have the same kind?
3752 if (CCI->getAssociatedExpression()->getStmtClass() !=
3753 SC.getAssociatedExpression()->getStmtClass())
3754 if (!((isa<OMPArraySectionExpr>(
3755 SC.getAssociatedExpression()) ||
3756 isa<OMPArrayShapingExpr>(
3757 SC.getAssociatedExpression())) &&
3758 isa<ArraySubscriptExpr>(
3759 CCI->getAssociatedExpression())))
3760 return false;
3761
3762 const Decl *CCD = CCI->getAssociatedDeclaration();
3763 const Decl *SCD = SC.getAssociatedDeclaration();
3764 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3765 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3766 if (SCD != CCD)
3767 return false;
3768 std::advance(CCI, 1);
3769 if (CCI == CCE)
3770 break;
3771 }
3772 return true;
3773 })) {
3774 Visit(E->getBase());
3775 }
3776 } else if (!TryCaptureCXXThisMembers) {
3777 Visit(E->getBase());
3778 }
3779 }
3780 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3781 for (OMPClause *C : S->clauses()) {
3782 // Skip analysis of arguments of implicitly defined firstprivate clause
3783 // for task|target directives.
3784 // Skip analysis of arguments of implicitly defined map clause for target
3785 // directives.
3786 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3787 C->isImplicit() &&
3788 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3789 for (Stmt *CC : C->children()) {
3790 if (CC)
3791 Visit(CC);
3792 }
3793 }
3794 }
3795 // Check implicitly captured variables.
3796 VisitSubCaptures(S);
3797 }
3798
3799 void VisitOMPTileDirective(OMPTileDirective *S) {
3800 // #pragma omp tile does not introduce data sharing.
3801 VisitStmt(S);
3802 }
3803
3804 void VisitStmt(Stmt *S) {
3805 for (Stmt *C : S->children()) {
3806 if (C) {
3807 // Check implicitly captured variables in the task-based directives to
3808 // check if they must be firstprivatized.
3809 Visit(C);
3810 }
3811 }
3812 }
3813
3814 void visitSubCaptures(CapturedStmt *S) {
3815 for (const CapturedStmt::Capture &Cap : S->captures()) {
3816 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3817 continue;
3818 VarDecl *VD = Cap.getCapturedVar();
3819 // Do not try to map the variable if it or its sub-component was mapped
3820 // already.
3821 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3822 Stack->checkMappableExprComponentListsForDecl(
3823 VD, /*CurrentRegionOnly=*/true,
3824 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3825 OpenMPClauseKind) { return true; }))
3826 continue;
3827 DeclRefExpr *DRE = buildDeclRefExpr(
3828 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3829 Cap.getLocation(), /*RefersToCapture=*/true);
3830 Visit(DRE);
3831 }
3832 }
3833 bool isErrorFound() const { return ErrorFound; }
3834 ArrayRef<Expr *> getImplicitFirstprivate() const {
3835 return ImplicitFirstprivate;
3836 }
3837 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3838 OpenMPMapClauseKind MK) const {
3839 return ImplicitMap[DK][MK];
3840 }
3841 ArrayRef<OpenMPMapModifierKind>
3842 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3843 return ImplicitMapModifier[Kind];
3844 }
3845 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3846 return VarsWithInheritedDSA;
3847 }
3848
3849 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3850 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3851 // Process declare target link variables for the target directives.
3852 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3853 for (DeclRefExpr *E : Stack->getLinkGlobals())
3854 Visit(E);
3855 }
3856 }
3857};
3858} // namespace
3859
3860void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3861 switch (DKind) {
3862 case OMPD_parallel:
3863 case OMPD_parallel_for:
3864 case OMPD_parallel_for_simd:
3865 case OMPD_parallel_sections:
3866 case OMPD_parallel_master:
3867 case OMPD_teams:
3868 case OMPD_teams_distribute:
3869 case OMPD_teams_distribute_simd: {
3870 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3871 QualType KmpInt32PtrTy =
3872 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3873 Sema::CapturedParamNameType Params[] = {
3874 std::make_pair(".global_tid.", KmpInt32PtrTy),
3875 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3876 std::make_pair(StringRef(), QualType()) // __context with shared vars
3877 };
3878 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3879 Params);
3880 break;
3881 }
3882 case OMPD_target_teams:
3883 case OMPD_target_parallel:
3884 case OMPD_target_parallel_for:
3885 case OMPD_target_parallel_for_simd:
3886 case OMPD_target_teams_distribute:
3887 case OMPD_target_teams_distribute_simd: {
3888 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3889 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3890 QualType KmpInt32PtrTy =
3891 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3892 QualType Args[] = {VoidPtrTy};
3893 FunctionProtoType::ExtProtoInfo EPI;
3894 EPI.Variadic = true;
3895 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3896 Sema::CapturedParamNameType Params[] = {
3897 std::make_pair(".global_tid.", KmpInt32Ty),
3898 std::make_pair(".part_id.", KmpInt32PtrTy),
3899 std::make_pair(".privates.", VoidPtrTy),
3900 std::make_pair(
3901 ".copy_fn.",
3902 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3903 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3904 std::make_pair(StringRef(), QualType()) // __context with shared vars
3905 };
3906 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3907 Params, /*OpenMPCaptureLevel=*/0);
3908 // Mark this captured region as inlined, because we don't use outlined
3909 // function directly.
3910 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3911 AlwaysInlineAttr::CreateImplicit(
3912 Context, {}, AttributeCommonInfo::AS_Keyword,
3913 AlwaysInlineAttr::Keyword_forceinline));
3914 Sema::CapturedParamNameType ParamsTarget[] = {
3915 std::make_pair(StringRef(), QualType()) // __context with shared vars
3916 };
3917 // Start a captured region for 'target' with no implicit parameters.
3918 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3919 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3920 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3921 std::make_pair(".global_tid.", KmpInt32PtrTy),
3922 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3923 std::make_pair(StringRef(), QualType()) // __context with shared vars
3924 };
3925 // Start a captured region for 'teams' or 'parallel'. Both regions have
3926 // the same implicit parameters.
3927 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3928 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3929 break;
3930 }
3931 case OMPD_target:
3932 case OMPD_target_simd: {
3933 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3934 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3935 QualType KmpInt32PtrTy =
3936 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3937 QualType Args[] = {VoidPtrTy};
3938 FunctionProtoType::ExtProtoInfo EPI;
3939 EPI.Variadic = true;
3940 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3941 Sema::CapturedParamNameType Params[] = {
3942 std::make_pair(".global_tid.", KmpInt32Ty),
3943 std::make_pair(".part_id.", KmpInt32PtrTy),
3944 std::make_pair(".privates.", VoidPtrTy),
3945 std::make_pair(
3946 ".copy_fn.",
3947 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3948 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3949 std::make_pair(StringRef(), QualType()) // __context with shared vars
3950 };
3951 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3952 Params, /*OpenMPCaptureLevel=*/0);
3953 // Mark this captured region as inlined, because we don't use outlined
3954 // function directly.
3955 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3956 AlwaysInlineAttr::CreateImplicit(
3957 Context, {}, AttributeCommonInfo::AS_Keyword,
3958 AlwaysInlineAttr::Keyword_forceinline));
3959 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3960 std::make_pair(StringRef(), QualType()),
3961 /*OpenMPCaptureLevel=*/1);
3962 break;
3963 }
3964 case OMPD_atomic:
3965 case OMPD_critical:
3966 case OMPD_section:
3967 case OMPD_master:
3968 case OMPD_tile:
3969 break;
3970 case OMPD_simd:
3971 case OMPD_for:
3972 case OMPD_for_simd:
3973 case OMPD_sections:
3974 case OMPD_single:
3975 case OMPD_taskgroup:
3976 case OMPD_distribute:
3977 case OMPD_distribute_simd:
3978 case OMPD_ordered:
3979 case OMPD_target_data: {
3980 Sema::CapturedParamNameType Params[] = {
3981 std::make_pair(StringRef(), QualType()) // __context with shared vars
3982 };
3983 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3984 Params);
3985 break;
3986 }
3987 case OMPD_task: {
3988 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3989 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3990 QualType KmpInt32PtrTy =
3991 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3992 QualType Args[] = {VoidPtrTy};
3993 FunctionProtoType::ExtProtoInfo EPI;
3994 EPI.Variadic = true;
3995 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3996 Sema::CapturedParamNameType Params[] = {
3997 std::make_pair(".global_tid.", KmpInt32Ty),
3998 std::make_pair(".part_id.", KmpInt32PtrTy),
3999 std::make_pair(".privates.", VoidPtrTy),
4000 std::make_pair(
4001 ".copy_fn.",
4002 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4003 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4004 std::make_pair(StringRef(), QualType()) // __context with shared vars
4005 };
4006 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4007 Params);
4008 // Mark this captured region as inlined, because we don't use outlined
4009 // function directly.
4010 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4011 AlwaysInlineAttr::CreateImplicit(
4012 Context, {}, AttributeCommonInfo::AS_Keyword,
4013 AlwaysInlineAttr::Keyword_forceinline));
4014 break;
4015 }
4016 case OMPD_taskloop:
4017 case OMPD_taskloop_simd:
4018 case OMPD_master_taskloop:
4019 case OMPD_master_taskloop_simd: {
4020 QualType KmpInt32Ty =
4021 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4022 .withConst();
4023 QualType KmpUInt64Ty =
4024 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4025 .withConst();
4026 QualType KmpInt64Ty =
4027 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4028 .withConst();
4029 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4030 QualType KmpInt32PtrTy =
4031 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4032 QualType Args[] = {VoidPtrTy};
4033 FunctionProtoType::ExtProtoInfo EPI;
4034 EPI.Variadic = true;
4035 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4036 Sema::CapturedParamNameType Params[] = {
4037 std::make_pair(".global_tid.", KmpInt32Ty),
4038 std::make_pair(".part_id.", KmpInt32PtrTy),
4039 std::make_pair(".privates.", VoidPtrTy),
4040 std::make_pair(
4041 ".copy_fn.",
4042 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4043 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4044 std::make_pair(".lb.", KmpUInt64Ty),
4045 std::make_pair(".ub.", KmpUInt64Ty),
4046 std::make_pair(".st.", KmpInt64Ty),
4047 std::make_pair(".liter.", KmpInt32Ty),
4048 std::make_pair(".reductions.", VoidPtrTy),
4049 std::make_pair(StringRef(), QualType()) // __context with shared vars
4050 };
4051 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4052 Params);
4053 // Mark this captured region as inlined, because we don't use outlined
4054 // function directly.
4055 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4056 AlwaysInlineAttr::CreateImplicit(
4057 Context, {}, AttributeCommonInfo::AS_Keyword,
4058 AlwaysInlineAttr::Keyword_forceinline));
4059 break;
4060 }
4061 case OMPD_parallel_master_taskloop:
4062 case OMPD_parallel_master_taskloop_simd: {
4063 QualType KmpInt32Ty =
4064 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4065 .withConst();
4066 QualType KmpUInt64Ty =
4067 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4068 .withConst();
4069 QualType KmpInt64Ty =
4070 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4071 .withConst();
4072 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4073 QualType KmpInt32PtrTy =
4074 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4075 Sema::CapturedParamNameType ParamsParallel[] = {
4076 std::make_pair(".global_tid.", KmpInt32PtrTy),
4077 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4078 std::make_pair(StringRef(), QualType()) // __context with shared vars
4079 };
4080 // Start a captured region for 'parallel'.
4081 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4082 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4083 QualType Args[] = {VoidPtrTy};
4084 FunctionProtoType::ExtProtoInfo EPI;
4085 EPI.Variadic = true;
4086 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4087 Sema::CapturedParamNameType Params[] = {
4088 std::make_pair(".global_tid.", KmpInt32Ty),
4089 std::make_pair(".part_id.", KmpInt32PtrTy),
4090 std::make_pair(".privates.", VoidPtrTy),
4091 std::make_pair(
4092 ".copy_fn.",
4093 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4094 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4095 std::make_pair(".lb.", KmpUInt64Ty),
4096 std::make_pair(".ub.", KmpUInt64Ty),
4097 std::make_pair(".st.", KmpInt64Ty),
4098 std::make_pair(".liter.", KmpInt32Ty),
4099 std::make_pair(".reductions.", VoidPtrTy),
4100 std::make_pair(StringRef(), QualType()) // __context with shared vars
4101 };
4102 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4103 Params, /*OpenMPCaptureLevel=*/1);
4104 // Mark this captured region as inlined, because we don't use outlined
4105 // function directly.
4106 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4107 AlwaysInlineAttr::CreateImplicit(
4108 Context, {}, AttributeCommonInfo::AS_Keyword,
4109 AlwaysInlineAttr::Keyword_forceinline));
4110 break;
4111 }
4112 case OMPD_distribute_parallel_for_simd:
4113 case OMPD_distribute_parallel_for: {
4114 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4115 QualType KmpInt32PtrTy =
4116 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4117 Sema::CapturedParamNameType Params[] = {
4118 std::make_pair(".global_tid.", KmpInt32PtrTy),
4119 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4120 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4121 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4122 std::make_pair(StringRef(), QualType()) // __context with shared vars
4123 };
4124 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4125 Params);
4126 break;
4127 }
4128 case OMPD_target_teams_distribute_parallel_for:
4129 case OMPD_target_teams_distribute_parallel_for_simd: {
4130 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4131 QualType KmpInt32PtrTy =
4132 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4133 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4134
4135 QualType Args[] = {VoidPtrTy};
4136 FunctionProtoType::ExtProtoInfo EPI;
4137 EPI.Variadic = true;
4138 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4139 Sema::CapturedParamNameType Params[] = {
4140 std::make_pair(".global_tid.", KmpInt32Ty),
4141 std::make_pair(".part_id.", KmpInt32PtrTy),
4142 std::make_pair(".privates.", VoidPtrTy),
4143 std::make_pair(
4144 ".copy_fn.",
4145 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4146 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4147 std::make_pair(StringRef(), QualType()) // __context with shared vars
4148 };
4149 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4150 Params, /*OpenMPCaptureLevel=*/0);
4151 // Mark this captured region as inlined, because we don't use outlined
4152 // function directly.
4153 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4154 AlwaysInlineAttr::CreateImplicit(
4155 Context, {}, AttributeCommonInfo::AS_Keyword,
4156 AlwaysInlineAttr::Keyword_forceinline));
4157 Sema::CapturedParamNameType ParamsTarget[] = {
4158 std::make_pair(StringRef(), QualType()) // __context with shared vars
4159 };
4160 // Start a captured region for 'target' with no implicit parameters.
4161 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4162 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4163
4164 Sema::CapturedParamNameType ParamsTeams[] = {
4165 std::make_pair(".global_tid.", KmpInt32PtrTy),
4166 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4167 std::make_pair(StringRef(), QualType()) // __context with shared vars
4168 };
4169 // Start a captured region for 'target' with no implicit parameters.
4170 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4171 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4172
4173 Sema::CapturedParamNameType ParamsParallel[] = {
4174 std::make_pair(".global_tid.", KmpInt32PtrTy),
4175 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4176 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4177 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4178 std::make_pair(StringRef(), QualType()) // __context with shared vars
4179 };
4180 // Start a captured region for 'teams' or 'parallel'. Both regions have
4181 // the same implicit parameters.
4182 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4183 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4184 break;
4185 }
4186
4187 case OMPD_teams_distribute_parallel_for:
4188 case OMPD_teams_distribute_parallel_for_simd: {
4189 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4190 QualType KmpInt32PtrTy =
4191 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4192
4193 Sema::CapturedParamNameType ParamsTeams[] = {
4194 std::make_pair(".global_tid.", KmpInt32PtrTy),
4195 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4196 std::make_pair(StringRef(), QualType()) // __context with shared vars
4197 };
4198 // Start a captured region for 'target' with no implicit parameters.
4199 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4200 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4201
4202 Sema::CapturedParamNameType ParamsParallel[] = {
4203 std::make_pair(".global_tid.", KmpInt32PtrTy),
4204 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4205 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4206 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4207 std::make_pair(StringRef(), QualType()) // __context with shared vars
4208 };
4209 // Start a captured region for 'teams' or 'parallel'. Both regions have
4210 // the same implicit parameters.
4211 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4212 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4213 break;
4214 }
4215 case OMPD_target_update:
4216 case OMPD_target_enter_data:
4217 case OMPD_target_exit_data: {
4218 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4219 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4220 QualType KmpInt32PtrTy =
4221 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4222 QualType Args[] = {VoidPtrTy};
4223 FunctionProtoType::ExtProtoInfo EPI;
4224 EPI.Variadic = true;
4225 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4226 Sema::CapturedParamNameType Params[] = {
4227 std::make_pair(".global_tid.", KmpInt32Ty),
4228 std::make_pair(".part_id.", KmpInt32PtrTy),
4229 std::make_pair(".privates.", VoidPtrTy),
4230 std::make_pair(
4231 ".copy_fn.",
4232 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4233 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4234 std::make_pair(StringRef(), QualType()) // __context with shared vars
4235 };
4236 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4237 Params);
4238 // Mark this captured region as inlined, because we don't use outlined
4239 // function directly.
4240 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4241 AlwaysInlineAttr::CreateImplicit(
4242 Context, {}, AttributeCommonInfo::AS_Keyword,
4243 AlwaysInlineAttr::Keyword_forceinline));
4244 break;
4245 }
4246 case OMPD_threadprivate:
4247 case OMPD_allocate:
4248 case OMPD_taskyield:
4249 case OMPD_barrier:
4250 case OMPD_taskwait:
4251 case OMPD_cancellation_point:
4252 case OMPD_cancel:
4253 case OMPD_flush:
4254 case OMPD_depobj:
4255 case OMPD_scan:
4256 case OMPD_declare_reduction:
4257 case OMPD_declare_mapper:
4258 case OMPD_declare_simd:
4259 case OMPD_declare_target:
4260 case OMPD_end_declare_target:
4261 case OMPD_requires:
4262 case OMPD_declare_variant:
4263 case OMPD_begin_declare_variant:
4264 case OMPD_end_declare_variant:
4265 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 4265)
;
4266 case OMPD_unknown:
4267 default:
4268 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 4268)
;
4269 }
4270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setContext(CurContext);
4271}
4272
4273int Sema::getNumberOfConstructScopes(unsigned Level) const {
4274 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4275}
4276
4277int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4278 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4279 getOpenMPCaptureRegions(CaptureRegions, DKind);
4280 return CaptureRegions.size();
4281}
4282
4283static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4284 Expr *CaptureExpr, bool WithInit,
4285 bool AsExpression) {
4286 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 4286, __PRETTY_FUNCTION__))
;
4287 ASTContext &C = S.getASTContext();
4288 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4289 QualType Ty = Init->getType();
4290 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4291 if (S.getLangOpts().CPlusPlus) {
4292 Ty = C.getLValueReferenceType(Ty);
4293 } else {
4294 Ty = C.getPointerType(Ty);
4295 ExprResult Res =
4296 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4297 if (!Res.isUsable())
4298 return nullptr;
4299 Init = Res.get();
4300 }
4301 WithInit = true;
4302 }
4303 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4304 CaptureExpr->getBeginLoc());
4305 if (!WithInit)
4306 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4307 S.CurContext->addHiddenDecl(CED);
4308 Sema::TentativeAnalysisScope Trap(S);
4309 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4310 return CED;
4311}
4312
4313static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4314 bool WithInit) {
4315 OMPCapturedExprDecl *CD;
4316 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4317 CD = cast<OMPCapturedExprDecl>(VD);
4318 else
4319 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4320 /*AsExpression=*/false);
4321 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4322 CaptureExpr->getExprLoc());
4323}
4324
4325static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4326 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4327 if (!Ref) {
4328 OMPCapturedExprDecl *CD = buildCaptureDecl(
4329 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4330 /*WithInit=*/true, /*AsExpression=*/true);
4331 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4332 CaptureExpr->getExprLoc());
4333 }
4334 ExprResult Res = Ref;
4335 if (!S.getLangOpts().CPlusPlus &&
4336 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4337 Ref->getType()->isPointerType()) {
4338 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4339 if (!Res.isUsable())
4340 return ExprError();
4341 }
4342 return S.DefaultLvalueConversion(Res.get());
4343}
4344
4345namespace {
4346// OpenMP directives parsed in this section are represented as a
4347// CapturedStatement with an associated statement. If a syntax error
4348// is detected during the parsing of the associated statement, the
4349// compiler must abort processing and close the CapturedStatement.
4350//
4351// Combined directives such as 'target parallel' have more than one
4352// nested CapturedStatements. This RAII ensures that we unwind out
4353// of all the nested CapturedStatements when an error is found.
4354class CaptureRegionUnwinderRAII {
4355private:
4356 Sema &S;
4357 bool &ErrorFound;
4358 OpenMPDirectiveKind DKind = OMPD_unknown;
4359
4360public:
4361 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4362 OpenMPDirectiveKind DKind)
4363 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4364 ~CaptureRegionUnwinderRAII() {
4365 if (ErrorFound) {
4366 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4367 while (--ThisCaptureLevel >= 0)
4368 S.ActOnCapturedRegionError();
4369 }
4370 }
4371};
4372} // namespace
4373
4374void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4375 // Capture variables captured by reference in lambdas for target-based
4376 // directives.
4377 if (!CurContext->isDependentContext() &&
4378 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4379 isOpenMPTargetDataManagementDirective(
4380 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4381 QualType Type = V->getType();
4382 if (const auto *RD = Type.getCanonicalType()
4383 .getNonReferenceType()
4384 ->getAsCXXRecordDecl()) {
4385 bool SavedForceCaptureByReferenceInTargetExecutable =
4386 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4387 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4388 /*V=*/true);
4389 if (RD->isLambda()) {
4390 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4391 FieldDecl *ThisCapture;
4392 RD->getCaptureFields(Captures, ThisCapture);
4393 for (const LambdaCapture &LC : RD->captures()) {
4394 if (LC.getCaptureKind() == LCK_ByRef) {
4395 VarDecl *VD = LC.getCapturedVar();
4396 DeclContext *VDC = VD->getDeclContext();
4397 if (!VDC->Encloses(CurContext))
4398 continue;
4399 MarkVariableReferenced(LC.getLocation(), VD);
4400 } else if (LC.getCaptureKind() == LCK_This) {
4401 QualType ThisTy = getCurrentThisType();
4402 if (!ThisTy.isNull() &&
4403 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4404 CheckCXXThisCapture(LC.getLocation());
4405 }
4406 }
4407 }
4408 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4409 SavedForceCaptureByReferenceInTargetExecutable);
4410 }
4411 }
4412}
4413
4414static bool checkOrderedOrderSpecified(Sema &S,
4415 const ArrayRef<OMPClause *> Clauses) {
4416 const OMPOrderedClause *Ordered = nullptr;
4417 const OMPOrderClause *Order = nullptr;
4418
4419 for (const OMPClause *Clause : Clauses) {
4420 if (Clause->getClauseKind() == OMPC_ordered)
4421 Ordered = cast<OMPOrderedClause>(Clause);
4422 else if (Clause->getClauseKind() == OMPC_order) {
4423 Order = cast<OMPOrderClause>(Clause);
4424 if (Order->getKind() != OMPC_ORDER_concurrent)
4425 Order = nullptr;
4426 }
4427 if (Ordered && Order)
4428 break;
4429 }
4430
4431 if (Ordered && Order) {
4432 S.Diag(Order->getKindKwLoc(),
4433 diag::err_omp_simple_clause_incompatible_with_ordered)
4434 << getOpenMPClauseName(OMPC_order)
4435 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4436 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4437 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4438 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4439 return true;
4440 }
4441 return false;
4442}
4443
4444StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4445 ArrayRef<OMPClause *> Clauses) {
4446 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4447 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4448 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4449 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master)
4450 return S;
4451
4452 bool ErrorFound = false;
4453 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4454 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4455 if (!S.isUsable()) {
4456 ErrorFound = true;
4457 return StmtError();
4458 }
4459
4460 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4461 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4462 OMPOrderedClause *OC = nullptr;
4463 OMPScheduleClause *SC = nullptr;
4464 SmallVector<const OMPLinearClause *, 4> LCs;
4465 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4466 // This is required for proper codegen.
4467 for (OMPClause *Clause : Clauses) {
4468 if (!LangOpts.OpenMPSimd &&
4469 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4470 Clause->getClauseKind() == OMPC_in_reduction) {
4471 // Capture taskgroup task_reduction descriptors inside the tasking regions
4472 // with the corresponding in_reduction items.
4473 auto *IRC = cast<OMPInReductionClause>(Clause);
4474 for (Expr *E : IRC->taskgroup_descriptors())
4475 if (E)
4476 MarkDeclarationsReferencedInExpr(E);
4477 }
4478 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4479 Clause->getClauseKind() == OMPC_copyprivate ||
4480 (getLangOpts().OpenMPUseTLS &&
4481 getASTContext().getTargetInfo().isTLSSupported() &&
4482 Clause->getClauseKind() == OMPC_copyin)) {
4483 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4484 // Mark all variables in private list clauses as used in inner region.
4485 for (Stmt *VarRef : Clause->children()) {
4486 if (auto *E = cast_or_null<Expr>(VarRef)) {
4487 MarkDeclarationsReferencedInExpr(E);
4488 }
4489 }
4490 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4491 } else if (isOpenMPLoopTransformationDirective(
4492 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4493 assert(CaptureRegions.empty() &&((CaptureRegions.empty() && "No captured regions in loop transformation directives."
) ? static_cast<void> (0) : __assert_fail ("CaptureRegions.empty() && \"No captured regions in loop transformation directives.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 4494, __PRETTY_FUNCTION__))
4494 "No captured regions in loop transformation directives.")((CaptureRegions.empty() && "No captured regions in loop transformation directives."
) ? static_cast<void> (0) : __assert_fail ("CaptureRegions.empty() && \"No captured regions in loop transformation directives.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 4494, __PRETTY_FUNCTION__))
;
4495 } else if (CaptureRegions.size() > 1 ||
4496 CaptureRegions.back() != OMPD_unknown) {
4497 if (auto *C = OMPClauseWithPreInit::get(Clause))
4498 PICs.push_back(C);
4499 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4500 if (Expr *E = C->getPostUpdateExpr())
4501 MarkDeclarationsReferencedInExpr(E);
4502 }
4503 }
4504 if (Clause->getClauseKind() == OMPC_schedule)
4505 SC = cast<OMPScheduleClause>(Clause);
4506 else if (Clause->getClauseKind() == OMPC_ordered)
4507 OC = cast<OMPOrderedClause>(Clause);
4508 else if (Clause->getClauseKind() == OMPC_linear)
4509 LCs.push_back(cast<OMPLinearClause>(Clause));
4510 }
4511 // Capture allocator expressions if used.
4512 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4513 MarkDeclarationsReferencedInExpr(E);
4514 // OpenMP, 2.7.1 Loop Construct, Restrictions
4515 // The nonmonotonic modifier cannot be specified if an ordered clause is
4516 // specified.
4517 if (SC &&
4518 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4519 SC->getSecondScheduleModifier() ==
4520 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4521 OC) {
4522 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4523 ? SC->getFirstScheduleModifierLoc()
4524 : SC->getSecondScheduleModifierLoc(),
4525 diag::err_omp_simple_clause_incompatible_with_ordered)
4526 << getOpenMPClauseName(OMPC_schedule)
4527 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4528 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4529 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4530 ErrorFound = true;
4531 }
4532 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4533 // If an order(concurrent) clause is present, an ordered clause may not appear
4534 // on the same directive.
4535 if (checkOrderedOrderSpecified(*this, Clauses))
4536 ErrorFound = true;
4537 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4538 for (const OMPLinearClause *C : LCs) {
4539 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4540 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4541 }
4542 ErrorFound = true;
4543 }
4544 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4545 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4546 OC->getNumForLoops()) {
4547 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4548 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4549 ErrorFound = true;
4550 }
4551 if (ErrorFound) {
4552 return StmtError();
4553 }
4554 StmtResult SR = S;
4555 unsigned CompletedRegions = 0;
4556 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4557 // Mark all variables in private list clauses as used in inner region.
4558 // Required for proper codegen of combined directives.
4559 // TODO: add processing for other clauses.
4560 if (ThisCaptureRegion != OMPD_unknown) {
4561 for (const clang::OMPClauseWithPreInit *C : PICs) {
4562 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4563 // Find the particular capture region for the clause if the
4564 // directive is a combined one with multiple capture regions.
4565 // If the directive is not a combined one, the capture region
4566 // associated with the clause is OMPD_unknown and is generated
4567 // only once.
4568 if (CaptureRegion == ThisCaptureRegion ||
4569 CaptureRegion == OMPD_unknown) {
4570 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4571 for (Decl *D : DS->decls())
4572 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4573 }
4574 }
4575 }
4576 }
4577 if (ThisCaptureRegion == OMPD_target) {
4578 // Capture allocator traits in the target region. They are used implicitly
4579 // and, thus, are not captured by default.
4580 for (OMPClause *C : Clauses) {
4581 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4582 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4583 ++I) {
4584 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4585 if (Expr *E = D.AllocatorTraits)
4586 MarkDeclarationsReferencedInExpr(E);
4587 }
4588 continue;
4589 }
4590 }
4591 }
4592 if (++CompletedRegions == CaptureRegions.size())
4593 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4594 SR = ActOnCapturedRegionEnd(SR.get());
4595 }
4596 return SR;
4597}
4598
4599static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4600 OpenMPDirectiveKind CancelRegion,
4601 SourceLocation StartLoc) {
4602 // CancelRegion is only needed for cancel and cancellation_point.
4603 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4604 return false;
4605
4606 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4607 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4608 return false;
4609
4610 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4611 << getOpenMPDirectiveName(CancelRegion);
4612 return true;
4613}
4614
4615static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4616 OpenMPDirectiveKind CurrentRegion,
4617 const DeclarationNameInfo &CurrentName,
4618 OpenMPDirectiveKind CancelRegion,
4619 SourceLocation StartLoc) {
4620 if (Stack->getCurScope()) {
4621 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4622 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4623 bool NestingProhibited = false;
4624 bool CloseNesting = true;
4625 bool OrphanSeen = false;
4626 enum {
4627 NoRecommend,
4628 ShouldBeInParallelRegion,
4629 ShouldBeInOrderedRegion,
4630 ShouldBeInTargetRegion,
4631 ShouldBeInTeamsRegion,
4632 ShouldBeInLoopSimdRegion,
4633 } Recommend = NoRecommend;
4634 if (isOpenMPSimdDirective(ParentRegion) &&
4635 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4636 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4637 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4638 CurrentRegion != OMPD_scan))) {
4639 // OpenMP [2.16, Nesting of Regions]
4640 // OpenMP constructs may not be nested inside a simd region.
4641 // OpenMP [2.8.1,simd Construct, Restrictions]
4642 // An ordered construct with the simd clause is the only OpenMP
4643 // construct that can appear in the simd region.
4644 // Allowing a SIMD construct nested in another SIMD construct is an
4645 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4646 // message.
4647 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4648 // The only OpenMP constructs that can be encountered during execution of
4649 // a simd region are the atomic construct, the loop construct, the simd
4650 // construct and the ordered construct with the simd clause.
4651 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4652 ? diag::err_omp_prohibited_region_simd
4653 : diag::warn_omp_nesting_simd)
4654 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4655 return CurrentRegion != OMPD_simd;
4656 }
4657 if (ParentRegion == OMPD_atomic) {
4658 // OpenMP [2.16, Nesting of Regions]
4659 // OpenMP constructs may not be nested inside an atomic region.
4660 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4661 return true;
4662 }
4663 if (CurrentRegion == OMPD_section) {
4664 // OpenMP [2.7.2, sections Construct, Restrictions]
4665 // Orphaned section directives are prohibited. That is, the section
4666 // directives must appear within the sections construct and must not be
4667 // encountered elsewhere in the sections region.
4668 if (ParentRegion != OMPD_sections &&
4669 ParentRegion != OMPD_parallel_sections) {
4670 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4671 << (ParentRegion != OMPD_unknown)
4672 << getOpenMPDirectiveName(ParentRegion);
4673 return true;
4674 }
4675 return false;
4676 }
4677 // Allow some constructs (except teams and cancellation constructs) to be
4678 // orphaned (they could be used in functions, called from OpenMP regions
4679 // with the required preconditions).
4680 if (ParentRegion == OMPD_unknown &&
4681 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4682 CurrentRegion != OMPD_cancellation_point &&
4683 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4684 return false;
4685 if (CurrentRegion == OMPD_cancellation_point ||
4686 CurrentRegion == OMPD_cancel) {
4687 // OpenMP [2.16, Nesting of Regions]
4688 // A cancellation point construct for which construct-type-clause is
4689 // taskgroup must be nested inside a task construct. A cancellation
4690 // point construct for which construct-type-clause is not taskgroup must
4691 // be closely nested inside an OpenMP construct that matches the type
4692 // specified in construct-type-clause.
4693 // A cancel construct for which construct-type-clause is taskgroup must be
4694 // nested inside a task construct. A cancel construct for which
4695 // construct-type-clause is not taskgroup must be closely nested inside an
4696 // OpenMP construct that matches the type specified in
4697 // construct-type-clause.
4698 NestingProhibited =
4699 !((CancelRegion == OMPD_parallel &&
4700 (ParentRegion == OMPD_parallel ||
4701 ParentRegion == OMPD_target_parallel)) ||
4702 (CancelRegion == OMPD_for &&
4703 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4704 ParentRegion == OMPD_target_parallel_for ||
4705 ParentRegion == OMPD_distribute_parallel_for ||
4706 ParentRegion == OMPD_teams_distribute_parallel_for ||
4707 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4708 (CancelRegion == OMPD_taskgroup &&
4709 (ParentRegion == OMPD_task ||
4710 (SemaRef.getLangOpts().OpenMP >= 50 &&
4711 (ParentRegion == OMPD_taskloop ||
4712 ParentRegion == OMPD_master_taskloop ||
4713 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4714 (CancelRegion == OMPD_sections &&
4715 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4716 ParentRegion == OMPD_parallel_sections)));
4717 OrphanSeen = ParentRegion == OMPD_unknown;
4718 } else if (CurrentRegion == OMPD_master) {
4719 // OpenMP [2.16, Nesting of Regions]
4720 // A master region may not be closely nested inside a worksharing,
4721 // atomic, or explicit task region.
4722 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4723 isOpenMPTaskingDirective(ParentRegion);
4724 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4725 // OpenMP [2.16, Nesting of Regions]
4726 // A critical region may not be nested (closely or otherwise) inside a
4727 // critical region with the same name. Note that this restriction is not
4728 // sufficient to prevent deadlock.
4729 SourceLocation PreviousCriticalLoc;
4730 bool DeadLock = Stack->hasDirective(
4731 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4732 const DeclarationNameInfo &DNI,
4733 SourceLocation Loc) {
4734 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4735 PreviousCriticalLoc = Loc;
4736 return true;
4737 }
4738 return false;
4739 },
4740 false /* skip top directive */);
4741 if (DeadLock) {
4742 SemaRef.Diag(StartLoc,
4743 diag::err_omp_prohibited_region_critical_same_name)
4744 << CurrentName.getName();
4745 if (PreviousCriticalLoc.isValid())
4746 SemaRef.Diag(PreviousCriticalLoc,
4747 diag::note_omp_previous_critical_region);
4748 return true;
4749 }
4750 } else if (CurrentRegion == OMPD_barrier) {
4751 // OpenMP [2.16, Nesting of Regions]
4752 // A barrier region may not be closely nested inside a worksharing,
4753 // explicit task, critical, ordered, atomic, or master region.
4754 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4755 isOpenMPTaskingDirective(ParentRegion) ||
4756 ParentRegion == OMPD_master ||
4757 ParentRegion == OMPD_parallel_master ||
4758 ParentRegion == OMPD_critical ||
4759 ParentRegion == OMPD_ordered;
4760 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4761 !isOpenMPParallelDirective(CurrentRegion) &&
4762 !isOpenMPTeamsDirective(CurrentRegion)) {
4763 // OpenMP [2.16, Nesting of Regions]
4764 // A worksharing region may not be closely nested inside a worksharing,
4765 // explicit task, critical, ordered, atomic, or master region.
4766 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4767 isOpenMPTaskingDirective(ParentRegion) ||
4768 ParentRegion == OMPD_master ||
4769 ParentRegion == OMPD_parallel_master ||
4770 ParentRegion == OMPD_critical ||
4771 ParentRegion == OMPD_ordered;
4772 Recommend = ShouldBeInParallelRegion;
4773 } else if (CurrentRegion == OMPD_ordered) {
4774 // OpenMP [2.16, Nesting of Regions]
4775 // An ordered region may not be closely nested inside a critical,
4776 // atomic, or explicit task region.
4777 // An ordered region must be closely nested inside a loop region (or
4778 // parallel loop region) with an ordered clause.
4779 // OpenMP [2.8.1,simd Construct, Restrictions]
4780 // An ordered construct with the simd clause is the only OpenMP construct
4781 // that can appear in the simd region.
4782 NestingProhibited = ParentRegion == OMPD_critical ||
4783 isOpenMPTaskingDirective(ParentRegion) ||
4784 !(isOpenMPSimdDirective(ParentRegion) ||
4785 Stack->isParentOrderedRegion());
4786 Recommend = ShouldBeInOrderedRegion;
4787 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4788 // OpenMP [2.16, Nesting of Regions]
4789 // If specified, a teams construct must be contained within a target
4790 // construct.
4791 NestingProhibited =
4792 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4793 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4794 ParentRegion != OMPD_target);
4795 OrphanSeen = ParentRegion == OMPD_unknown;
4796 Recommend = ShouldBeInTargetRegion;
4797 } else if (CurrentRegion == OMPD_scan) {
4798 // OpenMP [2.16, Nesting of Regions]
4799 // If specified, a teams construct must be contained within a target
4800 // construct.
4801 NestingProhibited =
4802 SemaRef.LangOpts.OpenMP < 50 ||
4803 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4804 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4805 ParentRegion != OMPD_parallel_for_simd);
4806 OrphanSeen = ParentRegion == OMPD_unknown;
4807 Recommend = ShouldBeInLoopSimdRegion;
4808 }
4809 if (!NestingProhibited &&
4810 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4811 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4812 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4813 // OpenMP [2.16, Nesting of Regions]
4814 // distribute, parallel, parallel sections, parallel workshare, and the
4815 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4816 // constructs that can be closely nested in the teams region.
4817 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4818 !isOpenMPDistributeDirective(CurrentRegion);
4819 Recommend = ShouldBeInParallelRegion;
4820 }
4821 if (!NestingProhibited &&
4822 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4823 // OpenMP 4.5 [2.17 Nesting of Regions]
4824 // The region associated with the distribute construct must be strictly
4825 // nested inside a teams region
4826 NestingProhibited =
4827 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4828 Recommend = ShouldBeInTeamsRegion;
4829 }
4830 if (!NestingProhibited &&
4831 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4832 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4833 // OpenMP 4.5 [2.17 Nesting of Regions]
4834 // If a target, target update, target data, target enter data, or
4835 // target exit data construct is encountered during execution of a
4836 // target region, the behavior is unspecified.
4837 NestingProhibited = Stack->hasDirective(
4838 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4839 SourceLocation) {
4840 if (isOpenMPTargetExecutionDirective(K)) {
4841 OffendingRegion = K;
4842 return true;
4843 }
4844 return false;
4845 },
4846 false /* don't skip top directive */);
4847 CloseNesting = false;
4848 }
4849 if (NestingProhibited) {
4850 if (OrphanSeen) {
4851 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4852 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4853 } else {
4854 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4855 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4856 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4857 }
4858 return true;
4859 }
4860 }
4861 return false;
4862}
4863
4864struct Kind2Unsigned {
4865 using argument_type = OpenMPDirectiveKind;
4866 unsigned operator()(argument_type DK) { return unsigned(DK); }
4867};
4868static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4869 ArrayRef<OMPClause *> Clauses,
4870 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4871 bool ErrorFound = false;
4872 unsigned NamedModifiersNumber = 0;
4873 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4874 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4875 SmallVector<SourceLocation, 4> NameModifierLoc;
4876 for (const OMPClause *C : Clauses) {
4877 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4878 // At most one if clause without a directive-name-modifier can appear on
4879 // the directive.
4880 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4881 if (FoundNameModifiers[CurNM]) {
4882 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4883 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4884 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4885 ErrorFound = true;
4886 } else if (CurNM != OMPD_unknown) {
4887 NameModifierLoc.push_back(IC->getNameModifierLoc());
4888 ++NamedModifiersNumber;
4889 }
4890 FoundNameModifiers[CurNM] = IC;
4891 if (CurNM == OMPD_unknown)
4892 continue;
4893 // Check if the specified name modifier is allowed for the current
4894 // directive.
4895 // At most one if clause with the particular directive-name-modifier can
4896 // appear on the directive.
4897 bool MatchFound = false;
4898 for (auto NM : AllowedNameModifiers) {
4899 if (CurNM == NM) {
4900 MatchFound = true;
4901 break;
4902 }
4903 }
4904 if (!MatchFound) {
4905 S.Diag(IC->getNameModifierLoc(),
4906 diag::err_omp_wrong_if_directive_name_modifier)
4907 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4908 ErrorFound = true;
4909 }
4910 }
4911 }
4912 // If any if clause on the directive includes a directive-name-modifier then
4913 // all if clauses on the directive must include a directive-name-modifier.
4914 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4915 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4916 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4917 diag::err_omp_no_more_if_clause);
4918 } else {
4919 std::string Values;
4920 std::string Sep(", ");
4921 unsigned AllowedCnt = 0;
4922 unsigned TotalAllowedNum =
4923 AllowedNameModifiers.size() - NamedModifiersNumber;
4924 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4925 ++Cnt) {
4926 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4927 if (!FoundNameModifiers[NM]) {
4928 Values += "'";
4929 Values += getOpenMPDirectiveName(NM);
4930 Values += "'";
4931 if (AllowedCnt + 2 == TotalAllowedNum)
4932 Values += " or ";
4933 else if (AllowedCnt + 1 != TotalAllowedNum)
4934 Values += Sep;
4935 ++AllowedCnt;
4936 }
4937 }
4938 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4939 diag::err_omp_unnamed_if_clause)
4940 << (TotalAllowedNum > 1) << Values;
4941 }
4942 for (SourceLocation Loc : NameModifierLoc) {
4943 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4944 }
4945 ErrorFound = true;
4946 }
4947 return ErrorFound;
4948}
4949
4950static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4951 SourceLocation &ELoc,
4952 SourceRange &ERange,
4953 bool AllowArraySection) {
4954 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4955 RefExpr->containsUnexpandedParameterPack())
4956 return std::make_pair(nullptr, true);
4957
4958 // OpenMP [3.1, C/C++]
4959 // A list item is a variable name.
4960 // OpenMP [2.9.3.3, Restrictions, p.1]
4961 // A variable that is part of another variable (as an array or
4962 // structure element) cannot appear in a private clause.
4963 RefExpr = RefExpr->IgnoreParens();
4964 enum {
4965 NoArrayExpr = -1,
4966 ArraySubscript = 0,
4967 OMPArraySection = 1
4968 } IsArrayExpr = NoArrayExpr;
4969 if (AllowArraySection) {
4970 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4971 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4972 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4973 Base = TempASE->getBase()->IgnoreParenImpCasts();
4974 RefExpr = Base;
4975 IsArrayExpr = ArraySubscript;
4976 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4977 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4978 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4979 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4980 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4981 Base = TempASE->getBase()->IgnoreParenImpCasts();
4982 RefExpr = Base;
4983 IsArrayExpr = OMPArraySection;
4984 }
4985 }
4986 ELoc = RefExpr->getExprLoc();
4987 ERange = RefExpr->getSourceRange();
4988 RefExpr = RefExpr->IgnoreParenImpCasts();
4989 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4990 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4991 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4992 (S.getCurrentThisType().isNull() || !ME ||
4993 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4994 !isa<FieldDecl>(ME->getMemberDecl()))) {
4995 if (IsArrayExpr != NoArrayExpr) {
4996 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4997 << ERange;
4998 } else {
4999 S.Diag(ELoc,
5000 AllowArraySection
5001 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5002 : diag::err_omp_expected_var_name_member_expr)
5003 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5004 }
5005 return std::make_pair(nullptr, false);
5006 }
5007 return std::make_pair(
5008 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5009}
5010
5011namespace {
5012/// Checks if the allocator is used in uses_allocators clause to be allowed in
5013/// target regions.
5014class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5015 DSAStackTy *S = nullptr;
5016
5017public:
5018 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5019 return S->isUsesAllocatorsDecl(E->getDecl())
5020 .getValueOr(
5021 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5022 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5023 }
5024 bool VisitStmt(const Stmt *S) {
5025 for (const Stmt *Child : S->children()) {
5026 if (Child && Visit(Child))
5027 return true;
5028 }
5029 return false;
5030 }
5031 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5032};
5033} // namespace
5034
5035static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5036 ArrayRef<OMPClause *> Clauses) {
5037 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5038, __PRETTY_FUNCTION__))
5038 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5038, __PRETTY_FUNCTION__))
;
5039 auto AllocateRange =
5040 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5041 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5042 DeclToCopy;
5043 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5044 return isOpenMPPrivate(C->getClauseKind());
5045 });
5046 for (OMPClause *Cl : PrivateRange) {
5047 MutableArrayRef<Expr *>::iterator I, It, Et;
5048 if (Cl->getClauseKind() == OMPC_private) {
5049 auto *PC = cast<OMPPrivateClause>(Cl);
5050 I = PC->private_copies().begin();
5051 It = PC->varlist_begin();
5052 Et = PC->varlist_end();
5053 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5054 auto *PC = cast<OMPFirstprivateClause>(Cl);
5055 I = PC->private_copies().begin();
5056 It = PC->varlist_begin();
5057 Et = PC->varlist_end();
5058 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5059 auto *PC = cast<OMPLastprivateClause>(Cl);
5060 I = PC->private_copies().begin();
5061 It = PC->varlist_begin();
5062 Et = PC->varlist_end();
5063 } else if (Cl->getClauseKind() == OMPC_linear) {
5064 auto *PC = cast<OMPLinearClause>(Cl);
5065 I = PC->privates().begin();
5066 It = PC->varlist_begin();
5067 Et = PC->varlist_end();
5068 } else if (Cl->getClauseKind() == OMPC_reduction) {
5069 auto *PC = cast<OMPReductionClause>(Cl);
5070 I = PC->privates().begin();
5071 It = PC->varlist_begin();
5072 Et = PC->varlist_end();
5073 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5074 auto *PC = cast<OMPTaskReductionClause>(Cl);
5075 I = PC->privates().begin();
5076 It = PC->varlist_begin();
5077 Et = PC->varlist_end();
5078 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5079 auto *PC = cast<OMPInReductionClause>(Cl);
5080 I = PC->privates().begin();
5081 It = PC->varlist_begin();
5082 Et = PC->varlist_end();
5083 } else {
5084 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5084)
;
5085 }
5086 for (Expr *E : llvm::make_range(It, Et)) {
5087 if (!*I) {
5088 ++I;
5089 continue;
5090 }
5091 SourceLocation ELoc;
5092 SourceRange ERange;
5093 Expr *SimpleRefExpr = E;
5094 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5095 /*AllowArraySection=*/true);
5096 DeclToCopy.try_emplace(Res.first,
5097 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5098 ++I;
5099 }
5100 }
5101 for (OMPClause *C : AllocateRange) {
5102 auto *AC = cast<OMPAllocateClause>(C);
5103 if (S.getLangOpts().OpenMP >= 50 &&
5104 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5105 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5106 AC->getAllocator()) {
5107 Expr *Allocator = AC->getAllocator();
5108 // OpenMP, 2.12.5 target Construct
5109 // Memory allocators that do not appear in a uses_allocators clause cannot
5110 // appear as an allocator in an allocate clause or be used in the target
5111 // region unless a requires directive with the dynamic_allocators clause
5112 // is present in the same compilation unit.
5113 AllocatorChecker Checker(Stack);
5114 if (Checker.Visit(Allocator))
5115 S.Diag(Allocator->getExprLoc(),
5116 diag::err_omp_allocator_not_in_uses_allocators)
5117 << Allocator->getSourceRange();
5118 }
5119 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5120 getAllocatorKind(S, Stack, AC->getAllocator());
5121 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5122 // For task, taskloop or target directives, allocation requests to memory
5123 // allocators with the trait access set to thread result in unspecified
5124 // behavior.
5125 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5126 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5127 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5128 S.Diag(AC->getAllocator()->getExprLoc(),
5129 diag::warn_omp_allocate_thread_on_task_target_directive)
5130 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5131 }
5132 for (Expr *E : AC->varlists()) {
5133 SourceLocation ELoc;
5134 SourceRange ERange;
5135 Expr *SimpleRefExpr = E;
5136 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5137 ValueDecl *VD = Res.first;
5138 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5139 if (!isOpenMPPrivate(Data.CKind)) {
5140 S.Diag(E->getExprLoc(),
5141 diag::err_omp_expected_private_copy_for_allocate);
5142 continue;
5143 }
5144 VarDecl *PrivateVD = DeclToCopy[VD];
5145 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5146 AllocatorKind, AC->getAllocator()))
5147 continue;
5148 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5149 E->getSourceRange());
5150 }
5151 }
5152}
5153
5154static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5155 CXXScopeSpec &MapperIdScopeSpec,
5156 const DeclarationNameInfo &MapperId,
5157 QualType Type,
5158 Expr *UnresolvedMapper);
5159
5160/// Perform DFS through the structure/class data members trying to find
5161/// member(s) with user-defined 'default' mapper and generate implicit map
5162/// clauses for such members with the found 'default' mapper.
5163static void
5164processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5165 SmallVectorImpl<OMPClause *> &Clauses) {
5166 // Check for the deault mapper for data members.
5167 if (S.getLangOpts().OpenMP < 50)
5168 return;
5169 SmallVector<OMPClause *, 4> ImplicitMaps;
5170 DeclarationNameInfo DefaultMapperId;
5171 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5172 &S.Context.Idents.get("default")));
5173 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5174 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5175 if (!C)
5176 continue;
5177 SmallVector<Expr *, 4> SubExprs;
5178 auto *MI = C->mapperlist_begin();
5179 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5180 ++I, ++MI) {
5181 // Expression is mapped using mapper - skip it.
5182 if (*MI)
5183 continue;
5184 Expr *E = *I;
5185 // Expression is dependent - skip it, build the mapper when it gets
5186 // instantiated.
5187 if (E->isTypeDependent() || E->isValueDependent() ||
5188 E->containsUnexpandedParameterPack())
5189 continue;
5190 // Array section - need to check for the mapping of the array section
5191 // element.
5192 QualType CanonType = E->getType().getCanonicalType();
5193 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5194 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5195 QualType BaseType =
5196 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5197 QualType ElemType;
5198 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5199 ElemType = ATy->getElementType();
5200 else
5201 ElemType = BaseType->getPointeeType();
5202 CanonType = ElemType;
5203 }
5204
5205 // DFS over data members in structures/classes.
5206 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5207 1, {CanonType, nullptr});
5208 llvm::DenseMap<const Type *, Expr *> Visited;
5209 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5210 1, {nullptr, 1});
5211 while (!Types.empty()) {
5212 QualType BaseType;
5213 FieldDecl *CurFD;
5214 std::tie(BaseType, CurFD) = Types.pop_back_val();
5215 while (ParentChain.back().second == 0)
5216 ParentChain.pop_back();
5217 --ParentChain.back().second;
5218 if (BaseType.isNull())
5219 continue;
5220 // Only structs/classes are allowed to have mappers.
5221 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5222 if (!RD)
5223 continue;
5224 auto It = Visited.find(BaseType.getTypePtr());
5225 if (It == Visited.end()) {
5226 // Try to find the associated user-defined mapper.
5227 CXXScopeSpec MapperIdScopeSpec;
5228 ExprResult ER = buildUserDefinedMapperRef(
5229 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5230 BaseType, /*UnresolvedMapper=*/nullptr);
5231 if (ER.isInvalid())
5232 continue;
5233 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5234 }
5235 // Found default mapper.
5236 if (It->second) {
5237 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5238 VK_LValue, OK_Ordinary, E);
5239 OE->setIsUnique(/*V=*/true);
5240 Expr *BaseExpr = OE;
5241 for (const auto &P : ParentChain) {
5242 if (P.first) {
5243 BaseExpr = S.BuildMemberExpr(
5244 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5245 NestedNameSpecifierLoc(), SourceLocation(), P.first,
5246 DeclAccessPair::make(P.first, P.first->getAccess()),
5247 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5248 P.first->getType(), VK_LValue, OK_Ordinary);
5249 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5250 }
5251 }
5252 if (CurFD)
5253 BaseExpr = S.BuildMemberExpr(
5254 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5255 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5256 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5257 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5258 CurFD->getType(), VK_LValue, OK_Ordinary);
5259 SubExprs.push_back(BaseExpr);
5260 continue;
5261 }
5262 // Check for the "default" mapper for data memebers.
5263 bool FirstIter = true;
5264 for (FieldDecl *FD : RD->fields()) {
5265 if (!FD)
5266 continue;
5267 QualType FieldTy = FD->getType();
5268 if (FieldTy.isNull() ||
5269 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5270 continue;
5271 if (FirstIter) {
5272 FirstIter = false;
5273 ParentChain.emplace_back(CurFD, 1);
5274 } else {
5275 ++ParentChain.back().second;
5276 }
5277 Types.emplace_back(FieldTy, FD);
5278 }
5279 }
5280 }
5281 if (SubExprs.empty())
5282 continue;
5283 CXXScopeSpec MapperIdScopeSpec;
5284 DeclarationNameInfo MapperId;
5285 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5286 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5287 MapperIdScopeSpec, MapperId, C->getMapType(),
5288 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5289 SubExprs, OMPVarListLocTy()))
5290 Clauses.push_back(NewClause);
5291 }
5292}
5293
5294StmtResult Sema::ActOnOpenMPExecutableDirective(
5295 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5296 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5297 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5298 StmtResult Res = StmtError();
5299 // First check CancelRegion which is then used in checkNestingOfRegions.
5300 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5301 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5302 StartLoc))
5303 return StmtError();
5304
5305 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5306 VarsWithInheritedDSAType VarsWithInheritedDSA;
5307 bool ErrorFound = false;
5308 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5309 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5310 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5311 !isOpenMPLoopTransformationDirective(Kind)) {
5312 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5312, __PRETTY_FUNCTION__))
;
5313
5314 // Check default data sharing attributes for referenced variables.
5315 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5316 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5317 Stmt *S = AStmt;
5318 while (--ThisCaptureLevel >= 0)
5319 S = cast<CapturedStmt>(S)->getCapturedStmt();
5320 DSAChecker.Visit(S);
5321 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5322 !isOpenMPTaskingDirective(Kind)) {
5323 // Visit subcaptures to generate implicit clauses for captured vars.
5324 auto *CS = cast<CapturedStmt>(AStmt);
5325 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5326 getOpenMPCaptureRegions(CaptureRegions, Kind);
5327 // Ignore outer tasking regions for target directives.
5328 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5329 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5330 DSAChecker.visitSubCaptures(CS);
5331 }
5332 if (DSAChecker.isErrorFound())
5333 return StmtError();
5334 // Generate list of implicitly defined firstprivate variables.
5335 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5336
5337 SmallVector<Expr *, 4> ImplicitFirstprivates(
5338 DSAChecker.getImplicitFirstprivate().begin(),
5339 DSAChecker.getImplicitFirstprivate().end());
5340 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5341 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5342 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5343 ImplicitMapModifiers[DefaultmapKindNum];
5344 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5345 ImplicitMapModifiersLoc[DefaultmapKindNum];
5346 // Get the original location of present modifier from Defaultmap clause.
5347 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5348 for (OMPClause *C : Clauses) {
5349 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5350 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5351 PresentModifierLocs[DMC->getDefaultmapKind()] =
5352 DMC->getDefaultmapModifierLoc();
5353 }
5354 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5355 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5356 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5357 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5358 Kind, static_cast<OpenMPMapClauseKind>(I));
5359 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5360 }
5361 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5362 DSAChecker.getImplicitMapModifier(Kind);
5363 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5364 ImplicitModifier.end());
5365 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5366 ImplicitModifier.size(), PresentModifierLocs[VC]);
5367 }
5368 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5369 for (OMPClause *C : Clauses) {
5370 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5371 for (Expr *E : IRC->taskgroup_descriptors())
5372 if (E)
5373 ImplicitFirstprivates.emplace_back(E);
5374 }
5375 // OpenMP 5.0, 2.10.1 task Construct
5376 // [detach clause]... The event-handle will be considered as if it was
5377 // specified on a firstprivate clause.
5378 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5379 ImplicitFirstprivates.push_back(DC->getEventHandler());
5380 }
5381 if (!ImplicitFirstprivates.empty()) {
5382 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5383 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5384 SourceLocation())) {
5385 ClausesWithImplicit.push_back(Implicit);
5386 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5387 ImplicitFirstprivates.size();
5388 } else {
5389 ErrorFound = true;
5390 }
5391 }
5392 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5393 int ClauseKindCnt = -1;
5394 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5395 ++ClauseKindCnt;
5396 if (ImplicitMap.empty())
5397 continue;
5398 CXXScopeSpec MapperIdScopeSpec;
5399 DeclarationNameInfo MapperId;
5400 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5401 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5402 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5403 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5404 SourceLocation(), SourceLocation(), ImplicitMap,
5405 OMPVarListLocTy())) {
5406 ClausesWithImplicit.emplace_back(Implicit);
5407 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5408 ImplicitMap.size();
5409 } else {
5410 ErrorFound = true;
5411 }
5412 }
5413 }
5414 // Build expressions for implicit maps of data members with 'default'
5415 // mappers.
5416 if (LangOpts.OpenMP >= 50)
5417 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5418 ClausesWithImplicit);
5419 }
5420
5421 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5422 switch (Kind) {
5423 case OMPD_parallel:
5424 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5425 EndLoc);
5426 AllowedNameModifiers.push_back(OMPD_parallel);
5427 break;
5428 case OMPD_simd:
5429 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5430 VarsWithInheritedDSA);
5431 if (LangOpts.OpenMP >= 50)
5432 AllowedNameModifiers.push_back(OMPD_simd);
5433 break;
5434 case OMPD_tile:
5435 Res =
5436 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5437 break;
5438 case OMPD_for:
5439 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5440 VarsWithInheritedDSA);
5441 break;
5442 case OMPD_for_simd:
5443 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5444 EndLoc, VarsWithInheritedDSA);
5445 if (LangOpts.OpenMP >= 50)
5446 AllowedNameModifiers.push_back(OMPD_simd);
5447 break;
5448 case OMPD_sections:
5449 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5450 EndLoc);
5451 break;
5452 case OMPD_section:
5453 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5454, __PRETTY_FUNCTION__))
5454 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5454, __PRETTY_FUNCTION__))
;
5455 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5456 break;
5457 case OMPD_single:
5458 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5459 EndLoc);
5460 break;
5461 case OMPD_master:
5462 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5463, __PRETTY_FUNCTION__))
5463 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5463, __PRETTY_FUNCTION__))
;
5464 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5465 break;
5466 case OMPD_critical:
5467 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5468 StartLoc, EndLoc);
5469 break;
5470 case OMPD_parallel_for:
5471 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5472 EndLoc, VarsWithInheritedDSA);
5473 AllowedNameModifiers.push_back(OMPD_parallel);
5474 break;
5475 case OMPD_parallel_for_simd:
5476 Res = ActOnOpenMPParallelForSimdDirective(
5477 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5478 AllowedNameModifiers.push_back(OMPD_parallel);
5479 if (LangOpts.OpenMP >= 50)
5480 AllowedNameModifiers.push_back(OMPD_simd);
5481 break;
5482 case OMPD_parallel_master:
5483 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5484 StartLoc, EndLoc);
5485 AllowedNameModifiers.push_back(OMPD_parallel);
5486 break;
5487 case OMPD_parallel_sections:
5488 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5489 StartLoc, EndLoc);
5490 AllowedNameModifiers.push_back(OMPD_parallel);
5491 break;
5492 case OMPD_task:
5493 Res =
5494 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5495 AllowedNameModifiers.push_back(OMPD_task);
5496 break;
5497 case OMPD_taskyield:
5498 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5499, __PRETTY_FUNCTION__))
5499 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5499, __PRETTY_FUNCTION__))
;
5500 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5501, __PRETTY_FUNCTION__))
5501 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5501, __PRETTY_FUNCTION__))
;
5502 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5503 break;
5504 case OMPD_barrier:
5505 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5506, __PRETTY_FUNCTION__))
5506 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5506, __PRETTY_FUNCTION__))
;
5507 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5508, __PRETTY_FUNCTION__))
5508 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5508, __PRETTY_FUNCTION__))
;
5509 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5510 break;
5511 case OMPD_taskwait:
5512 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5513, __PRETTY_FUNCTION__))
5513 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5513, __PRETTY_FUNCTION__))
;
5514 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5515, __PRETTY_FUNCTION__))
5515 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5515, __PRETTY_FUNCTION__))
;
5516 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5517 break;
5518 case OMPD_taskgroup:
5519 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5520 EndLoc);
5521 break;
5522 case OMPD_flush:
5523 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5524, __PRETTY_FUNCTION__))
5524 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5524, __PRETTY_FUNCTION__))
;
5525 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5526 break;
5527 case OMPD_depobj:
5528 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5529, __PRETTY_FUNCTION__))
5529 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5529, __PRETTY_FUNCTION__))
;
5530 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5531 break;
5532 case OMPD_scan:
5533 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5534, __PRETTY_FUNCTION__))
5534 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5534, __PRETTY_FUNCTION__))
;
5535 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5536 break;
5537 case OMPD_ordered:
5538 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5539 EndLoc);
5540 break;
5541 case OMPD_atomic:
5542 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5543 EndLoc);
5544 break;
5545 case OMPD_teams:
5546 Res =
5547 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5548 break;
5549 case OMPD_target:
5550 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5551 EndLoc);
5552 AllowedNameModifiers.push_back(OMPD_target);
5553 break;
5554 case OMPD_target_parallel:
5555 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5556 StartLoc, EndLoc);
5557 AllowedNameModifiers.push_back(OMPD_target);
5558 AllowedNameModifiers.push_back(OMPD_parallel);
5559 break;
5560 case OMPD_target_parallel_for:
5561 Res = ActOnOpenMPTargetParallelForDirective(
5562 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5563 AllowedNameModifiers.push_back(OMPD_target);
5564 AllowedNameModifiers.push_back(OMPD_parallel);
5565 break;
5566 case OMPD_cancellation_point:
5567 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5568, __PRETTY_FUNCTION__))
5568 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5568, __PRETTY_FUNCTION__))
;
5569 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5570, __PRETTY_FUNCTION__))
5570 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5570, __PRETTY_FUNCTION__))
;
5571 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5572 break;
5573 case OMPD_cancel:
5574 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5575, __PRETTY_FUNCTION__))
5575 "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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5575, __PRETTY_FUNCTION__))
;
5576 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5577 CancelRegion);
5578 AllowedNameModifiers.push_back(OMPD_cancel);
5579 break;
5580 case OMPD_target_data:
5581 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5582 EndLoc);
5583 AllowedNameModifiers.push_back(OMPD_target_data);
5584 break;
5585 case OMPD_target_enter_data:
5586 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5587 EndLoc, AStmt);
5588 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5589 break;
5590 case OMPD_target_exit_data:
5591 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5592 EndLoc, AStmt);
5593 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5594 break;
5595 case OMPD_taskloop:
5596 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5597 EndLoc, VarsWithInheritedDSA);
5598 AllowedNameModifiers.push_back(OMPD_taskloop);
5599 break;
5600 case OMPD_taskloop_simd:
5601 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5602 EndLoc, VarsWithInheritedDSA);
5603 AllowedNameModifiers.push_back(OMPD_taskloop);
5604 if (LangOpts.OpenMP >= 50)
5605 AllowedNameModifiers.push_back(OMPD_simd);
5606 break;
5607 case OMPD_master_taskloop:
5608 Res = ActOnOpenMPMasterTaskLoopDirective(
5609 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5610 AllowedNameModifiers.push_back(OMPD_taskloop);
5611 break;
5612 case OMPD_master_taskloop_simd:
5613 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5614 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5615 AllowedNameModifiers.push_back(OMPD_taskloop);
5616 if (LangOpts.OpenMP >= 50)
5617 AllowedNameModifiers.push_back(OMPD_simd);
5618 break;
5619 case OMPD_parallel_master_taskloop:
5620 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5621 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5622 AllowedNameModifiers.push_back(OMPD_taskloop);
5623 AllowedNameModifiers.push_back(OMPD_parallel);
5624 break;
5625 case OMPD_parallel_master_taskloop_simd:
5626 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5627 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5628 AllowedNameModifiers.push_back(OMPD_taskloop);
5629 AllowedNameModifiers.push_back(OMPD_parallel);
5630 if (LangOpts.OpenMP >= 50)
5631 AllowedNameModifiers.push_back(OMPD_simd);
5632 break;
5633 case OMPD_distribute:
5634 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5635 EndLoc, VarsWithInheritedDSA);
5636 break;
5637 case OMPD_target_update:
5638 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5639 EndLoc, AStmt);
5640 AllowedNameModifiers.push_back(OMPD_target_update);
5641 break;
5642 case OMPD_distribute_parallel_for:
5643 Res = ActOnOpenMPDistributeParallelForDirective(
5644 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5645 AllowedNameModifiers.push_back(OMPD_parallel);
5646 break;
5647 case OMPD_distribute_parallel_for_simd:
5648 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5649 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5650 AllowedNameModifiers.push_back(OMPD_parallel);
5651 if (LangOpts.OpenMP >= 50)
5652 AllowedNameModifiers.push_back(OMPD_simd);
5653 break;
5654 case OMPD_distribute_simd:
5655 Res = ActOnOpenMPDistributeSimdDirective(
5656 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5657 if (LangOpts.OpenMP >= 50)
5658 AllowedNameModifiers.push_back(OMPD_simd);
5659 break;
5660 case OMPD_target_parallel_for_simd:
5661 Res = ActOnOpenMPTargetParallelForSimdDirective(
5662 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5663 AllowedNameModifiers.push_back(OMPD_target);
5664 AllowedNameModifiers.push_back(OMPD_parallel);
5665 if (LangOpts.OpenMP >= 50)
5666 AllowedNameModifiers.push_back(OMPD_simd);
5667 break;
5668 case OMPD_target_simd:
5669 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5670 EndLoc, VarsWithInheritedDSA);
5671 AllowedNameModifiers.push_back(OMPD_target);
5672 if (LangOpts.OpenMP >= 50)
5673 AllowedNameModifiers.push_back(OMPD_simd);
5674 break;
5675 case OMPD_teams_distribute:
5676 Res = ActOnOpenMPTeamsDistributeDirective(
5677 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5678 break;
5679 case OMPD_teams_distribute_simd:
5680 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5681 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5682 if (LangOpts.OpenMP >= 50)
5683 AllowedNameModifiers.push_back(OMPD_simd);
5684 break;
5685 case OMPD_teams_distribute_parallel_for_simd:
5686 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5687 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5688 AllowedNameModifiers.push_back(OMPD_parallel);
5689 if (LangOpts.OpenMP >= 50)
5690 AllowedNameModifiers.push_back(OMPD_simd);
5691 break;
5692 case OMPD_teams_distribute_parallel_for:
5693 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5694 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5695 AllowedNameModifiers.push_back(OMPD_parallel);
5696 break;
5697 case OMPD_target_teams:
5698 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5699 EndLoc);
5700 AllowedNameModifiers.push_back(OMPD_target);
5701 break;
5702 case OMPD_target_teams_distribute:
5703 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5704 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5705 AllowedNameModifiers.push_back(OMPD_target);
5706 break;
5707 case OMPD_target_teams_distribute_parallel_for:
5708 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5709 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5710 AllowedNameModifiers.push_back(OMPD_target);
5711 AllowedNameModifiers.push_back(OMPD_parallel);
5712 break;
5713 case OMPD_target_teams_distribute_parallel_for_simd:
5714 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5715 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5716 AllowedNameModifiers.push_back(OMPD_target);
5717 AllowedNameModifiers.push_back(OMPD_parallel);
5718 if (LangOpts.OpenMP >= 50)
5719 AllowedNameModifiers.push_back(OMPD_simd);
5720 break;
5721 case OMPD_target_teams_distribute_simd:
5722 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5723 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5724 AllowedNameModifiers.push_back(OMPD_target);
5725 if (LangOpts.OpenMP >= 50)
5726 AllowedNameModifiers.push_back(OMPD_simd);
5727 break;
5728 case OMPD_declare_target:
5729 case OMPD_end_declare_target:
5730 case OMPD_threadprivate:
5731 case OMPD_allocate:
5732 case OMPD_declare_reduction:
5733 case OMPD_declare_mapper:
5734 case OMPD_declare_simd:
5735 case OMPD_requires:
5736 case OMPD_declare_variant:
5737 case OMPD_begin_declare_variant:
5738 case OMPD_end_declare_variant:
5739 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5739)
;
5740 case OMPD_unknown:
5741 default:
5742 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5742)
;
5743 }
5744
5745 ErrorFound = Res.isInvalid() || ErrorFound;
5746
5747 // Check variables in the clauses if default(none) or
5748 // default(firstprivate) was specified.
5749 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5750 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5751 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
5752 for (OMPClause *C : Clauses) {
5753 switch (C->getClauseKind()) {
5754 case OMPC_num_threads:
5755 case OMPC_dist_schedule:
5756 // Do not analyse if no parent teams directive.
5757 if (isOpenMPTeamsDirective(Kind))
5758 break;
5759 continue;
5760 case OMPC_if:
5761 if (isOpenMPTeamsDirective(Kind) &&
5762 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5763 break;
5764 if (isOpenMPParallelDirective(Kind) &&
5765 isOpenMPTaskLoopDirective(Kind) &&
5766 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5767 break;
5768 continue;
5769 case OMPC_schedule:
5770 case OMPC_detach:
5771 break;
5772 case OMPC_grainsize:
5773 case OMPC_num_tasks:
5774 case OMPC_final:
5775 case OMPC_priority:
5776 // Do not analyze if no parent parallel directive.
5777 if (isOpenMPParallelDirective(Kind))
5778 break;
5779 continue;
5780 case OMPC_ordered:
5781 case OMPC_device:
5782 case OMPC_num_teams:
5783 case OMPC_thread_limit:
5784 case OMPC_hint:
5785 case OMPC_collapse:
5786 case OMPC_safelen:
5787 case OMPC_simdlen:
5788 case OMPC_sizes:
5789 case OMPC_default:
5790 case OMPC_proc_bind:
5791 case OMPC_private:
5792 case OMPC_firstprivate:
5793 case OMPC_lastprivate:
5794 case OMPC_shared:
5795 case OMPC_reduction:
5796 case OMPC_task_reduction:
5797 case OMPC_in_reduction:
5798 case OMPC_linear:
5799 case OMPC_aligned:
5800 case OMPC_copyin:
5801 case OMPC_copyprivate:
5802 case OMPC_nowait:
5803 case OMPC_untied:
5804 case OMPC_mergeable:
5805 case OMPC_allocate:
5806 case OMPC_read:
5807 case OMPC_write:
5808 case OMPC_update:
5809 case OMPC_capture:
5810 case OMPC_seq_cst:
5811 case OMPC_acq_rel:
5812 case OMPC_acquire:
5813 case OMPC_release:
5814 case OMPC_relaxed:
5815 case OMPC_depend:
5816 case OMPC_threads:
5817 case OMPC_simd:
5818 case OMPC_map:
5819 case OMPC_nogroup:
5820 case OMPC_defaultmap:
5821 case OMPC_to:
5822 case OMPC_from:
5823 case OMPC_use_device_ptr:
5824 case OMPC_use_device_addr:
5825 case OMPC_is_device_ptr:
5826 case OMPC_nontemporal:
5827 case OMPC_order:
5828 case OMPC_destroy:
5829 case OMPC_inclusive:
5830 case OMPC_exclusive:
5831 case OMPC_uses_allocators:
5832 case OMPC_affinity:
5833 continue;
5834 case OMPC_allocator:
5835 case OMPC_flush:
5836 case OMPC_depobj:
5837 case OMPC_threadprivate:
5838 case OMPC_uniform:
5839 case OMPC_unknown:
5840 case OMPC_unified_address:
5841 case OMPC_unified_shared_memory:
5842 case OMPC_reverse_offload:
5843 case OMPC_dynamic_allocators:
5844 case OMPC_atomic_default_mem_order:
5845 case OMPC_device_type:
5846 case OMPC_match:
5847 default:
5848 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5848)
;
5849 }
5850 for (Stmt *CC : C->children()) {
5851 if (CC)
5852 DSAChecker.Visit(CC);
5853 }
5854 }
5855 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5856 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5857 }
5858 for (const auto &P : VarsWithInheritedDSA) {
5859 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5860 continue;
5861 ErrorFound = true;
5862 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5863 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5864 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5865 << P.first << P.second->getSourceRange();
5866 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5867 } else if (getLangOpts().OpenMP >= 50) {
5868 Diag(P.second->getExprLoc(),
5869 diag::err_omp_defaultmap_no_attr_for_variable)
5870 << P.first << P.second->getSourceRange();
5871 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
5872 diag::note_omp_defaultmap_attr_none);
5873 }
5874 }
5875
5876 if (!AllowedNameModifiers.empty())
5877 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5878 ErrorFound;
5879
5880 if (ErrorFound)
5881 return StmtError();
5882
5883 if (!CurContext->isDependentContext() &&
5884 isOpenMPTargetExecutionDirective(Kind) &&
5885 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5886 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5887 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5888 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5889 // Register target to DSA Stack.
5890 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
5891 }
5892
5893 return Res;
5894}
5895
5896Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5897 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5898 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5899 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5900 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5901 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5901, __PRETTY_FUNCTION__))
;
5902 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5902, __PRETTY_FUNCTION__))
;
5903 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 5903, __PRETTY_FUNCTION__))
;
5904 if (!DG || DG.get().isNull())
5905 return DeclGroupPtrTy();
5906
5907 const int SimdId = 0;
5908 if (!DG.get().isSingleDecl()) {
5909 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5910 << SimdId;
5911 return DG;
5912 }
5913 Decl *ADecl = DG.get().getSingleDecl();
5914 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5915 ADecl = FTD->getTemplatedDecl();
5916
5917 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5918 if (!FD) {
5919 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5920 return DeclGroupPtrTy();
5921 }
5922
5923 // OpenMP [2.8.2, declare simd construct, Description]
5924 // The parameter of the simdlen clause must be a constant positive integer
5925 // expression.
5926 ExprResult SL;
5927 if (Simdlen)
5928 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5929 // OpenMP [2.8.2, declare simd construct, Description]
5930 // The special this pointer can be used as if was one of the arguments to the
5931 // function in any of the linear, aligned, or uniform clauses.
5932 // The uniform clause declares one or more arguments to have an invariant
5933 // value for all concurrent invocations of the function in the execution of a
5934 // single SIMD loop.
5935 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5936 const Expr *UniformedLinearThis = nullptr;
5937 for (const Expr *E : Uniforms) {
5938 E = E->IgnoreParenImpCasts();
5939 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5940 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5941 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5942 FD->getParamDecl(PVD->getFunctionScopeIndex())
5943 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5944 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5945 continue;
5946 }
5947 if (isa<CXXThisExpr>(E)) {
5948 UniformedLinearThis = E;
5949 continue;
5950 }
5951 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5952 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5953 }
5954 // OpenMP [2.8.2, declare simd construct, Description]
5955 // The aligned clause declares that the object to which each list item points
5956 // is aligned to the number of bytes expressed in the optional parameter of
5957 // the aligned clause.
5958 // The special this pointer can be used as if was one of the arguments to the
5959 // function in any of the linear, aligned, or uniform clauses.
5960 // The type of list items appearing in the aligned clause must be array,
5961 // pointer, reference to array, or reference to pointer.
5962 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5963 const Expr *AlignedThis = nullptr;
5964 for (const Expr *E : Aligneds) {
5965 E = E->IgnoreParenImpCasts();
5966 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5967 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5968 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5969 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5970 FD->getParamDecl(PVD->getFunctionScopeIndex())
5971 ->getCanonicalDecl() == CanonPVD) {
5972 // OpenMP [2.8.1, simd construct, Restrictions]
5973 // A list-item cannot appear in more than one aligned clause.
5974 if (AlignedArgs.count(CanonPVD) > 0) {
5975 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5976 << 1 << getOpenMPClauseName(OMPC_aligned)
5977 << E->getSourceRange();
5978 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5979 diag::note_omp_explicit_dsa)
5980 << getOpenMPClauseName(OMPC_aligned);
5981 continue;
5982 }
5983 AlignedArgs[CanonPVD] = E;
5984 QualType QTy = PVD->getType()
5985 .getNonReferenceType()
5986 .getUnqualifiedType()
5987 .getCanonicalType();
5988 const Type *Ty = QTy.getTypePtrOrNull();
5989 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5990 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5991 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5992 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5993 }
5994 continue;
5995 }
5996 }
5997 if (isa<CXXThisExpr>(E)) {
5998 if (AlignedThis) {
5999 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6000 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6001 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6002 << getOpenMPClauseName(OMPC_aligned);
6003 }
6004 AlignedThis = E;
6005 continue;
6006 }
6007 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6008 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6009 }
6010 // The optional parameter of the aligned clause, alignment, must be a constant
6011 // positive integer expression. If no optional parameter is specified,
6012 // implementation-defined default alignments for SIMD instructions on the
6013 // target platforms are assumed.
6014 SmallVector<const Expr *, 4> NewAligns;
6015 for (Expr *E : Alignments) {
6016 ExprResult Align;
6017 if (E)
6018 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6019 NewAligns.push_back(Align.get());
6020 }
6021 // OpenMP [2.8.2, declare simd construct, Description]
6022 // The linear clause declares one or more list items to be private to a SIMD
6023 // lane and to have a linear relationship with respect to the iteration space
6024 // of a loop.
6025 // The special this pointer can be used as if was one of the arguments to the
6026 // function in any of the linear, aligned, or uniform clauses.
6027 // When a linear-step expression is specified in a linear clause it must be
6028 // either a constant integer expression or an integer-typed parameter that is
6029 // specified in a uniform clause on the directive.
6030 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6031 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6032 auto MI = LinModifiers.begin();
6033 for (const Expr *E : Linears) {
6034 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6035 ++MI;
6036 E = E->IgnoreParenImpCasts();
6037 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6038 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6039 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6040 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6041 FD->getParamDecl(PVD->getFunctionScopeIndex())
6042 ->getCanonicalDecl() == CanonPVD) {
6043 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6044 // A list-item cannot appear in more than one linear clause.
6045 if (LinearArgs.count(CanonPVD) > 0) {
6046 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6047 << getOpenMPClauseName(OMPC_linear)
6048 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6049 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6050 diag::note_omp_explicit_dsa)
6051 << getOpenMPClauseName(OMPC_linear);
6052 continue;
6053 }
6054 // Each argument can appear in at most one uniform or linear clause.
6055 if (UniformedArgs.count(CanonPVD) > 0) {
6056 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6057 << getOpenMPClauseName(OMPC_linear)
6058 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6059 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6060 diag::note_omp_explicit_dsa)
6061 << getOpenMPClauseName(OMPC_uniform);
6062 continue;
6063 }
6064 LinearArgs[CanonPVD] = E;
6065 if (E->isValueDependent() || E->isTypeDependent() ||
6066 E->isInstantiationDependent() ||
6067 E->containsUnexpandedParameterPack())
6068 continue;
6069 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6070 PVD->getOriginalType(),
6071 /*IsDeclareSimd=*/true);
6072 continue;
6073 }
6074 }
6075 if (isa<CXXThisExpr>(E)) {
6076 if (UniformedLinearThis) {
6077 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6078 << getOpenMPClauseName(OMPC_linear)
6079 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6080 << E->getSourceRange();
6081 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6082 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6083 : OMPC_linear);
6084 continue;
6085 }
6086 UniformedLinearThis = E;
6087 if (E->isValueDependent() || E->isTypeDependent() ||
6088 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6089 continue;
6090 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6091 E->getType(), /*IsDeclareSimd=*/true);
6092 continue;
6093 }
6094 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6095 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6096 }
6097 Expr *Step = nullptr;
6098 Expr *NewStep = nullptr;
6099 SmallVector<Expr *, 4> NewSteps;
6100 for (Expr *E : Steps) {
6101 // Skip the same step expression, it was checked already.
6102 if (Step == E || !E) {
6103 NewSteps.push_back(E ? NewStep : nullptr);
6104 continue;
6105 }
6106 Step = E;
6107 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6108 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6109 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6110 if (UniformedArgs.count(CanonPVD) == 0) {
6111 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6112 << Step->getSourceRange();
6113 } else if (E->isValueDependent() || E->isTypeDependent() ||
6114 E->isInstantiationDependent() ||
6115 E->containsUnexpandedParameterPack() ||
6116 CanonPVD->getType()->hasIntegerRepresentation()) {
6117 NewSteps.push_back(Step);
6118 } else {
6119 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6120 << Step->getSourceRange();
6121 }
6122 continue;
6123 }
6124 NewStep = Step;
6125 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6126 !Step->isInstantiationDependent() &&
6127 !Step->containsUnexpandedParameterPack()) {
6128 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6129 .get();
6130 if (NewStep)
6131 NewStep =
6132 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6133 }
6134 NewSteps.push_back(NewStep);
6135 }
6136 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6137 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6138 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6139 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6140 const_cast<Expr **>(Linears.data()), Linears.size(),
6141 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6142 NewSteps.data(), NewSteps.size(), SR);
6143 ADecl->addAttr(NewAttr);
6144 return DG;
6145}
6146
6147static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6148 QualType NewType) {
6149 assert(NewType->isFunctionProtoType() &&((NewType->isFunctionProtoType() && "Expected function type with prototype."
) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6150, __PRETTY_FUNCTION__))
6150 "Expected function type with prototype.")((NewType->isFunctionProtoType() && "Expected function type with prototype."
) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6150, __PRETTY_FUNCTION__))
;
6151 assert(FD->getType()->isFunctionNoProtoType() &&((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype."
) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6152, __PRETTY_FUNCTION__))
6152 "Expected function with type with no prototype.")((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype."
) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6152, __PRETTY_FUNCTION__))
;
6153 assert(FDWithProto->getType()->isFunctionProtoType() &&((FDWithProto->getType()->isFunctionProtoType() &&
"Expected function with prototype.") ? static_cast<void>
(0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6154, __PRETTY_FUNCTION__))
6154 "Expected function with prototype.")((FDWithProto->getType()->isFunctionProtoType() &&
"Expected function with prototype.") ? static_cast<void>
(0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6154, __PRETTY_FUNCTION__))
;
6155 // Synthesize parameters with the same types.
6156 FD->setType(NewType);
6157 SmallVector<ParmVarDecl *, 16> Params;
6158 for (const ParmVarDecl *P : FDWithProto->parameters()) {
6159 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6160 SourceLocation(), nullptr, P->getType(),
6161 /*TInfo=*/nullptr, SC_None, nullptr);
6162 Param->setScopeInfo(0, Params.size());
6163 Param->setImplicit();
6164 Params.push_back(Param);
6165 }
6166
6167 FD->setParams(Params);
6168}
6169
6170void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6171 if (D->isInvalidDecl())
6172 return;
6173 FunctionDecl *FD = nullptr;
6174 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6175 FD = UTemplDecl->getTemplatedDecl();
6176 else
6177 FD = cast<FunctionDecl>(D);
6178 assert(FD && "Expected a function declaration!")((FD && "Expected a function declaration!") ? static_cast
<void> (0) : __assert_fail ("FD && \"Expected a function declaration!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6178, __PRETTY_FUNCTION__))
;
6179
6180 // If we are intantiating templates we do *not* apply scoped assumptions but
6181 // only global ones. We apply scoped assumption to the template definition
6182 // though.
6183 if (!inTemplateInstantiation()) {
6184 for (AssumptionAttr *AA : OMPAssumeScoped)
6185 FD->addAttr(AA);
6186 }
6187 for (AssumptionAttr *AA : OMPAssumeGlobal)
6188 FD->addAttr(AA);
6189}
6190
6191Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6192 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6193
6194void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6195 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6196 SmallVectorImpl<FunctionDecl *> &Bases) {
6197 if (!D.getIdentifier())
6198 return;
6199
6200 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6201
6202 // Template specialization is an extension, check if we do it.
6203 bool IsTemplated = !TemplateParamLists.empty();
6204 if (IsTemplated &
6205 !DVScope.TI->isExtensionActive(
6206 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6207 return;
6208
6209 IdentifierInfo *BaseII = D.getIdentifier();
6210 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6211 LookupOrdinaryName);
6212 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6213
6214 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6215 QualType FType = TInfo->getType();
6216
6217 bool IsConstexpr =
6218 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6219 bool IsConsteval =
6220 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6221
6222 for (auto *Candidate : Lookup) {
6223 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6224 FunctionDecl *UDecl = nullptr;
6225 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6226 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6227 else if (!IsTemplated)
6228 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6229 if (!UDecl)
6230 continue;
6231
6232 // Don't specialize constexpr/consteval functions with
6233 // non-constexpr/consteval functions.
6234 if (UDecl->isConstexpr() && !IsConstexpr)
6235 continue;
6236 if (UDecl->isConsteval() && !IsConsteval)
6237 continue;
6238
6239 QualType UDeclTy = UDecl->getType();
6240 if (!UDeclTy->isDependentType()) {
6241 QualType NewType = Context.mergeFunctionTypes(
6242 FType, UDeclTy, /* OfBlockPointer */ false,
6243 /* Unqualified */ false, /* AllowCXX */ true);
6244 if (NewType.isNull())
6245 continue;
6246 }
6247
6248 // Found a base!
6249 Bases.push_back(UDecl);
6250 }
6251
6252 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6253 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6254 // If no base was found we create a declaration that we use as base.
6255 if (Bases.empty() && UseImplicitBase) {
6256 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6257 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6258 BaseD->setImplicit(true);
6259 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6260 Bases.push_back(BaseTemplD->getTemplatedDecl());
6261 else
6262 Bases.push_back(cast<FunctionDecl>(BaseD));
6263 }
6264
6265 std::string MangledName;
6266 MangledName += D.getIdentifier()->getName();
6267 MangledName += getOpenMPVariantManglingSeparatorStr();
6268 MangledName += DVScope.NameSuffix;
6269 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6270
6271 VariantII.setMangledOpenMPVariantName(true);
6272 D.SetIdentifier(&VariantII, D.getBeginLoc());
6273}
6274
6275void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6276 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6277 // Do not mark function as is used to prevent its emission if this is the
6278 // only place where it is used.
6279 EnterExpressionEvaluationContext Unevaluated(
6280 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6281
6282 FunctionDecl *FD = nullptr;
6283 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6284 FD = UTemplDecl->getTemplatedDecl();
6285 else
6286 FD = cast<FunctionDecl>(D);
6287 auto *VariantFuncRef = DeclRefExpr::Create(
6288 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6289 /* RefersToEnclosingVariableOrCapture */ false,
6290 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
6291
6292 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6293 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6294 Context, VariantFuncRef, DVScope.TI);
6295 for (FunctionDecl *BaseFD : Bases)
6296 BaseFD->addAttr(OMPDeclareVariantA);
6297}
6298
6299ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6300 SourceLocation LParenLoc,
6301 MultiExprArg ArgExprs,
6302 SourceLocation RParenLoc, Expr *ExecConfig) {
6303 // The common case is a regular call we do not want to specialize at all. Try
6304 // to make that case fast by bailing early.
6305 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6306 if (!CE)
6307 return Call;
6308
6309 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6310 if (!CalleeFnDecl)
6311 return Call;
6312
6313 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6314 return Call;
6315
6316 ASTContext &Context = getASTContext();
6317 std::function<void(StringRef)> DiagUnknownTrait = [this,
6318 CE](StringRef ISATrait) {
6319 // TODO Track the selector locations in a way that is accessible here to
6320 // improve the diagnostic location.
6321 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6322 << ISATrait;
6323 };
6324 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6325 getCurFunctionDecl());
6326
6327 QualType CalleeFnType = CalleeFnDecl->getType();
6328
6329 SmallVector<Expr *, 4> Exprs;
6330 SmallVector<VariantMatchInfo, 4> VMIs;
6331 while (CalleeFnDecl) {
6332 for (OMPDeclareVariantAttr *A :
6333 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6334 Expr *VariantRef = A->getVariantFuncRef();
6335
6336 VariantMatchInfo VMI;
6337 OMPTraitInfo &TI = A->getTraitInfo();
6338 TI.getAsVariantMatchInfo(Context, VMI);
6339 if (!isVariantApplicableInContext(VMI, OMPCtx,
6340 /* DeviceSetOnly */ false))
6341 continue;
6342
6343 VMIs.push_back(VMI);
6344 Exprs.push_back(VariantRef);
6345 }
6346
6347 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6348 }
6349
6350 ExprResult NewCall;
6351 do {
6352 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6353 if (BestIdx < 0)
6354 return Call;
6355 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6356 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6357
6358 {
6359 // Try to build a (member) call expression for the current best applicable
6360 // variant expression. We allow this to fail in which case we continue
6361 // with the next best variant expression. The fail case is part of the
6362 // implementation defined behavior in the OpenMP standard when it talks
6363 // about what differences in the function prototypes: "Any differences
6364 // that the specific OpenMP context requires in the prototype of the
6365 // variant from the base function prototype are implementation defined."
6366 // This wording is there to allow the specialized variant to have a
6367 // different type than the base function. This is intended and OK but if
6368 // we cannot create a call the difference is not in the "implementation
6369 // defined range" we allow.
6370 Sema::TentativeAnalysisScope Trap(*this);
6371
6372 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6373 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6374 BestExpr = MemberExpr::CreateImplicit(
6375 Context, MemberCall->getImplicitObjectArgument(),
6376 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6377 MemberCall->getValueKind(), MemberCall->getObjectKind());
6378 }
6379 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6380 ExecConfig);
6381 if (NewCall.isUsable()) {
6382 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6383 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6384 QualType NewType = Context.mergeFunctionTypes(
6385 CalleeFnType, NewCalleeFnDecl->getType(),
6386 /* OfBlockPointer */ false,
6387 /* Unqualified */ false, /* AllowCXX */ true);
6388 if (!NewType.isNull())
6389 break;
6390 // Don't use the call if the function type was not compatible.
6391 NewCall = nullptr;
6392 }
6393 }
6394 }
6395
6396 VMIs.erase(VMIs.begin() + BestIdx);
6397 Exprs.erase(Exprs.begin() + BestIdx);
6398 } while (!VMIs.empty());
6399
6400 if (!NewCall.isUsable())
6401 return Call;
6402 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6403}
6404
6405Optional<std::pair<FunctionDecl *, Expr *>>
6406Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6407 Expr *VariantRef, OMPTraitInfo &TI,
6408 SourceRange SR) {
6409 if (!DG || DG.get().isNull())
6410 return None;
6411
6412 const int VariantId = 1;
6413 // Must be applied only to single decl.
6414 if (!DG.get().isSingleDecl()) {
6415 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6416 << VariantId << SR;
6417 return None;
6418 }
6419 Decl *ADecl = DG.get().getSingleDecl();
6420 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6421 ADecl = FTD->getTemplatedDecl();
6422
6423 // Decl must be a function.
6424 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6425 if (!FD) {
6426 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6427 << VariantId << SR;
6428 return None;
6429 }
6430
6431 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6432 return FD->hasAttrs() &&
6433 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6434 FD->hasAttr<TargetAttr>());
6435 };
6436 // OpenMP is not compatible with CPU-specific attributes.
6437 if (HasMultiVersionAttributes(FD)) {
6438 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6439 << SR;
6440 return None;
6441 }
6442
6443 // Allow #pragma omp declare variant only if the function is not used.
6444 if (FD->isUsed(false))
6445 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6446 << FD->getLocation();
6447
6448 // Check if the function was emitted already.
6449 const FunctionDecl *Definition;
6450 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6451 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6452 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6453 << FD->getLocation();
6454
6455 // The VariantRef must point to function.
6456 if (!VariantRef) {
6457 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6458 return None;
6459 }
6460
6461 auto ShouldDelayChecks = [](Expr *&E, bool) {
6462 return E && (E->isTypeDependent() || E->isValueDependent() ||
6463 E->containsUnexpandedParameterPack() ||
6464 E->isInstantiationDependent());
6465 };
6466 // Do not check templates, wait until instantiation.
6467 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6468 TI.anyScoreOrCondition(ShouldDelayChecks))
6469 return std::make_pair(FD, VariantRef);
6470
6471 // Deal with non-constant score and user condition expressions.
6472 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6473 bool IsScore) -> bool {
6474 if (!E || E->isIntegerConstantExpr(Context))
6475 return false;
6476
6477 if (IsScore) {
6478 // We warn on non-constant scores and pretend they were not present.
6479 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6480 << E;
6481 E = nullptr;
6482 } else {
6483 // We could replace a non-constant user condition with "false" but we
6484 // will soon need to handle these anyway for the dynamic version of
6485 // OpenMP context selectors.
6486 Diag(E->getExprLoc(),
6487 diag::err_omp_declare_variant_user_condition_not_constant)
6488 << E;
6489 }
6490 return true;
6491 };
6492 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6493 return None;
6494
6495 // Convert VariantRef expression to the type of the original function to
6496 // resolve possible conflicts.
6497 ExprResult VariantRefCast = VariantRef;
6498 if (LangOpts.CPlusPlus) {
6499 QualType FnPtrType;
6500 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6501 if (Method && !Method->isStatic()) {
6502 const Type *ClassType =
6503 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6504 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6505 ExprResult ER;
6506 {
6507 // Build adrr_of unary op to correctly handle type checks for member
6508 // functions.
6509 Sema::TentativeAnalysisScope Trap(*this);
6510 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6511 VariantRef);
6512 }
6513 if (!ER.isUsable()) {
6514 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6515 << VariantId << VariantRef->getSourceRange();
6516 return None;
6517 }
6518 VariantRef = ER.get();
6519 } else {
6520 FnPtrType = Context.getPointerType(FD->getType());
6521 }
6522 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6523 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6524 ImplicitConversionSequence ICS = TryImplicitConversion(
6525 VariantRef, FnPtrType.getUnqualifiedType(),
6526 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6527 /*InOverloadResolution=*/false,
6528 /*CStyle=*/false,
6529 /*AllowObjCWritebackConversion=*/false);
6530 if (ICS.isFailure()) {
6531 Diag(VariantRef->getExprLoc(),
6532 diag::err_omp_declare_variant_incompat_types)
6533 << VariantRef->getType()
6534 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6535 << VariantRef->getSourceRange();
6536 return None;
6537 }
6538 VariantRefCast = PerformImplicitConversion(
6539 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6540 if (!VariantRefCast.isUsable())
6541 return None;
6542 }
6543 // Drop previously built artificial addr_of unary op for member functions.
6544 if (Method && !Method->isStatic()) {
6545 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6546 if (auto *UO = dyn_cast<UnaryOperator>(
6547 PossibleAddrOfVariantRef->IgnoreImplicit()))
6548 VariantRefCast = UO->getSubExpr();
6549 }
6550 }
6551
6552 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6553 if (!ER.isUsable() ||
6554 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6555 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6556 << VariantId << VariantRef->getSourceRange();
6557 return None;
6558 }
6559
6560 // The VariantRef must point to function.
6561 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6562 if (!DRE) {
6563 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6564 << VariantId << VariantRef->getSourceRange();
6565 return None;
6566 }
6567 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6568 if (!NewFD) {
6569 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6570 << VariantId << VariantRef->getSourceRange();
6571 return None;
6572 }
6573
6574 // Check if function types are compatible in C.
6575 if (!LangOpts.CPlusPlus) {
6576 QualType NewType =
6577 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6578 if (NewType.isNull()) {
6579 Diag(VariantRef->getExprLoc(),
6580 diag::err_omp_declare_variant_incompat_types)
6581 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6582 return None;
6583 }
6584 if (NewType->isFunctionProtoType()) {
6585 if (FD->getType()->isFunctionNoProtoType())
6586 setPrototype(*this, FD, NewFD, NewType);
6587 else if (NewFD->getType()->isFunctionNoProtoType())
6588 setPrototype(*this, NewFD, FD, NewType);
6589 }
6590 }
6591
6592 // Check if variant function is not marked with declare variant directive.
6593 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6594 Diag(VariantRef->getExprLoc(),
6595 diag::warn_omp_declare_variant_marked_as_declare_variant)
6596 << VariantRef->getSourceRange();
6597 SourceRange SR =
6598 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6599 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6600 return None;
6601 }
6602
6603 enum DoesntSupport {
6604 VirtFuncs = 1,
6605 Constructors = 3,
6606 Destructors = 4,
6607 DeletedFuncs = 5,
6608 DefaultedFuncs = 6,
6609 ConstexprFuncs = 7,
6610 ConstevalFuncs = 8,
6611 };
6612 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6613 if (CXXFD->isVirtual()) {
6614 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6615 << VirtFuncs;
6616 return None;
6617 }
6618
6619 if (isa<CXXConstructorDecl>(FD)) {
6620 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6621 << Constructors;
6622 return None;
6623 }
6624
6625 if (isa<CXXDestructorDecl>(FD)) {
6626 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6627 << Destructors;
6628 return None;
6629 }
6630 }
6631
6632 if (FD->isDeleted()) {
6633 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6634 << DeletedFuncs;
6635 return None;
6636 }
6637
6638 if (FD->isDefaulted()) {
6639 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6640 << DefaultedFuncs;
6641 return None;
6642 }
6643
6644 if (FD->isConstexpr()) {
6645 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6646 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6647 return None;
6648 }
6649
6650 // Check general compatibility.
6651 if (areMultiversionVariantFunctionsCompatible(
6652 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6653 PartialDiagnosticAt(SourceLocation(),
6654 PartialDiagnostic::NullDiagnostic()),
6655 PartialDiagnosticAt(
6656 VariantRef->getExprLoc(),
6657 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6658 PartialDiagnosticAt(VariantRef->getExprLoc(),
6659 PDiag(diag::err_omp_declare_variant_diff)
6660 << FD->getLocation()),
6661 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6662 /*CLinkageMayDiffer=*/true))
6663 return None;
6664 return std::make_pair(FD, cast<Expr>(DRE));
6665}
6666
6667void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6668 Expr *VariantRef,
6669 OMPTraitInfo &TI,
6670 SourceRange SR) {
6671 auto *NewAttr =
6672 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6673 FD->addAttr(NewAttr);
6674}
6675
6676StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6677 Stmt *AStmt,
6678 SourceLocation StartLoc,
6679 SourceLocation EndLoc) {
6680 if (!AStmt)
6681 return StmtError();
6682
6683 auto *CS = cast<CapturedStmt>(AStmt);
6684 // 1.2.2 OpenMP Language Terminology
6685 // Structured block - An executable statement with a single entry at the
6686 // top and a single exit at the bottom.
6687 // The point of exit cannot be a branch out of the structured block.
6688 // longjmp() and throw() must not violate the entry/exit criteria.
6689 CS->getCapturedDecl()->setNothrow();
6690
6691 setFunctionHasBranchProtectedScope();
6692
6693 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6694 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
6695 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6696}
6697
6698namespace {
6699/// Iteration space of a single for loop.
6700struct LoopIterationSpace final {
6701 /// True if the condition operator is the strict compare operator (<, > or
6702 /// !=).
6703 bool IsStrictCompare = false;
6704 /// Condition of the loop.
6705 Expr *PreCond = nullptr;
6706 /// This expression calculates the number of iterations in the loop.
6707 /// It is always possible to calculate it before starting the loop.
6708 Expr *NumIterations = nullptr;
6709 /// The loop counter variable.
6710 Expr *CounterVar = nullptr;
6711 /// Private loop counter variable.
6712 Expr *PrivateCounterVar = nullptr;
6713 /// This is initializer for the initial value of #CounterVar.
6714 Expr *CounterInit = nullptr;
6715 /// This is step for the #CounterVar used to generate its update:
6716 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6717 Expr *CounterStep = nullptr;
6718 /// Should step be subtracted?
6719 bool Subtract = false;
6720 /// Source range of the loop init.
6721 SourceRange InitSrcRange;
6722 /// Source range of the loop condition.
6723 SourceRange CondSrcRange;
6724 /// Source range of the loop increment.
6725 SourceRange IncSrcRange;
6726 /// Minimum value that can have the loop control variable. Used to support
6727 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6728 /// since only such variables can be used in non-loop invariant expressions.
6729 Expr *MinValue = nullptr;
6730 /// Maximum value that can have the loop control variable. Used to support
6731 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6732 /// since only such variables can be used in non-loop invariant expressions.
6733 Expr *MaxValue = nullptr;
6734 /// true, if the lower bound depends on the outer loop control var.
6735 bool IsNonRectangularLB = false;
6736 /// true, if the upper bound depends on the outer loop control var.
6737 bool IsNonRectangularUB = false;
6738 /// Index of the loop this loop depends on and forms non-rectangular loop
6739 /// nest.
6740 unsigned LoopDependentIdx = 0;
6741 /// Final condition for the non-rectangular loop nest support. It is used to
6742 /// check that the number of iterations for this particular counter must be
6743 /// finished.
6744 Expr *FinalCondition = nullptr;
6745};
6746
6747/// Helper class for checking canonical form of the OpenMP loops and
6748/// extracting iteration space of each loop in the loop nest, that will be used
6749/// for IR generation.
6750class OpenMPIterationSpaceChecker {
6751 /// Reference to Sema.
6752 Sema &SemaRef;
6753 /// Does the loop associated directive support non-rectangular loops?
6754 bool SupportsNonRectangular;
6755 /// Data-sharing stack.
6756 DSAStackTy &Stack;
6757 /// A location for diagnostics (when there is no some better location).
6758 SourceLocation DefaultLoc;
6759 /// A location for diagnostics (when increment is not compatible).
6760 SourceLocation ConditionLoc;
6761 /// A source location for referring to loop init later.
6762 SourceRange InitSrcRange;
6763 /// A source location for referring to condition later.
6764 SourceRange ConditionSrcRange;
6765 /// A source location for referring to increment later.
6766 SourceRange IncrementSrcRange;
6767 /// Loop variable.
6768 ValueDecl *LCDecl = nullptr;
6769 /// Reference to loop variable.
6770 Expr *LCRef = nullptr;
6771 /// Lower bound (initializer for the var).
6772 Expr *LB = nullptr;
6773 /// Upper bound.
6774 Expr *UB = nullptr;
6775 /// Loop step (increment).
6776 Expr *Step = nullptr;
6777 /// This flag is true when condition is one of:
6778 /// Var < UB
6779 /// Var <= UB
6780 /// UB > Var
6781 /// UB >= Var
6782 /// This will have no value when the condition is !=
6783 llvm::Optional<bool> TestIsLessOp;
6784 /// This flag is true when condition is strict ( < or > ).
6785 bool TestIsStrictOp = false;
6786 /// This flag is true when step is subtracted on each iteration.
6787 bool SubtractStep = false;
6788 /// The outer loop counter this loop depends on (if any).
6789 const ValueDecl *DepDecl = nullptr;
6790 /// Contains number of loop (starts from 1) on which loop counter init
6791 /// expression of this loop depends on.
6792 Optional<unsigned> InitDependOnLC;
6793 /// Contains number of loop (starts from 1) on which loop counter condition
6794 /// expression of this loop depends on.
6795 Optional<unsigned> CondDependOnLC;
6796 /// Checks if the provide statement depends on the loop counter.
6797 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6798 /// Original condition required for checking of the exit condition for
6799 /// non-rectangular loop.
6800 Expr *Condition = nullptr;
6801
6802public:
6803 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
6804 DSAStackTy &Stack, SourceLocation DefaultLoc)
6805 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
6806 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
6807 /// Check init-expr for canonical loop form and save loop counter
6808 /// variable - #Var and its initialization value - #LB.
6809 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6810 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6811 /// for less/greater and for strict/non-strict comparison.
6812 bool checkAndSetCond(Expr *S);
6813 /// Check incr-expr for canonical loop form and return true if it
6814 /// does not conform, otherwise save loop step (#Step).
6815 bool checkAndSetInc(Expr *S);
6816 /// Return the loop counter variable.
6817 ValueDecl *getLoopDecl() const { return LCDecl; }
6818 /// Return the reference expression to loop counter variable.
6819 Expr *getLoopDeclRefExpr() const { return LCRef; }
6820 /// Source range of the loop init.
6821 SourceRange getInitSrcRange() const { return InitSrcRange; }
6822 /// Source range of the loop condition.
6823 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6824 /// Source range of the loop increment.
6825 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6826 /// True if the step should be subtracted.
6827 bool shouldSubtractStep() const { return SubtractStep; }
6828 /// True, if the compare operator is strict (<, > or !=).
6829 bool isStrictTestOp() const { return TestIsStrictOp; }
6830 /// Build the expression to calculate the number of iterations.
6831 Expr *buildNumIterations(
6832 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6833 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6834 /// Build the precondition expression for the loops.
6835 Expr *
6836 buildPreCond(Scope *S, Expr *Cond,
6837 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6838 /// Build reference expression to the counter be used for codegen.
6839 DeclRefExpr *
6840 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6841 DSAStackTy &DSA) const;
6842 /// Build reference expression to the private counter be used for
6843 /// codegen.
6844 Expr *buildPrivateCounterVar() const;
6845 /// Build initialization of the counter be used for codegen.
6846 Expr *buildCounterInit() const;
6847 /// Build step of the counter be used for codegen.
6848 Expr *buildCounterStep() const;
6849 /// Build loop data with counter value for depend clauses in ordered
6850 /// directives.
6851 Expr *
6852 buildOrderedLoopData(Scope *S, Expr *Counter,
6853 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6854 SourceLocation Loc, Expr *Inc = nullptr,
6855 OverloadedOperatorKind OOK = OO_Amp);
6856 /// Builds the minimum value for the loop counter.
6857 std::pair<Expr *, Expr *> buildMinMaxValues(
6858 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6859 /// Builds final condition for the non-rectangular loops.
6860 Expr *buildFinalCondition(Scope *S) const;
6861 /// Return true if any expression is dependent.
6862 bool dependent() const;
6863 /// Returns true if the initializer forms non-rectangular loop.
6864 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6865 /// Returns true if the condition forms non-rectangular loop.
6866 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6867 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
6868 unsigned getLoopDependentIdx() const {
6869 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6870 }
6871
6872private:
6873 /// Check the right-hand side of an assignment in the increment
6874 /// expression.
6875 bool checkAndSetIncRHS(Expr *RHS);
6876 /// Helper to set loop counter variable and its initializer.
6877 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6878 bool EmitDiags);
6879 /// Helper to set upper bound.
6880 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6881 SourceRange SR, SourceLocation SL);
6882 /// Helper to set loop increment.
6883 bool setStep(Expr *NewStep, bool Subtract);
6884};
6885
6886bool OpenMPIterationSpaceChecker::dependent() const {
6887 if (!LCDecl) {
6888 assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void>
(0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6888, __PRETTY_FUNCTION__))
;
6889 return false;
6890 }
6891 return LCDecl->getType()->isDependentType() ||
6892 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6893 (Step && Step->isValueDependent());
6894}
6895
6896bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6897 Expr *NewLCRefExpr,
6898 Expr *NewLB, bool EmitDiags) {
6899 // State consistency checking to ensure correct usage.
6900 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6901, __PRETTY_FUNCTION__))
6901 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6901, __PRETTY_FUNCTION__))
;
6902 if (!NewLCDecl || !NewLB)
6903 return true;
6904 LCDecl = getCanonicalDecl(NewLCDecl);
6905 LCRef = NewLCRefExpr;
6906 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6907 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6908 if ((Ctor->isCopyOrMoveConstructor() ||
6909 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6910 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6911 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6912 LB = NewLB;
6913 if (EmitDiags)
6914 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6915 return false;
6916}
6917
6918bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6919 llvm::Optional<bool> LessOp,
6920 bool StrictOp, SourceRange SR,
6921 SourceLocation SL) {
6922 // State consistency checking to ensure correct usage.
6923 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6924, __PRETTY_FUNCTION__))
6924 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6924, __PRETTY_FUNCTION__))
;
6925 if (!NewUB)
6926 return true;
6927 UB = NewUB;
6928 if (LessOp)
6929 TestIsLessOp = LessOp;
6930 TestIsStrictOp = StrictOp;
6931 ConditionSrcRange = SR;
6932 ConditionLoc = SL;
6933 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6934 return false;
6935}
6936
6937bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6938 // State consistency checking to ensure correct usage.
6939 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)((LCDecl != nullptr && LB != nullptr && Step ==
nullptr) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && Step == nullptr"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 6939, __PRETTY_FUNCTION__))
;
6940 if (!NewStep)
6941 return true;
6942 if (!NewStep->isValueDependent()) {
6943 // Check that the step is integer expression.
6944 SourceLocation StepLoc = NewStep->getBeginLoc();
6945 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6946 StepLoc, getExprAsWritten(NewStep));
6947 if (Val.isInvalid())
6948 return true;
6949 NewStep = Val.get();
6950
6951 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6952 // If test-expr is of form var relational-op b and relational-op is < or
6953 // <= then incr-expr must cause var to increase on each iteration of the
6954 // loop. If test-expr is of form var relational-op b and relational-op is
6955 // > or >= then incr-expr must cause var to decrease on each iteration of
6956 // the loop.
6957 // If test-expr is of form b relational-op var and relational-op is < or
6958 // <= then incr-expr must cause var to decrease on each iteration of the
6959 // loop. If test-expr is of form b relational-op var and relational-op is
6960 // > or >= then incr-expr must cause var to increase on each iteration of
6961 // the loop.
6962 Optional<llvm::APSInt> Result =
6963 NewStep->getIntegerConstantExpr(SemaRef.Context);
6964 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6965 bool IsConstNeg =
6966 Result && Result->isSigned() && (Subtract != Result->isNegative());
6967 bool IsConstPos =
6968 Result && Result->isSigned() && (Subtract == Result->isNegative());
6969 bool IsConstZero = Result && !Result->getBoolValue();
6970
6971 // != with increment is treated as <; != with decrement is treated as >
6972 if (!TestIsLessOp.hasValue())
6973 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6974 if (UB && (IsConstZero ||
6975 (TestIsLessOp.getValue() ?
6976 (IsConstNeg || (IsUnsigned && Subtract)) :
6977 (IsConstPos || (IsUnsigned && !Subtract))))) {
6978 SemaRef.Diag(NewStep->getExprLoc(),
6979 diag::err_omp_loop_incr_not_compatible)
6980 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6981 SemaRef.Diag(ConditionLoc,
6982 diag::note_omp_loop_cond_requres_compatible_incr)
6983 << TestIsLessOp.getValue() << ConditionSrcRange;
6984 return true;
6985 }
6986 if (TestIsLessOp.getValue() == Subtract) {
6987 NewStep =
6988 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6989 .get();
6990 Subtract = !Subtract;
6991 }
6992 }
6993
6994 Step = NewStep;
6995 SubtractStep = Subtract;
6996 return false;
6997}
6998
6999namespace {
7000/// Checker for the non-rectangular loops. Checks if the initializer or
7001/// condition expression references loop counter variable.
7002class LoopCounterRefChecker final
7003 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7004 Sema &SemaRef;
7005 DSAStackTy &Stack;
7006 const ValueDecl *CurLCDecl = nullptr;
7007 const ValueDecl *DepDecl = nullptr;
7008 const ValueDecl *PrevDepDecl = nullptr;
7009 bool IsInitializer = true;
7010 bool SupportsNonRectangular;
7011 unsigned BaseLoopId = 0;
7012 bool checkDecl(const Expr *E, const ValueDecl *VD) {
7013 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7014 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7015 << (IsInitializer ? 0 : 1);
7016 return false;
7017 }
7018 const auto &&Data = Stack.isLoopControlVariable(VD);
7019 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7020 // The type of the loop iterator on which we depend may not have a random
7021 // access iterator type.
7022 if (Data.first && VD->getType()->isRecordType()) {
7023 SmallString<128> Name;
7024 llvm::raw_svector_ostream OS(Name);
7025 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7026 /*Qualified=*/true);
7027 SemaRef.Diag(E->getExprLoc(),
7028 diag::err_omp_wrong_dependency_iterator_type)
7029 << OS.str();
7030 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7031 return false;
7032 }
7033 if (Data.first && !SupportsNonRectangular) {
7034 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7035 return false;
7036 }
7037 if (Data.first &&
7038 (DepDecl || (PrevDepDecl &&
7039 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7040 if (!DepDecl && PrevDepDecl)
7041 DepDecl = PrevDepDecl;
7042 SmallString<128> Name;
7043 llvm::raw_svector_ostream OS(Name);
7044 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7045 /*Qualified=*/true);
7046 SemaRef.Diag(E->getExprLoc(),
7047 diag::err_omp_invariant_or_linear_dependency)
7048 << OS.str();
7049 return false;
7050 }
7051 if (Data.first) {
7052 DepDecl = VD;
7053 BaseLoopId = Data.first;
7054 }
7055 return Data.first;
7056 }
7057
7058public:
7059 bool VisitDeclRefExpr(const DeclRefExpr *E) {
7060 const ValueDecl *VD = E->getDecl();
7061 if (isa<VarDecl>(VD))
7062 return checkDecl(E, VD);
7063 return false;
7064 }
7065 bool VisitMemberExpr(const MemberExpr *E) {
7066 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7067 const ValueDecl *VD = E->getMemberDecl();
7068 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7069 return checkDecl(E, VD);
7070 }
7071 return false;
7072 }
7073 bool VisitStmt(const Stmt *S) {
7074 bool Res = false;
7075 for (const Stmt *Child : S->children())
7076 Res = (Child && Visit(Child)) || Res;
7077 return Res;
7078 }
7079 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7080 const ValueDecl *CurLCDecl, bool IsInitializer,
7081 const ValueDecl *PrevDepDecl = nullptr,
7082 bool SupportsNonRectangular = true)
7083 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7084 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7085 SupportsNonRectangular(SupportsNonRectangular) {}
7086 unsigned getBaseLoopId() const {
7087 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 7087, __PRETTY_FUNCTION__))
;
7088 return BaseLoopId;
7089 }
7090 const ValueDecl *getDepDecl() const {
7091 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 7091, __PRETTY_FUNCTION__))
;
7092 return DepDecl;
7093 }
7094};
7095} // namespace
7096
7097Optional<unsigned>
7098OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7099 bool IsInitializer) {
7100 // Check for the non-rectangular loops.
7101 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7102 DepDecl, SupportsNonRectangular);
7103 if (LoopStmtChecker.Visit(S)) {
7104 DepDecl = LoopStmtChecker.getDepDecl();
7105 return LoopStmtChecker.getBaseLoopId();
7106 }
7107 return llvm::None;
7108}
7109
7110bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7111 // Check init-expr for canonical loop form and save loop counter
7112 // variable - #Var and its initialization value - #LB.
7113 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7114 // var = lb
7115 // integer-type var = lb
7116 // random-access-iterator-type var = lb
7117 // pointer-type var = lb
7118 //
7119 if (!S) {
7120 if (EmitDiags) {
7121 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7122 }
7123 return true;
7124 }
7125 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7126 if (!ExprTemp->cleanupsHaveSideEffects())
7127 S = ExprTemp->getSubExpr();
7128
7129 InitSrcRange = S->getSourceRange();
7130 if (Expr *E = dyn_cast<Expr>(S))
7131 S = E->IgnoreParens();
7132 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7133 if (BO->getOpcode() == BO_Assign) {
7134 Expr *LHS = BO->getLHS()->IgnoreParens();
7135 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7136 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7137 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7138 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7139 EmitDiags);
7140 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7141 }
7142 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7143 if (ME->isArrow() &&
7144 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7145 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7146 EmitDiags);
7147 }
7148 }
7149 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7150 if (DS->isSingleDecl()) {
7151 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7152 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7153 // Accept non-canonical init form here but emit ext. warning.
7154 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7155 SemaRef.Diag(S->getBeginLoc(),
7156 diag::ext_omp_loop_not_canonical_init)
7157 << S->getSourceRange();
7158 return setLCDeclAndLB(
7159 Var,
7160 buildDeclRefExpr(SemaRef, Var,
7161 Var->getType().getNonReferenceType(),
7162 DS->getBeginLoc()),
7163 Var->getInit(), EmitDiags);
7164 }
7165 }
7166 }
7167 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7168 if (CE->getOperator() == OO_Equal) {
7169 Expr *LHS = CE->getArg(0);
7170 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7171 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7172 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7173 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7174 EmitDiags);
7175 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7176 }
7177 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7178 if (ME->isArrow() &&
7179 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7180 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7181 EmitDiags);
7182 }
7183 }
7184 }
7185
7186 if (dependent() || SemaRef.CurContext->isDependentContext())
7187 return false;
7188 if (EmitDiags) {
7189 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7190 << S->getSourceRange();
7191 }
7192 return true;
7193}
7194
7195/// Ignore parenthesizes, implicit casts, copy constructor and return the
7196/// variable (which may be the loop variable) if possible.
7197static const ValueDecl *getInitLCDecl(const Expr *E) {
7198 if (!E)
7199 return nullptr;
7200 E = getExprAsWritten(E);
7201 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7202 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7203 if ((Ctor->isCopyOrMoveConstructor() ||
7204 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7205 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7206 E = CE->getArg(0)->IgnoreParenImpCasts();
7207 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7208 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7209 return getCanonicalDecl(VD);
7210 }
7211 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7212 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7213 return getCanonicalDecl(ME->getMemberDecl());
7214 return nullptr;
7215}
7216
7217bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7218 // Check test-expr for canonical form, save upper-bound UB, flags for
7219 // less/greater and for strict/non-strict comparison.
7220 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7221 // var relational-op b
7222 // b relational-op var
7223 //
7224 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7225 if (!S) {
7226 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7227 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7228 return true;
7229 }
7230 Condition = S;
7231 S = getExprAsWritten(S);
7232 SourceLocation CondLoc = S->getBeginLoc();
7233 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7234 if (BO->isRelationalOp()) {
7235 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7236 return setUB(BO->getRHS(),
7237 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
7238 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7239 BO->getSourceRange(), BO->getOperatorLoc());
7240 if (getInitLCDecl(BO->getRHS()) == LCDecl)
7241 return setUB(BO->getLHS(),
7242 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
7243 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7244 BO->getSourceRange(), BO->getOperatorLoc());
7245 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
7246 return setUB(
7247 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
7248 /*LessOp=*/llvm::None,
7249 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
7250 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7251 if (CE->getNumArgs() == 2) {
7252 auto Op = CE->getOperator();
7253 switch (Op) {
7254 case OO_Greater:
7255 case OO_GreaterEqual:
7256 case OO_Less:
7257 case OO_LessEqual:
7258 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7259 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
7260 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7261 CE->getOperatorLoc());
7262 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
7263 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
7264 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7265 CE->getOperatorLoc());
7266 break;
7267 case OO_ExclaimEqual:
7268 if (IneqCondIsCanonical)
7269 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
7270 : CE->getArg(0),
7271 /*LessOp=*/llvm::None,
7272 /*StrictOp=*/true, CE->getSourceRange(),
7273 CE->getOperatorLoc());
7274 break;
7275 default:
7276 break;
7277 }
7278 }
7279 }
7280 if (dependent() || SemaRef.CurContext->isDependentContext())
7281 return false;
7282 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7283 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7284 return true;
7285}
7286
7287bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7288 // RHS of canonical loop form increment can be:
7289 // var + incr
7290 // incr + var
7291 // var - incr
7292 //
7293 RHS = RHS->IgnoreParenImpCasts();
7294 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7295 if (BO->isAdditiveOp()) {
7296 bool IsAdd = BO->getOpcode() == BO_Add;
7297 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7298 return setStep(BO->getRHS(), !IsAdd);
7299 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7300 return setStep(BO->getLHS(), /*Subtract=*/false);
7301 }
7302 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7303 bool IsAdd = CE->getOperator() == OO_Plus;
7304 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7305 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7306 return setStep(CE->getArg(1), !IsAdd);
7307 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7308 return setStep(CE->getArg(0), /*Subtract=*/false);
7309 }
7310 }
7311 if (dependent() || SemaRef.CurContext->isDependentContext())
7312 return false;
7313 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7314 << RHS->getSourceRange() << LCDecl;
7315 return true;
7316}
7317
7318bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7319 // Check incr-expr for canonical loop form and return true if it
7320 // does not conform.
7321 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7322 // ++var
7323 // var++
7324 // --var
7325 // var--
7326 // var += incr
7327 // var -= incr
7328 // var = var + incr
7329 // var = incr + var
7330 // var = var - incr
7331 //
7332 if (!S) {
7333 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7334 return true;
7335 }
7336 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7337 if (!ExprTemp->cleanupsHaveSideEffects())
7338 S = ExprTemp->getSubExpr();
7339
7340 IncrementSrcRange = S->getSourceRange();
7341 S = S->IgnoreParens();
7342 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7343 if (UO->isIncrementDecrementOp() &&
7344 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7345 return setStep(SemaRef
7346 .ActOnIntegerConstant(UO->getBeginLoc(),
7347 (UO->isDecrementOp() ? -1 : 1))
7348 .get(),
7349 /*Subtract=*/false);
7350 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7351 switch (BO->getOpcode()) {
7352 case BO_AddAssign:
7353 case BO_SubAssign:
7354 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7355 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7356 break;
7357 case BO_Assign:
7358 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7359 return checkAndSetIncRHS(BO->getRHS());
7360 break;
7361 default:
7362 break;
7363 }
7364 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7365 switch (CE->getOperator()) {
7366 case OO_PlusPlus:
7367 case OO_MinusMinus:
7368 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7369 return setStep(SemaRef
7370 .ActOnIntegerConstant(
7371 CE->getBeginLoc(),
7372 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7373 .get(),
7374 /*Subtract=*/false);
7375 break;
7376 case OO_PlusEqual:
7377 case OO_MinusEqual:
7378 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7379 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7380 break;
7381 case OO_Equal:
7382 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7383 return checkAndSetIncRHS(CE->getArg(1));
7384 break;
7385 default:
7386 break;
7387 }
7388 }
7389 if (dependent() || SemaRef.CurContext->isDependentContext())
7390 return false;
7391 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7392 << S->getSourceRange() << LCDecl;
7393 return true;
7394}
7395
7396static ExprResult
7397tryBuildCapture(Sema &SemaRef, Expr *Capture,
7398 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7399 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7400 return Capture;
7401 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7402 return SemaRef.PerformImplicitConversion(
7403 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7404 /*AllowExplicit=*/true);
7405 auto I = Captures.find(Capture);
7406 if (I != Captures.end())
7407 return buildCapture(SemaRef, Capture, I->second);
7408 DeclRefExpr *Ref = nullptr;
7409 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7410 Captures[Capture] = Ref;
7411 return Res;
7412}
7413
7414/// Calculate number of iterations, transforming to unsigned, if number of
7415/// iterations may be larger than the original type.
7416static Expr *
7417calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7418 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7419 bool TestIsStrictOp, bool RoundToStep,
7420 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7421 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7422 if (!NewStep.isUsable())
7423 return nullptr;
7424 llvm::APSInt LRes, SRes;
7425 bool IsLowerConst = false, IsStepConst = false;
7426 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7427 LRes = *Res;
7428 IsLowerConst = true;
7429 }
7430 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7431 SRes = *Res;
7432 IsStepConst = true;
7433 }
7434 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7435 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7436 (TestIsStrictOp && LRes.isStrictlyPositive()));
7437 bool NeedToReorganize = false;
7438 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7439 if (!NoNeedToConvert && IsLowerConst &&
7440 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7441 NoNeedToConvert = true;
7442 if (RoundToStep) {
7443 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7444 ? LRes.getBitWidth()
7445 : SRes.getBitWidth();
7446 LRes = LRes.extend(BW + 1);
7447 LRes.setIsSigned(true);
7448 SRes = SRes.extend(BW + 1);
7449 SRes.setIsSigned(true);
7450 LRes -= SRes;
7451 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7452 LRes = LRes.trunc(BW);
7453 }
7454 if (TestIsStrictOp) {
7455 unsigned BW = LRes.getBitWidth();
7456 LRes = LRes.extend(BW + 1);
7457 LRes.setIsSigned(true);
7458 ++LRes;
7459 NoNeedToConvert =
7460 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7461 // truncate to the original bitwidth.
7462 LRes = LRes.trunc(BW);
7463 }
7464 NeedToReorganize = NoNeedToConvert;
7465 }
7466 llvm::APSInt URes;
7467 bool IsUpperConst = false;
7468 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7469 URes = *Res;
7470 IsUpperConst = true;
7471 }
7472 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7473 (!RoundToStep || IsStepConst)) {
7474 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7475 : URes.getBitWidth();
7476 LRes = LRes.extend(BW + 1);
7477 LRes.setIsSigned(true);
7478 URes = URes.extend(BW + 1);
7479 URes.setIsSigned(true);
7480 URes -= LRes;
7481 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7482 NeedToReorganize = NoNeedToConvert;
7483 }
7484 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7485 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7486 // unsigned.
7487 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7488 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7489 QualType LowerTy = Lower->getType();
7490 QualType UpperTy = Upper->getType();
7491 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7492 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7493 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7494 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7495 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7496 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7497 Upper =
7498 SemaRef
7499 .PerformImplicitConversion(
7500 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7501 CastType, Sema::AA_Converting)
7502 .get();
7503 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7504 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7505 }
7506 }
7507 if (!Lower || !Upper || NewStep.isInvalid())
7508 return nullptr;
7509
7510 ExprResult Diff;
7511 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7512 // 1]).
7513 if (NeedToReorganize) {
7514 Diff = Lower;
7515
7516 if (RoundToStep) {
7517 // Lower - Step
7518 Diff =
7519 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7520 if (!Diff.isUsable())
7521 return nullptr;
7522 }
7523
7524 // Lower - Step [+ 1]
7525 if (TestIsStrictOp)
7526 Diff = SemaRef.BuildBinOp(
7527 S, DefaultLoc, BO_Add, Diff.get(),
7528 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7529 if (!Diff.isUsable())
7530 return nullptr;
7531
7532 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7533 if (!Diff.isUsable())
7534 return nullptr;
7535
7536 // Upper - (Lower - Step [+ 1]).
7537 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7538 if (!Diff.isUsable())
7539 return nullptr;
7540 } else {
7541 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7542
7543 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7544 // BuildBinOp already emitted error, this one is to point user to upper
7545 // and lower bound, and to tell what is passed to 'operator-'.
7546 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7547 << Upper->getSourceRange() << Lower->getSourceRange();
7548 return nullptr;
7549 }
7550
7551 if (!Diff.isUsable())
7552 return nullptr;
7553
7554 // Upper - Lower [- 1]
7555 if (TestIsStrictOp)
7556 Diff = SemaRef.BuildBinOp(
7557 S, DefaultLoc, BO_Sub, Diff.get(),
7558 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7559 if (!Diff.isUsable())
7560 return nullptr;
7561
7562 if (RoundToStep) {
7563 // Upper - Lower [- 1] + Step
7564 Diff =
7565 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7566 if (!Diff.isUsable())
7567 return nullptr;
7568 }
7569 }
7570
7571 // Parentheses (for dumping/debugging purposes only).
7572 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7573 if (!Diff.isUsable())
7574 return nullptr;
7575
7576 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7577 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7578 if (!Diff.isUsable())
7579 return nullptr;
7580
7581 return Diff.get();
7582}
7583
7584/// Build the expression to calculate the number of iterations.
7585Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7586 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7587 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7588 QualType VarType = LCDecl->getType().getNonReferenceType();
7589 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7590 !SemaRef.getLangOpts().CPlusPlus)
7591 return nullptr;
7592 Expr *LBVal = LB;
7593 Expr *UBVal = UB;
7594 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7595 // max(LB(MinVal), LB(MaxVal))
7596 if (InitDependOnLC) {
7597 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
7598 if (!IS.MinValue || !IS.MaxValue)
7599 return nullptr;
7600 // OuterVar = Min
7601 ExprResult MinValue =
7602 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7603 if (!MinValue.isUsable())
7604 return nullptr;
7605
7606 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7607 IS.CounterVar, MinValue.get());
7608 if (!LBMinVal.isUsable())
7609 return nullptr;
7610 // OuterVar = Min, LBVal
7611 LBMinVal =
7612 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7613 if (!LBMinVal.isUsable())
7614 return nullptr;
7615 // (OuterVar = Min, LBVal)
7616 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7617 if (!LBMinVal.isUsable())
7618 return nullptr;
7619
7620 // OuterVar = Max
7621 ExprResult MaxValue =
7622 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7623 if (!MaxValue.isUsable())
7624 return nullptr;
7625
7626 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7627 IS.CounterVar, MaxValue.get());
7628 if (!LBMaxVal.isUsable())
7629 return nullptr;
7630 // OuterVar = Max, LBVal
7631 LBMaxVal =
7632 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7633 if (!LBMaxVal.isUsable())
7634 return nullptr;
7635 // (OuterVar = Max, LBVal)
7636 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7637 if (!LBMaxVal.isUsable())
7638 return nullptr;
7639
7640 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7641 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7642 if (!LBMin || !LBMax)
7643 return nullptr;
7644 // LB(MinVal) < LB(MaxVal)
7645 ExprResult MinLessMaxRes =
7646 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7647 if (!MinLessMaxRes.isUsable())
7648 return nullptr;
7649 Expr *MinLessMax =
7650 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7651 if (!MinLessMax)
7652 return nullptr;
7653 if (TestIsLessOp.getValue()) {
7654 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7655 // LB(MaxVal))
7656 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7657 MinLessMax, LBMin, LBMax);
7658 if (!MinLB.isUsable())
7659 return nullptr;
7660 LBVal = MinLB.get();
7661 } else {
7662 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7663 // LB(MaxVal))
7664 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7665 MinLessMax, LBMax, LBMin);
7666 if (!MaxLB.isUsable())
7667 return nullptr;
7668 LBVal = MaxLB.get();
7669 }
7670 }
7671 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7672 // min(UB(MinVal), UB(MaxVal))
7673 if (CondDependOnLC) {
7674 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
7675 if (!IS.MinValue || !IS.MaxValue)
7676 return nullptr;
7677 // OuterVar = Min
7678 ExprResult MinValue =
7679 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7680 if (!MinValue.isUsable())
7681 return nullptr;
7682
7683 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7684 IS.CounterVar, MinValue.get());
7685 if (!UBMinVal.isUsable())
7686 return nullptr;
7687 // OuterVar = Min, UBVal
7688 UBMinVal =
7689 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7690 if (!UBMinVal.isUsable())
7691 return nullptr;
7692 // (OuterVar = Min, UBVal)
7693 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7694 if (!UBMinVal.isUsable())
7695 return nullptr;
7696
7697 // OuterVar = Max
7698 ExprResult MaxValue =
7699 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7700 if (!MaxValue.isUsable())
7701 return nullptr;
7702
7703 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7704 IS.CounterVar, MaxValue.get());
7705 if (!UBMaxVal.isUsable())
7706 return nullptr;
7707 // OuterVar = Max, UBVal
7708 UBMaxVal =
7709 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7710 if (!UBMaxVal.isUsable())
7711 return nullptr;
7712 // (OuterVar = Max, UBVal)
7713 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7714 if (!UBMaxVal.isUsable())
7715 return nullptr;
7716
7717 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7718 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7719 if (!UBMin || !UBMax)
7720 return nullptr;
7721 // UB(MinVal) > UB(MaxVal)
7722 ExprResult MinGreaterMaxRes =
7723 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7724 if (!MinGreaterMaxRes.isUsable())
7725 return nullptr;
7726 Expr *MinGreaterMax =
7727 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7728 if (!MinGreaterMax)
7729 return nullptr;
7730 if (TestIsLessOp.getValue()) {
7731 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7732 // UB(MaxVal))
7733 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7734 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7735 if (!MaxUB.isUsable())
7736 return nullptr;
7737 UBVal = MaxUB.get();
7738 } else {
7739 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7740 // UB(MaxVal))
7741 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7742 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7743 if (!MinUB.isUsable())
7744 return nullptr;
7745 UBVal = MinUB.get();
7746 }
7747 }
7748 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7749 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7750 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7751 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7752 if (!Upper || !Lower)
7753 return nullptr;
7754
7755 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7756 Step, VarType, TestIsStrictOp,
7757 /*RoundToStep=*/true, Captures);
7758 if (!Diff.isUsable())
7759 return nullptr;
7760
7761 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7762 QualType Type = Diff.get()->getType();
7763 ASTContext &C = SemaRef.Context;
7764 bool UseVarType = VarType->hasIntegerRepresentation() &&
7765 C.getTypeSize(Type) > C.getTypeSize(VarType);
7766 if (!Type->isIntegerType() || UseVarType) {
7767 unsigned NewSize =
7768 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7769 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7770 : Type->hasSignedIntegerRepresentation();
7771 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7772 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7773 Diff = SemaRef.PerformImplicitConversion(
7774 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7775 if (!Diff.isUsable())
7776 return nullptr;
7777 }
7778 }
7779 if (LimitedType) {
7780 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7781 if (NewSize != C.getTypeSize(Type)) {
7782 if (NewSize < C.getTypeSize(Type)) {
7783 assert(NewSize == 64 && "incorrect loop var size")((NewSize == 64 && "incorrect loop var size") ? static_cast
<void> (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 7783, __PRETTY_FUNCTION__))
;
7784 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7785 << InitSrcRange << ConditionSrcRange;
7786 }
7787 QualType NewType = C.getIntTypeForBitwidth(
7788 NewSize, Type->hasSignedIntegerRepresentation() ||
7789 C.getTypeSize(Type) < NewSize);
7790 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7791 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7792 Sema::AA_Converting, true);
7793 if (!Diff.isUsable())
7794 return nullptr;
7795 }
7796 }
7797 }
7798
7799 return Diff.get();
7800}
7801
7802std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7803 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7804 // Do not build for iterators, they cannot be used in non-rectangular loop
7805 // nests.
7806 if (LCDecl->getType()->isRecordType())
7807 return std::make_pair(nullptr, nullptr);
7808 // If we subtract, the min is in the condition, otherwise the min is in the
7809 // init value.
7810 Expr *MinExpr = nullptr;
7811 Expr *MaxExpr = nullptr;
7812 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7813 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7814 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7815 : CondDependOnLC.hasValue();
7816 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7817 : InitDependOnLC.hasValue();
7818 Expr *Lower =
7819 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7820 Expr *Upper =
7821 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7822 if (!Upper || !Lower)
7823 return std::make_pair(nullptr, nullptr);
7824
7825 if (TestIsLessOp.getValue())
7826 MinExpr = Lower;
7827 else
7828 MaxExpr = Upper;
7829
7830 // Build minimum/maximum value based on number of iterations.
7831 QualType VarType = LCDecl->getType().getNonReferenceType();
7832
7833 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7834 Step, VarType, TestIsStrictOp,
7835 /*RoundToStep=*/false, Captures);
7836 if (!Diff.isUsable())
7837 return std::make_pair(nullptr, nullptr);
7838
7839 // ((Upper - Lower [- 1]) / Step) * Step
7840 // Parentheses (for dumping/debugging purposes only).
7841 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7842 if (!Diff.isUsable())
7843 return std::make_pair(nullptr, nullptr);
7844
7845 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7846 if (!NewStep.isUsable())
7847 return std::make_pair(nullptr, nullptr);
7848 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7849 if (!Diff.isUsable())
7850 return std::make_pair(nullptr, nullptr);
7851
7852 // Parentheses (for dumping/debugging purposes only).
7853 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7854 if (!Diff.isUsable())
7855 return std::make_pair(nullptr, nullptr);
7856
7857 // Convert to the ptrdiff_t, if original type is pointer.
7858 if (VarType->isAnyPointerType() &&
7859 !SemaRef.Context.hasSameType(
7860 Diff.get()->getType(),
7861 SemaRef.Context.getUnsignedPointerDiffType())) {
7862 Diff = SemaRef.PerformImplicitConversion(
7863 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7864 Sema::AA_Converting, /*AllowExplicit=*/true);
7865 }
7866 if (!Diff.isUsable())
7867 return std::make_pair(nullptr, nullptr);
7868
7869 if (TestIsLessOp.getValue()) {
7870 // MinExpr = Lower;
7871 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7872 Diff = SemaRef.BuildBinOp(
7873 S, DefaultLoc, BO_Add,
7874 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7875 Diff.get());
7876 if (!Diff.isUsable())
7877 return std::make_pair(nullptr, nullptr);
7878 } else {
7879 // MaxExpr = Upper;
7880 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7881 Diff = SemaRef.BuildBinOp(
7882 S, DefaultLoc, BO_Sub,
7883 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7884 Diff.get());
7885 if (!Diff.isUsable())
7886 return std::make_pair(nullptr, nullptr);
7887 }
7888
7889 // Convert to the original type.
7890 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7891 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7892 Sema::AA_Converting,
7893 /*AllowExplicit=*/true);
7894 if (!Diff.isUsable())
7895 return std::make_pair(nullptr, nullptr);
7896
7897 Sema::TentativeAnalysisScope Trap(SemaRef);
7898 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7899 if (!Diff.isUsable())
7900 return std::make_pair(nullptr, nullptr);
7901
7902 if (TestIsLessOp.getValue())
7903 MaxExpr = Diff.get();
7904 else
7905 MinExpr = Diff.get();
7906
7907 return std::make_pair(MinExpr, MaxExpr);
7908}
7909
7910Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7911 if (InitDependOnLC || CondDependOnLC)
7912 return Condition;
7913 return nullptr;
7914}
7915
7916Expr *OpenMPIterationSpaceChecker::buildPreCond(
7917 Scope *S, Expr *Cond,
7918 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7919 // Do not build a precondition when the condition/initialization is dependent
7920 // to prevent pessimistic early loop exit.
7921 // TODO: this can be improved by calculating min/max values but not sure that
7922 // it will be very effective.
7923 if (CondDependOnLC || InitDependOnLC)
7924 return SemaRef.PerformImplicitConversion(
7925 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7926 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7927 /*AllowExplicit=*/true).get();
7928
7929 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7930 Sema::TentativeAnalysisScope Trap(SemaRef);
7931
7932 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7933 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7934 if (!NewLB.isUsable() || !NewUB.isUsable())
7935 return nullptr;
7936
7937 ExprResult CondExpr =
7938 SemaRef.BuildBinOp(S, DefaultLoc,
7939 TestIsLessOp.getValue() ?
7940 (TestIsStrictOp ? BO_LT : BO_LE) :
7941 (TestIsStrictOp ? BO_GT : BO_GE),
7942 NewLB.get(), NewUB.get());
7943 if (CondExpr.isUsable()) {
7944 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7945 SemaRef.Context.BoolTy))
7946 CondExpr = SemaRef.PerformImplicitConversion(
7947 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7948 /*AllowExplicit=*/true);
7949 }
7950
7951 // Otherwise use original loop condition and evaluate it in runtime.
7952 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7953}
7954
7955/// Build reference expression to the counter be used for codegen.
7956DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7957 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7958 DSAStackTy &DSA) const {
7959 auto *VD = dyn_cast<VarDecl>(LCDecl);
7960 if (!VD) {
7961 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7962 DeclRefExpr *Ref = buildDeclRefExpr(
7963 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7964 const DSAStackTy::DSAVarData Data =
7965 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7966 // If the loop control decl is explicitly marked as private, do not mark it
7967 // as captured again.
7968 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7969 Captures.insert(std::make_pair(LCRef, Ref));
7970 return Ref;
7971 }
7972 return cast<DeclRefExpr>(LCRef);
7973}
7974
7975Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7976 if (LCDecl && !LCDecl->isInvalidDecl()) {
7977 QualType Type = LCDecl->getType().getNonReferenceType();
7978 VarDecl *PrivateVar = buildVarDecl(
7979 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7980 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7981 isa<VarDecl>(LCDecl)
7982 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7983 : nullptr);
7984 if (PrivateVar->isInvalidDecl())
7985 return nullptr;
7986 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7987 }
7988 return nullptr;
7989}
7990
7991/// Build initialization of the counter to be used for codegen.
7992Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7993
7994/// Build step of the counter be used for codegen.
7995Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7996
7997Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7998 Scope *S, Expr *Counter,
7999 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8000 Expr *Inc, OverloadedOperatorKind OOK) {
8001 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8002 if (!Cnt)
8003 return nullptr;
8004 if (Inc) {
8005 assert((OOK == OO_Plus || OOK == OO_Minus) &&(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8006, __PRETTY_FUNCTION__))
8006 "Expected only + or - operations for depend clauses.")(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8006, __PRETTY_FUNCTION__))
;
8007 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8008 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8009 if (!Cnt)
8010 return nullptr;
8011 }
8012 QualType VarType = LCDecl->getType().getNonReferenceType();
8013 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8014 !SemaRef.getLangOpts().CPlusPlus)
8015 return nullptr;
8016 // Upper - Lower
8017 Expr *Upper = TestIsLessOp.getValue()
8018 ? Cnt
8019 : tryBuildCapture(SemaRef, LB, Captures).get();
8020 Expr *Lower = TestIsLessOp.getValue()
8021 ? tryBuildCapture(SemaRef, LB, Captures).get()
8022 : Cnt;
8023 if (!Upper || !Lower)
8024 return nullptr;
8025
8026 ExprResult Diff = calculateNumIters(
8027 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8028 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8029 if (!Diff.isUsable())
8030 return nullptr;
8031
8032 return Diff.get();
8033}
8034} // namespace
8035
8036void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8037 assert(getLangOpts().OpenMP && "OpenMP is not active.")((getLangOpts().OpenMP && "OpenMP is not active.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8037, __PRETTY_FUNCTION__))
;
8038 assert(Init && "Expected loop in canonical form.")((Init && "Expected loop in canonical form.") ? static_cast
<void> (0) : __assert_fail ("Init && \"Expected loop in canonical form.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8038, __PRETTY_FUNCTION__))
;
8039 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
8040 if (AssociatedLoops > 0 &&
8041 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
8042 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
8043 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8044 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
8045 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8046 if (ValueDecl *D = ISC.getLoopDecl()) {
8047 auto *VD = dyn_cast<VarDecl>(D);
8048 DeclRefExpr *PrivateRef = nullptr;
8049 if (!VD) {
8050 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8051 VD = Private;
8052 } else {
8053 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8054 /*WithInit=*/false);
8055 VD = cast<VarDecl>(PrivateRef->getDecl());
8056 }
8057 }
8058 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
8059 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
8060 if (LD != D->getCanonicalDecl()) {
8061 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
8062 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8063 MarkDeclarationsReferencedInExpr(
8064 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8065 Var->getType().getNonLValueExprType(Context),
8066 ForLoc, /*RefersToCapture=*/true));
8067 }
8068 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
8069 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8070 // Referenced in a Construct, C/C++]. The loop iteration variable in the
8071 // associated for-loop of a simd construct with just one associated
8072 // for-loop may be listed in a linear clause with a constant-linear-step
8073 // that is the increment of the associated for-loop. The loop iteration
8074 // variable(s) in the associated for-loop(s) of a for or parallel for
8075 // construct may be listed in a private or lastprivate clause.
8076 DSAStackTy::DSAVarData DVar =
8077 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
8078 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8079 // is declared in the loop and it is predetermined as a private.
8080 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8081 OpenMPClauseKind PredeterminedCKind =
8082 isOpenMPSimdDirective(DKind)
8083 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8084 : OMPC_private;
8085 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8086 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8087 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8088 DVar.CKind != OMPC_private))) ||
8089 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8090 DKind == OMPD_master_taskloop ||
8091 DKind == OMPD_parallel_master_taskloop ||
8092 isOpenMPDistributeDirective(DKind)) &&
8093 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8094 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8095 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8096 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8097 << getOpenMPClauseName(DVar.CKind)
8098 << getOpenMPDirectiveName(DKind)
8099 << getOpenMPClauseName(PredeterminedCKind);
8100 if (DVar.RefExpr == nullptr)
8101 DVar.CKind = PredeterminedCKind;
8102 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
8103 /*IsLoopIterVar=*/true);
8104 } else if (LoopDeclRefExpr) {
8105 // Make the loop iteration variable private (for worksharing
8106 // constructs), linear (for simd directives with the only one
8107 // associated loop) or lastprivate (for simd directives with several
8108 // collapsed or ordered loops).
8109 if (DVar.CKind == OMPC_unknown)
8110 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8111 PrivateRef);
8112 }
8113 }
8114 }
8115 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
8116 }
8117}
8118
8119/// Called on a for stmt to check and extract its iteration space
8120/// for further processing (such as collapsing).
8121static bool checkOpenMPIterationSpace(
8122 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8123 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8124 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8125 Expr *OrderedLoopCountExpr,
8126 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8127 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8128 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8129 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
3
Assuming the condition is false
8130 // OpenMP [2.9.1, Canonical Loop Form]
8131 // for (init-expr; test-expr; incr-expr) structured-block
8132 // for (range-decl: range-expr) structured-block
8133 auto *For = dyn_cast_or_null<ForStmt>(S);
4
Assuming 'S' is not a 'ForStmt'
8134 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
5
Assuming 'S' is not a 'CXXForRangeStmt'
8135 // Ranged for is supported only in OpenMP 5.0.
8136 if (!For
5.1
'For' is null
&& (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
6
Assuming field 'OpenMP' is <= 45
8137 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8138 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7
Assuming pointer value is null
8
Assuming pointer value is null
8139 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8140 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9
Assuming 'CurrentNestedLoopCount' is <= 0
8141 if (TotalNestedLoopCount > 1) {
10
Assuming 'TotalNestedLoopCount' is > 1
11
Taking true branch
8142 if (CollapseLoopCountExpr
11.1
'CollapseLoopCountExpr' is null
&& OrderedLoopCountExpr)
8143 SemaRef.Diag(DSA.getConstructLoc(),
8144 diag::note_omp_collapse_ordered_expr)
8145 << 2 << CollapseLoopCountExpr->getSourceRange()
8146 << OrderedLoopCountExpr->getSourceRange();
8147 else if (CollapseLoopCountExpr
11.2
'CollapseLoopCountExpr' is null
)
12
Taking false branch
8148 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8149 diag::note_omp_collapse_ordered_expr)
8150 << 0 << CollapseLoopCountExpr->getSourceRange();
8151 else
8152 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
13
Called C++ object pointer is null
8153 diag::note_omp_collapse_ordered_expr)
8154 << 1 << OrderedLoopCountExpr->getSourceRange();
8155 }
8156 return true;
8157 }
8158 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&((((For && For->getBody()) || (CXXFor && CXXFor
->getBody())) && "No loop body.") ? static_cast<
void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8159, __PRETTY_FUNCTION__))
8159 "No loop body.")((((For && For->getBody()) || (CXXFor && CXXFor
->getBody())) && "No loop body.") ? static_cast<
void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8159, __PRETTY_FUNCTION__))
;
8160
8161 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8162 For ? For->getForLoc() : CXXFor->getForLoc());
8163
8164 // Check init.
8165 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8166 if (ISC.checkAndSetInit(Init))
8167 return true;
8168
8169 bool HasErrors = false;
8170
8171 // Check loop variable's type.
8172 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8173 // OpenMP [2.6, Canonical Loop Form]
8174 // Var is one of the following:
8175 // A variable of signed or unsigned integer type.
8176 // For C++, a variable of a random access iterator type.
8177 // For C, a variable of a pointer type.
8178 QualType VarType = LCDecl->getType().getNonReferenceType();
8179 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8180 !VarType->isPointerType() &&
8181 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8182 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8183 << SemaRef.getLangOpts().CPlusPlus;
8184 HasErrors = true;
8185 }
8186
8187 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8188 // a Construct
8189 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8190 // parallel for construct is (are) private.
8191 // The loop iteration variable in the associated for-loop of a simd
8192 // construct with just one associated for-loop is linear with a
8193 // constant-linear-step that is the increment of the associated for-loop.
8194 // Exclude loop var from the list of variables with implicitly defined data
8195 // sharing attributes.
8196 VarsWithImplicitDSA.erase(LCDecl);
8197
8198 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")((isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8198, __PRETTY_FUNCTION__))
;
8199
8200 // Check test-expr.
8201 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8202
8203 // Check incr-expr.
8204 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8205 }
8206
8207 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8208 return HasErrors;
8209
8210 // Build the loop's iteration space representation.
8211 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8212 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8213 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8214 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8215 (isOpenMPWorksharingDirective(DKind) ||
8216 isOpenMPTaskLoopDirective(DKind) ||
8217 isOpenMPDistributeDirective(DKind) ||
8218 isOpenMPLoopTransformationDirective(DKind)),
8219 Captures);
8220 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8221 ISC.buildCounterVar(Captures, DSA);
8222 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8223 ISC.buildPrivateCounterVar();
8224 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8225 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8226 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8227 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8228 ISC.getConditionSrcRange();
8229 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8230 ISC.getIncrementSrcRange();
8231 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8232 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8233 ISC.isStrictTestOp();
8234 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8235 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8236 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8237 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8238 ISC.buildFinalCondition(DSA.getCurScope());
8239 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8240 ISC.doesInitDependOnLC();
8241 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8242 ISC.doesCondDependOnLC();
8243 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8244 ISC.getLoopDependentIdx();
8245
8246 HasErrors |=
8247 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8248 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8249 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8250 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8251 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8252 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8253 if (!HasErrors && DSA.isOrderedRegion()) {
8254 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8255 if (CurrentNestedLoopCount <
8256 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8257 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8258 CurrentNestedLoopCount,
8259 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8260 DSA.getOrderedRegionParam().second->setLoopCounter(
8261 CurrentNestedLoopCount,
8262 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8263 }
8264 }
8265 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8266 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8267 // Erroneous case - clause has some problems.
8268 continue;
8269 }
8270 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8271 Pair.second.size() <= CurrentNestedLoopCount) {
8272 // Erroneous case - clause has some problems.
8273 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8274 continue;
8275 }
8276 Expr *CntValue;
8277 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8278 CntValue = ISC.buildOrderedLoopData(
8279 DSA.getCurScope(),
8280 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8281 Pair.first->getDependencyLoc());
8282 else
8283 CntValue = ISC.buildOrderedLoopData(
8284 DSA.getCurScope(),
8285 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8286 Pair.first->getDependencyLoc(),
8287 Pair.second[CurrentNestedLoopCount].first,
8288 Pair.second[CurrentNestedLoopCount].second);
8289 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8290 }
8291 }
8292
8293 return HasErrors;
8294}
8295
8296/// Build 'VarRef = Start.
8297static ExprResult
8298buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8299 ExprResult Start, bool IsNonRectangularLB,
8300 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8301 // Build 'VarRef = Start.
8302 ExprResult NewStart = IsNonRectangularLB
8303 ? Start.get()
8304 : tryBuildCapture(SemaRef, Start.get(), Captures);
8305 if (!NewStart.isUsable())
8306 return ExprError();
8307 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8308 VarRef.get()->getType())) {
8309 NewStart = SemaRef.PerformImplicitConversion(
8310 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8311 /*AllowExplicit=*/true);
8312 if (!NewStart.isUsable())
8313 return ExprError();
8314 }
8315
8316 ExprResult Init =
8317 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8318 return Init;
8319}
8320
8321/// Build 'VarRef = Start + Iter * Step'.
8322static ExprResult buildCounterUpdate(
8323 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8324 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8325 bool IsNonRectangularLB,
8326 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8327 // Add parentheses (for debugging purposes only).
8328 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8329 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8330 !Step.isUsable())
8331 return ExprError();
8332
8333 ExprResult NewStep = Step;
8334 if (Captures)
8335 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8336 if (NewStep.isInvalid())
8337 return ExprError();
8338 ExprResult Update =
8339 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8340 if (!Update.isUsable())
8341 return ExprError();
8342
8343 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8344 // 'VarRef = Start (+|-) Iter * Step'.
8345 if (!Start.isUsable())
8346 return ExprError();
8347 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8348 if (!NewStart.isUsable())
8349 return ExprError();
8350 if (Captures && !IsNonRectangularLB)
8351 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8352 if (NewStart.isInvalid())
8353 return ExprError();
8354
8355 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8356 ExprResult SavedUpdate = Update;
8357 ExprResult UpdateVal;
8358 if (VarRef.get()->getType()->isOverloadableType() ||
8359 NewStart.get()->getType()->isOverloadableType() ||
8360 Update.get()->getType()->isOverloadableType()) {
8361 Sema::TentativeAnalysisScope Trap(SemaRef);
8362
8363 Update =
8364 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8365 if (Update.isUsable()) {
8366 UpdateVal =
8367 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8368 VarRef.get(), SavedUpdate.get());
8369 if (UpdateVal.isUsable()) {
8370 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8371 UpdateVal.get());
8372 }
8373 }
8374 }
8375
8376 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8377 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8378 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8379 NewStart.get(), SavedUpdate.get());
8380 if (!Update.isUsable())
8381 return ExprError();
8382
8383 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8384 VarRef.get()->getType())) {
8385 Update = SemaRef.PerformImplicitConversion(
8386 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8387 if (!Update.isUsable())
8388 return ExprError();
8389 }
8390
8391 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8392 }
8393 return Update;
8394}
8395
8396/// Convert integer expression \a E to make it have at least \a Bits
8397/// bits.
8398static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8399 if (E == nullptr)
8400 return ExprError();
8401 ASTContext &C = SemaRef.Context;
8402 QualType OldType = E->getType();
8403 unsigned HasBits = C.getTypeSize(OldType);
8404 if (HasBits >= Bits)
8405 return ExprResult(E);
8406 // OK to convert to signed, because new type has more bits than old.
8407 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8408 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8409 true);
8410}
8411
8412/// Check if the given expression \a E is a constant integer that fits
8413/// into \a Bits bits.
8414static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8415 if (E == nullptr)
8416 return false;
8417 if (Optional<llvm::APSInt> Result =
8418 E->getIntegerConstantExpr(SemaRef.Context))
8419 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8420 return false;
8421}
8422
8423/// Build preinits statement for the given declarations.
8424static Stmt *buildPreInits(ASTContext &Context,
8425 MutableArrayRef<Decl *> PreInits) {
8426 if (!PreInits.empty()) {
8427 return new (Context) DeclStmt(
8428 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8429 SourceLocation(), SourceLocation());
8430 }
8431 return nullptr;
8432}
8433
8434/// Build preinits statement for the given declarations.
8435static Stmt *
8436buildPreInits(ASTContext &Context,
8437 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8438 if (!Captures.empty()) {
8439 SmallVector<Decl *, 16> PreInits;
8440 for (const auto &Pair : Captures)
8441 PreInits.push_back(Pair.second->getDecl());
8442 return buildPreInits(Context, PreInits);
8443 }
8444 return nullptr;
8445}
8446
8447/// Build postupdate expression for the given list of postupdates expressions.
8448static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8449 Expr *PostUpdate = nullptr;
8450 if (!PostUpdates.empty()) {
8451 for (Expr *E : PostUpdates) {
8452 Expr *ConvE = S.BuildCStyleCastExpr(
8453 E->getExprLoc(),
8454 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8455 E->getExprLoc(), E)
8456 .get();
8457 PostUpdate = PostUpdate
8458 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8459 PostUpdate, ConvE)
8460 .get()
8461 : ConvE;
8462 }
8463 }
8464 return PostUpdate;
8465}
8466
8467/// Called on a for stmt to check itself and nested loops (if any).
8468/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8469/// number of collapsed loops otherwise.
8470static unsigned
8471checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8472 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8473 DSAStackTy &DSA,
8474 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8475 OMPLoopBasedDirective::HelperExprs &Built) {
8476 unsigned NestedLoopCount = 1;
8477 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8478 !isOpenMPLoopTransformationDirective(DKind);
8479
8480 if (CollapseLoopCountExpr) {
8481 // Found 'collapse' clause - calculate collapse number.
8482 Expr::EvalResult Result;
8483 if (!CollapseLoopCountExpr->isValueDependent() &&
8484 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8485 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8486 } else {
8487 Built.clear(/*Size=*/1);
8488 return 1;
8489 }
8490 }
8491 unsigned OrderedLoopCount = 1;
8492 if (OrderedLoopCountExpr) {
8493 // Found 'ordered' clause - calculate collapse number.
8494 Expr::EvalResult EVResult;
8495 if (!OrderedLoopCountExpr->isValueDependent() &&
8496 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8497 SemaRef.getASTContext())) {
8498 llvm::APSInt Result = EVResult.Val.getInt();
8499 if (Result.getLimitedValue() < NestedLoopCount) {
8500 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8501 diag::err_omp_wrong_ordered_loop_count)
8502 << OrderedLoopCountExpr->getSourceRange();
8503 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8504 diag::note_collapse_loop_count)
8505 << CollapseLoopCountExpr->getSourceRange();
8506 }
8507 OrderedLoopCount = Result.getLimitedValue();
8508 } else {
8509 Built.clear(/*Size=*/1);
8510 return 1;
8511 }
8512 }
8513 // This is helper routine for loop directives (e.g., 'for', 'simd',
8514 // 'for simd', etc.).
8515 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8516 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
8517 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
8518 if (!OMPLoopBasedDirective::doForAllLoops(
8519 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
8520 SupportsNonPerfectlyNested, NumLoops,
8521 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
8522 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
8523 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
8524 if (checkOpenMPIterationSpace(
2
Calling 'checkOpenMPIterationSpace'
8525 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8526 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
1
Passing value via 9th parameter 'OrderedLoopCountExpr'
8527 VarsWithImplicitDSA, IterSpaces, Captures))
8528 return true;
8529 if (Cnt > 0 && Cnt >= NestedLoopCount &&
8530 IterSpaces[Cnt].CounterVar) {
8531 // Handle initialization of captured loop iterator variables.
8532 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8533 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8534 Captures[DRE] = DRE;
8535 }
8536 }
8537 return false;
8538 }))
8539 return 0;
8540
8541 Built.clear(/* size */ NestedLoopCount);
8542
8543 if (SemaRef.CurContext->isDependentContext())
8544 return NestedLoopCount;
8545
8546 // An example of what is generated for the following code:
8547 //
8548 // #pragma omp simd collapse(2) ordered(2)
8549 // for (i = 0; i < NI; ++i)
8550 // for (k = 0; k < NK; ++k)
8551 // for (j = J0; j < NJ; j+=2) {
8552 // <loop body>
8553 // }
8554 //
8555 // We generate the code below.
8556 // Note: the loop body may be outlined in CodeGen.
8557 // Note: some counters may be C++ classes, operator- is used to find number of
8558 // iterations and operator+= to calculate counter value.
8559 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8560 // or i64 is currently supported).
8561 //
8562 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8563 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8564 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8565 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8566 // // similar updates for vars in clauses (e.g. 'linear')
8567 // <loop body (using local i and j)>
8568 // }
8569 // i = NI; // assign final values of counters
8570 // j = NJ;
8571 //
8572
8573 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8574 // the iteration counts of the collapsed for loops.
8575 // Precondition tests if there is at least one iteration (all conditions are
8576 // true).
8577 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8578 Expr *N0 = IterSpaces[0].NumIterations;
8579 ExprResult LastIteration32 =
8580 widenIterationCount(/*Bits=*/32,
8581 SemaRef
8582 .PerformImplicitConversion(
8583 N0->IgnoreImpCasts(), N0->getType(),
8584 Sema::AA_Converting, /*AllowExplicit=*/true)
8585 .get(),
8586 SemaRef);
8587 ExprResult LastIteration64 = widenIterationCount(
8588 /*Bits=*/64,
8589 SemaRef
8590 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8591 Sema::AA_Converting,
8592 /*AllowExplicit=*/true)
8593 .get(),
8594 SemaRef);
8595
8596 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8597 return NestedLoopCount;
8598
8599 ASTContext &C = SemaRef.Context;
8600 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8601
8602 Scope *CurScope = DSA.getCurScope();
8603 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8604 if (PreCond.isUsable()) {
8605 PreCond =
8606 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8607 PreCond.get(), IterSpaces[Cnt].PreCond);
8608 }
8609 Expr *N = IterSpaces[Cnt].NumIterations;
8610 SourceLocation Loc = N->getExprLoc();
8611 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8612 if (LastIteration32.isUsable())
8613 LastIteration32 = SemaRef.BuildBinOp(
8614 CurScope, Loc, BO_Mul, LastIteration32.get(),
8615 SemaRef
8616 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8617 Sema::AA_Converting,
8618 /*AllowExplicit=*/true)
8619 .get());
8620 if (LastIteration64.isUsable())
8621 LastIteration64 = SemaRef.BuildBinOp(
8622 CurScope, Loc, BO_Mul, LastIteration64.get(),
8623 SemaRef
8624 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8625 Sema::AA_Converting,
8626 /*AllowExplicit=*/true)
8627 .get());
8628 }
8629
8630 // Choose either the 32-bit or 64-bit version.
8631 ExprResult LastIteration = LastIteration64;
8632 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8633 (LastIteration32.isUsable() &&
8634 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8635 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8636 fitsInto(
8637 /*Bits=*/32,
8638 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8639 LastIteration64.get(), SemaRef))))
8640 LastIteration = LastIteration32;
8641 QualType VType = LastIteration.get()->getType();
8642 QualType RealVType = VType;
8643 QualType StrideVType = VType;
8644 if (isOpenMPTaskLoopDirective(DKind)) {
8645 VType =
8646 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8647 StrideVType =
8648 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8649 }
8650
8651 if (!LastIteration.isUsable())
8652 return 0;
8653
8654 // Save the number of iterations.
8655 ExprResult NumIterations = LastIteration;
8656 {
8657 LastIteration = SemaRef.BuildBinOp(
8658 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8659 LastIteration.get(),
8660 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8661 if (!LastIteration.isUsable())
8662 return 0;
8663 }
8664
8665 // Calculate the last iteration number beforehand instead of doing this on
8666 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8667 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8668 ExprResult CalcLastIteration;
8669 if (!IsConstant) {
8670 ExprResult SaveRef =
8671 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8672 LastIteration = SaveRef;
8673
8674 // Prepare SaveRef + 1.
8675 NumIterations = SemaRef.BuildBinOp(
8676 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8677 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8678 if (!NumIterations.isUsable())
8679 return 0;
8680 }
8681
8682 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8683
8684 // Build variables passed into runtime, necessary for worksharing directives.
8685 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8686 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8687 isOpenMPDistributeDirective(DKind) ||
8688 isOpenMPLoopTransformationDirective(DKind)) {
8689 // Lower bound variable, initialized with zero.
8690 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8691 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8692 SemaRef.AddInitializerToDecl(LBDecl,
8693 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8694 /*DirectInit*/ false);
8695
8696 // Upper bound variable, initialized with last iteration number.
8697 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8698 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8699 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8700 /*DirectInit*/ false);
8701
8702 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8703 // This will be used to implement clause 'lastprivate'.
8704 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8705 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8706 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8707 SemaRef.AddInitializerToDecl(ILDecl,
8708 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8709 /*DirectInit*/ false);
8710
8711 // Stride variable returned by runtime (we initialize it to 1 by default).
8712 VarDecl *STDecl =
8713 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8714 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8715 SemaRef.AddInitializerToDecl(STDecl,
8716 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8717 /*DirectInit*/ false);
8718
8719 // Build expression: UB = min(UB, LastIteration)
8720 // It is necessary for CodeGen of directives with static scheduling.
8721 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8722 UB.get(), LastIteration.get());
8723 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8724 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8725 LastIteration.get(), UB.get());
8726 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8727 CondOp.get());
8728 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8729
8730 // If we have a combined directive that combines 'distribute', 'for' or
8731 // 'simd' we need to be able to access the bounds of the schedule of the
8732 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8733 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8734 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8735 // Lower bound variable, initialized with zero.
8736 VarDecl *CombLBDecl =
8737 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8738 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8739 SemaRef.AddInitializerToDecl(
8740 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8741 /*DirectInit*/ false);
8742
8743 // Upper bound variable, initialized with last iteration number.
8744 VarDecl *CombUBDecl =
8745 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8746 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8747 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8748 /*DirectInit*/ false);
8749
8750 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8751 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8752 ExprResult CombCondOp =
8753 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8754 LastIteration.get(), CombUB.get());
8755 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8756 CombCondOp.get());
8757 CombEUB =
8758 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8759
8760 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8761 // We expect to have at least 2 more parameters than the 'parallel'
8762 // directive does - the lower and upper bounds of the previous schedule.
8763 assert(CD->getNumParams() >= 4 &&((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8764, __PRETTY_FUNCTION__))
8764 "Unexpected number of parameters in loop combined directive")((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8764, __PRETTY_FUNCTION__))
;
8765
8766 // Set the proper type for the bounds given what we learned from the
8767 // enclosed loops.
8768 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8769 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8770
8771 // Previous lower and upper bounds are obtained from the region
8772 // parameters.
8773 PrevLB =
8774 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8775 PrevUB =
8776 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8777 }
8778 }
8779
8780 // Build the iteration variable and its initialization before loop.
8781 ExprResult IV;
8782 ExprResult Init, CombInit;
8783 {
8784 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8785 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8786 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
8787 isOpenMPTaskLoopDirective(DKind) ||
8788 isOpenMPDistributeDirective(DKind) ||
8789 isOpenMPLoopTransformationDirective(DKind))
8790 ? LB.get()
8791 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8792 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8793 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8794
8795 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8796 Expr *CombRHS =
8797 (isOpenMPWorksharingDirective(DKind) ||
8798 isOpenMPTaskLoopDirective(DKind) ||
8799 isOpenMPDistributeDirective(DKind))
8800 ? CombLB.get()
8801 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8802 CombInit =
8803 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8804 CombInit =
8805 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8806 }
8807 }
8808
8809 bool UseStrictCompare =
8810 RealVType->hasUnsignedIntegerRepresentation() &&
8811 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8812 return LIS.IsStrictCompare;
8813 });
8814 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8815 // unsigned IV)) for worksharing loops.
8816 SourceLocation CondLoc = AStmt->getBeginLoc();
8817 Expr *BoundUB = UB.get();
8818 if (UseStrictCompare) {
8819 BoundUB =
8820 SemaRef
8821 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8822 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8823 .get();
8824 BoundUB =
8825 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8826 }
8827 ExprResult Cond =
8828 (isOpenMPWorksharingDirective(DKind) ||
8829 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
8830 isOpenMPLoopTransformationDirective(DKind))
8831 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8832 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8833 BoundUB)
8834 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8835 NumIterations.get());
8836 ExprResult CombDistCond;
8837 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8838 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8839 NumIterations.get());
8840 }
8841
8842 ExprResult CombCond;
8843 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8844 Expr *BoundCombUB = CombUB.get();
8845 if (UseStrictCompare) {
8846 BoundCombUB =
8847 SemaRef
8848 .BuildBinOp(
8849 CurScope, CondLoc, BO_Add, BoundCombUB,
8850 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8851 .get();
8852 BoundCombUB =
8853 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8854 .get();
8855 }
8856 CombCond =
8857 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8858 IV.get(), BoundCombUB);
8859 }
8860 // Loop increment (IV = IV + 1)
8861 SourceLocation IncLoc = AStmt->getBeginLoc();
8862 ExprResult Inc =
8863 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8864 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8865 if (!Inc.isUsable())
8866 return 0;
8867 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8868 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8869 if (!Inc.isUsable())
8870 return 0;
8871
8872 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8873 // Used for directives with static scheduling.
8874 // In combined construct, add combined version that use CombLB and CombUB
8875 // base variables for the update
8876 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8877 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8878 isOpenMPDistributeDirective(DKind) ||
8879 isOpenMPLoopTransformationDirective(DKind)) {
8880 // LB + ST
8881 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8882 if (!NextLB.isUsable())
8883 return 0;
8884 // LB = LB + ST
8885 NextLB =
8886 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8887 NextLB =
8888 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8889 if (!NextLB.isUsable())
8890 return 0;
8891 // UB + ST
8892 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8893 if (!NextUB.isUsable())
8894 return 0;
8895 // UB = UB + ST
8896 NextUB =
8897 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8898 NextUB =
8899 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8900 if (!NextUB.isUsable())
8901 return 0;
8902 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8903 CombNextLB =
8904 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8905 if (!NextLB.isUsable())
8906 return 0;
8907 // LB = LB + ST
8908 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8909 CombNextLB.get());
8910 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8911 /*DiscardedValue*/ false);
8912 if (!CombNextLB.isUsable())
8913 return 0;
8914 // UB + ST
8915 CombNextUB =
8916 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8917 if (!CombNextUB.isUsable())
8918 return 0;
8919 // UB = UB + ST
8920 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8921 CombNextUB.get());
8922 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8923 /*DiscardedValue*/ false);
8924 if (!CombNextUB.isUsable())
8925 return 0;
8926 }
8927 }
8928
8929 // Create increment expression for distribute loop when combined in a same
8930 // directive with for as IV = IV + ST; ensure upper bound expression based
8931 // on PrevUB instead of NumIterations - used to implement 'for' when found
8932 // in combination with 'distribute', like in 'distribute parallel for'
8933 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8934 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8935 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8936 DistCond = SemaRef.BuildBinOp(
8937 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8938 assert(DistCond.isUsable() && "distribute cond expr was not built")((DistCond.isUsable() && "distribute cond expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8938, __PRETTY_FUNCTION__))
;
8939
8940 DistInc =
8941 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8942 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8942, __PRETTY_FUNCTION__))
;
8943 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8944 DistInc.get());
8945 DistInc =
8946 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8947 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 8947, __PRETTY_FUNCTION__))
;
8948
8949 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8950 // construct
8951 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8952 ExprResult IsUBGreater =
8953 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8954 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8955 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8956 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8957 CondOp.get());
8958 PrevEUB =
8959 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8960
8961 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8962 // parallel for is in combination with a distribute directive with
8963 // schedule(static, 1)
8964 Expr *BoundPrevUB = PrevUB.get();
8965 if (UseStrictCompare) {
8966 BoundPrevUB =
8967 SemaRef
8968 .BuildBinOp(
8969 CurScope, CondLoc, BO_Add, BoundPrevUB,
8970 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8971 .get();
8972 BoundPrevUB =
8973 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8974 .get();
8975 }
8976 ParForInDistCond =
8977 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8978 IV.get(), BoundPrevUB);
8979 }
8980
8981 // Build updates and final values of the loop counters.
8982 bool HasErrors = false;
8983 Built.Counters.resize(NestedLoopCount);
8984 Built.Inits.resize(NestedLoopCount);
8985 Built.Updates.resize(NestedLoopCount);
8986 Built.Finals.resize(NestedLoopCount);
8987 Built.DependentCounters.resize(NestedLoopCount);
8988 Built.DependentInits.resize(NestedLoopCount);
8989 Built.FinalsConditions.resize(NestedLoopCount);
8990 {
8991 // We implement the following algorithm for obtaining the
8992 // original loop iteration variable values based on the
8993 // value of the collapsed loop iteration variable IV.
8994 //
8995 // Let n+1 be the number of collapsed loops in the nest.
8996 // Iteration variables (I0, I1, .... In)
8997 // Iteration counts (N0, N1, ... Nn)
8998 //
8999 // Acc = IV;
9000 //
9001 // To compute Ik for loop k, 0 <= k <= n, generate:
9002 // Prod = N(k+1) * N(k+2) * ... * Nn;
9003 // Ik = Acc / Prod;
9004 // Acc -= Ik * Prod;
9005 //
9006 ExprResult Acc = IV;
9007 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9008 LoopIterationSpace &IS = IterSpaces[Cnt];
9009 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9010 ExprResult Iter;
9011
9012 // Compute prod
9013 ExprResult Prod =
9014 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9015 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9016 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9017 IterSpaces[K].NumIterations);
9018
9019 // Iter = Acc / Prod
9020 // If there is at least one more inner loop to avoid
9021 // multiplication by 1.
9022 if (Cnt + 1 < NestedLoopCount)
9023 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9024 Acc.get(), Prod.get());
9025 else
9026 Iter = Acc;
9027 if (!Iter.isUsable()) {
9028 HasErrors = true;
9029 break;
9030 }
9031
9032 // Update Acc:
9033 // Acc -= Iter * Prod
9034 // Check if there is at least one more inner loop to avoid
9035 // multiplication by 1.
9036 if (Cnt + 1 < NestedLoopCount)
9037 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9038 Iter.get(), Prod.get());
9039 else
9040 Prod = Iter;
9041 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9042 Acc.get(), Prod.get());
9043
9044 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9045 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9046 DeclRefExpr *CounterVar = buildDeclRefExpr(
9047 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9048 /*RefersToCapture=*/true);
9049 ExprResult Init =
9050 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9051 IS.CounterInit, IS.IsNonRectangularLB, Captures);
9052 if (!Init.isUsable()) {
9053 HasErrors = true;
9054 break;
9055 }
9056 ExprResult Update = buildCounterUpdate(
9057 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9058 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9059 if (!Update.isUsable()) {
9060 HasErrors = true;
9061 break;
9062 }
9063
9064 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9065 ExprResult Final =
9066 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9067 IS.CounterInit, IS.NumIterations, IS.CounterStep,
9068 IS.Subtract, IS.IsNonRectangularLB, &Captures);
9069 if (!Final.isUsable()) {
9070 HasErrors = true;
9071 break;
9072 }
9073
9074 if (!Update.isUsable() || !Final.isUsable()) {
9075 HasErrors = true;
9076 break;
9077 }
9078 // Save results
9079 Built.Counters[Cnt] = IS.CounterVar;
9080 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9081 Built.Inits[Cnt] = Init.get();
9082 Built.Updates[Cnt] = Update.get();
9083 Built.Finals[Cnt] = Final.get();
9084 Built.DependentCounters[Cnt] = nullptr;
9085 Built.DependentInits[Cnt] = nullptr;
9086 Built.FinalsConditions[Cnt] = nullptr;
9087 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9088 Built.DependentCounters[Cnt] =
9089 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9090 Built.DependentInits[Cnt] =
9091 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9092 Built.FinalsConditions[Cnt] = IS.FinalCondition;
9093 }
9094 }
9095 }
9096
9097 if (HasErrors)
9098 return 0;
9099
9100 // Save results
9101 Built.IterationVarRef = IV.get();
9102 Built.LastIteration = LastIteration.get();
9103 Built.NumIterations = NumIterations.get();
9104 Built.CalcLastIteration = SemaRef
9105 .ActOnFinishFullExpr(CalcLastIteration.get(),
9106 /*DiscardedValue=*/false)
9107 .get();
9108 Built.PreCond = PreCond.get();
9109 Built.PreInits = buildPreInits(C, Captures);
9110 Built.Cond = Cond.get();
9111 Built.Init = Init.get();
9112 Built.Inc = Inc.get();
9113 Built.LB = LB.get();
9114 Built.UB = UB.get();
9115 Built.IL = IL.get();
9116 Built.ST = ST.get();
9117 Built.EUB = EUB.get();
9118 Built.NLB = NextLB.get();
9119 Built.NUB = NextUB.get();
9120 Built.PrevLB = PrevLB.get();
9121 Built.PrevUB = PrevUB.get();
9122 Built.DistInc = DistInc.get();
9123 Built.PrevEUB = PrevEUB.get();
9124 Built.DistCombinedFields.LB = CombLB.get();
9125 Built.DistCombinedFields.UB = CombUB.get();
9126 Built.DistCombinedFields.EUB = CombEUB.get();
9127 Built.DistCombinedFields.Init = CombInit.get();
9128 Built.DistCombinedFields.Cond = CombCond.get();
9129 Built.DistCombinedFields.NLB = CombNextLB.get();
9130 Built.DistCombinedFields.NUB = CombNextUB.get();
9131 Built.DistCombinedFields.DistCond = CombDistCond.get();
9132 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9133
9134 return NestedLoopCount;
9135}
9136
9137static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9138 auto CollapseClauses =
9139 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9140 if (CollapseClauses.begin() != CollapseClauses.end())
9141 return (*CollapseClauses.begin())->getNumForLoops();
9142 return nullptr;
9143}
9144
9145static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9146 auto OrderedClauses =
9147 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9148 if (OrderedClauses.begin() != OrderedClauses.end())
9149 return (*OrderedClauses.begin())->getNumForLoops();
9150 return nullptr;
9151}
9152
9153static bool checkSimdlenSafelenSpecified(Sema &S,
9154 const ArrayRef<OMPClause *> Clauses) {
9155 const OMPSafelenClause *Safelen = nullptr;
9156 const OMPSimdlenClause *Simdlen = nullptr;
9157
9158 for (const OMPClause *Clause : Clauses) {
9159 if (Clause->getClauseKind() == OMPC_safelen)
9160 Safelen = cast<OMPSafelenClause>(Clause);
9161 else if (Clause->getClauseKind() == OMPC_simdlen)
9162 Simdlen = cast<OMPSimdlenClause>(Clause);
9163 if (Safelen && Simdlen)
9164 break;
9165 }
9166
9167 if (Simdlen && Safelen) {
9168 const Expr *SimdlenLength = Simdlen->getSimdlen();
9169 const Expr *SafelenLength = Safelen->getSafelen();
9170 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9171 SimdlenLength->isInstantiationDependent() ||
9172 SimdlenLength->containsUnexpandedParameterPack())
9173 return false;
9174 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9175 SafelenLength->isInstantiationDependent() ||
9176 SafelenLength->containsUnexpandedParameterPack())
9177 return false;
9178 Expr::EvalResult SimdlenResult, SafelenResult;
9179 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9180 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9181 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9182 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9183 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9184 // If both simdlen and safelen clauses are specified, the value of the
9185 // simdlen parameter must be less than or equal to the value of the safelen
9186 // parameter.
9187 if (SimdlenRes > SafelenRes) {
9188 S.Diag(SimdlenLength->getExprLoc(),
9189 diag::err_omp_wrong_simdlen_safelen_values)
9190 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9191 return true;
9192 }
9193 }
9194 return false;
9195}
9196
9197StmtResult
9198Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9199 SourceLocation StartLoc, SourceLocation EndLoc,
9200 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9201 if (!AStmt)
9202 return StmtError();
9203
9204 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9204, __PRETTY_FUNCTION__))
;
9205 OMPLoopBasedDirective::HelperExprs B;
9206 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9207 // define the nested loops number.
9208 unsigned NestedLoopCount = checkOpenMPLoop(
9209 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9210 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9211 if (NestedLoopCount == 0)
9212 return StmtError();
9213
9214 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9215, __PRETTY_FUNCTION__))
9215 "omp simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9215, __PRETTY_FUNCTION__))
;
9216
9217 if (!CurContext->isDependentContext()) {
9218 // Finalize the clauses that need pre-built expressions for CodeGen.
9219 for (OMPClause *C : Clauses) {
9220 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9221 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9222 B.NumIterations, *this, CurScope,
9223 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9224 return StmtError();
9225 }
9226 }
9227
9228 if (checkSimdlenSafelenSpecified(*this, Clauses))
9229 return StmtError();
9230
9231 setFunctionHasBranchProtectedScope();
9232 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9233 Clauses, AStmt, B);
9234}
9235
9236StmtResult
9237Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9238 SourceLocation StartLoc, SourceLocation EndLoc,
9239 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9240 if (!AStmt)
9241 return StmtError();
9242
9243 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9243, __PRETTY_FUNCTION__))
;
9244 OMPLoopBasedDirective::HelperExprs B;
9245 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9246 // define the nested loops number.
9247 unsigned NestedLoopCount = checkOpenMPLoop(
9248 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9249 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9250 if (NestedLoopCount == 0)
9251 return StmtError();
9252
9253 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9254, __PRETTY_FUNCTION__))
9254 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9254, __PRETTY_FUNCTION__))
;
9255
9256 if (!CurContext->isDependentContext()) {
9257 // Finalize the clauses that need pre-built expressions for CodeGen.
9258 for (OMPClause *C : Clauses) {
9259 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9260 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9261 B.NumIterations, *this, CurScope,
9262 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9263 return StmtError();
9264 }
9265 }
9266
9267 setFunctionHasBranchProtectedScope();
9268 return OMPForDirective::Create(
9269 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9271}
9272
9273StmtResult Sema::ActOnOpenMPForSimdDirective(
9274 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9275 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9276 if (!AStmt)
9277 return StmtError();
9278
9279 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9279, __PRETTY_FUNCTION__))
;
9280 OMPLoopBasedDirective::HelperExprs B;
9281 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9282 // define the nested loops number.
9283 unsigned NestedLoopCount =
9284 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9285 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9286 VarsWithImplicitDSA, B);
9287 if (NestedLoopCount == 0)
9288 return StmtError();
9289
9290 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9291, __PRETTY_FUNCTION__))
9291 "omp for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9291, __PRETTY_FUNCTION__))
;
9292
9293 if (!CurContext->isDependentContext()) {
9294 // Finalize the clauses that need pre-built expressions for CodeGen.
9295 for (OMPClause *C : Clauses) {
9296 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9297 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9298 B.NumIterations, *this, CurScope,
9299 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9300 return StmtError();
9301 }
9302 }
9303
9304 if (checkSimdlenSafelenSpecified(*this, Clauses))
9305 return StmtError();
9306
9307 setFunctionHasBranchProtectedScope();
9308 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9309 Clauses, AStmt, B);
9310}
9311
9312StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9313 Stmt *AStmt,
9314 SourceLocation StartLoc,
9315 SourceLocation EndLoc) {
9316 if (!AStmt)
9317 return StmtError();
9318
9319 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9319, __PRETTY_FUNCTION__))
;
9320 auto BaseStmt = AStmt;
9321 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9322 BaseStmt = CS->getCapturedStmt();
9323 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9324 auto S = C->children();
9325 if (S.begin() == S.end())
9326 return StmtError();
9327 // All associated statements must be '#pragma omp section' except for
9328 // the first one.
9329 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9330 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9331 if (SectionStmt)
9332 Diag(SectionStmt->getBeginLoc(),
9333 diag::err_omp_sections_substmt_not_section);
9334 return StmtError();
9335 }
9336 cast<OMPSectionDirective>(SectionStmt)
9337 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9338 }
9339 } else {
9340 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9341 return StmtError();
9342 }
9343
9344 setFunctionHasBranchProtectedScope();
9345
9346 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9347 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
9348 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9349}
9350
9351StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9352 SourceLocation StartLoc,
9353 SourceLocation EndLoc) {
9354 if (!AStmt)
9355 return StmtError();
9356
9357 setFunctionHasBranchProtectedScope();
9358 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9359
9360 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9361 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9362}
9363
9364StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9365 Stmt *AStmt,
9366 SourceLocation StartLoc,
9367 SourceLocation EndLoc) {
9368 if (!AStmt)
9369 return StmtError();
9370
9371 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9371, __PRETTY_FUNCTION__))
;
9372
9373 setFunctionHasBranchProtectedScope();
9374
9375 // OpenMP [2.7.3, single Construct, Restrictions]
9376 // The copyprivate clause must not be used with the nowait clause.
9377 const OMPClause *Nowait = nullptr;
9378 const OMPClause *Copyprivate = nullptr;
9379 for (const OMPClause *Clause : Clauses) {
9380 if (Clause->getClauseKind() == OMPC_nowait)
9381 Nowait = Clause;
9382 else if (Clause->getClauseKind() == OMPC_copyprivate)
9383 Copyprivate = Clause;
9384 if (Copyprivate && Nowait) {
9385 Diag(Copyprivate->getBeginLoc(),
9386 diag::err_omp_single_copyprivate_with_nowait);
9387 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9388 return StmtError();
9389 }
9390 }
9391
9392 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9393}
9394
9395StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9396 SourceLocation StartLoc,
9397 SourceLocation EndLoc) {
9398 if (!AStmt)
9399 return StmtError();
9400
9401 setFunctionHasBranchProtectedScope();
9402
9403 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9404}
9405
9406StmtResult Sema::ActOnOpenMPCriticalDirective(
9407 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9408 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9409 if (!AStmt)
9410 return StmtError();
9411
9412 bool ErrorFound = false;
9413 llvm::APSInt Hint;
9414 SourceLocation HintLoc;
9415 bool DependentHint = false;
9416 for (const OMPClause *C : Clauses) {
9417 if (C->getClauseKind() == OMPC_hint) {
9418 if (!DirName.getName()) {
9419 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9420 ErrorFound = true;
9421 }
9422 Expr *E = cast<OMPHintClause>(C)->getHint();
9423 if (E->isTypeDependent() || E->isValueDependent() ||
9424 E->isInstantiationDependent()) {
9425 DependentHint = true;
9426 } else {
9427 Hint = E->EvaluateKnownConstInt(Context);
9428 HintLoc = C->getBeginLoc();
9429 }
9430 }
9431 }
9432 if (ErrorFound)
9433 return StmtError();
9434 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
9435 if (Pair.first && DirName.getName() && !DependentHint) {
9436 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9437 Diag(StartLoc, diag::err_omp_critical_with_hint);
9438 if (HintLoc.isValid())
9439 Diag(HintLoc, diag::note_omp_critical_hint_here)
9440 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9441 else
9442 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9443 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9444 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9445 << 1
9446 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9447 /*Radix=*/10, /*Signed=*/false);
9448 } else {
9449 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9450 }
9451 }
9452 }
9453
9454 setFunctionHasBranchProtectedScope();
9455
9456 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9457 Clauses, AStmt);
9458 if (!Pair.first && DirName.getName() && !DependentHint)
9459 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
9460 return Dir;
9461}
9462
9463StmtResult Sema::ActOnOpenMPParallelForDirective(
9464 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9465 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9466 if (!AStmt)
9467 return StmtError();
9468
9469 auto *CS = cast<CapturedStmt>(AStmt);
9470 // 1.2.2 OpenMP Language Terminology
9471 // Structured block - An executable statement with a single entry at the
9472 // top and a single exit at the bottom.
9473 // The point of exit cannot be a branch out of the structured block.
9474 // longjmp() and throw() must not violate the entry/exit criteria.
9475 CS->getCapturedDecl()->setNothrow();
9476
9477 OMPLoopBasedDirective::HelperExprs B;
9478 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9479 // define the nested loops number.
9480 unsigned NestedLoopCount =
9481 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9482 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9483 VarsWithImplicitDSA, B);
9484 if (NestedLoopCount == 0)
9485 return StmtError();
9486
9487 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp parallel for loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9488, __PRETTY_FUNCTION__))
9488 "omp parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp parallel for loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9488, __PRETTY_FUNCTION__))
;
9489
9490 if (!CurContext->isDependentContext()) {
9491 // Finalize the clauses that need pre-built expressions for CodeGen.
9492 for (OMPClause *C : Clauses) {
9493 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9494 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9495 B.NumIterations, *this, CurScope,
9496 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9497 return StmtError();
9498 }
9499 }
9500
9501 setFunctionHasBranchProtectedScope();
9502 return OMPParallelForDirective::Create(
9503 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9504 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9505}
9506
9507StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9508 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9509 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9510 if (!AStmt)
9511 return StmtError();
9512
9513 auto *CS = cast<CapturedStmt>(AStmt);
9514 // 1.2.2 OpenMP Language Terminology
9515 // Structured block - An executable statement with a single entry at the
9516 // top and a single exit at the bottom.
9517 // The point of exit cannot be a branch out of the structured block.
9518 // longjmp() and throw() must not violate the entry/exit criteria.
9519 CS->getCapturedDecl()->setNothrow();
9520
9521 OMPLoopBasedDirective::HelperExprs B;
9522 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9523 // define the nested loops number.
9524 unsigned NestedLoopCount =
9525 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9526 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9527 VarsWithImplicitDSA, B);
9528 if (NestedLoopCount == 0)
9529 return StmtError();
9530
9531 if (!CurContext->isDependentContext()) {
9532 // Finalize the clauses that need pre-built expressions for CodeGen.
9533 for (OMPClause *C : Clauses) {
9534 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9535 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9536 B.NumIterations, *this, CurScope,
9537 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9538 return StmtError();
9539 }
9540 }
9541
9542 if (checkSimdlenSafelenSpecified(*this, Clauses))
9543 return StmtError();
9544
9545 setFunctionHasBranchProtectedScope();
9546 return OMPParallelForSimdDirective::Create(
9547 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9548}
9549
9550StmtResult
9551Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9552 Stmt *AStmt, SourceLocation StartLoc,
9553 SourceLocation EndLoc) {
9554 if (!AStmt)
9555 return StmtError();
9556
9557 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9557, __PRETTY_FUNCTION__))
;
9558 auto *CS = cast<CapturedStmt>(AStmt);
9559 // 1.2.2 OpenMP Language Terminology
9560 // Structured block - An executable statement with a single entry at the
9561 // top and a single exit at the bottom.
9562 // The point of exit cannot be a branch out of the structured block.
9563 // longjmp() and throw() must not violate the entry/exit criteria.
9564 CS->getCapturedDecl()->setNothrow();
9565
9566 setFunctionHasBranchProtectedScope();
9567
9568 return OMPParallelMasterDirective::Create(
9569 Context, StartLoc, EndLoc, Clauses, AStmt,
9570 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9571}
9572
9573StmtResult
9574Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9575 Stmt *AStmt, SourceLocation StartLoc,
9576 SourceLocation EndLoc) {
9577 if (!AStmt)
9578 return StmtError();
9579
9580 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9580, __PRETTY_FUNCTION__))
;
9581 auto BaseStmt = AStmt;
9582 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9583 BaseStmt = CS->getCapturedStmt();
9584 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9585 auto S = C->children();
9586 if (S.begin() == S.end())
9587 return StmtError();
9588 // All associated statements must be '#pragma omp section' except for
9589 // the first one.
9590 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9591 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9592 if (SectionStmt)
9593 Diag(SectionStmt->getBeginLoc(),
9594 diag::err_omp_parallel_sections_substmt_not_section);
9595 return StmtError();
9596 }
9597 cast<OMPSectionDirective>(SectionStmt)
9598 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9599 }
9600 } else {
9601 Diag(AStmt->getBeginLoc(),
9602 diag::err_omp_parallel_sections_not_compound_stmt);
9603 return StmtError();
9604 }
9605
9606 setFunctionHasBranchProtectedScope();
9607
9608 return OMPParallelSectionsDirective::Create(
9609 Context, StartLoc, EndLoc, Clauses, AStmt,
9610 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9611}
9612
9613/// detach and mergeable clauses are mutially exclusive, check for it.
9614static bool checkDetachMergeableClauses(Sema &S,
9615 ArrayRef<OMPClause *> Clauses) {
9616 const OMPClause *PrevClause = nullptr;
9617 bool ErrorFound = false;
9618 for (const OMPClause *C : Clauses) {
9619 if (C->getClauseKind() == OMPC_detach ||
9620 C->getClauseKind() == OMPC_mergeable) {
9621 if (!PrevClause) {
9622 PrevClause = C;
9623 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9624 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9625 << getOpenMPClauseName(C->getClauseKind())
9626 << getOpenMPClauseName(PrevClause->getClauseKind());
9627 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9628 << getOpenMPClauseName(PrevClause->getClauseKind());
9629 ErrorFound = true;
9630 }
9631 }
9632 }
9633 return ErrorFound;
9634}
9635
9636StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9637 Stmt *AStmt, SourceLocation StartLoc,
9638 SourceLocation EndLoc) {
9639 if (!AStmt)
9640 return StmtError();
9641
9642 // OpenMP 5.0, 2.10.1 task Construct
9643 // If a detach clause appears on the directive, then a mergeable clause cannot
9644 // appear on the same directive.
9645 if (checkDetachMergeableClauses(*this, Clauses))
9646 return StmtError();
9647
9648 auto *CS = cast<CapturedStmt>(AStmt);
9649 // 1.2.2 OpenMP Language Terminology
9650 // Structured block - An executable statement with a single entry at the
9651 // top and a single exit at the bottom.
9652 // The point of exit cannot be a branch out of the structured block.
9653 // longjmp() and throw() must not violate the entry/exit criteria.
9654 CS->getCapturedDecl()->setNothrow();
9655
9656 setFunctionHasBranchProtectedScope();
9657
9658 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9659 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9660}
9661
9662StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9663 SourceLocation EndLoc) {
9664 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9665}
9666
9667StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9668 SourceLocation EndLoc) {
9669 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9670}
9671
9672StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9673 SourceLocation EndLoc) {
9674 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9675}
9676
9677StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9678 Stmt *AStmt,
9679 SourceLocation StartLoc,
9680 SourceLocation EndLoc) {
9681 if (!AStmt)
9682 return StmtError();
9683
9684 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9684, __PRETTY_FUNCTION__))
;
9685
9686 setFunctionHasBranchProtectedScope();
9687
9688 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9689 AStmt,
9690 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9691}
9692
9693StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9694 SourceLocation StartLoc,
9695 SourceLocation EndLoc) {
9696 OMPFlushClause *FC = nullptr;
9697 OMPClause *OrderClause = nullptr;
9698 for (OMPClause *C : Clauses) {
9699 if (C->getClauseKind() == OMPC_flush)
9700 FC = cast<OMPFlushClause>(C);
9701 else
9702 OrderClause = C;
9703 }
9704 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9705 SourceLocation MemOrderLoc;
9706 for (const OMPClause *C : Clauses) {
9707 if (C->getClauseKind() == OMPC_acq_rel ||
9708 C->getClauseKind() == OMPC_acquire ||
9709 C->getClauseKind() == OMPC_release) {
9710 if (MemOrderKind != OMPC_unknown) {
9711 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9712 << getOpenMPDirectiveName(OMPD_flush) << 1
9713 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9714 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9715 << getOpenMPClauseName(MemOrderKind);
9716 } else {
9717 MemOrderKind = C->getClauseKind();
9718 MemOrderLoc = C->getBeginLoc();
9719 }
9720 }
9721 }
9722 if (FC && OrderClause) {
9723 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9724 << getOpenMPClauseName(OrderClause->getClauseKind());
9725 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9726 << getOpenMPClauseName(OrderClause->getClauseKind());
9727 return StmtError();
9728 }
9729 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9730}
9731
9732StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9733 SourceLocation StartLoc,
9734 SourceLocation EndLoc) {
9735 if (Clauses.empty()) {
9736 Diag(StartLoc, diag::err_omp_depobj_expected);
9737 return StmtError();
9738 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9739 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9740 return StmtError();
9741 }
9742 // Only depobj expression and another single clause is allowed.
9743 if (Clauses.size() > 2) {
9744 Diag(Clauses[2]->getBeginLoc(),
9745 diag::err_omp_depobj_single_clause_expected);
9746 return StmtError();
9747 } else if (Clauses.size() < 1) {
9748 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9749 return StmtError();
9750 }
9751 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9752}
9753
9754StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9755 SourceLocation StartLoc,
9756 SourceLocation EndLoc) {
9757 // Check that exactly one clause is specified.
9758 if (Clauses.size() != 1) {
9759 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9760 diag::err_omp_scan_single_clause_expected);
9761 return StmtError();
9762 }
9763 // Check that scan directive is used in the scopeof the OpenMP loop body.
9764 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
9765 Scope *ParentS = S->getParent();
9766 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9767 !ParentS->getBreakParent()->isOpenMPLoopScope())
9768 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9769 << getOpenMPDirectiveName(OMPD_scan) << 5);
9770 }
9771 // Check that only one instance of scan directives is used in the same outer
9772 // region.
9773 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
9774 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9775 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
9776 diag::note_omp_previous_directive)
9777 << "scan";
9778 return StmtError();
9779 }
9780 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
9781 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9782}
9783
9784StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9785 Stmt *AStmt,
9786 SourceLocation StartLoc,
9787 SourceLocation EndLoc) {
9788 const OMPClause *DependFound = nullptr;
9789 const OMPClause *DependSourceClause = nullptr;
9790 const OMPClause *DependSinkClause = nullptr;
9791 bool ErrorFound = false;
9792 const OMPThreadsClause *TC = nullptr;
9793 const OMPSIMDClause *SC = nullptr;
9794 for (const OMPClause *C : Clauses) {
9795 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9796 DependFound = C;
9797 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9798 if (DependSourceClause) {
9799 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9800 << getOpenMPDirectiveName(OMPD_ordered)
9801 << getOpenMPClauseName(OMPC_depend) << 2;
9802 ErrorFound = true;
9803 } else {
9804 DependSourceClause = C;
9805 }
9806 if (DependSinkClause) {
9807 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9808 << 0;
9809 ErrorFound = true;
9810 }
9811 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9812 if (DependSourceClause) {
9813 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9814 << 1;
9815 ErrorFound = true;
9816 }
9817 DependSinkClause = C;
9818 }
9819 } else if (C->getClauseKind() == OMPC_threads) {
9820 TC = cast<OMPThreadsClause>(C);
9821 } else if (C->getClauseKind() == OMPC_simd) {
9822 SC = cast<OMPSIMDClause>(C);
9823 }
9824 }
9825 if (!ErrorFound && !SC &&
9826 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
9827 // OpenMP [2.8.1,simd Construct, Restrictions]
9828 // An ordered construct with the simd clause is the only OpenMP construct
9829 // that can appear in the simd region.
9830 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9831 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9832 ErrorFound = true;
9833 } else if (DependFound && (TC || SC)) {
9834 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9835 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9836 ErrorFound = true;
9837 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9838 Diag(DependFound->getBeginLoc(),
9839 diag::err_omp_ordered_directive_without_param);
9840 ErrorFound = true;
9841 } else if (TC || Clauses.empty()) {
9842 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9843 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9844 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9845 << (TC != nullptr);
9846 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9847 ErrorFound = true;
9848 }
9849 }
9850 if ((!AStmt && !DependFound) || ErrorFound)
9851 return StmtError();
9852
9853 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9854 // During execution of an iteration of a worksharing-loop or a loop nest
9855 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9856 // must not execute more than one ordered region corresponding to an ordered
9857 // construct without a depend clause.
9858 if (!DependFound) {
9859 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
9860 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9861 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
9862 diag::note_omp_previous_directive)
9863 << "ordered";
9864 return StmtError();
9865 }
9866 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
9867 }
9868
9869 if (AStmt) {
9870 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 9870, __PRETTY_FUNCTION__))
;
9871
9872 setFunctionHasBranchProtectedScope();
9873 }
9874
9875 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9876}
9877
9878namespace {
9879/// Helper class for checking expression in 'omp atomic [update]'
9880/// construct.
9881class OpenMPAtomicUpdateChecker {
9882 /// Error results for atomic update expressions.
9883 enum ExprAnalysisErrorCode {
9884 /// A statement is not an expression statement.
9885 NotAnExpression,
9886 /// Expression is not builtin binary or unary operation.
9887 NotABinaryOrUnaryExpression,
9888 /// Unary operation is not post-/pre- increment/decrement operation.
9889 NotAnUnaryIncDecExpression,
9890 /// An expression is not of scalar type.
9891 NotAScalarType,
9892 /// A binary operation is not an assignment operation.
9893 NotAnAssignmentOp,
9894 /// RHS part of the binary operation is not a binary expression.
9895 NotABinaryExpression,
9896 /// RHS part is not additive/multiplicative/shift/biwise binary
9897 /// expression.
9898 NotABinaryOperator,
9899 /// RHS binary operation does not have reference to the updated LHS
9900 /// part.
9901 NotAnUpdateExpression,
9902 /// No errors is found.
9903 NoError
9904 };
9905 /// Reference to Sema.
9906 Sema &SemaRef;
9907 /// A location for note diagnostics (when error is found).
9908 SourceLocation NoteLoc;
9909 /// 'x' lvalue part of the source atomic expression.
9910 Expr *X;
9911 /// 'expr' rvalue part of the source atomic expression.
9912 Expr *E;
9913 /// Helper expression of the form
9914 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9915 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9916 Expr *UpdateExpr;
9917 /// Is 'x' a LHS in a RHS part of full update expression. It is
9918 /// important for non-associative operations.
9919 bool IsXLHSInRHSPart;
9920 BinaryOperatorKind Op;
9921 SourceLocation OpLoc;
9922 /// true if the source expression is a postfix unary operation, false
9923 /// if it is a prefix unary operation.
9924 bool IsPostfixUpdate;
9925
9926public:
9927 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9928 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9929 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9930 /// Check specified statement that it is suitable for 'atomic update'
9931 /// constructs and extract 'x', 'expr' and Operation from the original
9932 /// expression. If DiagId and NoteId == 0, then only check is performed
9933 /// without error notification.
9934 /// \param DiagId Diagnostic which should be emitted if error is found.
9935 /// \param NoteId Diagnostic note for the main error message.
9936 /// \return true if statement is not an update expression, false otherwise.
9937 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9938 /// Return the 'x' lvalue part of the source atomic expression.
9939 Expr *getX() const { return X; }
9940 /// Return the 'expr' rvalue part of the source atomic expression.
9941 Expr *getExpr() const { return E; }
9942 /// Return the update expression used in calculation of the updated
9943 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9944 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9945 Expr *getUpdateExpr() const { return UpdateExpr; }
9946 /// Return true if 'x' is LHS in RHS part of full update expression,
9947 /// false otherwise.
9948 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9949
9950 /// true if the source expression is a postfix unary operation, false
9951 /// if it is a prefix unary operation.
9952 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9953
9954private:
9955 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9956 unsigned NoteId = 0);
9957};
9958} // namespace
9959
9960bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9961 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9962 ExprAnalysisErrorCode ErrorFound = NoError;
9963 SourceLocation ErrorLoc, NoteLoc;
9964 SourceRange ErrorRange, NoteRange;
9965 // Allowed constructs are:
9966 // x = x binop expr;
9967 // x = expr binop x;
9968 if (AtomicBinOp->getOpcode() == BO_Assign) {
9969 X = AtomicBinOp->getLHS();
9970 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9971 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9972 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9973 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9974 AtomicInnerBinOp->isBitwiseOp()) {
9975 Op = AtomicInnerBinOp->getOpcode();
9976 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9977 Expr *LHS = AtomicInnerBinOp->getLHS();
9978 Expr *RHS = AtomicInnerBinOp->getRHS();
9979 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9980 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9981 /*Canonical=*/true);
9982 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9983 /*Canonical=*/true);
9984 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9985 /*Canonical=*/true);
9986 if (XId == LHSId) {
9987 E = RHS;
9988 IsXLHSInRHSPart = true;
9989 } else if (XId == RHSId) {
9990 E = LHS;
9991 IsXLHSInRHSPart = false;
9992 } else {
9993 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9994 ErrorRange = AtomicInnerBinOp->getSourceRange();
9995 NoteLoc = X->getExprLoc();
9996 NoteRange = X->getSourceRange();
9997 ErrorFound = NotAnUpdateExpression;
9998 }
9999 } else {
10000 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10001 ErrorRange = AtomicInnerBinOp->getSourceRange();
10002 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10003 NoteRange = SourceRange(NoteLoc, NoteLoc);
10004 ErrorFound = NotABinaryOperator;
10005 }
10006 } else {
10007 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10008 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10009 ErrorFound = NotABinaryExpression;
10010 }
10011 } else {
10012 ErrorLoc = AtomicBinOp->getExprLoc();
10013 ErrorRange = AtomicBinOp->getSourceRange();
10014 NoteLoc = AtomicBinOp->getOperatorLoc();
10015 NoteRange = SourceRange(NoteLoc, NoteLoc);
10016 ErrorFound = NotAnAssignmentOp;
10017 }
10018 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10019 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10020 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10021 return true;
10022 }
10023 if (SemaRef.CurContext->isDependentContext())
10024 E = X = UpdateExpr = nullptr;
10025 return ErrorFound != NoError;
10026}
10027
10028bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10029 unsigned NoteId) {
10030 ExprAnalysisErrorCode ErrorFound = NoError;
10031 SourceLocation ErrorLoc, NoteLoc;
10032 SourceRange ErrorRange, NoteRange;
10033 // Allowed constructs are:
10034 // x++;
10035 // x--;
10036 // ++x;
10037 // --x;
10038 // x binop= expr;
10039 // x = x binop expr;
10040 // x = expr binop x;
10041 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10042 AtomicBody = AtomicBody->IgnoreParenImpCasts();
10043 if (AtomicBody->getType()->isScalarType() ||
10044 AtomicBody->isInstantiationDependent()) {
10045 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10046 AtomicBody->IgnoreParenImpCasts())) {
10047 // Check for Compound Assignment Operation
10048 Op = BinaryOperator::getOpForCompoundAssignment(
10049 AtomicCompAssignOp->getOpcode());
10050 OpLoc = AtomicCompAssignOp->getOperatorLoc();
10051 E = AtomicCompAssignOp->getRHS();
10052 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10053 IsXLHSInRHSPart = true;
10054 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10055 AtomicBody->IgnoreParenImpCasts())) {
10056 // Check for Binary Operation
10057 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10058 return true;
10059 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10060 AtomicBody->IgnoreParenImpCasts())) {
10061 // Check for Unary Operation
10062 if (AtomicUnaryOp->isIncrementDecrementOp()) {
10063 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10064 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10065 OpLoc = AtomicUnaryOp->getOperatorLoc();
10066 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10067 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10068 IsXLHSInRHSPart = true;
10069 } else {
10070 ErrorFound = NotAnUnaryIncDecExpression;
10071 ErrorLoc = AtomicUnaryOp->getExprLoc();
10072 ErrorRange = AtomicUnaryOp->getSourceRange();
10073 NoteLoc = AtomicUnaryOp->getOperatorLoc();
10074 NoteRange = SourceRange(NoteLoc, NoteLoc);
10075 }
10076 } else if (!AtomicBody->isInstantiationDependent()) {
10077 ErrorFound = NotABinaryOrUnaryExpression;
10078 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10079 NoteRange = ErrorRange = AtomicBody->getSourceRange();
10080 }
10081 } else {
10082 ErrorFound = NotAScalarType;
10083 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10084 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10085 }
10086 } else {
10087 ErrorFound = NotAnExpression;
10088 NoteLoc = ErrorLoc = S->getBeginLoc();
10089 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10090 }
10091 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10092 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10093 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10094 return true;
10095 }
10096 if (SemaRef.CurContext->isDependentContext())
10097 E = X = UpdateExpr = nullptr;
10098 if (ErrorFound == NoError && E && X) {
10099 // Build an update expression of form 'OpaqueValueExpr(x) binop
10100 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10101 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10102 auto *OVEX = new (SemaRef.getASTContext())
10103 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
10104 auto *OVEExpr = new (SemaRef.getASTContext())
10105 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
10106 ExprResult Update =
10107 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10108 IsXLHSInRHSPart ? OVEExpr : OVEX);
10109 if (Update.isInvalid())
10110 return true;
10111 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10112 Sema::AA_Casting);
10113 if (Update.isInvalid())
10114 return true;
10115 UpdateExpr = Update.get();
10116 }
10117 return ErrorFound != NoError;
10118}
10119
10120StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10121 Stmt *AStmt,
10122 SourceLocation StartLoc,
10123 SourceLocation EndLoc) {
10124 // Register location of the first atomic directive.
10125 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
10126 if (!AStmt)
10127 return StmtError();
10128
10129 // 1.2.2 OpenMP Language Terminology
10130 // Structured block - An executable statement with a single entry at the
10131 // top and a single exit at the bottom.
10132 // The point of exit cannot be a branch out of the structured block.
10133 // longjmp() and throw() must not violate the entry/exit criteria.
10134 OpenMPClauseKind AtomicKind = OMPC_unknown;
10135 SourceLocation AtomicKindLoc;
10136 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10137 SourceLocation MemOrderLoc;
10138 for (const OMPClause *C : Clauses) {
10139 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10140 C->getClauseKind() == OMPC_update ||
10141 C->getClauseKind() == OMPC_capture) {
10142 if (AtomicKind != OMPC_unknown) {
10143 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10144 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10145 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10146 << getOpenMPClauseName(AtomicKind);
10147 } else {
10148 AtomicKind = C->getClauseKind();
10149 AtomicKindLoc = C->getBeginLoc();
10150 }
10151 }
10152 if (C->getClauseKind() == OMPC_seq_cst ||
10153 C->getClauseKind() == OMPC_acq_rel ||
10154 C->getClauseKind() == OMPC_acquire ||
10155 C->getClauseKind() == OMPC_release ||
10156 C->getClauseKind() == OMPC_relaxed) {
10157 if (MemOrderKind != OMPC_unknown) {
10158 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10159 << getOpenMPDirectiveName(OMPD_atomic) << 0
10160 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10161 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10162 << getOpenMPClauseName(MemOrderKind);
10163 } else {
10164 MemOrderKind = C->getClauseKind();
10165 MemOrderLoc = C->getBeginLoc();
10166 }
10167 }
10168 }
10169 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10170 // If atomic-clause is read then memory-order-clause must not be acq_rel or
10171 // release.
10172 // If atomic-clause is write then memory-order-clause must not be acq_rel or
10173 // acquire.
10174 // If atomic-clause is update or not present then memory-order-clause must not
10175 // be acq_rel or acquire.
10176 if ((AtomicKind == OMPC_read &&
10177 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10178 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10179 AtomicKind == OMPC_unknown) &&
10180 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10181 SourceLocation Loc = AtomicKindLoc;
10182 if (AtomicKind == OMPC_unknown)
10183 Loc = StartLoc;
10184 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10185 << getOpenMPClauseName(AtomicKind)
10186 << (AtomicKind == OMPC_unknown ? 1 : 0)
10187 << getOpenMPClauseName(MemOrderKind);
10188 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10189 << getOpenMPClauseName(MemOrderKind);
10190 }
10191
10192 Stmt *Body = AStmt;
10193 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10194 Body = EWC->getSubExpr();
10195
10196 Expr *X = nullptr;
10197 Expr *V = nullptr;
10198 Expr *E = nullptr;
10199 Expr *UE = nullptr;
10200 bool IsXLHSInRHSPart = false;
10201 bool IsPostfixUpdate = false;
10202 // OpenMP [2.12.6, atomic Construct]
10203 // In the next expressions:
10204 // * x and v (as applicable) are both l-value expressions with scalar type.
10205 // * During the execution of an atomic region, multiple syntactic
10206 // occurrences of x must designate the same storage location.
10207 // * Neither of v and expr (as applicable) may access the storage location
10208 // designated by x.
10209 // * Neither of x and expr (as applicable) may access the storage location
10210 // designated by v.
10211 // * expr is an expression with scalar type.
10212 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10213 // * binop, binop=, ++, and -- are not overloaded operators.
10214 // * The expression x binop expr must be numerically equivalent to x binop
10215 // (expr). This requirement is satisfied if the operators in expr have
10216 // precedence greater than binop, or by using parentheses around expr or
10217 // subexpressions of expr.
10218 // * The expression expr binop x must be numerically equivalent to (expr)
10219 // binop x. This requirement is satisfied if the operators in expr have
10220 // precedence equal to or greater than binop, or by using parentheses around
10221 // expr or subexpressions of expr.
10222 // * For forms that allow multiple occurrences of x, the number of times
10223 // that x is evaluated is unspecified.
10224 if (AtomicKind == OMPC_read) {
10225 enum {
10226 NotAnExpression,
10227 NotAnAssignmentOp,
10228 NotAScalarType,
10229 NotAnLValue,
10230 NoError
10231 } ErrorFound = NoError;
10232 SourceLocation ErrorLoc, NoteLoc;
10233 SourceRange ErrorRange, NoteRange;
10234 // If clause is read:
10235 // v = x;
10236 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10237 const auto *AtomicBinOp =
10238 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10239 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10240 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10241 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10242 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10243 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10244 if (!X->isLValue() || !V->isLValue()) {
10245 const Expr *NotLValueExpr = X->isLValue() ? V : X;
10246 ErrorFound = NotAnLValue;
10247 ErrorLoc = AtomicBinOp->getExprLoc();
10248 ErrorRange = AtomicBinOp->getSourceRange();
10249 NoteLoc = NotLValueExpr->getExprLoc();
10250 NoteRange = NotLValueExpr->getSourceRange();
10251 }
10252 } else if (!X->isInstantiationDependent() ||
10253 !V->isInstantiationDependent()) {
10254 const Expr *NotScalarExpr =
10255 (X->isInstantiationDependent() || X->getType()->isScalarType())
10256 ? V
10257 : X;
10258 ErrorFound = NotAScalarType;
10259 ErrorLoc = AtomicBinOp->getExprLoc();
10260 ErrorRange = AtomicBinOp->getSourceRange();
10261 NoteLoc = NotScalarExpr->getExprLoc();
10262 NoteRange = NotScalarExpr->getSourceRange();
10263 }
10264 } else if (!AtomicBody->isInstantiationDependent()) {
10265 ErrorFound = NotAnAssignmentOp;
10266 ErrorLoc = AtomicBody->getExprLoc();
10267 ErrorRange = AtomicBody->getSourceRange();
10268 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10269 : AtomicBody->getExprLoc();
10270 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10271 : AtomicBody->getSourceRange();
10272 }
10273 } else {
10274 ErrorFound = NotAnExpression;
10275 NoteLoc = ErrorLoc = Body->getBeginLoc();
10276 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10277 }
10278 if (ErrorFound != NoError) {
10279 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10280 << ErrorRange;
10281 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10282 << NoteRange;
10283 return StmtError();
10284 }
10285 if (CurContext->isDependentContext())
10286 V = X = nullptr;
10287 } else if (AtomicKind == OMPC_write) {
10288 enum {
10289 NotAnExpression,
10290 NotAnAssignmentOp,
10291 NotAScalarType,
10292 NotAnLValue,
10293 NoError
10294 } ErrorFound = NoError;
10295 SourceLocation ErrorLoc, NoteLoc;
10296 SourceRange ErrorRange, NoteRange;
10297 // If clause is write:
10298 // x = expr;
10299 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10300 const auto *AtomicBinOp =
10301 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10302 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10303 X = AtomicBinOp->getLHS();
10304 E = AtomicBinOp->getRHS();
10305 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10306 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10307 if (!X->isLValue()) {
10308 ErrorFound = NotAnLValue;
10309 ErrorLoc = AtomicBinOp->getExprLoc();
10310 ErrorRange = AtomicBinOp->getSourceRange();
10311 NoteLoc = X->getExprLoc();
10312 NoteRange = X->getSourceRange();
10313 }
10314 } else if (!X->isInstantiationDependent() ||
10315 !E->isInstantiationDependent()) {
10316 const Expr *NotScalarExpr =
10317 (X->isInstantiationDependent() || X->getType()->isScalarType())
10318 ? E
10319 : X;
10320 ErrorFound = NotAScalarType;
10321 ErrorLoc = AtomicBinOp->getExprLoc();
10322 ErrorRange = AtomicBinOp->getSourceRange();
10323 NoteLoc = NotScalarExpr->getExprLoc();
10324 NoteRange = NotScalarExpr->getSourceRange();
10325 }
10326 } else if (!AtomicBody->isInstantiationDependent()) {
10327 ErrorFound = NotAnAssignmentOp;
10328 ErrorLoc = AtomicBody->getExprLoc();
10329 ErrorRange = AtomicBody->getSourceRange();
10330 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10331 : AtomicBody->getExprLoc();
10332 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10333 : AtomicBody->getSourceRange();
10334 }
10335 } else {
10336 ErrorFound = NotAnExpression;
10337 NoteLoc = ErrorLoc = Body->getBeginLoc();
10338 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10339 }
10340 if (ErrorFound != NoError) {
10341 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10342 << ErrorRange;
10343 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10344 << NoteRange;
10345 return StmtError();
10346 }
10347 if (CurContext->isDependentContext())
10348 E = X = nullptr;
10349 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10350 // If clause is update:
10351 // x++;
10352 // x--;
10353 // ++x;
10354 // --x;
10355 // x binop= expr;
10356 // x = x binop expr;
10357 // x = expr binop x;
10358 OpenMPAtomicUpdateChecker Checker(*this);
10359 if (Checker.checkStatement(
10360 Body, (AtomicKind == OMPC_update)
10361 ? diag::err_omp_atomic_update_not_expression_statement
10362 : diag::err_omp_atomic_not_expression_statement,
10363 diag::note_omp_atomic_update))
10364 return StmtError();
10365 if (!CurContext->isDependentContext()) {
10366 E = Checker.getExpr();
10367 X = Checker.getX();
10368 UE = Checker.getUpdateExpr();
10369 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10370 }
10371 } else if (AtomicKind == OMPC_capture) {
10372 enum {
10373 NotAnAssignmentOp,
10374 NotACompoundStatement,
10375 NotTwoSubstatements,
10376 NotASpecificExpression,
10377 NoError
10378 } ErrorFound = NoError;
10379 SourceLocation ErrorLoc, NoteLoc;
10380 SourceRange ErrorRange, NoteRange;
10381 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10382 // If clause is a capture:
10383 // v = x++;
10384 // v = x--;
10385 // v = ++x;
10386 // v = --x;
10387 // v = x binop= expr;
10388 // v = x = x binop expr;
10389 // v = x = expr binop x;
10390 const auto *AtomicBinOp =
10391 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10392 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10393 V = AtomicBinOp->getLHS();
10394 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10395 OpenMPAtomicUpdateChecker Checker(*this);
10396 if (Checker.checkStatement(
10397 Body, diag::err_omp_atomic_capture_not_expression_statement,
10398 diag::note_omp_atomic_update))
10399 return StmtError();
10400 E = Checker.getExpr();
10401 X = Checker.getX();
10402 UE = Checker.getUpdateExpr();
10403 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10404 IsPostfixUpdate = Checker.isPostfixUpdate();
10405 } else if (!AtomicBody->isInstantiationDependent()) {
10406 ErrorLoc = AtomicBody->getExprLoc();
10407 ErrorRange = AtomicBody->getSourceRange();
10408 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10409 : AtomicBody->getExprLoc();
10410 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10411 : AtomicBody->getSourceRange();
10412 ErrorFound = NotAnAssignmentOp;
10413 }
10414 if (ErrorFound != NoError) {
10415 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10416 << ErrorRange;
10417 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10418 return StmtError();
10419 }
10420 if (CurContext->isDependentContext())
10421 UE = V = E = X = nullptr;
10422 } else {
10423 // If clause is a capture:
10424 // { v = x; x = expr; }
10425 // { v = x; x++; }
10426 // { v = x; x--; }
10427 // { v = x; ++x; }
10428 // { v = x; --x; }
10429 // { v = x; x binop= expr; }
10430 // { v = x; x = x binop expr; }
10431 // { v = x; x = expr binop x; }
10432 // { x++; v = x; }
10433 // { x--; v = x; }
10434 // { ++x; v = x; }
10435 // { --x; v = x; }
10436 // { x binop= expr; v = x; }
10437 // { x = x binop expr; v = x; }
10438 // { x = expr binop x; v = x; }
10439 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10440 // Check that this is { expr1; expr2; }
10441 if (CS->size() == 2) {
10442 Stmt *First = CS->body_front();
10443 Stmt *Second = CS->body_back();
10444 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10445 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10446 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10447 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10448 // Need to find what subexpression is 'v' and what is 'x'.
10449 OpenMPAtomicUpdateChecker Checker(*this);
10450 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10451 BinaryOperator *BinOp = nullptr;
10452 if (IsUpdateExprFound) {
10453 BinOp = dyn_cast<BinaryOperator>(First);
10454 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10455 }
10456 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10457 // { v = x; x++; }
10458 // { v = x; x--; }
10459 // { v = x; ++x; }
10460 // { v = x; --x; }
10461 // { v = x; x binop= expr; }
10462 // { v = x; x = x binop expr; }
10463 // { v = x; x = expr binop x; }
10464 // Check that the first expression has form v = x.
10465 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10466 llvm::FoldingSetNodeID XId, PossibleXId;
10467 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10468 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10469 IsUpdateExprFound = XId == PossibleXId;
10470 if (IsUpdateExprFound) {
10471 V = BinOp->getLHS();
10472 X = Checker.getX();
10473 E = Checker.getExpr();
10474 UE = Checker.getUpdateExpr();
10475 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10476 IsPostfixUpdate = true;
10477 }
10478 }
10479 if (!IsUpdateExprFound) {
10480 IsUpdateExprFound = !Checker.checkStatement(First);
10481 BinOp = nullptr;
10482 if (IsUpdateExprFound) {
10483 BinOp = dyn_cast<BinaryOperator>(Second);
10484 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10485 }
10486 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10487 // { x++; v = x; }
10488 // { x--; v = x; }
10489 // { ++x; v = x; }
10490 // { --x; v = x; }
10491 // { x binop= expr; v = x; }
10492 // { x = x binop expr; v = x; }
10493 // { x = expr binop x; v = x; }
10494 // Check that the second expression has form v = x.
10495 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10496 llvm::FoldingSetNodeID XId, PossibleXId;
10497 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10498 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10499 IsUpdateExprFound = XId == PossibleXId;
10500 if (IsUpdateExprFound) {
10501 V = BinOp->getLHS();
10502 X = Checker.getX();
10503 E = Checker.getExpr();
10504 UE = Checker.getUpdateExpr();
10505 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10506 IsPostfixUpdate = false;
10507 }
10508 }
10509 }
10510 if (!IsUpdateExprFound) {
10511 // { v = x; x = expr; }
10512 auto *FirstExpr = dyn_cast<Expr>(First);
10513 auto *SecondExpr = dyn_cast<Expr>(Second);
10514 if (!FirstExpr || !SecondExpr ||
10515 !(FirstExpr->isInstantiationDependent() ||
10516 SecondExpr->isInstantiationDependent())) {
10517 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10518 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10519 ErrorFound = NotAnAssignmentOp;
10520 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10521 : First->getBeginLoc();
10522 NoteRange = ErrorRange = FirstBinOp
10523 ? FirstBinOp->getSourceRange()
10524 : SourceRange(ErrorLoc, ErrorLoc);
10525 } else {
10526 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10527 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10528 ErrorFound = NotAnAssignmentOp;
10529 NoteLoc = ErrorLoc = SecondBinOp
10530 ? SecondBinOp->getOperatorLoc()
10531 : Second->getBeginLoc();
10532 NoteRange = ErrorRange =
10533 SecondBinOp ? SecondBinOp->getSourceRange()
10534 : SourceRange(ErrorLoc, ErrorLoc);
10535 } else {
10536 Expr *PossibleXRHSInFirst =
10537 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10538 Expr *PossibleXLHSInSecond =
10539 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10540 llvm::FoldingSetNodeID X1Id, X2Id;
10541 PossibleXRHSInFirst->Profile(X1Id, Context,
10542 /*Canonical=*/true);
10543 PossibleXLHSInSecond->Profile(X2Id, Context,
10544 /*Canonical=*/true);
10545 IsUpdateExprFound = X1Id == X2Id;
10546 if (IsUpdateExprFound) {
10547 V = FirstBinOp->getLHS();
10548 X = SecondBinOp->getLHS();
10549 E = SecondBinOp->getRHS();
10550 UE = nullptr;
10551 IsXLHSInRHSPart = false;
10552 IsPostfixUpdate = true;
10553 } else {
10554 ErrorFound = NotASpecificExpression;
10555 ErrorLoc = FirstBinOp->getExprLoc();
10556 ErrorRange = FirstBinOp->getSourceRange();
10557 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10558 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10559 }
10560 }
10561 }
10562 }
10563 }
10564 } else {
10565 NoteLoc = ErrorLoc = Body->getBeginLoc();
10566 NoteRange = ErrorRange =
10567 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10568 ErrorFound = NotTwoSubstatements;
10569 }
10570 } else {
10571 NoteLoc = ErrorLoc = Body->getBeginLoc();
10572 NoteRange = ErrorRange =
10573 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10574 ErrorFound = NotACompoundStatement;
10575 }
10576 if (ErrorFound != NoError) {
10577 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10578 << ErrorRange;
10579 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10580 return StmtError();
10581 }
10582 if (CurContext->isDependentContext())
10583 UE = V = E = X = nullptr;
10584 }
10585 }
10586
10587 setFunctionHasBranchProtectedScope();
10588
10589 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10590 X, V, E, UE, IsXLHSInRHSPart,
10591 IsPostfixUpdate);
10592}
10593
10594StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10595 Stmt *AStmt,
10596 SourceLocation StartLoc,
10597 SourceLocation EndLoc) {
10598 if (!AStmt)
10599 return StmtError();
10600
10601 auto *CS = cast<CapturedStmt>(AStmt);
10602 // 1.2.2 OpenMP Language Terminology
10603 // Structured block - An executable statement with a single entry at the
10604 // top and a single exit at the bottom.
10605 // The point of exit cannot be a branch out of the structured block.
10606 // longjmp() and throw() must not violate the entry/exit criteria.
10607 CS->getCapturedDecl()->setNothrow();
10608 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10609 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10610 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10611 // 1.2.2 OpenMP Language Terminology
10612 // Structured block - An executable statement with a single entry at the
10613 // top and a single exit at the bottom.
10614 // The point of exit cannot be a branch out of the structured block.
10615 // longjmp() and throw() must not violate the entry/exit criteria.
10616 CS->getCapturedDecl()->setNothrow();
10617 }
10618
10619 // OpenMP [2.16, Nesting of Regions]
10620 // If specified, a teams construct must be contained within a target
10621 // construct. That target construct must contain no statements or directives
10622 // outside of the teams construct.
10623 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
10624 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10625 bool OMPTeamsFound = true;
10626 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10627 auto I = CS->body_begin();
10628 while (I != CS->body_end()) {
10629 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10630 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10631 OMPTeamsFound) {
10632
10633 OMPTeamsFound = false;
10634 break;
10635 }
10636 ++I;
10637 }
10638 assert(I != CS->body_end() && "Not found statement")((I != CS->body_end() && "Not found statement") ? static_cast
<void> (0) : __assert_fail ("I != CS->body_end() && \"Not found statement\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 10638, __PRETTY_FUNCTION__))
;
10639 S = *I;
10640 } else {
10641 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10642 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10643 }
10644 if (!OMPTeamsFound) {
10645 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10646 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
10647 diag::note_omp_nested_teams_construct_here);
10648 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10649 << isa<OMPExecutableDirective>(S);
10650 return StmtError();
10651 }
10652 }
10653
10654 setFunctionHasBranchProtectedScope();
10655
10656 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10657}
10658
10659StmtResult
10660Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10661 Stmt *AStmt, SourceLocation StartLoc,
10662 SourceLocation EndLoc) {
10663 if (!AStmt)
10664 return StmtError();
10665
10666 auto *CS = cast<CapturedStmt>(AStmt);
10667 // 1.2.2 OpenMP Language Terminology
10668 // Structured block - An executable statement with a single entry at the
10669 // top and a single exit at the bottom.
10670 // The point of exit cannot be a branch out of the structured block.
10671 // longjmp() and throw() must not violate the entry/exit criteria.
10672 CS->getCapturedDecl()->setNothrow();
10673 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10674 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10675 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10676 // 1.2.2 OpenMP Language Terminology
10677 // Structured block - An executable statement with a single entry at the
10678 // top and a single exit at the bottom.
10679 // The point of exit cannot be a branch out of the structured block.
10680 // longjmp() and throw() must not violate the entry/exit criteria.
10681 CS->getCapturedDecl()->setNothrow();
10682 }
10683
10684 setFunctionHasBranchProtectedScope();
10685
10686 return OMPTargetParallelDirective::Create(
10687 Context, StartLoc, EndLoc, Clauses, AStmt,
10688 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10689}
10690
10691StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10692 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10693 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10694 if (!AStmt)
10695 return StmtError();
10696
10697 auto *CS = cast<CapturedStmt>(AStmt);
10698 // 1.2.2 OpenMP Language Terminology
10699 // Structured block - An executable statement with a single entry at the
10700 // top and a single exit at the bottom.
10701 // The point of exit cannot be a branch out of the structured block.
10702 // longjmp() and throw() must not violate the entry/exit criteria.
10703 CS->getCapturedDecl()->setNothrow();
10704 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10705 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10706 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10707 // 1.2.2 OpenMP Language Terminology
10708 // Structured block - An executable statement with a single entry at the
10709 // top and a single exit at the bottom.
10710 // The point of exit cannot be a branch out of the structured block.
10711 // longjmp() and throw() must not violate the entry/exit criteria.
10712 CS->getCapturedDecl()->setNothrow();
10713 }
10714
10715 OMPLoopBasedDirective::HelperExprs B;
10716 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10717 // define the nested loops number.
10718 unsigned NestedLoopCount =
10719 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10720 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10721 VarsWithImplicitDSA, B);
10722 if (NestedLoopCount == 0)
10723 return StmtError();
10724
10725 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 10726, __PRETTY_FUNCTION__))
10726 "omp target parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 10726, __PRETTY_FUNCTION__))
;
10727
10728 if (!CurContext->isDependentContext()) {
10729 // Finalize the clauses that need pre-built expressions for CodeGen.
10730 for (OMPClause *C : Clauses) {
10731 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10732 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10733 B.NumIterations, *this, CurScope,
10734 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10735 return StmtError();
10736 }
10737 }
10738
10739 setFunctionHasBranchProtectedScope();
10740 return OMPTargetParallelForDirective::Create(
10741 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10742 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10743}
10744
10745/// Check for existence of a map clause in the list of clauses.
10746static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10747 const OpenMPClauseKind K) {
10748 return llvm::any_of(
10749 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10750}
10751
10752template <typename... Params>
10753static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10754 const Params... ClauseTypes) {
10755 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10756}
10757
10758StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10759 Stmt *AStmt,
10760 SourceLocation StartLoc,
10761 SourceLocation EndLoc) {
10762 if (!AStmt)
10763 return StmtError();
10764
10765 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 10765, __PRETTY_FUNCTION__))
;
10766
10767 // OpenMP [2.12.2, target data Construct, Restrictions]
10768 // At least one map, use_device_addr or use_device_ptr clause must appear on
10769 // the directive.
10770 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10771 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10772 StringRef Expected;
10773 if (LangOpts.OpenMP < 50)
10774 Expected = "'map' or 'use_device_ptr'";
10775 else
10776 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10777 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10778 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10779 return StmtError();
10780 }
10781
10782 setFunctionHasBranchProtectedScope();
10783
10784 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10785 AStmt);
10786}
10787
10788StmtResult
10789Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10790 SourceLocation StartLoc,
10791 SourceLocation EndLoc, Stmt *AStmt) {
10792 if (!AStmt)
10793 return StmtError();
10794
10795 auto *CS = cast<CapturedStmt>(AStmt);
10796 // 1.2.2 OpenMP Language Terminology
10797 // Structured block - An executable statement with a single entry at the
10798 // top and a single exit at the bottom.
10799 // The point of exit cannot be a branch out of the structured block.
10800 // longjmp() and throw() must not violate the entry/exit criteria.
10801 CS->getCapturedDecl()->setNothrow();
10802 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10803 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10804 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10805 // 1.2.2 OpenMP Language Terminology
10806 // Structured block - An executable statement with a single entry at the
10807 // top and a single exit at the bottom.
10808 // The point of exit cannot be a branch out of the structured block.
10809 // longjmp() and throw() must not violate the entry/exit criteria.
10810 CS->getCapturedDecl()->setNothrow();
10811 }
10812
10813 // OpenMP [2.10.2, Restrictions, p. 99]
10814 // At least one map clause must appear on the directive.
10815 if (!hasClauses(Clauses, OMPC_map)) {
10816 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10817 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10818 return StmtError();
10819 }
10820
10821 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10822 AStmt);
10823}
10824
10825StmtResult
10826Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10827 SourceLocation StartLoc,
10828 SourceLocation EndLoc, Stmt *AStmt) {
10829 if (!AStmt)
10830 return StmtError();
10831
10832 auto *CS = cast<CapturedStmt>(AStmt);
10833 // 1.2.2 OpenMP Language Terminology
10834 // Structured block - An executable statement with a single entry at the
10835 // top and a single exit at the bottom.
10836 // The point of exit cannot be a branch out of the structured block.
10837 // longjmp() and throw() must not violate the entry/exit criteria.
10838 CS->getCapturedDecl()->setNothrow();
10839 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10840 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10841 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10842 // 1.2.2 OpenMP Language Terminology
10843 // Structured block - An executable statement with a single entry at the
10844 // top and a single exit at the bottom.
10845 // The point of exit cannot be a branch out of the structured block.
10846 // longjmp() and throw() must not violate the entry/exit criteria.
10847 CS->getCapturedDecl()->setNothrow();
10848 }
10849
10850 // OpenMP [2.10.3, Restrictions, p. 102]
10851 // At least one map clause must appear on the directive.
10852 if (!hasClauses(Clauses, OMPC_map)) {
10853 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10854 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10855 return StmtError();
10856 }
10857
10858 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10859 AStmt);
10860}
10861
10862StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10863 SourceLocation StartLoc,
10864 SourceLocation EndLoc,
10865 Stmt *AStmt) {
10866 if (!AStmt)
10867 return StmtError();
10868
10869 auto *CS = cast<CapturedStmt>(AStmt);
10870 // 1.2.2 OpenMP Language Terminology
10871 // Structured block - An executable statement with a single entry at the
10872 // top and a single exit at the bottom.
10873 // The point of exit cannot be a branch out of the structured block.
10874 // longjmp() and throw() must not violate the entry/exit criteria.
10875 CS->getCapturedDecl()->setNothrow();
10876 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10877 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10878 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10879 // 1.2.2 OpenMP Language Terminology
10880 // Structured block - An executable statement with a single entry at the
10881 // top and a single exit at the bottom.
10882 // The point of exit cannot be a branch out of the structured block.
10883 // longjmp() and throw() must not violate the entry/exit criteria.
10884 CS->getCapturedDecl()->setNothrow();
10885 }
10886
10887 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10888 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10889 return StmtError();
10890 }
10891 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10892 AStmt);
10893}
10894
10895StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10896 Stmt *AStmt, SourceLocation StartLoc,
10897 SourceLocation EndLoc) {
10898 if (!AStmt)
10899 return StmtError();
10900
10901 auto *CS = cast<CapturedStmt>(AStmt);
10902 // 1.2.2 OpenMP Language Terminology
10903 // Structured block - An executable statement with a single entry at the
10904 // top and a single exit at the bottom.
10905 // The point of exit cannot be a branch out of the structured block.
10906 // longjmp() and throw() must not violate the entry/exit criteria.
10907 CS->getCapturedDecl()->setNothrow();
10908
10909 setFunctionHasBranchProtectedScope();
10910
10911 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10912
10913 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10914}
10915
10916StmtResult
10917Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10918 SourceLocation EndLoc,
10919 OpenMPDirectiveKind CancelRegion) {
10920 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10921 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10922 return StmtError();
10923 }
10924 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10925 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10926 return StmtError();
10927 }
10928 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10929 CancelRegion);
10930}
10931
10932StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10933 SourceLocation StartLoc,
10934 SourceLocation EndLoc,
10935 OpenMPDirectiveKind CancelRegion) {
10936 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10937 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10938 return StmtError();
10939 }
10940 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10941 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10942 return StmtError();
10943 }
10944 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
10945 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10946 CancelRegion);
10947}
10948
10949static bool checkGrainsizeNumTasksClauses(Sema &S,
10950 ArrayRef<OMPClause *> Clauses) {
10951 const OMPClause *PrevClause = nullptr;
10952 bool ErrorFound = false;
10953 for (const OMPClause *C : Clauses) {
10954 if (C->getClauseKind() == OMPC_grainsize ||
10955 C->getClauseKind() == OMPC_num_tasks) {
10956 if (!PrevClause)
10957 PrevClause = C;
10958 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10959 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10960 << getOpenMPClauseName(C->getClauseKind())
10961 << getOpenMPClauseName(PrevClause->getClauseKind());
10962 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10963 << getOpenMPClauseName(PrevClause->getClauseKind());
10964 ErrorFound = true;
10965 }
10966 }
10967 }
10968 return ErrorFound;
10969}
10970
10971static bool checkReductionClauseWithNogroup(Sema &S,
10972 ArrayRef<OMPClause *> Clauses) {
10973 const OMPClause *ReductionClause = nullptr;
10974 const OMPClause *NogroupClause = nullptr;
10975 for (const OMPClause *C : Clauses) {
10976 if (C->getClauseKind() == OMPC_reduction) {
10977 ReductionClause = C;
10978 if (NogroupClause)
10979 break;
10980 continue;
10981 }
10982 if (C->getClauseKind() == OMPC_nogroup) {
10983 NogroupClause = C;
10984 if (ReductionClause)
10985 break;
10986 continue;
10987 }
10988 }
10989 if (ReductionClause && NogroupClause) {
10990 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10991 << SourceRange(NogroupClause->getBeginLoc(),
10992 NogroupClause->getEndLoc());
10993 return true;
10994 }
10995 return false;
10996}
10997
10998StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10999 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11000 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11001 if (!AStmt)
11002 return StmtError();
11003
11004 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11004, __PRETTY_FUNCTION__))
;
11005 OMPLoopBasedDirective::HelperExprs B;
11006 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11007 // define the nested loops number.
11008 unsigned NestedLoopCount =
11009 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11010 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11011 VarsWithImplicitDSA, B);
11012 if (NestedLoopCount == 0)
11013 return StmtError();
11014
11015 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11016, __PRETTY_FUNCTION__))
11016 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11016, __PRETTY_FUNCTION__))
;
11017
11018 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11019 // The grainsize clause and num_tasks clause are mutually exclusive and may
11020 // not appear on the same taskloop directive.
11021 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11022 return StmtError();
11023 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11024 // If a reduction clause is present on the taskloop directive, the nogroup
11025 // clause must not be specified.
11026 if (checkReductionClauseWithNogroup(*this, Clauses))
11027 return StmtError();
11028
11029 setFunctionHasBranchProtectedScope();
11030 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11031 NestedLoopCount, Clauses, AStmt, B,
11032 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11033}
11034
11035StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11036 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11037 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11038 if (!AStmt)
11039 return StmtError();
11040
11041 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11041, __PRETTY_FUNCTION__))
;
11042 OMPLoopBasedDirective::HelperExprs B;
11043 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11044 // define the nested loops number.
11045 unsigned NestedLoopCount =
11046 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11047 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11048 VarsWithImplicitDSA, B);
11049 if (NestedLoopCount == 0)
11050 return StmtError();
11051
11052 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11053, __PRETTY_FUNCTION__))
11053 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11053, __PRETTY_FUNCTION__))
;
11054
11055 if (!CurContext->isDependentContext()) {
11056 // Finalize the clauses that need pre-built expressions for CodeGen.
11057 for (OMPClause *C : Clauses) {
11058 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11059 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11060 B.NumIterations, *this, CurScope,
11061 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11062 return StmtError();
11063 }
11064 }
11065
11066 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11067 // The grainsize clause and num_tasks clause are mutually exclusive and may
11068 // not appear on the same taskloop directive.
11069 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11070 return StmtError();
11071 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11072 // If a reduction clause is present on the taskloop directive, the nogroup
11073 // clause must not be specified.
11074 if (checkReductionClauseWithNogroup(*this, Clauses))
11075 return StmtError();
11076 if (checkSimdlenSafelenSpecified(*this, Clauses))
11077 return StmtError();
11078
11079 setFunctionHasBranchProtectedScope();
11080 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11081 NestedLoopCount, Clauses, AStmt, B);
11082}
11083
11084StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11085 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11086 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11087 if (!AStmt)
11088 return StmtError();
11089
11090 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11090, __PRETTY_FUNCTION__))
;
11091 OMPLoopBasedDirective::HelperExprs B;
11092 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11093 // define the nested loops number.
11094 unsigned NestedLoopCount =
11095 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11096 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11097 VarsWithImplicitDSA, B);
11098 if (NestedLoopCount == 0)
11099 return StmtError();
11100
11101 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11102, __PRETTY_FUNCTION__))
11102 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11102, __PRETTY_FUNCTION__))
;
11103
11104 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11105 // The grainsize clause and num_tasks clause are mutually exclusive and may
11106 // not appear on the same taskloop directive.
11107 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11108 return StmtError();
11109 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11110 // If a reduction clause is present on the taskloop directive, the nogroup
11111 // clause must not be specified.
11112 if (checkReductionClauseWithNogroup(*this, Clauses))
11113 return StmtError();
11114
11115 setFunctionHasBranchProtectedScope();
11116 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11117 NestedLoopCount, Clauses, AStmt, B,
11118 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11119}
11120
11121StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11122 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11123 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11124 if (!AStmt)
11125 return StmtError();
11126
11127 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11127, __PRETTY_FUNCTION__))
;
11128 OMPLoopBasedDirective::HelperExprs B;
11129 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11130 // define the nested loops number.
11131 unsigned NestedLoopCount =
11132 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11133 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11134 VarsWithImplicitDSA, B);
11135 if (NestedLoopCount == 0)
11136 return StmtError();
11137
11138 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11139, __PRETTY_FUNCTION__))
11139 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11139, __PRETTY_FUNCTION__))
;
11140
11141 if (!CurContext->isDependentContext()) {
11142 // Finalize the clauses that need pre-built expressions for CodeGen.
11143 for (OMPClause *C : Clauses) {
11144 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11145 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11146 B.NumIterations, *this, CurScope,
11147 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11148 return StmtError();
11149 }
11150 }
11151
11152 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11153 // The grainsize clause and num_tasks clause are mutually exclusive and may
11154 // not appear on the same taskloop directive.
11155 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11156 return StmtError();
11157 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11158 // If a reduction clause is present on the taskloop directive, the nogroup
11159 // clause must not be specified.
11160 if (checkReductionClauseWithNogroup(*this, Clauses))
11161 return StmtError();
11162 if (checkSimdlenSafelenSpecified(*this, Clauses))
11163 return StmtError();
11164
11165 setFunctionHasBranchProtectedScope();
11166 return OMPMasterTaskLoopSimdDirective::Create(
11167 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11168}
11169
11170StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11171 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11172 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11173 if (!AStmt)
11174 return StmtError();
11175
11176 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11176, __PRETTY_FUNCTION__))
;
11177 auto *CS = cast<CapturedStmt>(AStmt);
11178 // 1.2.2 OpenMP Language Terminology
11179 // Structured block - An executable statement with a single entry at the
11180 // top and a single exit at the bottom.
11181 // The point of exit cannot be a branch out of the structured block.
11182 // longjmp() and throw() must not violate the entry/exit criteria.
11183 CS->getCapturedDecl()->setNothrow();
11184 for (int ThisCaptureLevel =
11185 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11186 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11187 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11188 // 1.2.2 OpenMP Language Terminology
11189 // Structured block - An executable statement with a single entry at the
11190 // top and a single exit at the bottom.
11191 // The point of exit cannot be a branch out of the structured block.
11192 // longjmp() and throw() must not violate the entry/exit criteria.
11193 CS->getCapturedDecl()->setNothrow();
11194 }
11195
11196 OMPLoopBasedDirective::HelperExprs B;
11197 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11198 // define the nested loops number.
11199 unsigned NestedLoopCount = checkOpenMPLoop(
11200 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11201 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11202 VarsWithImplicitDSA, B);
11203 if (NestedLoopCount == 0)
11204 return StmtError();
11205
11206 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11207, __PRETTY_FUNCTION__))
11207 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11207, __PRETTY_FUNCTION__))
;
11208
11209 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11210 // The grainsize clause and num_tasks clause are mutually exclusive and may
11211 // not appear on the same taskloop directive.
11212 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11213 return StmtError();
11214 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11215 // If a reduction clause is present on the taskloop directive, the nogroup
11216 // clause must not be specified.
11217 if (checkReductionClauseWithNogroup(*this, Clauses))
11218 return StmtError();
11219
11220 setFunctionHasBranchProtectedScope();
11221 return OMPParallelMasterTaskLoopDirective::Create(
11222 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11223 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11224}
11225
11226StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11227 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11228 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11229 if (!AStmt)
11230 return StmtError();
11231
11232 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11232, __PRETTY_FUNCTION__))
;
11233 auto *CS = cast<CapturedStmt>(AStmt);
11234 // 1.2.2 OpenMP Language Terminology
11235 // Structured block - An executable statement with a single entry at the
11236 // top and a single exit at the bottom.
11237 // The point of exit cannot be a branch out of the structured block.
11238 // longjmp() and throw() must not violate the entry/exit criteria.
11239 CS->getCapturedDecl()->setNothrow();
11240 for (int ThisCaptureLevel =
11241 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11242 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11243 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11244 // 1.2.2 OpenMP Language Terminology
11245 // Structured block - An executable statement with a single entry at the
11246 // top and a single exit at the bottom.
11247 // The point of exit cannot be a branch out of the structured block.
11248 // longjmp() and throw() must not violate the entry/exit criteria.
11249 CS->getCapturedDecl()->setNothrow();
11250 }
11251
11252 OMPLoopBasedDirective::HelperExprs B;
11253 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11254 // define the nested loops number.
11255 unsigned NestedLoopCount = checkOpenMPLoop(
11256 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11257 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11258 VarsWithImplicitDSA, B);
11259 if (NestedLoopCount == 0)
11260 return StmtError();
11261
11262 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11263, __PRETTY_FUNCTION__))
11263 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11263, __PRETTY_FUNCTION__))
;
11264
11265 if (!CurContext->isDependentContext()) {
11266 // Finalize the clauses that need pre-built expressions for CodeGen.
11267 for (OMPClause *C : Clauses) {
11268 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11269 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11270 B.NumIterations, *this, CurScope,
11271 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11272 return StmtError();
11273 }
11274 }
11275
11276 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11277 // The grainsize clause and num_tasks clause are mutually exclusive and may
11278 // not appear on the same taskloop directive.
11279 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11280 return StmtError();
11281 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11282 // If a reduction clause is present on the taskloop directive, the nogroup
11283 // clause must not be specified.
11284 if (checkReductionClauseWithNogroup(*this, Clauses))
11285 return StmtError();
11286 if (checkSimdlenSafelenSpecified(*this, Clauses))
11287 return StmtError();
11288
11289 setFunctionHasBranchProtectedScope();
11290 return OMPParallelMasterTaskLoopSimdDirective::Create(
11291 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11292}
11293
11294StmtResult Sema::ActOnOpenMPDistributeDirective(
11295 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11296 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11297 if (!AStmt)
11298 return StmtError();
11299
11300 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11300, __PRETTY_FUNCTION__))
;
11301 OMPLoopBasedDirective::HelperExprs B;
11302 // In presence of clause 'collapse' with number of loops, it will
11303 // define the nested loops number.
11304 unsigned NestedLoopCount =
11305 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11306 nullptr /*ordered not a clause on distribute*/, AStmt,
11307 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11308 if (NestedLoopCount == 0)
11309 return StmtError();
11310
11311 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11312, __PRETTY_FUNCTION__))
11312 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11312, __PRETTY_FUNCTION__))
;
11313
11314 setFunctionHasBranchProtectedScope();
11315 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11316 NestedLoopCount, Clauses, AStmt, B);
11317}
11318
11319StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11320 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11321 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11322 if (!AStmt)
11323 return StmtError();
11324
11325 auto *CS = cast<CapturedStmt>(AStmt);
11326 // 1.2.2 OpenMP Language Terminology
11327 // Structured block - An executable statement with a single entry at the
11328 // top and a single exit at the bottom.
11329 // The point of exit cannot be a branch out of the structured block.
11330 // longjmp() and throw() must not violate the entry/exit criteria.
11331 CS->getCapturedDecl()->setNothrow();
11332 for (int ThisCaptureLevel =
11333 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11334 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11335 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11336 // 1.2.2 OpenMP Language Terminology
11337 // Structured block - An executable statement with a single entry at the
11338 // top and a single exit at the bottom.
11339 // The point of exit cannot be a branch out of the structured block.
11340 // longjmp() and throw() must not violate the entry/exit criteria.
11341 CS->getCapturedDecl()->setNothrow();
11342 }
11343
11344 OMPLoopBasedDirective::HelperExprs B;
11345 // In presence of clause 'collapse' with number of loops, it will
11346 // define the nested loops number.
11347 unsigned NestedLoopCount = checkOpenMPLoop(
11348 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11349 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11350 VarsWithImplicitDSA, B);
11351 if (NestedLoopCount == 0)
11352 return StmtError();
11353
11354 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11355, __PRETTY_FUNCTION__))
11355 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11355, __PRETTY_FUNCTION__))
;
11356
11357 setFunctionHasBranchProtectedScope();
11358 return OMPDistributeParallelForDirective::Create(
11359 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11360 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11361}
11362
11363StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11364 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11365 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11366 if (!AStmt)
11367 return StmtError();
11368
11369 auto *CS = cast<CapturedStmt>(AStmt);
11370 // 1.2.2 OpenMP Language Terminology
11371 // Structured block - An executable statement with a single entry at the
11372 // top and a single exit at the bottom.
11373 // The point of exit cannot be a branch out of the structured block.
11374 // longjmp() and throw() must not violate the entry/exit criteria.
11375 CS->getCapturedDecl()->setNothrow();
11376 for (int ThisCaptureLevel =
11377 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11378 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11379 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11380 // 1.2.2 OpenMP Language Terminology
11381 // Structured block - An executable statement with a single entry at the
11382 // top and a single exit at the bottom.
11383 // The point of exit cannot be a branch out of the structured block.
11384 // longjmp() and throw() must not violate the entry/exit criteria.
11385 CS->getCapturedDecl()->setNothrow();
11386 }
11387
11388 OMPLoopBasedDirective::HelperExprs B;
11389 // In presence of clause 'collapse' with number of loops, it will
11390 // define the nested loops number.
11391 unsigned NestedLoopCount = checkOpenMPLoop(
11392 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11393 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11394 VarsWithImplicitDSA, B);
11395 if (NestedLoopCount == 0)
11396 return StmtError();
11397
11398 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11399, __PRETTY_FUNCTION__))
11399 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11399, __PRETTY_FUNCTION__))
;
11400
11401 if (!CurContext->isDependentContext()) {
11402 // Finalize the clauses that need pre-built expressions for CodeGen.
11403 for (OMPClause *C : Clauses) {
11404 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11405 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11406 B.NumIterations, *this, CurScope,
11407 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11408 return StmtError();
11409 }
11410 }
11411
11412 if (checkSimdlenSafelenSpecified(*this, Clauses))
11413 return StmtError();
11414
11415 setFunctionHasBranchProtectedScope();
11416 return OMPDistributeParallelForSimdDirective::Create(
11417 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11418}
11419
11420StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11421 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11422 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11423 if (!AStmt)
11424 return StmtError();
11425
11426 auto *CS = cast<CapturedStmt>(AStmt);
11427 // 1.2.2 OpenMP Language Terminology
11428 // Structured block - An executable statement with a single entry at the
11429 // top and a single exit at the bottom.
11430 // The point of exit cannot be a branch out of the structured block.
11431 // longjmp() and throw() must not violate the entry/exit criteria.
11432 CS->getCapturedDecl()->setNothrow();
11433 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11434 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11435 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11436 // 1.2.2 OpenMP Language Terminology
11437 // Structured block - An executable statement with a single entry at the
11438 // top and a single exit at the bottom.
11439 // The point of exit cannot be a branch out of the structured block.
11440 // longjmp() and throw() must not violate the entry/exit criteria.
11441 CS->getCapturedDecl()->setNothrow();
11442 }
11443
11444 OMPLoopBasedDirective::HelperExprs B;
11445 // In presence of clause 'collapse' with number of loops, it will
11446 // define the nested loops number.
11447 unsigned NestedLoopCount =
11448 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11449 nullptr /*ordered not a clause on distribute*/, CS, *this,
11450 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11451 if (NestedLoopCount == 0)
11452 return StmtError();
11453
11454 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11455, __PRETTY_FUNCTION__))
11455 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11455, __PRETTY_FUNCTION__))
;
11456
11457 if (!CurContext->isDependentContext()) {
11458 // Finalize the clauses that need pre-built expressions for CodeGen.
11459 for (OMPClause *C : Clauses) {
11460 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11461 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11462 B.NumIterations, *this, CurScope,
11463 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11464 return StmtError();
11465 }
11466 }
11467
11468 if (checkSimdlenSafelenSpecified(*this, Clauses))
11469 return StmtError();
11470
11471 setFunctionHasBranchProtectedScope();
11472 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11473 NestedLoopCount, Clauses, AStmt, B);
11474}
11475
11476StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11477 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11478 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11479 if (!AStmt)
11480 return StmtError();
11481
11482 auto *CS = cast<CapturedStmt>(AStmt);
11483 // 1.2.2 OpenMP Language Terminology
11484 // Structured block - An executable statement with a single entry at the
11485 // top and a single exit at the bottom.
11486 // The point of exit cannot be a branch out of the structured block.
11487 // longjmp() and throw() must not violate the entry/exit criteria.
11488 CS->getCapturedDecl()->setNothrow();
11489 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11490 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11491 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11492 // 1.2.2 OpenMP Language Terminology
11493 // Structured block - An executable statement with a single entry at the
11494 // top and a single exit at the bottom.
11495 // The point of exit cannot be a branch out of the structured block.
11496 // longjmp() and throw() must not violate the entry/exit criteria.
11497 CS->getCapturedDecl()->setNothrow();
11498 }
11499
11500 OMPLoopBasedDirective::HelperExprs B;
11501 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11502 // define the nested loops number.
11503 unsigned NestedLoopCount = checkOpenMPLoop(
11504 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11505 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11506 VarsWithImplicitDSA, B);
11507 if (NestedLoopCount == 0)
11508 return StmtError();
11509
11510 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11511, __PRETTY_FUNCTION__))
11511 "omp target parallel for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11511, __PRETTY_FUNCTION__))
;
11512
11513 if (!CurContext->isDependentContext()) {
11514 // Finalize the clauses that need pre-built expressions for CodeGen.
11515 for (OMPClause *C : Clauses) {
11516 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11517 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11518 B.NumIterations, *this, CurScope,
11519 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11520 return StmtError();
11521 }
11522 }
11523 if (checkSimdlenSafelenSpecified(*this, Clauses))
11524 return StmtError();
11525
11526 setFunctionHasBranchProtectedScope();
11527 return OMPTargetParallelForSimdDirective::Create(
11528 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11529}
11530
11531StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11532 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11533 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11534 if (!AStmt)
11535 return StmtError();
11536
11537 auto *CS = cast<CapturedStmt>(AStmt);
11538 // 1.2.2 OpenMP Language Terminology
11539 // Structured block - An executable statement with a single entry at the
11540 // top and a single exit at the bottom.
11541 // The point of exit cannot be a branch out of the structured block.
11542 // longjmp() and throw() must not violate the entry/exit criteria.
11543 CS->getCapturedDecl()->setNothrow();
11544 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11545 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11546 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11547 // 1.2.2 OpenMP Language Terminology
11548 // Structured block - An executable statement with a single entry at the
11549 // top and a single exit at the bottom.
11550 // The point of exit cannot be a branch out of the structured block.
11551 // longjmp() and throw() must not violate the entry/exit criteria.
11552 CS->getCapturedDecl()->setNothrow();
11553 }
11554
11555 OMPLoopBasedDirective::HelperExprs B;
11556 // In presence of clause 'collapse' with number of loops, it will define the
11557 // nested loops number.
11558 unsigned NestedLoopCount =
11559 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11560 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11561 VarsWithImplicitDSA, B);
11562 if (NestedLoopCount == 0)
11563 return StmtError();
11564
11565 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target simd loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11566, __PRETTY_FUNCTION__))
11566 "omp target simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target simd loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11566, __PRETTY_FUNCTION__))
;
11567
11568 if (!CurContext->isDependentContext()) {
11569 // Finalize the clauses that need pre-built expressions for CodeGen.
11570 for (OMPClause *C : Clauses) {
11571 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11572 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11573 B.NumIterations, *this, CurScope,
11574 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11575 return StmtError();
11576 }
11577 }
11578
11579 if (checkSimdlenSafelenSpecified(*this, Clauses))
11580 return StmtError();
11581
11582 setFunctionHasBranchProtectedScope();
11583 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11584 NestedLoopCount, Clauses, AStmt, B);
11585}
11586
11587StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11588 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11589 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11590 if (!AStmt)
11591 return StmtError();
11592
11593 auto *CS = cast<CapturedStmt>(AStmt);
11594 // 1.2.2 OpenMP Language Terminology
11595 // Structured block - An executable statement with a single entry at the
11596 // top and a single exit at the bottom.
11597 // The point of exit cannot be a branch out of the structured block.
11598 // longjmp() and throw() must not violate the entry/exit criteria.
11599 CS->getCapturedDecl()->setNothrow();
11600 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11601 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11602 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11603 // 1.2.2 OpenMP Language Terminology
11604 // Structured block - An executable statement with a single entry at the
11605 // top and a single exit at the bottom.
11606 // The point of exit cannot be a branch out of the structured block.
11607 // longjmp() and throw() must not violate the entry/exit criteria.
11608 CS->getCapturedDecl()->setNothrow();
11609 }
11610
11611 OMPLoopBasedDirective::HelperExprs B;
11612 // In presence of clause 'collapse' with number of loops, it will
11613 // define the nested loops number.
11614 unsigned NestedLoopCount =
11615 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11616 nullptr /*ordered not a clause on distribute*/, CS, *this,
11617 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11618 if (NestedLoopCount == 0)
11619 return StmtError();
11620
11621 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11622, __PRETTY_FUNCTION__))
11622 "omp teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11622, __PRETTY_FUNCTION__))
;
11623
11624 setFunctionHasBranchProtectedScope();
11625
11626 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11627
11628 return OMPTeamsDistributeDirective::Create(
11629 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11630}
11631
11632StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11633 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11634 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11635 if (!AStmt)
11636 return StmtError();
11637
11638 auto *CS = cast<CapturedStmt>(AStmt);
11639 // 1.2.2 OpenMP Language Terminology
11640 // Structured block - An executable statement with a single entry at the
11641 // top and a single exit at the bottom.
11642 // The point of exit cannot be a branch out of the structured block.
11643 // longjmp() and throw() must not violate the entry/exit criteria.
11644 CS->getCapturedDecl()->setNothrow();
11645 for (int ThisCaptureLevel =
11646 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11647 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11648 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11649 // 1.2.2 OpenMP Language Terminology
11650 // Structured block - An executable statement with a single entry at the
11651 // top and a single exit at the bottom.
11652 // The point of exit cannot be a branch out of the structured block.
11653 // longjmp() and throw() must not violate the entry/exit criteria.
11654 CS->getCapturedDecl()->setNothrow();
11655 }
11656
11657 OMPLoopBasedDirective::HelperExprs B;
11658 // In presence of clause 'collapse' with number of loops, it will
11659 // define the nested loops number.
11660 unsigned NestedLoopCount = checkOpenMPLoop(
11661 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11662 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11663 VarsWithImplicitDSA, B);
11664
11665 if (NestedLoopCount == 0)
11666 return StmtError();
11667
11668 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11669, __PRETTY_FUNCTION__))
11669 "omp teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11669, __PRETTY_FUNCTION__))
;
11670
11671 if (!CurContext->isDependentContext()) {
11672 // Finalize the clauses that need pre-built expressions for CodeGen.
11673 for (OMPClause *C : Clauses) {
11674 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11675 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11676 B.NumIterations, *this, CurScope,
11677 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11678 return StmtError();
11679 }
11680 }
11681
11682 if (checkSimdlenSafelenSpecified(*this, Clauses))
11683 return StmtError();
11684
11685 setFunctionHasBranchProtectedScope();
11686
11687 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11688
11689 return OMPTeamsDistributeSimdDirective::Create(
11690 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11691}
11692
11693StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11694 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11695 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11696 if (!AStmt)
11697 return StmtError();
11698
11699 auto *CS = cast<CapturedStmt>(AStmt);
11700 // 1.2.2 OpenMP Language Terminology
11701 // Structured block - An executable statement with a single entry at the
11702 // top and a single exit at the bottom.
11703 // The point of exit cannot be a branch out of the structured block.
11704 // longjmp() and throw() must not violate the entry/exit criteria.
11705 CS->getCapturedDecl()->setNothrow();
11706
11707 for (int ThisCaptureLevel =
11708 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11709 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11710 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11711 // 1.2.2 OpenMP Language Terminology
11712 // Structured block - An executable statement with a single entry at the
11713 // top and a single exit at the bottom.
11714 // The point of exit cannot be a branch out of the structured block.
11715 // longjmp() and throw() must not violate the entry/exit criteria.
11716 CS->getCapturedDecl()->setNothrow();
11717 }
11718
11719 OMPLoopBasedDirective::HelperExprs B;
11720 // In presence of clause 'collapse' with number of loops, it will
11721 // define the nested loops number.
11722 unsigned NestedLoopCount = checkOpenMPLoop(
11723 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11724 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11725 VarsWithImplicitDSA, B);
11726
11727 if (NestedLoopCount == 0)
11728 return StmtError();
11729
11730 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11731, __PRETTY_FUNCTION__))
11731 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11731, __PRETTY_FUNCTION__))
;
11732
11733 if (!CurContext->isDependentContext()) {
11734 // Finalize the clauses that need pre-built expressions for CodeGen.
11735 for (OMPClause *C : Clauses) {
11736 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11737 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11738 B.NumIterations, *this, CurScope,
11739 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11740 return StmtError();
11741 }
11742 }
11743
11744 if (checkSimdlenSafelenSpecified(*this, Clauses))
11745 return StmtError();
11746
11747 setFunctionHasBranchProtectedScope();
11748
11749 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11750
11751 return OMPTeamsDistributeParallelForSimdDirective::Create(
11752 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11753}
11754
11755StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11756 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11757 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11758 if (!AStmt)
11759 return StmtError();
11760
11761 auto *CS = cast<CapturedStmt>(AStmt);
11762 // 1.2.2 OpenMP Language Terminology
11763 // Structured block - An executable statement with a single entry at the
11764 // top and a single exit at the bottom.
11765 // The point of exit cannot be a branch out of the structured block.
11766 // longjmp() and throw() must not violate the entry/exit criteria.
11767 CS->getCapturedDecl()->setNothrow();
11768
11769 for (int ThisCaptureLevel =
11770 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11771 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11772 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11773 // 1.2.2 OpenMP Language Terminology
11774 // Structured block - An executable statement with a single entry at the
11775 // top and a single exit at the bottom.
11776 // The point of exit cannot be a branch out of the structured block.
11777 // longjmp() and throw() must not violate the entry/exit criteria.
11778 CS->getCapturedDecl()->setNothrow();
11779 }
11780
11781 OMPLoopBasedDirective::HelperExprs B;
11782 // In presence of clause 'collapse' with number of loops, it will
11783 // define the nested loops number.
11784 unsigned NestedLoopCount = checkOpenMPLoop(
11785 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11786 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11787 VarsWithImplicitDSA, B);
11788
11789 if (NestedLoopCount == 0)
11790 return StmtError();
11791
11792 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11793, __PRETTY_FUNCTION__))
11793 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11793, __PRETTY_FUNCTION__))
;
11794
11795 setFunctionHasBranchProtectedScope();
11796
11797 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11798
11799 return OMPTeamsDistributeParallelForDirective::Create(
11800 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11801 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11802}
11803
11804StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11805 Stmt *AStmt,
11806 SourceLocation StartLoc,
11807 SourceLocation EndLoc) {
11808 if (!AStmt)
11809 return StmtError();
11810
11811 auto *CS = cast<CapturedStmt>(AStmt);
11812 // 1.2.2 OpenMP Language Terminology
11813 // Structured block - An executable statement with a single entry at the
11814 // top and a single exit at the bottom.
11815 // The point of exit cannot be a branch out of the structured block.
11816 // longjmp() and throw() must not violate the entry/exit criteria.
11817 CS->getCapturedDecl()->setNothrow();
11818
11819 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11820 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11821 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11822 // 1.2.2 OpenMP Language Terminology
11823 // Structured block - An executable statement with a single entry at the
11824 // top and a single exit at the bottom.
11825 // The point of exit cannot be a branch out of the structured block.
11826 // longjmp() and throw() must not violate the entry/exit criteria.
11827 CS->getCapturedDecl()->setNothrow();
11828 }
11829 setFunctionHasBranchProtectedScope();
11830
11831 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11832 AStmt);
11833}
11834
11835StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11836 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11837 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11838 if (!AStmt)
11839 return StmtError();
11840
11841 auto *CS = cast<CapturedStmt>(AStmt);
11842 // 1.2.2 OpenMP Language Terminology
11843 // Structured block - An executable statement with a single entry at the
11844 // top and a single exit at the bottom.
11845 // The point of exit cannot be a branch out of the structured block.
11846 // longjmp() and throw() must not violate the entry/exit criteria.
11847 CS->getCapturedDecl()->setNothrow();
11848 for (int ThisCaptureLevel =
11849 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11850 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11851 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11852 // 1.2.2 OpenMP Language Terminology
11853 // Structured block - An executable statement with a single entry at the
11854 // top and a single exit at the bottom.
11855 // The point of exit cannot be a branch out of the structured block.
11856 // longjmp() and throw() must not violate the entry/exit criteria.
11857 CS->getCapturedDecl()->setNothrow();
11858 }
11859
11860 OMPLoopBasedDirective::HelperExprs B;
11861 // In presence of clause 'collapse' with number of loops, it will
11862 // define the nested loops number.
11863 unsigned NestedLoopCount = checkOpenMPLoop(
11864 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11865 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11866 VarsWithImplicitDSA, B);
11867 if (NestedLoopCount == 0)
11868 return StmtError();
11869
11870 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11871, __PRETTY_FUNCTION__))
11871 "omp target teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11871, __PRETTY_FUNCTION__))
;
11872
11873 setFunctionHasBranchProtectedScope();
11874 return OMPTargetTeamsDistributeDirective::Create(
11875 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11876}
11877
11878StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11879 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11880 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11881 if (!AStmt)
11882 return StmtError();
11883
11884 auto *CS = cast<CapturedStmt>(AStmt);
11885 // 1.2.2 OpenMP Language Terminology
11886 // Structured block - An executable statement with a single entry at the
11887 // top and a single exit at the bottom.
11888 // The point of exit cannot be a branch out of the structured block.
11889 // longjmp() and throw() must not violate the entry/exit criteria.
11890 CS->getCapturedDecl()->setNothrow();
11891 for (int ThisCaptureLevel =
11892 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11893 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11894 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11895 // 1.2.2 OpenMP Language Terminology
11896 // Structured block - An executable statement with a single entry at the
11897 // top and a single exit at the bottom.
11898 // The point of exit cannot be a branch out of the structured block.
11899 // longjmp() and throw() must not violate the entry/exit criteria.
11900 CS->getCapturedDecl()->setNothrow();
11901 }
11902
11903 OMPLoopBasedDirective::HelperExprs B;
11904 // In presence of clause 'collapse' with number of loops, it will
11905 // define the nested loops number.
11906 unsigned NestedLoopCount = checkOpenMPLoop(
11907 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11908 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11909 VarsWithImplicitDSA, B);
11910 if (NestedLoopCount == 0)
11911 return StmtError();
11912
11913 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11914, __PRETTY_FUNCTION__))
11914 "omp target teams distribute parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11914, __PRETTY_FUNCTION__))
;
11915
11916 if (!CurContext->isDependentContext()) {
11917 // Finalize the clauses that need pre-built expressions for CodeGen.
11918 for (OMPClause *C : Clauses) {
11919 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11920 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11921 B.NumIterations, *this, CurScope,
11922 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11923 return StmtError();
11924 }
11925 }
11926
11927 setFunctionHasBranchProtectedScope();
11928 return OMPTargetTeamsDistributeParallelForDirective::Create(
11929 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11930 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11931}
11932
11933StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11934 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11935 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11936 if (!AStmt)
11937 return StmtError();
11938
11939 auto *CS = cast<CapturedStmt>(AStmt);
11940 // 1.2.2 OpenMP Language Terminology
11941 // Structured block - An executable statement with a single entry at the
11942 // top and a single exit at the bottom.
11943 // The point of exit cannot be a branch out of the structured block.
11944 // longjmp() and throw() must not violate the entry/exit criteria.
11945 CS->getCapturedDecl()->setNothrow();
11946 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11947 OMPD_target_teams_distribute_parallel_for_simd);
11948 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11949 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11950 // 1.2.2 OpenMP Language Terminology
11951 // Structured block - An executable statement with a single entry at the
11952 // top and a single exit at the bottom.
11953 // The point of exit cannot be a branch out of the structured block.
11954 // longjmp() and throw() must not violate the entry/exit criteria.
11955 CS->getCapturedDecl()->setNothrow();
11956 }
11957
11958 OMPLoopBasedDirective::HelperExprs B;
11959 // In presence of clause 'collapse' with number of loops, it will
11960 // define the nested loops number.
11961 unsigned NestedLoopCount =
11962 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11963 getCollapseNumberExpr(Clauses),
11964 nullptr /*ordered not a clause on distribute*/, CS, *this,
11965 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11966 if (NestedLoopCount == 0)
11967 return StmtError();
11968
11969 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11971, __PRETTY_FUNCTION__))
11970 "omp target teams distribute parallel for simd loop exprs were not "(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11971, __PRETTY_FUNCTION__))
11971 "built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 11971, __PRETTY_FUNCTION__))
;
11972
11973 if (!CurContext->isDependentContext()) {
11974 // Finalize the clauses that need pre-built expressions for CodeGen.
11975 for (OMPClause *C : Clauses) {
11976 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11977 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11978 B.NumIterations, *this, CurScope,
11979 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11980 return StmtError();
11981 }
11982 }
11983
11984 if (checkSimdlenSafelenSpecified(*this, Clauses))
11985 return StmtError();
11986
11987 setFunctionHasBranchProtectedScope();
11988 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11989 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11990}
11991
11992StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11993 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11994 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11995 if (!AStmt)
11996 return StmtError();
11997
11998 auto *CS = cast<CapturedStmt>(AStmt);
11999 // 1.2.2 OpenMP Language Terminology
12000 // Structured block - An executable statement with a single entry at the
12001 // top and a single exit at the bottom.
12002 // The point of exit cannot be a branch out of the structured block.
12003 // longjmp() and throw() must not violate the entry/exit criteria.
12004 CS->getCapturedDecl()->setNothrow();
12005 for (int ThisCaptureLevel =
12006 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12007 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12008 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12009 // 1.2.2 OpenMP Language Terminology
12010 // Structured block - An executable statement with a single entry at the
12011 // top and a single exit at the bottom.
12012 // The point of exit cannot be a branch out of the structured block.
12013 // longjmp() and throw() must not violate the entry/exit criteria.
12014 CS->getCapturedDecl()->setNothrow();
12015 }
12016
12017 OMPLoopBasedDirective::HelperExprs B;
12018 // In presence of clause 'collapse' with number of loops, it will
12019 // define the nested loops number.
12020 unsigned NestedLoopCount = checkOpenMPLoop(
12021 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12022 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12023 VarsWithImplicitDSA, B);
12024 if (NestedLoopCount == 0)
12025 return StmtError();
12026
12027 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute simd loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12028, __PRETTY_FUNCTION__))
12028 "omp target teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute simd loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12028, __PRETTY_FUNCTION__))
;
12029
12030 if (!CurContext->isDependentContext()) {
12031 // Finalize the clauses that need pre-built expressions for CodeGen.
12032 for (OMPClause *C : Clauses) {
12033 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12034 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12035 B.NumIterations, *this, CurScope,
12036 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12037 return StmtError();
12038 }
12039 }
12040
12041 if (checkSimdlenSafelenSpecified(*this, Clauses))
12042 return StmtError();
12043
12044 setFunctionHasBranchProtectedScope();
12045 return OMPTargetTeamsDistributeSimdDirective::Create(
12046 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12047}
12048
12049StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12050 Stmt *AStmt, SourceLocation StartLoc,
12051 SourceLocation EndLoc) {
12052 auto SizesClauses =
12053 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12054 if (SizesClauses.empty()) {
12055 // A missing 'sizes' clause is already reported by the parser.
12056 return StmtError();
12057 }
12058 const OMPSizesClause *SizesClause = *SizesClauses.begin();
12059 unsigned NumLoops = SizesClause->getNumSizes();
12060
12061 // Empty statement should only be possible if there already was an error.
12062 if (!AStmt)
12063 return StmtError();
12064
12065 // Verify and diagnose loop nest.
12066 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12067 Stmt *Body = nullptr;
12068 SmallVector<Stmt *, 4> OriginalInits;
12069 if (!OMPLoopBasedDirective::doForAllLoops(
12070 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false,
12071 NumLoops,
12072 [this, &LoopHelpers, &Body, &OriginalInits](unsigned Cnt,
12073 Stmt *CurStmt) {
12074 VarsWithInheritedDSAType TmpDSA;
12075 unsigned SingleNumLoops =
12076 checkOpenMPLoop(OMPD_tile, nullptr, nullptr, CurStmt, *this,
12077 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, TmpDSA, LoopHelpers[Cnt]);
12078 if (SingleNumLoops == 0)
12079 return true;
12080 assert(SingleNumLoops == 1 && "Expect single loop iteration space")((SingleNumLoops == 1 && "Expect single loop iteration space"
) ? static_cast<void> (0) : __assert_fail ("SingleNumLoops == 1 && \"Expect single loop iteration space\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12080, __PRETTY_FUNCTION__))
;
12081 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12082 OriginalInits.push_back(For->getInit());
12083 Body = For->getBody();
12084 } else {
12085 assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12086, __PRETTY_FUNCTION__))
12086 "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12086, __PRETTY_FUNCTION__))
;
12087 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12088 OriginalInits.push_back(CXXFor->getBeginStmt());
12089 Body = CXXFor->getBody();
12090 }
12091 return false;
12092 }))
12093 return StmtError();
12094
12095 // Delay tiling to when template is completely instantiated.
12096 if (CurContext->isDependentContext())
12097 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12098 NumLoops, AStmt, nullptr, nullptr);
12099
12100 // Collection of generated variable declaration.
12101 SmallVector<Decl *, 4> PreInits;
12102
12103 // Create iteration variables for the generated loops.
12104 SmallVector<VarDecl *, 4> FloorIndVars;
12105 SmallVector<VarDecl *, 4> TileIndVars;
12106 FloorIndVars.resize(NumLoops);
12107 TileIndVars.resize(NumLoops);
12108 for (unsigned I = 0; I < NumLoops; ++I) {
12109 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12110 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12111 PreInits.append(PI->decl_begin(), PI->decl_end());
12112 assert(LoopHelper.Counters.size() == 1 &&((LoopHelper.Counters.size() == 1 && "Expect single-dimensional loop iteration space"
) ? static_cast<void> (0) : __assert_fail ("LoopHelper.Counters.size() == 1 && \"Expect single-dimensional loop iteration space\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12113, __PRETTY_FUNCTION__))
12113 "Expect single-dimensional loop iteration space")((LoopHelper.Counters.size() == 1 && "Expect single-dimensional loop iteration space"
) ? static_cast<void> (0) : __assert_fail ("LoopHelper.Counters.size() == 1 && \"Expect single-dimensional loop iteration space\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12113, __PRETTY_FUNCTION__))
;
12114 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12115 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12116 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12117 QualType CntTy = IterVarRef->getType();
12118
12119 // Iteration variable for the floor (i.e. outer) loop.
12120 {
12121 std::string FloorCntName =
12122 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12123 VarDecl *FloorCntDecl =
12124 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12125 FloorIndVars[I] = FloorCntDecl;
12126 }
12127
12128 // Iteration variable for the tile (i.e. inner) loop.
12129 {
12130 std::string TileCntName =
12131 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12132
12133 // Reuse the iteration variable created by checkOpenMPLoop. It is also
12134 // used by the expressions to derive the original iteration variable's
12135 // value from the logical iteration number.
12136 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12137 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12138 TileIndVars[I] = TileCntDecl;
12139 }
12140 if (auto *PI = dyn_cast_or_null<DeclStmt>(OriginalInits[I]))
12141 PreInits.append(PI->decl_begin(), PI->decl_end());
12142 // Gather declarations for the data members used as counters.
12143 for (Expr *CounterRef : LoopHelper.Counters) {
12144 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12145 if (isa<OMPCapturedExprDecl>(CounterDecl))
12146 PreInits.push_back(CounterDecl);
12147 }
12148 }
12149
12150 // Once the original iteration values are set, append the innermost body.
12151 Stmt *Inner = Body;
12152
12153 // Create tile loops from the inside to the outside.
12154 for (int I = NumLoops - 1; I >= 0; --I) {
12155 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12156 Expr *NumIterations = LoopHelper.NumIterations;
12157 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12158 QualType CntTy = OrigCntVar->getType();
12159 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12160 Scope *CurScope = getCurScope();
12161
12162 // Commonly used variables.
12163 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12164 OrigCntVar->getExprLoc());
12165 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12166 OrigCntVar->getExprLoc());
12167
12168 // For init-statement: auto .tile.iv = .floor.iv
12169 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12170 /*DirectInit=*/false);
12171 Decl *CounterDecl = TileIndVars[I];
12172 StmtResult InitStmt = new (Context)
12173 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12174 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12175 if (!InitStmt.isUsable())
12176 return StmtError();
12177
12178 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12179 // NumIterations)
12180 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12181 BO_Add, FloorIV, DimTileSize);
12182 if (!EndOfTile.isUsable())
12183 return StmtError();
12184 ExprResult IsPartialTile =
12185 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12186 NumIterations, EndOfTile.get());
12187 if (!IsPartialTile.isUsable())
12188 return StmtError();
12189 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12190 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12191 IsPartialTile.get(), NumIterations, EndOfTile.get());
12192 if (!MinTileAndIterSpace.isUsable())
12193 return StmtError();
12194 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12195 BO_LT, TileIV, MinTileAndIterSpace.get());
12196 if (!CondExpr.isUsable())
12197 return StmtError();
12198
12199 // For incr-statement: ++.tile.iv
12200 ExprResult IncrStmt =
12201 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12202 if (!IncrStmt.isUsable())
12203 return StmtError();
12204
12205 // Statements to set the original iteration variable's value from the
12206 // logical iteration number.
12207 // Generated for loop is:
12208 // Original_for_init;
12209 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12210 // NumIterations); ++.tile.iv) {
12211 // Original_Body;
12212 // Original_counter_update;
12213 // }
12214 // FIXME: If the innermost body is an loop itself, inserting these
12215 // statements stops it being recognized as a perfectly nested loop (e.g.
12216 // for applying tiling again). If this is the case, sink the expressions
12217 // further into the inner loop.
12218 SmallVector<Stmt *, 4> BodyParts;
12219 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12220 BodyParts.push_back(Inner);
12221 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12222 Inner->getEndLoc());
12223 Inner = new (Context)
12224 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12225 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12226 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12227 }
12228
12229 // Create floor loops from the inside to the outside.
12230 for (int I = NumLoops - 1; I >= 0; --I) {
12231 auto &LoopHelper = LoopHelpers[I];
12232 Expr *NumIterations = LoopHelper.NumIterations;
12233 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12234 QualType CntTy = OrigCntVar->getType();
12235 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12236 Scope *CurScope = getCurScope();
12237
12238 // Commonly used variables.
12239 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12240 OrigCntVar->getExprLoc());
12241
12242 // For init-statement: auto .floor.iv = 0
12243 AddInitializerToDecl(
12244 FloorIndVars[I],
12245 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12246 /*DirectInit=*/false);
12247 Decl *CounterDecl = FloorIndVars[I];
12248 StmtResult InitStmt = new (Context)
12249 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12250 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12251 if (!InitStmt.isUsable())
12252 return StmtError();
12253
12254 // For cond-expression: .floor.iv < NumIterations
12255 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12256 BO_LT, FloorIV, NumIterations);
12257 if (!CondExpr.isUsable())
12258 return StmtError();
12259
12260 // For incr-statement: .floor.iv += DimTileSize
12261 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12262 BO_AddAssign, FloorIV, DimTileSize);
12263 if (!IncrStmt.isUsable())
12264 return StmtError();
12265
12266 Inner = new (Context)
12267 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12268 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12269 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12270 }
12271
12272 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12273 AStmt, Inner,
12274 buildPreInits(Context, PreInits));
12275}
12276
12277OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
12278 SourceLocation StartLoc,
12279 SourceLocation LParenLoc,
12280 SourceLocation EndLoc) {
12281 OMPClause *Res = nullptr;
12282 switch (Kind) {
12283 case OMPC_final:
12284 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
12285 break;
12286 case OMPC_num_threads:
12287 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
12288 break;
12289 case OMPC_safelen:
12290 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
12291 break;
12292 case OMPC_simdlen:
12293 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
12294 break;
12295 case OMPC_allocator:
12296 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
12297 break;
12298 case OMPC_collapse:
12299 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
12300 break;
12301 case OMPC_ordered:
12302 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
12303 break;
12304 case OMPC_num_teams:
12305 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
12306 break;
12307 case OMPC_thread_limit:
12308 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
12309 break;
12310 case OMPC_priority:
12311 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
12312 break;
12313 case OMPC_grainsize:
12314 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
12315 break;
12316 case OMPC_num_tasks:
12317 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
12318 break;
12319 case OMPC_hint:
12320 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
12321 break;
12322 case OMPC_depobj:
12323 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
12324 break;
12325 case OMPC_detach:
12326 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
12327 break;
12328 case OMPC_device:
12329 case OMPC_if:
12330 case OMPC_default:
12331 case OMPC_proc_bind:
12332 case OMPC_schedule:
12333 case OMPC_private:
12334 case OMPC_firstprivate:
12335 case OMPC_lastprivate:
12336 case OMPC_shared:
12337 case OMPC_reduction:
12338 case OMPC_task_reduction:
12339 case OMPC_in_reduction:
12340 case OMPC_linear:
12341 case OMPC_aligned:
12342 case OMPC_copyin:
12343 case OMPC_copyprivate:
12344 case OMPC_nowait:
12345 case OMPC_untied:
12346 case OMPC_mergeable:
12347 case OMPC_threadprivate:
12348 case OMPC_sizes:
12349 case OMPC_allocate:
12350 case OMPC_flush:
12351 case OMPC_read:
12352 case OMPC_write:
12353 case OMPC_update:
12354 case OMPC_capture:
12355 case OMPC_seq_cst:
12356 case OMPC_acq_rel:
12357 case OMPC_acquire:
12358 case OMPC_release:
12359 case OMPC_relaxed:
12360 case OMPC_depend:
12361 case OMPC_threads:
12362 case OMPC_simd:
12363 case OMPC_map:
12364 case OMPC_nogroup:
12365 case OMPC_dist_schedule:
12366 case OMPC_defaultmap:
12367 case OMPC_unknown:
12368 case OMPC_uniform:
12369 case OMPC_to:
12370 case OMPC_from:
12371 case OMPC_use_device_ptr:
12372 case OMPC_use_device_addr:
12373 case OMPC_is_device_ptr:
12374 case OMPC_unified_address:
12375 case OMPC_unified_shared_memory:
12376 case OMPC_reverse_offload:
12377 case OMPC_dynamic_allocators:
12378 case OMPC_atomic_default_mem_order:
12379 case OMPC_device_type:
12380 case OMPC_match:
12381 case OMPC_nontemporal:
12382 case OMPC_order:
12383 case OMPC_destroy:
12384 case OMPC_inclusive:
12385 case OMPC_exclusive:
12386 case OMPC_uses_allocators:
12387 case OMPC_affinity:
12388 default:
12389 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12389)
;
12390 }
12391 return Res;
12392}
12393
12394// An OpenMP directive such as 'target parallel' has two captured regions:
12395// for the 'target' and 'parallel' respectively. This function returns
12396// the region in which to capture expressions associated with a clause.
12397// A return value of OMPD_unknown signifies that the expression should not
12398// be captured.
12399static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
12400 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
12401 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
12402 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12403 switch (CKind) {
12404 case OMPC_if:
12405 switch (DKind) {
12406 case OMPD_target_parallel_for_simd:
12407 if (OpenMPVersion >= 50 &&
12408 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12409 CaptureRegion = OMPD_parallel;
12410 break;
12411 }
12412 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12413 case OMPD_target_parallel:
12414 case OMPD_target_parallel_for:
12415 // If this clause applies to the nested 'parallel' region, capture within
12416 // the 'target' region, otherwise do not capture.
12417 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12418 CaptureRegion = OMPD_target;
12419 break;
12420 case OMPD_target_teams_distribute_parallel_for_simd:
12421 if (OpenMPVersion >= 50 &&
12422 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12423 CaptureRegion = OMPD_parallel;
12424 break;
12425 }
12426 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12427 case OMPD_target_teams_distribute_parallel_for:
12428 // If this clause applies to the nested 'parallel' region, capture within
12429 // the 'teams' region, otherwise do not capture.
12430 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12431 CaptureRegion = OMPD_teams;
12432 break;
12433 case OMPD_teams_distribute_parallel_for_simd:
12434 if (OpenMPVersion >= 50 &&
12435 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12436 CaptureRegion = OMPD_parallel;
12437 break;
12438 }
12439 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12440 case OMPD_teams_distribute_parallel_for:
12441 CaptureRegion = OMPD_teams;
12442 break;
12443 case OMPD_target_update:
12444 case OMPD_target_enter_data:
12445 case OMPD_target_exit_data:
12446 CaptureRegion = OMPD_task;
12447 break;
12448 case OMPD_parallel_master_taskloop:
12449 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
12450 CaptureRegion = OMPD_parallel;
12451 break;
12452 case OMPD_parallel_master_taskloop_simd:
12453 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
12454 NameModifier == OMPD_taskloop) {
12455 CaptureRegion = OMPD_parallel;
12456 break;
12457 }
12458 if (OpenMPVersion <= 45)
12459 break;
12460 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12461 CaptureRegion = OMPD_taskloop;
12462 break;
12463 case OMPD_parallel_for_simd:
12464 if (OpenMPVersion <= 45)
12465 break;
12466 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12467 CaptureRegion = OMPD_parallel;
12468 break;
12469 case OMPD_taskloop_simd:
12470 case OMPD_master_taskloop_simd:
12471 if (OpenMPVersion <= 45)
12472 break;
12473 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12474 CaptureRegion = OMPD_taskloop;
12475 break;
12476 case OMPD_distribute_parallel_for_simd:
12477 if (OpenMPVersion <= 45)
12478 break;
12479 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12480 CaptureRegion = OMPD_parallel;
12481 break;
12482 case OMPD_target_simd:
12483 if (OpenMPVersion >= 50 &&
12484 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12485 CaptureRegion = OMPD_target;
12486 break;
12487 case OMPD_teams_distribute_simd:
12488 case OMPD_target_teams_distribute_simd:
12489 if (OpenMPVersion >= 50 &&
12490 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12491 CaptureRegion = OMPD_teams;
12492 break;
12493 case OMPD_cancel:
12494 case OMPD_parallel:
12495 case OMPD_parallel_master:
12496 case OMPD_parallel_sections:
12497 case OMPD_parallel_for:
12498 case OMPD_target:
12499 case OMPD_target_teams:
12500 case OMPD_target_teams_distribute:
12501 case OMPD_distribute_parallel_for:
12502 case OMPD_task:
12503 case OMPD_taskloop:
12504 case OMPD_master_taskloop:
12505 case OMPD_target_data:
12506 case OMPD_simd:
12507 case OMPD_for_simd:
12508 case OMPD_distribute_simd:
12509 // Do not capture if-clause expressions.
12510 break;
12511 case OMPD_threadprivate:
12512 case OMPD_allocate:
12513 case OMPD_taskyield:
12514 case OMPD_barrier:
12515 case OMPD_taskwait:
12516 case OMPD_cancellation_point:
12517 case OMPD_flush:
12518 case OMPD_depobj:
12519 case OMPD_scan:
12520 case OMPD_declare_reduction:
12521 case OMPD_declare_mapper:
12522 case OMPD_declare_simd:
12523 case OMPD_declare_variant:
12524 case OMPD_begin_declare_variant:
12525 case OMPD_end_declare_variant:
12526 case OMPD_declare_target:
12527 case OMPD_end_declare_target:
12528 case OMPD_teams:
12529 case OMPD_tile:
12530 case OMPD_for:
12531 case OMPD_sections:
12532 case OMPD_section:
12533 case OMPD_single:
12534 case OMPD_master:
12535 case OMPD_critical:
12536 case OMPD_taskgroup:
12537 case OMPD_distribute:
12538 case OMPD_ordered:
12539 case OMPD_atomic:
12540 case OMPD_teams_distribute:
12541 case OMPD_requires:
12542 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12542)
;
12543 case OMPD_unknown:
12544 default:
12545 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12545)
;
12546 }
12547 break;
12548 case OMPC_num_threads:
12549 switch (DKind) {
12550 case OMPD_target_parallel:
12551 case OMPD_target_parallel_for:
12552 case OMPD_target_parallel_for_simd:
12553 CaptureRegion = OMPD_target;
12554 break;
12555 case OMPD_teams_distribute_parallel_for:
12556 case OMPD_teams_distribute_parallel_for_simd:
12557 case OMPD_target_teams_distribute_parallel_for:
12558 case OMPD_target_teams_distribute_parallel_for_simd:
12559 CaptureRegion = OMPD_teams;
12560 break;
12561 case OMPD_parallel:
12562 case OMPD_parallel_master:
12563 case OMPD_parallel_sections:
12564 case OMPD_parallel_for:
12565 case OMPD_parallel_for_simd:
12566 case OMPD_distribute_parallel_for:
12567 case OMPD_distribute_parallel_for_simd:
12568 case OMPD_parallel_master_taskloop:
12569 case OMPD_parallel_master_taskloop_simd:
12570 // Do not capture num_threads-clause expressions.
12571 break;
12572 case OMPD_target_data:
12573 case OMPD_target_enter_data:
12574 case OMPD_target_exit_data:
12575 case OMPD_target_update:
12576 case OMPD_target:
12577 case OMPD_target_simd:
12578 case OMPD_target_teams:
12579 case OMPD_target_teams_distribute:
12580 case OMPD_target_teams_distribute_simd:
12581 case OMPD_cancel:
12582 case OMPD_task:
12583 case OMPD_taskloop:
12584 case OMPD_taskloop_simd:
12585 case OMPD_master_taskloop:
12586 case OMPD_master_taskloop_simd:
12587 case OMPD_threadprivate:
12588 case OMPD_allocate:
12589 case OMPD_taskyield:
12590 case OMPD_barrier:
12591 case OMPD_taskwait:
12592 case OMPD_cancellation_point:
12593 case OMPD_flush:
12594 case OMPD_depobj:
12595 case OMPD_scan:
12596 case OMPD_declare_reduction:
12597 case OMPD_declare_mapper:
12598 case OMPD_declare_simd:
12599 case OMPD_declare_variant:
12600 case OMPD_begin_declare_variant:
12601 case OMPD_end_declare_variant:
12602 case OMPD_declare_target:
12603 case OMPD_end_declare_target:
12604 case OMPD_teams:
12605 case OMPD_simd:
12606 case OMPD_tile:
12607 case OMPD_for:
12608 case OMPD_for_simd:
12609 case OMPD_sections:
12610 case OMPD_section:
12611 case OMPD_single:
12612 case OMPD_master:
12613 case OMPD_critical:
12614 case OMPD_taskgroup:
12615 case OMPD_distribute:
12616 case OMPD_ordered:
12617 case OMPD_atomic:
12618 case OMPD_distribute_simd:
12619 case OMPD_teams_distribute:
12620 case OMPD_teams_distribute_simd:
12621 case OMPD_requires:
12622 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12622)
;
12623 case OMPD_unknown:
12624 default:
12625 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12625)
;
12626 }
12627 break;
12628 case OMPC_num_teams:
12629 switch (DKind) {
12630 case OMPD_target_teams:
12631 case OMPD_target_teams_distribute:
12632 case OMPD_target_teams_distribute_simd:
12633 case OMPD_target_teams_distribute_parallel_for:
12634 case OMPD_target_teams_distribute_parallel_for_simd:
12635 CaptureRegion = OMPD_target;
12636 break;
12637 case OMPD_teams_distribute_parallel_for:
12638 case OMPD_teams_distribute_parallel_for_simd:
12639 case OMPD_teams:
12640 case OMPD_teams_distribute:
12641 case OMPD_teams_distribute_simd:
12642 // Do not capture num_teams-clause expressions.
12643 break;
12644 case OMPD_distribute_parallel_for:
12645 case OMPD_distribute_parallel_for_simd:
12646 case OMPD_task:
12647 case OMPD_taskloop:
12648 case OMPD_taskloop_simd:
12649 case OMPD_master_taskloop:
12650 case OMPD_master_taskloop_simd:
12651 case OMPD_parallel_master_taskloop:
12652 case OMPD_parallel_master_taskloop_simd:
12653 case OMPD_target_data:
12654 case OMPD_target_enter_data:
12655 case OMPD_target_exit_data:
12656 case OMPD_target_update:
12657 case OMPD_cancel:
12658 case OMPD_parallel:
12659 case OMPD_parallel_master:
12660 case OMPD_parallel_sections:
12661 case OMPD_parallel_for:
12662 case OMPD_parallel_for_simd:
12663 case OMPD_target:
12664 case OMPD_target_simd:
12665 case OMPD_target_parallel:
12666 case OMPD_target_parallel_for:
12667 case OMPD_target_parallel_for_simd:
12668 case OMPD_threadprivate:
12669 case OMPD_allocate:
12670 case OMPD_taskyield:
12671 case OMPD_barrier:
12672 case OMPD_taskwait:
12673 case OMPD_cancellation_point:
12674 case OMPD_flush:
12675 case OMPD_depobj:
12676 case OMPD_scan:
12677 case OMPD_declare_reduction:
12678 case OMPD_declare_mapper:
12679 case OMPD_declare_simd:
12680 case OMPD_declare_variant:
12681 case OMPD_begin_declare_variant:
12682 case OMPD_end_declare_variant:
12683 case OMPD_declare_target:
12684 case OMPD_end_declare_target:
12685 case OMPD_simd:
12686 case OMPD_tile:
12687 case OMPD_for:
12688 case OMPD_for_simd:
12689 case OMPD_sections:
12690 case OMPD_section:
12691 case OMPD_single:
12692 case OMPD_master:
12693 case OMPD_critical:
12694 case OMPD_taskgroup:
12695 case OMPD_distribute:
12696 case OMPD_ordered:
12697 case OMPD_atomic:
12698 case OMPD_distribute_simd:
12699 case OMPD_requires:
12700 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12700)
;
12701 case OMPD_unknown:
12702 default:
12703 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12703)
;
12704 }
12705 break;
12706 case OMPC_thread_limit:
12707 switch (DKind) {
12708 case OMPD_target_teams:
12709 case OMPD_target_teams_distribute:
12710 case OMPD_target_teams_distribute_simd:
12711 case OMPD_target_teams_distribute_parallel_for:
12712 case OMPD_target_teams_distribute_parallel_for_simd:
12713 CaptureRegion = OMPD_target;
12714 break;
12715 case OMPD_teams_distribute_parallel_for:
12716 case OMPD_teams_distribute_parallel_for_simd:
12717 case OMPD_teams:
12718 case OMPD_teams_distribute:
12719 case OMPD_teams_distribute_simd:
12720 // Do not capture thread_limit-clause expressions.
12721 break;
12722 case OMPD_distribute_parallel_for:
12723 case OMPD_distribute_parallel_for_simd:
12724 case OMPD_task:
12725 case OMPD_taskloop:
12726 case OMPD_taskloop_simd:
12727 case OMPD_master_taskloop:
12728 case OMPD_master_taskloop_simd:
12729 case OMPD_parallel_master_taskloop:
12730 case OMPD_parallel_master_taskloop_simd:
12731 case OMPD_target_data:
12732 case OMPD_target_enter_data:
12733 case OMPD_target_exit_data:
12734 case OMPD_target_update:
12735 case OMPD_cancel:
12736 case OMPD_parallel:
12737 case OMPD_parallel_master:
12738 case OMPD_parallel_sections:
12739 case OMPD_parallel_for:
12740 case OMPD_parallel_for_simd:
12741 case OMPD_target:
12742 case OMPD_target_simd:
12743 case OMPD_target_parallel:
12744 case OMPD_target_parallel_for:
12745 case OMPD_target_parallel_for_simd:
12746 case OMPD_threadprivate:
12747 case OMPD_allocate:
12748 case OMPD_taskyield:
12749 case OMPD_barrier:
12750 case OMPD_taskwait:
12751 case OMPD_cancellation_point:
12752 case OMPD_flush:
12753 case OMPD_depobj:
12754 case OMPD_scan:
12755 case OMPD_declare_reduction:
12756 case OMPD_declare_mapper:
12757 case OMPD_declare_simd:
12758 case OMPD_declare_variant:
12759 case OMPD_begin_declare_variant:
12760 case OMPD_end_declare_variant:
12761 case OMPD_declare_target:
12762 case OMPD_end_declare_target:
12763 case OMPD_simd:
12764 case OMPD_tile:
12765 case OMPD_for:
12766 case OMPD_for_simd:
12767 case OMPD_sections:
12768 case OMPD_section:
12769 case OMPD_single:
12770 case OMPD_master:
12771 case OMPD_critical:
12772 case OMPD_taskgroup:
12773 case OMPD_distribute:
12774 case OMPD_ordered:
12775 case OMPD_atomic:
12776 case OMPD_distribute_simd:
12777 case OMPD_requires:
12778 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12778)
;
12779 case OMPD_unknown:
12780 default:
12781 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12781)
;
12782 }
12783 break;
12784 case OMPC_schedule:
12785 switch (DKind) {
12786 case OMPD_parallel_for:
12787 case OMPD_parallel_for_simd:
12788 case OMPD_distribute_parallel_for:
12789 case OMPD_distribute_parallel_for_simd:
12790 case OMPD_teams_distribute_parallel_for:
12791 case OMPD_teams_distribute_parallel_for_simd:
12792 case OMPD_target_parallel_for:
12793 case OMPD_target_parallel_for_simd:
12794 case OMPD_target_teams_distribute_parallel_for:
12795 case OMPD_target_teams_distribute_parallel_for_simd:
12796 CaptureRegion = OMPD_parallel;
12797 break;
12798 case OMPD_for:
12799 case OMPD_for_simd:
12800 // Do not capture schedule-clause expressions.
12801 break;
12802 case OMPD_task:
12803 case OMPD_taskloop:
12804 case OMPD_taskloop_simd:
12805 case OMPD_master_taskloop:
12806 case OMPD_master_taskloop_simd:
12807 case OMPD_parallel_master_taskloop:
12808 case OMPD_parallel_master_taskloop_simd:
12809 case OMPD_target_data:
12810 case OMPD_target_enter_data:
12811 case OMPD_target_exit_data:
12812 case OMPD_target_update:
12813 case OMPD_teams:
12814 case OMPD_teams_distribute:
12815 case OMPD_teams_distribute_simd:
12816 case OMPD_target_teams_distribute:
12817 case OMPD_target_teams_distribute_simd:
12818 case OMPD_target:
12819 case OMPD_target_simd:
12820 case OMPD_target_parallel:
12821 case OMPD_cancel:
12822 case OMPD_parallel:
12823 case OMPD_parallel_master:
12824 case OMPD_parallel_sections:
12825 case OMPD_threadprivate:
12826 case OMPD_allocate:
12827 case OMPD_taskyield:
12828 case OMPD_barrier:
12829 case OMPD_taskwait:
12830 case OMPD_cancellation_point:
12831 case OMPD_flush:
12832 case OMPD_depobj:
12833 case OMPD_scan:
12834 case OMPD_declare_reduction:
12835 case OMPD_declare_mapper:
12836 case OMPD_declare_simd:
12837 case OMPD_declare_variant:
12838 case OMPD_begin_declare_variant:
12839 case OMPD_end_declare_variant:
12840 case OMPD_declare_target:
12841 case OMPD_end_declare_target:
12842 case OMPD_simd:
12843 case OMPD_tile:
12844 case OMPD_sections:
12845 case OMPD_section:
12846 case OMPD_single:
12847 case OMPD_master:
12848 case OMPD_critical:
12849 case OMPD_taskgroup:
12850 case OMPD_distribute:
12851 case OMPD_ordered:
12852 case OMPD_atomic:
12853 case OMPD_distribute_simd:
12854 case OMPD_target_teams:
12855 case OMPD_requires:
12856 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12856)
;
12857 case OMPD_unknown:
12858 default:
12859 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12859)
;
12860 }
12861 break;
12862 case OMPC_dist_schedule:
12863 switch (DKind) {
12864 case OMPD_teams_distribute_parallel_for:
12865 case OMPD_teams_distribute_parallel_for_simd:
12866 case OMPD_teams_distribute:
12867 case OMPD_teams_distribute_simd:
12868 case OMPD_target_teams_distribute_parallel_for:
12869 case OMPD_target_teams_distribute_parallel_for_simd:
12870 case OMPD_target_teams_distribute:
12871 case OMPD_target_teams_distribute_simd:
12872 CaptureRegion = OMPD_teams;
12873 break;
12874 case OMPD_distribute_parallel_for:
12875 case OMPD_distribute_parallel_for_simd:
12876 case OMPD_distribute:
12877 case OMPD_distribute_simd:
12878 // Do not capture dist_schedule-clause expressions.
12879 break;
12880 case OMPD_parallel_for:
12881 case OMPD_parallel_for_simd:
12882 case OMPD_target_parallel_for_simd:
12883 case OMPD_target_parallel_for:
12884 case OMPD_task:
12885 case OMPD_taskloop:
12886 case OMPD_taskloop_simd:
12887 case OMPD_master_taskloop:
12888 case OMPD_master_taskloop_simd:
12889 case OMPD_parallel_master_taskloop:
12890 case OMPD_parallel_master_taskloop_simd:
12891 case OMPD_target_data:
12892 case OMPD_target_enter_data:
12893 case OMPD_target_exit_data:
12894 case OMPD_target_update:
12895 case OMPD_teams:
12896 case OMPD_target:
12897 case OMPD_target_simd:
12898 case OMPD_target_parallel:
12899 case OMPD_cancel:
12900 case OMPD_parallel:
12901 case OMPD_parallel_master:
12902 case OMPD_parallel_sections:
12903 case OMPD_threadprivate:
12904 case OMPD_allocate:
12905 case OMPD_taskyield:
12906 case OMPD_barrier:
12907 case OMPD_taskwait:
12908 case OMPD_cancellation_point:
12909 case OMPD_flush:
12910 case OMPD_depobj:
12911 case OMPD_scan:
12912 case OMPD_declare_reduction:
12913 case OMPD_declare_mapper:
12914 case OMPD_declare_simd:
12915 case OMPD_declare_variant:
12916 case OMPD_begin_declare_variant:
12917 case OMPD_end_declare_variant:
12918 case OMPD_declare_target:
12919 case OMPD_end_declare_target:
12920 case OMPD_simd:
12921 case OMPD_tile:
12922 case OMPD_for:
12923 case OMPD_for_simd:
12924 case OMPD_sections:
12925 case OMPD_section:
12926 case OMPD_single:
12927 case OMPD_master:
12928 case OMPD_critical:
12929 case OMPD_taskgroup:
12930 case OMPD_ordered:
12931 case OMPD_atomic:
12932 case OMPD_target_teams:
12933 case OMPD_requires:
12934 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with dist_schedule clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12934)
;
12935 case OMPD_unknown:
12936 default:
12937 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 12937)
;
12938 }
12939 break;
12940 case OMPC_device:
12941 switch (DKind) {
12942 case OMPD_target_update:
12943 case OMPD_target_enter_data:
12944 case OMPD_target_exit_data:
12945 case OMPD_target:
12946 case OMPD_target_simd:
12947 case OMPD_target_teams:
12948 case OMPD_target_parallel:
12949 case OMPD_target_teams_distribute:
12950 case OMPD_target_teams_distribute_simd:
12951 case OMPD_target_parallel_for:
12952 case OMPD_target_parallel_for_simd:
12953 case OMPD_target_teams_distribute_parallel_for:
12954 case OMPD_target_teams_distribute_parallel_for_simd:
12955 CaptureRegion = OMPD_task;
12956 break;
12957 case OMPD_target_data:
12958 // Do not capture device-clause expressions.
12959 break;
12960 case OMPD_teams_distribute_parallel_for:
12961 case OMPD_teams_distribute_parallel_for_simd:
12962 case OMPD_teams:
12963 case OMPD_teams_distribute:
12964 case OMPD_teams_distribute_simd:
12965 case OMPD_distribute_parallel_for:
12966 case OMPD_distribute_parallel_for_simd:
12967 case OMPD_task:
12968 case OMPD_taskloop:
12969 case OMPD_taskloop_simd:
12970 case OMPD_master_taskloop:
12971 case OMPD_master_taskloop_simd:
12972 case OMPD_parallel_master_taskloop:
12973 case OMPD_parallel_master_taskloop_simd:
12974 case OMPD_cancel:
12975 case OMPD_parallel:
12976 case OMPD_parallel_master:
12977 case OMPD_parallel_sections:
12978 case OMPD_parallel_for:
12979 case OMPD_parallel_for_simd:
12980 case OMPD_threadprivate:
12981 case OMPD_allocate:
12982 case OMPD_taskyield:
12983 case OMPD_barrier:
12984 case OMPD_taskwait:
12985 case OMPD_cancellation_point:
12986 case OMPD_flush:
12987 case OMPD_depobj:
12988 case OMPD_scan:
12989 case OMPD_declare_reduction:
12990 case OMPD_declare_mapper:
12991 case OMPD_declare_simd:
12992 case OMPD_declare_variant:
12993 case OMPD_begin_declare_variant:
12994 case OMPD_end_declare_variant:
12995 case OMPD_declare_target:
12996 case OMPD_end_declare_target:
12997 case OMPD_simd:
12998 case OMPD_tile:
12999 case OMPD_for:
13000 case OMPD_for_simd:
13001 case OMPD_sections:
13002 case OMPD_section:
13003 case OMPD_single:
13004 case OMPD_master:
13005 case OMPD_critical:
13006 case OMPD_taskgroup:
13007 case OMPD_distribute:
13008 case OMPD_ordered:
13009 case OMPD_atomic:
13010 case OMPD_distribute_simd:
13011 case OMPD_requires:
13012 llvm_unreachable("Unexpected OpenMP directive with device-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with device-clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13012)
;
13013 case OMPD_unknown:
13014 default:
13015 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13015)
;
13016 }
13017 break;
13018 case OMPC_grainsize:
13019 case OMPC_num_tasks:
13020 case OMPC_final:
13021 case OMPC_priority:
13022 switch (DKind) {
13023 case OMPD_task:
13024 case OMPD_taskloop:
13025 case OMPD_taskloop_simd:
13026 case OMPD_master_taskloop:
13027 case OMPD_master_taskloop_simd:
13028 break;
13029 case OMPD_parallel_master_taskloop:
13030 case OMPD_parallel_master_taskloop_simd:
13031 CaptureRegion = OMPD_parallel;
13032 break;
13033 case OMPD_target_update:
13034 case OMPD_target_enter_data:
13035 case OMPD_target_exit_data:
13036 case OMPD_target:
13037 case OMPD_target_simd:
13038 case OMPD_target_teams:
13039 case OMPD_target_parallel:
13040 case OMPD_target_teams_distribute:
13041 case OMPD_target_teams_distribute_simd:
13042 case OMPD_target_parallel_for:
13043 case OMPD_target_parallel_for_simd:
13044 case OMPD_target_teams_distribute_parallel_for:
13045 case OMPD_target_teams_distribute_parallel_for_simd:
13046 case OMPD_target_data:
13047 case OMPD_teams_distribute_parallel_for:
13048 case OMPD_teams_distribute_parallel_for_simd:
13049 case OMPD_teams:
13050 case OMPD_teams_distribute:
13051 case OMPD_teams_distribute_simd:
13052 case OMPD_distribute_parallel_for:
13053 case OMPD_distribute_parallel_for_simd:
13054 case OMPD_cancel:
13055 case OMPD_parallel:
13056 case OMPD_parallel_master:
13057 case OMPD_parallel_sections:
13058 case OMPD_parallel_for:
13059 case OMPD_parallel_for_simd:
13060 case OMPD_threadprivate:
13061 case OMPD_allocate:
13062 case OMPD_taskyield:
13063 case OMPD_barrier:
13064 case OMPD_taskwait:
13065 case OMPD_cancellation_point:
13066 case OMPD_flush:
13067 case OMPD_depobj:
13068 case OMPD_scan:
13069 case OMPD_declare_reduction:
13070 case OMPD_declare_mapper:
13071 case OMPD_declare_simd:
13072 case OMPD_declare_variant:
13073 case OMPD_begin_declare_variant:
13074 case OMPD_end_declare_variant:
13075 case OMPD_declare_target:
13076 case OMPD_end_declare_target:
13077 case OMPD_simd:
13078 case OMPD_tile:
13079 case OMPD_for:
13080 case OMPD_for_simd:
13081 case OMPD_sections:
13082 case OMPD_section:
13083 case OMPD_single:
13084 case OMPD_master:
13085 case OMPD_critical:
13086 case OMPD_taskgroup:
13087 case OMPD_distribute:
13088 case OMPD_ordered:
13089 case OMPD_atomic:
13090 case OMPD_distribute_simd:
13091 case OMPD_requires:
13092 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13092)
;
13093 case OMPD_unknown:
13094 default:
13095 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13095)
;
13096 }
13097 break;
13098 case OMPC_firstprivate:
13099 case OMPC_lastprivate:
13100 case OMPC_reduction:
13101 case OMPC_task_reduction:
13102 case OMPC_in_reduction:
13103 case OMPC_linear:
13104 case OMPC_default:
13105 case OMPC_proc_bind:
13106 case OMPC_safelen:
13107 case OMPC_simdlen:
13108 case OMPC_sizes:
13109 case OMPC_allocator:
13110 case OMPC_collapse:
13111 case OMPC_private:
13112 case OMPC_shared:
13113 case OMPC_aligned:
13114 case OMPC_copyin:
13115 case OMPC_copyprivate:
13116 case OMPC_ordered:
13117 case OMPC_nowait:
13118 case OMPC_untied:
13119 case OMPC_mergeable:
13120 case OMPC_threadprivate:
13121 case OMPC_allocate:
13122 case OMPC_flush:
13123 case OMPC_depobj:
13124 case OMPC_read:
13125 case OMPC_write:
13126 case OMPC_update:
13127 case OMPC_capture:
13128 case OMPC_seq_cst:
13129 case OMPC_acq_rel:
13130 case OMPC_acquire:
13131 case OMPC_release:
13132 case OMPC_relaxed:
13133 case OMPC_depend:
13134 case OMPC_threads:
13135 case OMPC_simd:
13136 case OMPC_map:
13137 case OMPC_nogroup:
13138 case OMPC_hint:
13139 case OMPC_defaultmap:
13140 case OMPC_unknown:
13141 case OMPC_uniform:
13142 case OMPC_to:
13143 case OMPC_from:
13144 case OMPC_use_device_ptr:
13145 case OMPC_use_device_addr:
13146 case OMPC_is_device_ptr:
13147 case OMPC_unified_address:
13148 case OMPC_unified_shared_memory:
13149 case OMPC_reverse_offload:
13150 case OMPC_dynamic_allocators:
13151 case OMPC_atomic_default_mem_order:
13152 case OMPC_device_type:
13153 case OMPC_match:
13154 case OMPC_nontemporal:
13155 case OMPC_order:
13156 case OMPC_destroy:
13157 case OMPC_detach:
13158 case OMPC_inclusive:
13159 case OMPC_exclusive:
13160 case OMPC_uses_allocators:
13161 case OMPC_affinity:
13162 default:
13163 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13163)
;
13164 }
13165 return CaptureRegion;
13166}
13167
13168OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
13169 Expr *Condition, SourceLocation StartLoc,
13170 SourceLocation LParenLoc,
13171 SourceLocation NameModifierLoc,
13172 SourceLocation ColonLoc,
13173 SourceLocation EndLoc) {
13174 Expr *ValExpr = Condition;
13175 Stmt *HelperValStmt = nullptr;
13176 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13177 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13178 !Condition->isInstantiationDependent() &&
13179 !Condition->containsUnexpandedParameterPack()) {
13180 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13181 if (Val.isInvalid())
13182 return nullptr;
13183
13184 ValExpr = Val.get();
13185
13186 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13187 CaptureRegion = getOpenMPCaptureRegionForClause(
13188 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
13189 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13190 ValExpr = MakeFullExpr(ValExpr).get();
13191 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13192 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13193 HelperValStmt = buildPreInits(Context, Captures);
13194 }
13195 }
13196
13197 return new (Context)
13198 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
13199 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
13200}
13201
13202OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
13203 SourceLocation StartLoc,
13204 SourceLocation LParenLoc,
13205 SourceLocation EndLoc) {
13206 Expr *ValExpr = Condition;
13207 Stmt *HelperValStmt = nullptr;
13208 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13209 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13210 !Condition->isInstantiationDependent() &&
13211 !Condition->containsUnexpandedParameterPack()) {
13212 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13213 if (Val.isInvalid())
13214 return nullptr;
13215
13216 ValExpr = MakeFullExpr(Val.get()).get();
13217
13218 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13219 CaptureRegion =
13220 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
13221 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13222 ValExpr = MakeFullExpr(ValExpr).get();
13223 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13224 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13225 HelperValStmt = buildPreInits(Context, Captures);
13226 }
13227 }
13228
13229 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
13230 StartLoc, LParenLoc, EndLoc);
13231}
13232
13233ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
13234 Expr *Op) {
13235 if (!Op)
13236 return ExprError();
13237
13238 class IntConvertDiagnoser : public ICEConvertDiagnoser {
13239 public:
13240 IntConvertDiagnoser()
13241 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
13242 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
13243 QualType T) override {
13244 return S.Diag(Loc, diag::err_omp_not_integral) << T;
13245 }
13246 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
13247 QualType T) override {
13248 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
13249 }
13250 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
13251 QualType T,
13252 QualType ConvTy) override {
13253 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
13254 }
13255 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
13256 QualType ConvTy) override {
13257 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13258 << ConvTy->isEnumeralType() << ConvTy;
13259 }
13260 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
13261 QualType T) override {
13262 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
13263 }
13264 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
13265 QualType ConvTy) override {
13266 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13267 << ConvTy->isEnumeralType() << ConvTy;
13268 }
13269 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
13270 QualType) override {
13271 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13271)
;
13272 }
13273 } ConvertDiagnoser;
13274 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
13275}
13276
13277static bool
13278isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
13279 bool StrictlyPositive, bool BuildCapture = false,
13280 OpenMPDirectiveKind DKind = OMPD_unknown,
13281 OpenMPDirectiveKind *CaptureRegion = nullptr,
13282 Stmt **HelperValStmt = nullptr) {
13283 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
13284 !ValExpr->isInstantiationDependent()) {
13285 SourceLocation Loc = ValExpr->getExprLoc();
13286 ExprResult Value =
13287 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
13288 if (Value.isInvalid())
13289 return false;
13290
13291 ValExpr = Value.get();
13292 // The expression must evaluate to a non-negative integer value.
13293 if (Optional<llvm::APSInt> Result =
13294 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
13295 if (Result->isSigned() &&
13296 !((!StrictlyPositive && Result->isNonNegative()) ||
13297 (StrictlyPositive && Result->isStrictlyPositive()))) {
13298 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
13299 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13300 << ValExpr->getSourceRange();
13301 return false;
13302 }
13303 }
13304 if (!BuildCapture)
13305 return true;
13306 *CaptureRegion =
13307 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
13308 if (*CaptureRegion != OMPD_unknown &&
13309 !SemaRef.CurContext->isDependentContext()) {
13310 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
13311 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13312 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
13313 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
13314 }
13315 }
13316 return true;
13317}
13318
13319OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
13320 SourceLocation StartLoc,
13321 SourceLocation LParenLoc,
13322 SourceLocation EndLoc) {
13323 Expr *ValExpr = NumThreads;
13324 Stmt *HelperValStmt = nullptr;
13325
13326 // OpenMP [2.5, Restrictions]
13327 // The num_threads expression must evaluate to a positive integer value.
13328 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
13329 /*StrictlyPositive=*/true))
13330 return nullptr;
13331
13332 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13333 OpenMPDirectiveKind CaptureRegion =
13334 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
13335 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13336 ValExpr = MakeFullExpr(ValExpr).get();
13337 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13338 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13339 HelperValStmt = buildPreInits(Context, Captures);
13340 }
13341
13342 return new (Context) OMPNumThreadsClause(
13343 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13344}
13345
13346ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
13347 OpenMPClauseKind CKind,
13348 bool StrictlyPositive) {
13349 if (!E)
13350 return ExprError();
13351 if (E->isValueDependent() || E->isTypeDependent() ||
13352 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
13353 return E;
13354 llvm::APSInt Result;
13355 ExprResult ICE =
13356 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
13357 if (ICE.isInvalid())
13358 return ExprError();
13359 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
13360 (!StrictlyPositive && !Result.isNonNegative())) {
13361 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
13362 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13363 << E->getSourceRange();
13364 return ExprError();
13365 }
13366 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
13367 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
13368 << E->getSourceRange();
13369 return ExprError();
13370 }
13371 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
13372 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
13373 else if (CKind == OMPC_ordered)
13374 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
13375 return ICE;
13376}
13377
13378OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
13379 SourceLocation LParenLoc,
13380 SourceLocation EndLoc) {
13381 // OpenMP [2.8.1, simd construct, Description]
13382 // The parameter of the safelen clause must be a constant
13383 // positive integer expression.
13384 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
13385 if (Safelen.isInvalid())
13386 return nullptr;
13387 return new (Context)
13388 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
13389}
13390
13391OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
13392 SourceLocation LParenLoc,
13393 SourceLocation EndLoc) {
13394 // OpenMP [2.8.1, simd construct, Description]
13395 // The parameter of the simdlen clause must be a constant
13396 // positive integer expression.
13397 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
13398 if (Simdlen.isInvalid())
13399 return nullptr;
13400 return new (Context)
13401 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
13402}
13403
13404/// Tries to find omp_allocator_handle_t type.
13405static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
13406 DSAStackTy *Stack) {
13407 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
13408 if (!OMPAllocatorHandleT.isNull())
13409 return true;
13410 // Build the predefined allocator expressions.
13411 bool ErrorFound = false;
13412 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
13413 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
13414 StringRef Allocator =
13415 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
13416 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
13417 auto *VD = dyn_cast_or_null<ValueDecl>(
13418 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
13419 if (!VD) {
13420 ErrorFound = true;
13421 break;
13422 }
13423 QualType AllocatorType =
13424 VD->getType().getNonLValueExprType(S.getASTContext());
13425 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
13426 if (!Res.isUsable()) {
13427 ErrorFound = true;
13428 break;
13429 }
13430 if (OMPAllocatorHandleT.isNull())
13431 OMPAllocatorHandleT = AllocatorType;
13432 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
13433 ErrorFound = true;
13434 break;
13435 }
13436 Stack->setAllocator(AllocatorKind, Res.get());
13437 }
13438 if (ErrorFound) {
13439 S.Diag(Loc, diag::err_omp_implied_type_not_found)
13440 << "omp_allocator_handle_t";
13441 return false;
13442 }
13443 OMPAllocatorHandleT.addConst();
13444 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
13445 return true;
13446}
13447
13448OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
13449 SourceLocation LParenLoc,
13450 SourceLocation EndLoc) {
13451 // OpenMP [2.11.3, allocate Directive, Description]
13452 // allocator is an expression of omp_allocator_handle_t type.
13453 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13454 return nullptr;
13455
13456 ExprResult Allocator = DefaultLvalueConversion(A);
13457 if (Allocator.isInvalid())
13458 return nullptr;
13459 Allocator = PerformImplicitConversion(Allocator.get(),
13460 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
13461 Sema::AA_Initializing,
13462 /*AllowExplicit=*/true);
13463 if (Allocator.isInvalid())
13464 return nullptr;
13465 return new (Context)
13466 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
13467}
13468
13469OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
13470 SourceLocation StartLoc,
13471 SourceLocation LParenLoc,
13472 SourceLocation EndLoc) {
13473 // OpenMP [2.7.1, loop construct, Description]
13474 // OpenMP [2.8.1, simd construct, Description]
13475 // OpenMP [2.9.6, distribute construct, Description]
13476 // The parameter of the collapse clause must be a constant
13477 // positive integer expression.
13478 ExprResult NumForLoopsResult =
13479 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
13480 if (NumForLoopsResult.isInvalid())
13481 return nullptr;
13482 return new (Context)
13483 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
13484}
13485
13486OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
13487 SourceLocation EndLoc,
13488 SourceLocation LParenLoc,
13489 Expr *NumForLoops) {
13490 // OpenMP [2.7.1, loop construct, Description]
13491 // OpenMP [2.8.1, simd construct, Description]
13492 // OpenMP [2.9.6, distribute construct, Description]
13493 // The parameter of the ordered clause must be a constant
13494 // positive integer expression if any.
13495 if (NumForLoops && LParenLoc.isValid()) {
13496 ExprResult NumForLoopsResult =
13497 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
13498 if (NumForLoopsResult.isInvalid())
13499 return nullptr;
13500 NumForLoops = NumForLoopsResult.get();
13501 } else {
13502 NumForLoops = nullptr;
13503 }
13504 auto *Clause = OMPOrderedClause::Create(
13505 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
13506 StartLoc, LParenLoc, EndLoc);
13507 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
13508 return Clause;
13509}
13510
13511OMPClause *Sema::ActOnOpenMPSimpleClause(
13512 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
13513 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13514 OMPClause *Res = nullptr;
13515 switch (Kind) {
13516 case OMPC_default:
13517 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
13518 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13519 break;
13520 case OMPC_proc_bind:
13521 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
13522 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13523 break;
13524 case OMPC_atomic_default_mem_order:
13525 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
13526 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
13527 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13528 break;
13529 case OMPC_order:
13530 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
13531 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13532 break;
13533 case OMPC_update:
13534 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
13535 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13536 break;
13537 case OMPC_if:
13538 case OMPC_final:
13539 case OMPC_num_threads:
13540 case OMPC_safelen:
13541 case OMPC_simdlen:
13542 case OMPC_sizes:
13543 case OMPC_allocator:
13544 case OMPC_collapse:
13545 case OMPC_schedule:
13546 case OMPC_private:
13547 case OMPC_firstprivate:
13548 case OMPC_lastprivate:
13549 case OMPC_shared:
13550 case OMPC_reduction:
13551 case OMPC_task_reduction:
13552 case OMPC_in_reduction:
13553 case OMPC_linear:
13554 case OMPC_aligned:
13555 case OMPC_copyin:
13556 case OMPC_copyprivate:
13557 case OMPC_ordered:
13558 case OMPC_nowait:
13559 case OMPC_untied:
13560 case OMPC_mergeable:
13561 case OMPC_threadprivate:
13562 case OMPC_allocate:
13563 case OMPC_flush:
13564 case OMPC_depobj:
13565 case OMPC_read:
13566 case OMPC_write:
13567 case OMPC_capture:
13568 case OMPC_seq_cst:
13569 case OMPC_acq_rel:
13570 case OMPC_acquire:
13571 case OMPC_release:
13572 case OMPC_relaxed:
13573 case OMPC_depend:
13574 case OMPC_device:
13575 case OMPC_threads:
13576 case OMPC_simd:
13577 case OMPC_map:
13578 case OMPC_num_teams:
13579 case OMPC_thread_limit:
13580 case OMPC_priority:
13581 case OMPC_grainsize:
13582 case OMPC_nogroup:
13583 case OMPC_num_tasks:
13584 case OMPC_hint:
13585 case OMPC_dist_schedule:
13586 case OMPC_defaultmap:
13587 case OMPC_unknown:
13588 case OMPC_uniform:
13589 case OMPC_to:
13590 case OMPC_from:
13591 case OMPC_use_device_ptr:
13592 case OMPC_use_device_addr:
13593 case OMPC_is_device_ptr:
13594 case OMPC_unified_address:
13595 case OMPC_unified_shared_memory:
13596 case OMPC_reverse_offload:
13597 case OMPC_dynamic_allocators:
13598 case OMPC_device_type:
13599 case OMPC_match:
13600 case OMPC_nontemporal:
13601 case OMPC_destroy:
13602 case OMPC_detach:
13603 case OMPC_inclusive:
13604 case OMPC_exclusive:
13605 case OMPC_uses_allocators:
13606 case OMPC_affinity:
13607 default:
13608 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13608)
;
13609 }
13610 return Res;
13611}
13612
13613static std::string
13614getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
13615 ArrayRef<unsigned> Exclude = llvm::None) {
13616 SmallString<256> Buffer;
13617 llvm::raw_svector_ostream Out(Buffer);
13618 unsigned Skipped = Exclude.size();
13619 auto S = Exclude.begin(), E = Exclude.end();
13620 for (unsigned I = First; I < Last; ++I) {
13621 if (std::find(S, E, I) != E) {
13622 --Skipped;
13623 continue;
13624 }
13625 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
13626 if (I + Skipped + 2 == Last)
13627 Out << " or ";
13628 else if (I + Skipped + 1 != Last)
13629 Out << ", ";
13630 }
13631 return std::string(Out.str());
13632}
13633
13634OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
13635 SourceLocation KindKwLoc,
13636 SourceLocation StartLoc,
13637 SourceLocation LParenLoc,
13638 SourceLocation EndLoc) {
13639 if (Kind == OMP_DEFAULT_unknown) {
13640 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13641 << getListOfPossibleValues(OMPC_default, /*First=*/0,
13642 /*Last=*/unsigned(OMP_DEFAULT_unknown))
13643 << getOpenMPClauseName(OMPC_default);
13644 return nullptr;
13645 }
13646
13647 switch (Kind) {
13648 case OMP_DEFAULT_none:
13649 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
13650 break;
13651 case OMP_DEFAULT_shared:
13652 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
13653 break;
13654 case OMP_DEFAULT_firstprivate:
13655 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
13656 break;
13657 default:
13658 llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13658)
;
13659 }
13660
13661 return new (Context)
13662 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13663}
13664
13665OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13666 SourceLocation KindKwLoc,
13667 SourceLocation StartLoc,
13668 SourceLocation LParenLoc,
13669 SourceLocation EndLoc) {
13670 if (Kind == OMP_PROC_BIND_unknown) {
13671 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13672 << getListOfPossibleValues(OMPC_proc_bind,
13673 /*First=*/unsigned(OMP_PROC_BIND_master),
13674 /*Last=*/5)
13675 << getOpenMPClauseName(OMPC_proc_bind);
13676 return nullptr;
13677 }
13678 return new (Context)
13679 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13680}
13681
13682OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13683 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13684 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13685 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13686 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13687 << getListOfPossibleValues(
13688 OMPC_atomic_default_mem_order, /*First=*/0,
13689 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13690 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13691 return nullptr;
13692 }
13693 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13694 LParenLoc, EndLoc);
13695}
13696
13697OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13698 SourceLocation KindKwLoc,
13699 SourceLocation StartLoc,
13700 SourceLocation LParenLoc,
13701 SourceLocation EndLoc) {
13702 if (Kind == OMPC_ORDER_unknown) {
13703 static_assert(OMPC_ORDER_unknown > 0,
13704 "OMPC_ORDER_unknown not greater than 0");
13705 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13706 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13707 /*Last=*/OMPC_ORDER_unknown)
13708 << getOpenMPClauseName(OMPC_order);
13709 return nullptr;
13710 }
13711 return new (Context)
13712 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13713}
13714
13715OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13716 SourceLocation KindKwLoc,
13717 SourceLocation StartLoc,
13718 SourceLocation LParenLoc,
13719 SourceLocation EndLoc) {
13720 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13721 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13722 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13723 OMPC_DEPEND_depobj};
13724 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13725 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13726 /*Last=*/OMPC_DEPEND_unknown, Except)
13727 << getOpenMPClauseName(OMPC_update);
13728 return nullptr;
13729 }
13730 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13731 EndLoc);
13732}
13733
13734OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
13735 SourceLocation StartLoc,
13736 SourceLocation LParenLoc,
13737 SourceLocation EndLoc) {
13738 for (Expr *SizeExpr : SizeExprs) {
13739 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
13740 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
13741 if (!NumForLoopsResult.isUsable())
13742 return nullptr;
13743 }
13744
13745 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(SizeExprs.size());
13746 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13747 SizeExprs);
13748}
13749
13750OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13751 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13752 SourceLocation StartLoc, SourceLocation LParenLoc,
13753 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13754 SourceLocation EndLoc) {
13755 OMPClause *Res = nullptr;
13756 switch (Kind) {
13757 case OMPC_schedule:
13758 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13759 assert(Argument.size() == NumberOfElements &&((Argument.size() == NumberOfElements && ArgumentLoc.
size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail
("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13760, __PRETTY_FUNCTION__))
13760 ArgumentLoc.size() == NumberOfElements)((Argument.size() == NumberOfElements && ArgumentLoc.
size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail
("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13760, __PRETTY_FUNCTION__))
;
13761 Res = ActOnOpenMPScheduleClause(
13762 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13763 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13764 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13765 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13766 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13767 break;
13768 case OMPC_if:
13769 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast
<void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13769, __PRETTY_FUNCTION__))
;
13770 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13771 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13772 DelimLoc, EndLoc);
13773 break;
13774 case OMPC_dist_schedule:
13775 Res = ActOnOpenMPDistScheduleClause(
13776 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13777 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13778 break;
13779 case OMPC_defaultmap:
13780 enum { Modifier, DefaultmapKind };
13781 Res = ActOnOpenMPDefaultmapClause(
13782 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13783 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13784 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13785 EndLoc);
13786 break;
13787 case OMPC_device:
13788 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast
<void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13788, __PRETTY_FUNCTION__))
;
13789 Res = ActOnOpenMPDeviceClause(
13790 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13791 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13792 break;
13793 case OMPC_final:
13794 case OMPC_num_threads:
13795 case OMPC_safelen:
13796 case OMPC_simdlen:
13797 case OMPC_sizes:
13798 case OMPC_allocator:
13799 case OMPC_collapse:
13800 case OMPC_default:
13801 case OMPC_proc_bind:
13802 case OMPC_private:
13803 case OMPC_firstprivate:
13804 case OMPC_lastprivate:
13805 case OMPC_shared:
13806 case OMPC_reduction:
13807 case OMPC_task_reduction:
13808 case OMPC_in_reduction:
13809 case OMPC_linear:
13810 case OMPC_aligned:
13811 case OMPC_copyin:
13812 case OMPC_copyprivate:
13813 case OMPC_ordered:
13814 case OMPC_nowait:
13815 case OMPC_untied:
13816 case OMPC_mergeable:
13817 case OMPC_threadprivate:
13818 case OMPC_allocate:
13819 case OMPC_flush:
13820 case OMPC_depobj:
13821 case OMPC_read:
13822 case OMPC_write:
13823 case OMPC_update:
13824 case OMPC_capture:
13825 case OMPC_seq_cst:
13826 case OMPC_acq_rel:
13827 case OMPC_acquire:
13828 case OMPC_release:
13829 case OMPC_relaxed:
13830 case OMPC_depend:
13831 case OMPC_threads:
13832 case OMPC_simd:
13833 case OMPC_map:
13834 case OMPC_num_teams:
13835 case OMPC_thread_limit:
13836 case OMPC_priority:
13837 case OMPC_grainsize:
13838 case OMPC_nogroup:
13839 case OMPC_num_tasks:
13840 case OMPC_hint:
13841 case OMPC_unknown:
13842 case OMPC_uniform:
13843 case OMPC_to:
13844 case OMPC_from:
13845 case OMPC_use_device_ptr:
13846 case OMPC_use_device_addr:
13847 case OMPC_is_device_ptr:
13848 case OMPC_unified_address:
13849 case OMPC_unified_shared_memory:
13850 case OMPC_reverse_offload:
13851 case OMPC_dynamic_allocators:
13852 case OMPC_atomic_default_mem_order:
13853 case OMPC_device_type:
13854 case OMPC_match:
13855 case OMPC_nontemporal:
13856 case OMPC_order:
13857 case OMPC_destroy:
13858 case OMPC_detach:
13859 case OMPC_inclusive:
13860 case OMPC_exclusive:
13861 case OMPC_uses_allocators:
13862 case OMPC_affinity:
13863 default:
13864 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 13864)
;
13865 }
13866 return Res;
13867}
13868
13869static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13870 OpenMPScheduleClauseModifier M2,
13871 SourceLocation M1Loc, SourceLocation M2Loc) {
13872 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13873 SmallVector<unsigned, 2> Excluded;
13874 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13875 Excluded.push_back(M2);
13876 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13877 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13878 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13879 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13880 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13881 << getListOfPossibleValues(OMPC_schedule,
13882 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13883 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13884 Excluded)
13885 << getOpenMPClauseName(OMPC_schedule);
13886 return true;
13887 }
13888 return false;
13889}
13890
13891OMPClause *Sema::ActOnOpenMPScheduleClause(
13892 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13893 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13894 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13895 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13896 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13897 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13898 return nullptr;
13899 // OpenMP, 2.7.1, Loop Construct, Restrictions
13900 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13901 // but not both.
13902 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13903 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13904 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13905 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13906 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13907 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13908 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13909 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13910 return nullptr;
13911 }
13912 if (Kind == OMPC_SCHEDULE_unknown) {
13913 std::string Values;
13914 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13915 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13916 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13917 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13918 Exclude);
13919 } else {
13920 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13921 /*Last=*/OMPC_SCHEDULE_unknown);
13922 }
13923 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13924 << Values << getOpenMPClauseName(OMPC_schedule);
13925 return nullptr;
13926 }
13927 // OpenMP, 2.7.1, Loop Construct, Restrictions
13928 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13929 // schedule(guided).
13930 // OpenMP 5.0 does not have this restriction.
13931 if (LangOpts.OpenMP < 50 &&
13932 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13933 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13934 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13935 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13936 diag::err_omp_schedule_nonmonotonic_static);
13937 return nullptr;
13938 }
13939 Expr *ValExpr = ChunkSize;
13940 Stmt *HelperValStmt = nullptr;
13941 if (ChunkSize) {
13942 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13943 !ChunkSize->isInstantiationDependent() &&
13944 !ChunkSize->containsUnexpandedParameterPack()) {
13945 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13946 ExprResult Val =
13947 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13948 if (Val.isInvalid())
13949 return nullptr;
13950
13951 ValExpr = Val.get();
13952
13953 // OpenMP [2.7.1, Restrictions]
13954 // chunk_size must be a loop invariant integer expression with a positive
13955 // value.
13956 if (Optional<llvm::APSInt> Result =
13957 ValExpr->getIntegerConstantExpr(Context)) {
13958 if (Result->isSigned() && !Result->isStrictlyPositive()) {
13959 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13960 << "schedule" << 1 << ChunkSize->getSourceRange();
13961 return nullptr;
13962 }
13963 } else if (getOpenMPCaptureRegionForClause(
13964 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
13965 LangOpts.OpenMP) != OMPD_unknown &&
13966 !CurContext->isDependentContext()) {
13967 ValExpr = MakeFullExpr(ValExpr).get();
13968 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13969 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13970 HelperValStmt = buildPreInits(Context, Captures);
13971 }
13972 }
13973 }
13974
13975 return new (Context)
13976 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13977 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13978}
13979
13980OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13981 SourceLocation StartLoc,
13982 SourceLocation EndLoc) {
13983 OMPClause *Res = nullptr;
13984 switch (Kind) {
13985 case OMPC_ordered:
13986 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13987 break;
13988 case OMPC_nowait:
13989 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13990 break;
13991 case OMPC_untied:
13992 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13993 break;
13994 case OMPC_mergeable:
13995 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13996 break;
13997 case OMPC_read:
13998 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13999 break;
14000 case OMPC_write:
14001 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
14002 break;
14003 case OMPC_update:
14004 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
14005 break;
14006 case OMPC_capture:
14007 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
14008 break;
14009 case OMPC_seq_cst:
14010 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
14011 break;
14012 case OMPC_acq_rel:
14013 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
14014 break;
14015 case OMPC_acquire:
14016 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
14017 break;
14018 case OMPC_release:
14019 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
14020 break;
14021 case OMPC_relaxed:
14022 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
14023 break;
14024 case OMPC_threads:
14025 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
14026 break;
14027 case OMPC_simd:
14028 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
14029 break;
14030 case OMPC_nogroup:
14031 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
14032 break;
14033 case OMPC_unified_address:
14034 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
14035 break;
14036 case OMPC_unified_shared_memory:
14037 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14038 break;
14039 case OMPC_reverse_offload:
14040 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
14041 break;
14042 case OMPC_dynamic_allocators:
14043 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
14044 break;
14045 case OMPC_destroy:
14046 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
14047 break;
14048 case OMPC_if:
14049 case OMPC_final:
14050 case OMPC_num_threads:
14051 case OMPC_safelen:
14052 case OMPC_simdlen:
14053 case OMPC_sizes:
14054 case OMPC_allocator:
14055 case OMPC_collapse:
14056 case OMPC_schedule:
14057 case OMPC_private:
14058 case OMPC_firstprivate:
14059 case OMPC_lastprivate:
14060 case OMPC_shared:
14061 case OMPC_reduction:
14062 case OMPC_task_reduction:
14063 case OMPC_in_reduction:
14064 case OMPC_linear:
14065 case OMPC_aligned:
14066 case OMPC_copyin:
14067 case OMPC_copyprivate:
14068 case OMPC_default:
14069 case OMPC_proc_bind:
14070 case OMPC_threadprivate:
14071 case OMPC_allocate:
14072 case OMPC_flush:
14073 case OMPC_depobj:
14074 case OMPC_depend:
14075 case OMPC_device:
14076 case OMPC_map:
14077 case OMPC_num_teams:
14078 case OMPC_thread_limit:
14079 case OMPC_priority:
14080 case OMPC_grainsize:
14081 case OMPC_num_tasks:
14082 case OMPC_hint:
14083 case OMPC_dist_schedule:
14084 case OMPC_defaultmap:
14085 case OMPC_unknown:
14086 case OMPC_uniform:
14087 case OMPC_to:
14088 case OMPC_from:
14089 case OMPC_use_device_ptr:
14090 case OMPC_use_device_addr:
14091 case OMPC_is_device_ptr:
14092 case OMPC_atomic_default_mem_order:
14093 case OMPC_device_type:
14094 case OMPC_match:
14095 case OMPC_nontemporal:
14096 case OMPC_order:
14097 case OMPC_detach:
14098 case OMPC_inclusive:
14099 case OMPC_exclusive:
14100 case OMPC_uses_allocators:
14101 case OMPC_affinity:
14102 default:
14103 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14103)
;
14104 }
14105 return Res;
14106}
14107
14108OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
14109 SourceLocation EndLoc) {
14110 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
14111 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
14112}
14113
14114OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
14115 SourceLocation EndLoc) {
14116 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
14117}
14118
14119OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
14120 SourceLocation EndLoc) {
14121 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
14122}
14123
14124OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
14125 SourceLocation EndLoc) {
14126 return new (Context) OMPReadClause(StartLoc, EndLoc);
14127}
14128
14129OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
14130 SourceLocation EndLoc) {
14131 return new (Context) OMPWriteClause(StartLoc, EndLoc);
14132}
14133
14134OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
14135 SourceLocation EndLoc) {
14136 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
14137}
14138
14139OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
14140 SourceLocation EndLoc) {
14141 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
14142}
14143
14144OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
14145 SourceLocation EndLoc) {
14146 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
14147}
14148
14149OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
14150 SourceLocation EndLoc) {
14151 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
14152}
14153
14154OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
14155 SourceLocation EndLoc) {
14156 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
14157}
14158
14159OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
14160 SourceLocation EndLoc) {
14161 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
14162}
14163
14164OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
14165 SourceLocation EndLoc) {
14166 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
14167}
14168
14169OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
14170 SourceLocation EndLoc) {
14171 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
14172}
14173
14174OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
14175 SourceLocation EndLoc) {
14176 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
14177}
14178
14179OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
14180 SourceLocation EndLoc) {
14181 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
14182}
14183
14184OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
14185 SourceLocation EndLoc) {
14186 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
14187}
14188
14189OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
14190 SourceLocation EndLoc) {
14191 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14192}
14193
14194OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
14195 SourceLocation EndLoc) {
14196 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
14197}
14198
14199OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
14200 SourceLocation EndLoc) {
14201 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
14202}
14203
14204OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
14205 SourceLocation EndLoc) {
14206 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
14207}
14208
14209OMPClause *Sema::ActOnOpenMPVarListClause(
14210 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
14211 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
14212 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
14213 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
14214 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
14215 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
14216 SourceLocation ExtraModifierLoc,
14217 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
14218 ArrayRef<SourceLocation> MotionModifiersLoc) {
14219 SourceLocation StartLoc = Locs.StartLoc;
14220 SourceLocation LParenLoc = Locs.LParenLoc;
14221 SourceLocation EndLoc = Locs.EndLoc;
14222 OMPClause *Res = nullptr;
14223 switch (Kind) {
14224 case OMPC_private:
14225 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
14226 break;
14227 case OMPC_firstprivate:
14228 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
14229 break;
14230 case OMPC_lastprivate:
14231 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14232, __PRETTY_FUNCTION__))
14232 "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14232, __PRETTY_FUNCTION__))
;
14233 Res = ActOnOpenMPLastprivateClause(
14234 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
14235 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
14236 break;
14237 case OMPC_shared:
14238 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
14239 break;
14240 case OMPC_reduction:
14241 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14242, __PRETTY_FUNCTION__))
14242 "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14242, __PRETTY_FUNCTION__))
;
14243 Res = ActOnOpenMPReductionClause(
14244 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
14245 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
14246 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
14247 break;
14248 case OMPC_task_reduction:
14249 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
14250 EndLoc, ReductionOrMapperIdScopeSpec,
14251 ReductionOrMapperId);
14252 break;
14253 case OMPC_in_reduction:
14254 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
14255 EndLoc, ReductionOrMapperIdScopeSpec,
14256 ReductionOrMapperId);
14257 break;
14258 case OMPC_linear:
14259 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown
&& "Unexpected linear modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14260, __PRETTY_FUNCTION__))
14260 "Unexpected linear modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown
&& "Unexpected linear modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14260, __PRETTY_FUNCTION__))
;
14261 Res = ActOnOpenMPLinearClause(
14262 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
14263 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
14264 ColonLoc, EndLoc);
14265 break;
14266 case OMPC_aligned:
14267 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
14268 LParenLoc, ColonLoc, EndLoc);
14269 break;
14270 case OMPC_copyin:
14271 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
14272 break;
14273 case OMPC_copyprivate:
14274 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
14275 break;
14276 case OMPC_flush:
14277 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
14278 break;
14279 case OMPC_depend:
14280 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown
&& "Unexpected depend modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14281, __PRETTY_FUNCTION__))
14281 "Unexpected depend modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown
&& "Unexpected depend modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14281, __PRETTY_FUNCTION__))
;
14282 Res = ActOnOpenMPDependClause(
14283 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
14284 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
14285 break;
14286 case OMPC_map:
14287 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown
&& "Unexpected map modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14288, __PRETTY_FUNCTION__))
14288 "Unexpected map modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown
&& "Unexpected map modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14288, __PRETTY_FUNCTION__))
;
14289 Res = ActOnOpenMPMapClause(
14290 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
14291 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
14292 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
14293 break;
14294 case OMPC_to:
14295 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
14296 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
14297 ColonLoc, VarList, Locs);
14298 break;
14299 case OMPC_from:
14300 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
14301 ReductionOrMapperIdScopeSpec,
14302 ReductionOrMapperId, ColonLoc, VarList, Locs);
14303 break;
14304 case OMPC_use_device_ptr:
14305 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
14306 break;
14307 case OMPC_use_device_addr:
14308 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
14309 break;
14310 case OMPC_is_device_ptr:
14311 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
14312 break;
14313 case OMPC_allocate:
14314 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
14315 LParenLoc, ColonLoc, EndLoc);
14316 break;
14317 case OMPC_nontemporal:
14318 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
14319 break;
14320 case OMPC_inclusive:
14321 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
14322 break;
14323 case OMPC_exclusive:
14324 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
14325 break;
14326 case OMPC_affinity:
14327 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
14328 DepModOrTailExpr, VarList);
14329 break;
14330 case OMPC_if:
14331 case OMPC_depobj:
14332 case OMPC_final:
14333 case OMPC_num_threads:
14334 case OMPC_safelen:
14335 case OMPC_simdlen:
14336 case OMPC_sizes:
14337 case OMPC_allocator:
14338 case OMPC_collapse:
14339 case OMPC_default:
14340 case OMPC_proc_bind:
14341 case OMPC_schedule:
14342 case OMPC_ordered:
14343 case OMPC_nowait:
14344 case OMPC_untied:
14345 case OMPC_mergeable:
14346 case OMPC_threadprivate:
14347 case OMPC_read:
14348 case OMPC_write:
14349 case OMPC_update:
14350 case OMPC_capture:
14351 case OMPC_seq_cst:
14352 case OMPC_acq_rel:
14353 case OMPC_acquire:
14354 case OMPC_release:
14355 case OMPC_relaxed:
14356 case OMPC_device:
14357 case OMPC_threads:
14358 case OMPC_simd:
14359 case OMPC_num_teams:
14360 case OMPC_thread_limit:
14361 case OMPC_priority:
14362 case OMPC_grainsize:
14363 case OMPC_nogroup:
14364 case OMPC_num_tasks:
14365 case OMPC_hint:
14366 case OMPC_dist_schedule:
14367 case OMPC_defaultmap:
14368 case OMPC_unknown:
14369 case OMPC_uniform:
14370 case OMPC_unified_address:
14371 case OMPC_unified_shared_memory:
14372 case OMPC_reverse_offload:
14373 case OMPC_dynamic_allocators:
14374 case OMPC_atomic_default_mem_order:
14375 case OMPC_device_type:
14376 case OMPC_match:
14377 case OMPC_order:
14378 case OMPC_destroy:
14379 case OMPC_detach:
14380 case OMPC_uses_allocators:
14381 default:
14382 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14382)
;
14383 }
14384 return Res;
14385}
14386
14387ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
14388 ExprObjectKind OK, SourceLocation Loc) {
14389 ExprResult Res = BuildDeclRefExpr(
14390 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
14391 if (!Res.isUsable())
14392 return ExprError();
14393 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
14394 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
14395 if (!Res.isUsable())
14396 return ExprError();
14397 }
14398 if (VK != VK_LValue && Res.get()->isGLValue()) {
14399 Res = DefaultLvalueConversion(Res.get());
14400 if (!Res.isUsable())
14401 return ExprError();
14402 }
14403 return Res;
14404}
14405
14406OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
14407 SourceLocation StartLoc,
14408 SourceLocation LParenLoc,
14409 SourceLocation EndLoc) {
14410 SmallVector<Expr *, 8> Vars;
14411 SmallVector<Expr *, 8> PrivateCopies;
14412 for (Expr *RefExpr : VarList) {
14413 assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ?
static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14413, __PRETTY_FUNCTION__))
;
14414 SourceLocation ELoc;
14415 SourceRange ERange;
14416 Expr *SimpleRefExpr = RefExpr;
14417 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14418 if (Res.second) {
14419 // It will be analyzed later.
14420 Vars.push_back(RefExpr);
14421 PrivateCopies.push_back(nullptr);
14422 }
14423 ValueDecl *D = Res.first;
14424 if (!D)
14425 continue;
14426
14427 QualType Type = D->getType();
14428 auto *VD = dyn_cast<VarDecl>(D);
14429
14430 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14431 // A variable that appears in a private clause must not have an incomplete
14432 // type or a reference type.
14433 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
14434 continue;
14435 Type = Type.getNonReferenceType();
14436
14437 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14438 // A variable that is privatized must not have a const-qualified type
14439 // unless it is of class type with a mutable member. This restriction does
14440 // not apply to the firstprivate clause.
14441 //
14442 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
14443 // A variable that appears in a private clause must not have a
14444 // const-qualified type unless it is of class type with a mutable member.
14445 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
14446 continue;
14447
14448 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14449 // in a Construct]
14450 // Variables with the predetermined data-sharing attributes may not be
14451 // listed in data-sharing attributes clauses, except for the cases
14452 // listed below. For these exceptions only, listing a predetermined
14453 // variable in a data-sharing attribute clause is allowed and overrides
14454 // the variable's predetermined data-sharing attributes.
14455 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14456 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
14457 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14458 << getOpenMPClauseName(OMPC_private);
14459 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14460 continue;
14461 }
14462
14463 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14464 // Variably modified types are not supported for tasks.
14465 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14466 isOpenMPTaskingDirective(CurrDir)) {
14467 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14468 << getOpenMPClauseName(OMPC_private) << Type
14469 << getOpenMPDirectiveName(CurrDir);
14470 bool IsDecl =
14471 !VD ||
14472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14473 Diag(D->getLocation(),
14474 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14475 << D;
14476 continue;
14477 }
14478
14479 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14480 // A list item cannot appear in both a map clause and a data-sharing
14481 // attribute clause on the same construct
14482 //
14483 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14484 // A list item cannot appear in both a map clause and a data-sharing
14485 // attribute clause on the same construct unless the construct is a
14486 // combined construct.
14487 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
14488 CurrDir == OMPD_target) {
14489 OpenMPClauseKind ConflictKind;
14490 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
14491 VD, /*CurrentRegionOnly=*/true,
14492 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
14493 OpenMPClauseKind WhereFoundClauseKind) -> bool {
14494 ConflictKind = WhereFoundClauseKind;
14495 return true;
14496 })) {
14497 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14498 << getOpenMPClauseName(OMPC_private)
14499 << getOpenMPClauseName(ConflictKind)
14500 << getOpenMPDirectiveName(CurrDir);
14501 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14502 continue;
14503 }
14504 }
14505
14506 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
14507 // A variable of class type (or array thereof) that appears in a private
14508 // clause requires an accessible, unambiguous default constructor for the
14509 // class type.
14510 // Generate helper private variable and initialize it with the default
14511 // value. The address of the original variable is replaced by the address of
14512 // the new private variable in CodeGen. This new variable is not added to
14513 // IdResolver, so the code in the OpenMP region uses original variable for
14514 // proper diagnostics.
14515 Type = Type.getUnqualifiedType();
14516 VarDecl *VDPrivate =
14517 buildVarDecl(*this, ELoc, Type, D->getName(),
14518 D->hasAttrs() ? &D->getAttrs() : nullptr,
14519 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14520 ActOnUninitializedDecl(VDPrivate);
14521 if (VDPrivate->isInvalidDecl())
14522 continue;
14523 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14524 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
14525
14526 DeclRefExpr *Ref = nullptr;
14527 if (!VD && !CurContext->isDependentContext())
14528 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14529 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
14530 Vars.push_back((VD || CurContext->isDependentContext())
14531 ? RefExpr->IgnoreParens()
14532 : Ref);
14533 PrivateCopies.push_back(VDPrivateRefExpr);
14534 }
14535
14536 if (Vars.empty())
14537 return nullptr;
14538
14539 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
14540 PrivateCopies);
14541}
14542
14543namespace {
14544class DiagsUninitializedSeveretyRAII {
14545private:
14546 DiagnosticsEngine &Diags;
14547 SourceLocation SavedLoc;
14548 bool IsIgnored = false;
14549
14550public:
14551 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
14552 bool IsIgnored)
14553 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
14554 if (!IsIgnored) {
14555 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
14556 /*Map*/ diag::Severity::Ignored, Loc);
14557 }
14558 }
14559 ~DiagsUninitializedSeveretyRAII() {
14560 if (!IsIgnored)
14561 Diags.popMappings(SavedLoc);
14562 }
14563};
14564}
14565
14566OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
14567 SourceLocation StartLoc,
14568 SourceLocation LParenLoc,
14569 SourceLocation EndLoc) {
14570 SmallVector<Expr *, 8> Vars;
14571 SmallVector<Expr *, 8> PrivateCopies;
14572 SmallVector<Expr *, 8> Inits;
14573 SmallVector<Decl *, 4> ExprCaptures;
14574 bool IsImplicitClause =
14575 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
14576 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
14577
14578 for (Expr *RefExpr : VarList) {
14579 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")((RefExpr && "NULL expr in OpenMP firstprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14579, __PRETTY_FUNCTION__))
;
14580 SourceLocation ELoc;
14581 SourceRange ERange;
14582 Expr *SimpleRefExpr = RefExpr;
14583 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14584 if (Res.second) {
14585 // It will be analyzed later.
14586 Vars.push_back(RefExpr);
14587 PrivateCopies.push_back(nullptr);
14588 Inits.push_back(nullptr);
14589 }
14590 ValueDecl *D = Res.first;
14591 if (!D)
14592 continue;
14593
14594 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
14595 QualType Type = D->getType();
14596 auto *VD = dyn_cast<VarDecl>(D);
14597
14598 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14599 // A variable that appears in a private clause must not have an incomplete
14600 // type or a reference type.
14601 if (RequireCompleteType(ELoc, Type,
14602 diag::err_omp_firstprivate_incomplete_type))
14603 continue;
14604 Type = Type.getNonReferenceType();
14605
14606 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
14607 // A variable of class type (or array thereof) that appears in a private
14608 // clause requires an accessible, unambiguous copy constructor for the
14609 // class type.
14610 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14611
14612 // If an implicit firstprivate variable found it was checked already.
14613 DSAStackTy::DSAVarData TopDVar;
14614 if (!IsImplicitClause) {
14615 DSAStackTy::DSAVarData DVar =
14616 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14617 TopDVar = DVar;
14618 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14619 bool IsConstant = ElemType.isConstant(Context);
14620 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
14621 // A list item that specifies a given variable may not appear in more
14622 // than one clause on the same directive, except that a variable may be
14623 // specified in both firstprivate and lastprivate clauses.
14624 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14625 // A list item may appear in a firstprivate or lastprivate clause but not
14626 // both.
14627 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
14628 (isOpenMPDistributeDirective(CurrDir) ||
14629 DVar.CKind != OMPC_lastprivate) &&
14630 DVar.RefExpr) {
14631 Diag(ELoc, diag::err_omp_wrong_dsa)
14632 << getOpenMPClauseName(DVar.CKind)
14633 << getOpenMPClauseName(OMPC_firstprivate);
14634 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14635 continue;
14636 }
14637
14638 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14639 // in a Construct]
14640 // Variables with the predetermined data-sharing attributes may not be
14641 // listed in data-sharing attributes clauses, except for the cases
14642 // listed below. For these exceptions only, listing a predetermined
14643 // variable in a data-sharing attribute clause is allowed and overrides
14644 // the variable's predetermined data-sharing attributes.
14645 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14646 // in a Construct, C/C++, p.2]
14647 // Variables with const-qualified type having no mutable member may be
14648 // listed in a firstprivate clause, even if they are static data members.
14649 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
14650 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
14651 Diag(ELoc, diag::err_omp_wrong_dsa)
14652 << getOpenMPClauseName(DVar.CKind)
14653 << getOpenMPClauseName(OMPC_firstprivate);
14654 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14655 continue;
14656 }
14657
14658 // OpenMP [2.9.3.4, Restrictions, p.2]
14659 // A list item that is private within a parallel region must not appear
14660 // in a firstprivate clause on a worksharing construct if any of the
14661 // worksharing regions arising from the worksharing construct ever bind
14662 // to any of the parallel regions arising from the parallel construct.
14663 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14664 // A list item that is private within a teams region must not appear in a
14665 // firstprivate clause on a distribute construct if any of the distribute
14666 // regions arising from the distribute construct ever bind to any of the
14667 // teams regions arising from the teams construct.
14668 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14669 // A list item that appears in a reduction clause of a teams construct
14670 // must not appear in a firstprivate clause on a distribute construct if
14671 // any of the distribute regions arising from the distribute construct
14672 // ever bind to any of the teams regions arising from the teams construct.
14673 if ((isOpenMPWorksharingDirective(CurrDir) ||
14674 isOpenMPDistributeDirective(CurrDir)) &&
14675 !isOpenMPParallelDirective(CurrDir) &&
14676 !isOpenMPTeamsDirective(CurrDir)) {
14677 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14678 if (DVar.CKind != OMPC_shared &&
14679 (isOpenMPParallelDirective(DVar.DKind) ||
14680 isOpenMPTeamsDirective(DVar.DKind) ||
14681 DVar.DKind == OMPD_unknown)) {
14682 Diag(ELoc, diag::err_omp_required_access)
14683 << getOpenMPClauseName(OMPC_firstprivate)
14684 << getOpenMPClauseName(OMPC_shared);
14685 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14686 continue;
14687 }
14688 }
14689 // OpenMP [2.9.3.4, Restrictions, p.3]
14690 // A list item that appears in a reduction clause of a parallel construct
14691 // must not appear in a firstprivate clause on a worksharing or task
14692 // construct if any of the worksharing or task regions arising from the
14693 // worksharing or task construct ever bind to any of the parallel regions
14694 // arising from the parallel construct.
14695 // OpenMP [2.9.3.4, Restrictions, p.4]
14696 // A list item that appears in a reduction clause in worksharing
14697 // construct must not appear in a firstprivate clause in a task construct
14698 // encountered during execution of any of the worksharing regions arising
14699 // from the worksharing construct.
14700 if (isOpenMPTaskingDirective(CurrDir)) {
14701 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
14702 D,
14703 [](OpenMPClauseKind C, bool AppliedToPointee) {
14704 return C == OMPC_reduction && !AppliedToPointee;
14705 },
14706 [](OpenMPDirectiveKind K) {
14707 return isOpenMPParallelDirective(K) ||
14708 isOpenMPWorksharingDirective(K) ||
14709 isOpenMPTeamsDirective(K);
14710 },
14711 /*FromParent=*/true);
14712 if (DVar.CKind == OMPC_reduction &&
14713 (isOpenMPParallelDirective(DVar.DKind) ||
14714 isOpenMPWorksharingDirective(DVar.DKind) ||
14715 isOpenMPTeamsDirective(DVar.DKind))) {
14716 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14717 << getOpenMPDirectiveName(DVar.DKind);
14718 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14719 continue;
14720 }
14721 }
14722
14723 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14724 // A list item cannot appear in both a map clause and a data-sharing
14725 // attribute clause on the same construct
14726 //
14727 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14728 // A list item cannot appear in both a map clause and a data-sharing
14729 // attribute clause on the same construct unless the construct is a
14730 // combined construct.
14731 if ((LangOpts.OpenMP <= 45 &&
14732 isOpenMPTargetExecutionDirective(CurrDir)) ||
14733 CurrDir == OMPD_target) {
14734 OpenMPClauseKind ConflictKind;
14735 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
14736 VD, /*CurrentRegionOnly=*/true,
14737 [&ConflictKind](
14738 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14739 OpenMPClauseKind WhereFoundClauseKind) {
14740 ConflictKind = WhereFoundClauseKind;
14741 return true;
14742 })) {
14743 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14744 << getOpenMPClauseName(OMPC_firstprivate)
14745 << getOpenMPClauseName(ConflictKind)
14746 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14747 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14748 continue;
14749 }
14750 }
14751 }
14752
14753 // Variably modified types are not supported for tasks.
14754 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14755 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
14756 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14757 << getOpenMPClauseName(OMPC_firstprivate) << Type
14758 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14759 bool IsDecl =
14760 !VD ||
14761 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14762 Diag(D->getLocation(),
14763 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14764 << D;
14765 continue;
14766 }
14767
14768 Type = Type.getUnqualifiedType();
14769 VarDecl *VDPrivate =
14770 buildVarDecl(*this, ELoc, Type, D->getName(),
14771 D->hasAttrs() ? &D->getAttrs() : nullptr,
14772 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14773 // Generate helper private variable and initialize it with the value of the
14774 // original variable. The address of the original variable is replaced by
14775 // the address of the new private variable in the CodeGen. This new variable
14776 // is not added to IdResolver, so the code in the OpenMP region uses
14777 // original variable for proper diagnostics and variable capturing.
14778 Expr *VDInitRefExpr = nullptr;
14779 // For arrays generate initializer for single element and replace it by the
14780 // original array element in CodeGen.
14781 if (Type->isArrayType()) {
14782 VarDecl *VDInit =
14783 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14784 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14785 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14786 ElemType = ElemType.getUnqualifiedType();
14787 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14788 ".firstprivate.temp");
14789 InitializedEntity Entity =
14790 InitializedEntity::InitializeVariable(VDInitTemp);
14791 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14792
14793 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14794 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14795 if (Result.isInvalid())
14796 VDPrivate->setInvalidDecl();
14797 else
14798 VDPrivate->setInit(Result.getAs<Expr>());
14799 // Remove temp variable declaration.
14800 Context.Deallocate(VDInitTemp);
14801 } else {
14802 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14803 ".firstprivate.temp");
14804 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14805 RefExpr->getExprLoc());
14806 AddInitializerToDecl(VDPrivate,
14807 DefaultLvalueConversion(VDInitRefExpr).get(),
14808 /*DirectInit=*/false);
14809 }
14810 if (VDPrivate->isInvalidDecl()) {
14811 if (IsImplicitClause) {
14812 Diag(RefExpr->getExprLoc(),
14813 diag::note_omp_task_predetermined_firstprivate_here);
14814 }
14815 continue;
14816 }
14817 CurContext->addDecl(VDPrivate);
14818 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14819 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14820 RefExpr->getExprLoc());
14821 DeclRefExpr *Ref = nullptr;
14822 if (!VD && !CurContext->isDependentContext()) {
14823 if (TopDVar.CKind == OMPC_lastprivate) {
14824 Ref = TopDVar.PrivateCopy;
14825 } else {
14826 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14827 if (!isOpenMPCapturedDecl(D))
14828 ExprCaptures.push_back(Ref->getDecl());
14829 }
14830 }
14831 if (!IsImplicitClause)
14832 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14833 Vars.push_back((VD || CurContext->isDependentContext())
14834 ? RefExpr->IgnoreParens()
14835 : Ref);
14836 PrivateCopies.push_back(VDPrivateRefExpr);
14837 Inits.push_back(VDInitRefExpr);
14838 }
14839
14840 if (Vars.empty())
14841 return nullptr;
14842
14843 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14844 Vars, PrivateCopies, Inits,
14845 buildPreInits(Context, ExprCaptures));
14846}
14847
14848OMPClause *Sema::ActOnOpenMPLastprivateClause(
14849 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14850 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14851 SourceLocation LParenLoc, SourceLocation EndLoc) {
14852 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14853 assert(ColonLoc.isValid() && "Colon location must be valid.")((ColonLoc.isValid() && "Colon location must be valid."
) ? static_cast<void> (0) : __assert_fail ("ColonLoc.isValid() && \"Colon location must be valid.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14853, __PRETTY_FUNCTION__))
;
14854 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14855 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14856 /*Last=*/OMPC_LASTPRIVATE_unknown)
14857 << getOpenMPClauseName(OMPC_lastprivate);
14858 return nullptr;
14859 }
14860
14861 SmallVector<Expr *, 8> Vars;
14862 SmallVector<Expr *, 8> SrcExprs;
14863 SmallVector<Expr *, 8> DstExprs;
14864 SmallVector<Expr *, 8> AssignmentOps;
14865 SmallVector<Decl *, 4> ExprCaptures;
14866 SmallVector<Expr *, 4> ExprPostUpdates;
14867 for (Expr *RefExpr : VarList) {
14868 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 14868, __PRETTY_FUNCTION__))
;
14869 SourceLocation ELoc;
14870 SourceRange ERange;
14871 Expr *SimpleRefExpr = RefExpr;
14872 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14873 if (Res.second) {
14874 // It will be analyzed later.
14875 Vars.push_back(RefExpr);
14876 SrcExprs.push_back(nullptr);
14877 DstExprs.push_back(nullptr);
14878 AssignmentOps.push_back(nullptr);
14879 }
14880 ValueDecl *D = Res.first;
14881 if (!D)
14882 continue;
14883
14884 QualType Type = D->getType();
14885 auto *VD = dyn_cast<VarDecl>(D);
14886
14887 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14888 // A variable that appears in a lastprivate clause must not have an
14889 // incomplete type or a reference type.
14890 if (RequireCompleteType(ELoc, Type,
14891 diag::err_omp_lastprivate_incomplete_type))
14892 continue;
14893 Type = Type.getNonReferenceType();
14894
14895 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14896 // A variable that is privatized must not have a const-qualified type
14897 // unless it is of class type with a mutable member. This restriction does
14898 // not apply to the firstprivate clause.
14899 //
14900 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14901 // A variable that appears in a lastprivate clause must not have a
14902 // const-qualified type unless it is of class type with a mutable member.
14903 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14904 continue;
14905
14906 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14907 // A list item that appears in a lastprivate clause with the conditional
14908 // modifier must be a scalar variable.
14909 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14910 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14911 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14912 VarDecl::DeclarationOnly;
14913 Diag(D->getLocation(),
14914 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14915 << D;
14916 continue;
14917 }
14918
14919 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14920 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14921 // in a Construct]
14922 // Variables with the predetermined data-sharing attributes may not be
14923 // listed in data-sharing attributes clauses, except for the cases
14924 // listed below.
14925 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14926 // A list item may appear in a firstprivate or lastprivate clause but not
14927 // both.
14928 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14929 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14930 (isOpenMPDistributeDirective(CurrDir) ||
14931 DVar.CKind != OMPC_firstprivate) &&
14932 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14933 Diag(ELoc, diag::err_omp_wrong_dsa)
14934 << getOpenMPClauseName(DVar.CKind)
14935 << getOpenMPClauseName(OMPC_lastprivate);
14936 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14937 continue;
14938 }
14939
14940 // OpenMP [2.14.3.5, Restrictions, p.2]
14941 // A list item that is private within a parallel region, or that appears in
14942 // the reduction clause of a parallel construct, must not appear in a
14943 // lastprivate clause on a worksharing construct if any of the corresponding
14944 // worksharing regions ever binds to any of the corresponding parallel
14945 // regions.
14946 DSAStackTy::DSAVarData TopDVar = DVar;
14947 if (isOpenMPWorksharingDirective(CurrDir) &&
14948 !isOpenMPParallelDirective(CurrDir) &&
14949 !isOpenMPTeamsDirective(CurrDir)) {
14950 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14951 if (DVar.CKind != OMPC_shared) {
14952 Diag(ELoc, diag::err_omp_required_access)
14953 << getOpenMPClauseName(OMPC_lastprivate)
14954 << getOpenMPClauseName(OMPC_shared);
14955 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14956 continue;
14957 }
14958 }
14959
14960 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14961 // A variable of class type (or array thereof) that appears in a
14962 // lastprivate clause requires an accessible, unambiguous default
14963 // constructor for the class type, unless the list item is also specified
14964 // in a firstprivate clause.
14965 // A variable of class type (or array thereof) that appears in a
14966 // lastprivate clause requires an accessible, unambiguous copy assignment
14967 // operator for the class type.
14968 Type = Context.getBaseElementType(Type).getNonReferenceType();
14969 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14970 Type.getUnqualifiedType(), ".lastprivate.src",
14971 D->hasAttrs() ? &D->getAttrs() : nullptr);
14972 DeclRefExpr *PseudoSrcExpr =
14973 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14974 VarDecl *DstVD =
14975 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14976 D->hasAttrs() ? &D->getAttrs() : nullptr);
14977 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14978 // For arrays generate assignment operation for single element and replace
14979 // it by the original array element in CodeGen.
14980 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14981 PseudoDstExpr, PseudoSrcExpr);
14982 if (AssignmentOp.isInvalid())
14983 continue;
14984 AssignmentOp =
14985 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14986 if (AssignmentOp.isInvalid())
14987 continue;
14988
14989 DeclRefExpr *Ref = nullptr;
14990 if (!VD && !CurContext->isDependentContext()) {
14991 if (TopDVar.CKind == OMPC_firstprivate) {
14992 Ref = TopDVar.PrivateCopy;
14993 } else {
14994 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14995 if (!isOpenMPCapturedDecl(D))
14996 ExprCaptures.push_back(Ref->getDecl());
14997 }
14998 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
14999 (!isOpenMPCapturedDecl(D) &&
15000 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
15001 ExprResult RefRes = DefaultLvalueConversion(Ref);
15002 if (!RefRes.isUsable())
15003 continue;
15004 ExprResult PostUpdateRes =
15005 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15006 RefRes.get());
15007 if (!PostUpdateRes.isUsable())
15008 continue;
15009 ExprPostUpdates.push_back(
15010 IgnoredValueConversions(PostUpdateRes.get()).get());
15011 }
15012 }
15013 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
15014 Vars.push_back((VD || CurContext->isDependentContext())
15015 ? RefExpr->IgnoreParens()
15016 : Ref);
15017 SrcExprs.push_back(PseudoSrcExpr);
15018 DstExprs.push_back(PseudoDstExpr);
15019 AssignmentOps.push_back(AssignmentOp.get());
15020 }
15021
15022 if (Vars.empty())
15023 return nullptr;
15024
15025 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15026 Vars, SrcExprs, DstExprs, AssignmentOps,
15027 LPKind, LPKindLoc, ColonLoc,
15028 buildPreInits(Context, ExprCaptures),
15029 buildPostUpdate(*this, ExprPostUpdates));
15030}
15031
15032OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
15033 SourceLocation StartLoc,
15034 SourceLocation LParenLoc,
15035 SourceLocation EndLoc) {
15036 SmallVector<Expr *, 8> Vars;
15037 for (Expr *RefExpr : VarList) {
15038 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15038, __PRETTY_FUNCTION__))
;
15039 SourceLocation ELoc;
15040 SourceRange ERange;
15041 Expr *SimpleRefExpr = RefExpr;
15042 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15043 if (Res.second) {
15044 // It will be analyzed later.
15045 Vars.push_back(RefExpr);
15046 }
15047 ValueDecl *D = Res.first;
15048 if (!D)
15049 continue;
15050
15051 auto *VD = dyn_cast<VarDecl>(D);
15052 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15053 // in a Construct]
15054 // Variables with the predetermined data-sharing attributes may not be
15055 // listed in data-sharing attributes clauses, except for the cases
15056 // listed below. For these exceptions only, listing a predetermined
15057 // variable in a data-sharing attribute clause is allowed and overrides
15058 // the variable's predetermined data-sharing attributes.
15059 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15060 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
15061 DVar.RefExpr) {
15062 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15063 << getOpenMPClauseName(OMPC_shared);
15064 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15065 continue;
15066 }
15067
15068 DeclRefExpr *Ref = nullptr;
15069 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
15070 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15071 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
15072 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
15073 ? RefExpr->IgnoreParens()
15074 : Ref);
15075 }
15076
15077 if (Vars.empty())
15078 return nullptr;
15079
15080 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
15081}
15082
15083namespace {
15084class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
15085 DSAStackTy *Stack;
15086
15087public:
15088 bool VisitDeclRefExpr(DeclRefExpr *E) {
15089 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
15090 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
15091 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
15092 return false;
15093 if (DVar.CKind != OMPC_unknown)
15094 return true;
15095 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
15096 VD,
15097 [](OpenMPClauseKind C, bool AppliedToPointee) {
15098 return isOpenMPPrivate(C) && !AppliedToPointee;
15099 },
15100 [](OpenMPDirectiveKind) { return true; },
15101 /*FromParent=*/true);
15102 return DVarPrivate.CKind != OMPC_unknown;
15103 }
15104 return false;
15105 }
15106 bool VisitStmt(Stmt *S) {
15107 for (Stmt *Child : S->children()) {
15108 if (Child && Visit(Child))
15109 return true;
15110 }
15111 return false;
15112 }
15113 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
15114};
15115} // namespace
15116
15117namespace {
15118// Transform MemberExpression for specified FieldDecl of current class to
15119// DeclRefExpr to specified OMPCapturedExprDecl.
15120class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
15121 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
15122 ValueDecl *Field = nullptr;
15123 DeclRefExpr *CapturedExpr = nullptr;
15124
15125public:
15126 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
15127 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
15128
15129 ExprResult TransformMemberExpr(MemberExpr *E) {
15130 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
15131 E->getMemberDecl() == Field) {
15132 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
15133 return CapturedExpr;
15134 }
15135 return BaseTransform::TransformMemberExpr(E);
15136 }
15137 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
15138};
15139} // namespace
15140
15141template <typename T, typename U>
15142static T filterLookupForUDReductionAndMapper(
15143 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
15144 for (U &Set : Lookups) {
15145 for (auto *D : Set) {
15146 if (T Res = Gen(cast<ValueDecl>(D)))
15147 return Res;
15148 }
15149 }
15150 return T();
15151}
15152
15153static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
15154 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")((!LookupResult::isVisible(SemaRef, D) && "not in slow case"
) ? static_cast<void> (0) : __assert_fail ("!LookupResult::isVisible(SemaRef, D) && \"not in slow case\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15154, __PRETTY_FUNCTION__))
;
15155
15156 for (auto RD : D->redecls()) {
15157 // Don't bother with extra checks if we already know this one isn't visible.
15158 if (RD == D)
15159 continue;
15160
15161 auto ND = cast<NamedDecl>(RD);
15162 if (LookupResult::isVisible(SemaRef, ND))
15163 return ND;
15164 }
15165
15166 return nullptr;
15167}
15168
15169static void
15170argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
15171 SourceLocation Loc, QualType Ty,
15172 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
15173 // Find all of the associated namespaces and classes based on the
15174 // arguments we have.
15175 Sema::AssociatedNamespaceSet AssociatedNamespaces;
15176 Sema::AssociatedClassSet AssociatedClasses;
15177 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
15178 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
15179 AssociatedClasses);
15180
15181 // C++ [basic.lookup.argdep]p3:
15182 // Let X be the lookup set produced by unqualified lookup (3.4.1)
15183 // and let Y be the lookup set produced by argument dependent
15184 // lookup (defined as follows). If X contains [...] then Y is
15185 // empty. Otherwise Y is the set of declarations found in the
15186 // namespaces associated with the argument types as described
15187 // below. The set of declarations found by the lookup of the name
15188 // is the union of X and Y.
15189 //
15190 // Here, we compute Y and add its members to the overloaded
15191 // candidate set.
15192 for (auto *NS : AssociatedNamespaces) {
15193 // When considering an associated namespace, the lookup is the
15194 // same as the lookup performed when the associated namespace is
15195 // used as a qualifier (3.4.3.2) except that:
15196 //
15197 // -- Any using-directives in the associated namespace are
15198 // ignored.
15199 //
15200 // -- Any namespace-scope friend functions declared in
15201 // associated classes are visible within their respective
15202 // namespaces even if they are not visible during an ordinary
15203 // lookup (11.4).
15204 DeclContext::lookup_result R = NS->lookup(Id.getName());
15205 for (auto *D : R) {
15206 auto *Underlying = D;
15207 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
15208 Underlying = USD->getTargetDecl();
15209
15210 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
15211 !isa<OMPDeclareMapperDecl>(Underlying))
15212 continue;
15213
15214 if (!SemaRef.isVisible(D)) {
15215 D = findAcceptableDecl(SemaRef, D);
15216 if (!D)
15217 continue;
15218 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
15219 Underlying = USD->getTargetDecl();
15220 }
15221 Lookups.emplace_back();
15222 Lookups.back().addDecl(Underlying);
15223 }
15224 }
15225}
15226
15227static ExprResult
15228buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
15229 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
15230 const DeclarationNameInfo &ReductionId, QualType Ty,
15231 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
15232 if (ReductionIdScopeSpec.isInvalid())
15233 return ExprError();
15234 SmallVector<UnresolvedSet<8>, 4> Lookups;
15235 if (S) {
15236 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
15237 Lookup.suppressDiagnostics();
15238 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
15239 NamedDecl *D = Lookup.getRepresentativeDecl();
15240 do {
15241 S = S->getParent();
15242 } while (S && !S->isDeclScope(D));
15243 if (S)
15244 S = S->getParent();
15245 Lookups.emplace_back();
15246 Lookups.back().append(Lookup.begin(), Lookup.end());
15247 Lookup.clear();
15248 }
15249 } else if (auto *ULE =
15250 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
15251 Lookups.push_back(UnresolvedSet<8>());
15252 Decl *PrevD = nullptr;
15253 for (NamedDecl *D : ULE->decls()) {
15254 if (D == PrevD)
15255 Lookups.push_back(UnresolvedSet<8>());
15256 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
15257 Lookups.back().addDecl(DRD);
15258 PrevD = D;
15259 }
15260 }
15261 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
15262 Ty->isInstantiationDependentType() ||
15263 Ty->containsUnexpandedParameterPack() ||
15264 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
15265 return !D->isInvalidDecl() &&
15266 (D->getType()->isDependentType() ||
15267 D->getType()->isInstantiationDependentType() ||
15268 D->getType()->containsUnexpandedParameterPack());
15269 })) {
15270 UnresolvedSet<8> ResSet;
15271 for (const UnresolvedSet<8> &Set : Lookups) {
15272 if (Set.empty())
15273 continue;
15274 ResSet.append(Set.begin(), Set.end());
15275 // The last item marks the end of all declarations at the specified scope.
15276 ResSet.addDecl(Set[Set.size() - 1]);
15277 }
15278 return UnresolvedLookupExpr::Create(
15279 SemaRef.Context, /*NamingClass=*/nullptr,
15280 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
15281 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
15282 }
15283 // Lookup inside the classes.
15284 // C++ [over.match.oper]p3:
15285 // For a unary operator @ with an operand of a type whose
15286 // cv-unqualified version is T1, and for a binary operator @ with
15287 // a left operand of a type whose cv-unqualified version is T1 and
15288 // a right operand of a type whose cv-unqualified version is T2,
15289 // three sets of candidate functions, designated member
15290 // candidates, non-member candidates and built-in candidates, are
15291 // constructed as follows:
15292 // -- If T1 is a complete class type or a class currently being
15293 // defined, the set of member candidates is the result of the
15294 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
15295 // the set of member candidates is empty.
15296 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
15297 Lookup.suppressDiagnostics();
15298 if (const auto *TyRec = Ty->getAs<RecordType>()) {
15299 // Complete the type if it can be completed.
15300 // If the type is neither complete nor being defined, bail out now.
15301 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
15302 TyRec->getDecl()->getDefinition()) {
15303 Lookup.clear();
15304 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
15305 if (Lookup.empty()) {
15306 Lookups.emplace_back();
15307 Lookups.back().append(Lookup.begin(), Lookup.end());
15308 }
15309 }
15310 }
15311 // Perform ADL.
15312 if (SemaRef.getLangOpts().CPlusPlus)
15313 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
15314 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15315 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
15316 if (!D->isInvalidDecl() &&
15317 SemaRef.Context.hasSameType(D->getType(), Ty))
15318 return D;
15319 return nullptr;
15320 }))
15321 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
15322 VK_LValue, Loc);
15323 if (SemaRef.getLangOpts().CPlusPlus) {
15324 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15325 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
15326 if (!D->isInvalidDecl() &&
15327 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
15328 !Ty.isMoreQualifiedThan(D->getType()))
15329 return D;
15330 return nullptr;
15331 })) {
15332 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
15333 /*DetectVirtual=*/false);
15334 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
15335 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
15336 VD->getType().getUnqualifiedType()))) {
15337 if (SemaRef.CheckBaseClassAccess(
15338 Loc, VD->getType(), Ty, Paths.front(),
15339 /*DiagID=*/0) != Sema::AR_inaccessible) {
15340 SemaRef.BuildBasePathArray(Paths, BasePath);
15341 return SemaRef.BuildDeclRefExpr(
15342 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
15343 }
15344 }
15345 }
15346 }
15347 }
15348 if (ReductionIdScopeSpec.isSet()) {
15349 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
15350 << Ty << Range;
15351 return ExprError();
15352 }
15353 return ExprEmpty();
15354}
15355
15356namespace {
15357/// Data for the reduction-based clauses.
15358struct ReductionData {
15359 /// List of original reduction items.
15360 SmallVector<Expr *, 8> Vars;
15361 /// List of private copies of the reduction items.
15362 SmallVector<Expr *, 8> Privates;
15363 /// LHS expressions for the reduction_op expressions.
15364 SmallVector<Expr *, 8> LHSs;
15365 /// RHS expressions for the reduction_op expressions.
15366 SmallVector<Expr *, 8> RHSs;
15367 /// Reduction operation expression.
15368 SmallVector<Expr *, 8> ReductionOps;
15369 /// inscan copy operation expressions.
15370 SmallVector<Expr *, 8> InscanCopyOps;
15371 /// inscan copy temp array expressions for prefix sums.
15372 SmallVector<Expr *, 8> InscanCopyArrayTemps;
15373 /// inscan copy temp array element expressions for prefix sums.
15374 SmallVector<Expr *, 8> InscanCopyArrayElems;
15375 /// Taskgroup descriptors for the corresponding reduction items in
15376 /// in_reduction clauses.
15377 SmallVector<Expr *, 8> TaskgroupDescriptors;
15378 /// List of captures for clause.
15379 SmallVector<Decl *, 4> ExprCaptures;
15380 /// List of postupdate expressions.
15381 SmallVector<Expr *, 4> ExprPostUpdates;
15382 /// Reduction modifier.
15383 unsigned RedModifier = 0;
15384 ReductionData() = delete;
15385 /// Reserves required memory for the reduction data.
15386 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
15387 Vars.reserve(Size);
15388 Privates.reserve(Size);
15389 LHSs.reserve(Size);
15390 RHSs.reserve(Size);
15391 ReductionOps.reserve(Size);
15392 if (RedModifier == OMPC_REDUCTION_inscan) {
15393 InscanCopyOps.reserve(Size);
15394 InscanCopyArrayTemps.reserve(Size);
15395 InscanCopyArrayElems.reserve(Size);
15396 }
15397 TaskgroupDescriptors.reserve(Size);
15398 ExprCaptures.reserve(Size);
15399 ExprPostUpdates.reserve(Size);
15400 }
15401 /// Stores reduction item and reduction operation only (required for dependent
15402 /// reduction item).
15403 void push(Expr *Item, Expr *ReductionOp) {
15404 Vars.emplace_back(Item);
15405 Privates.emplace_back(nullptr);
15406 LHSs.emplace_back(nullptr);
15407 RHSs.emplace_back(nullptr);
15408 ReductionOps.emplace_back(ReductionOp);
15409 TaskgroupDescriptors.emplace_back(nullptr);
15410 if (RedModifier == OMPC_REDUCTION_inscan) {
15411 InscanCopyOps.push_back(nullptr);
15412 InscanCopyArrayTemps.push_back(nullptr);
15413 InscanCopyArrayElems.push_back(nullptr);
15414 }
15415 }
15416 /// Stores reduction data.
15417 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
15418 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
15419 Expr *CopyArrayElem) {
15420 Vars.emplace_back(Item);
15421 Privates.emplace_back(Private);
15422 LHSs.emplace_back(LHS);
15423 RHSs.emplace_back(RHS);
15424 ReductionOps.emplace_back(ReductionOp);
15425 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
15426 if (RedModifier == OMPC_REDUCTION_inscan) {
15427 InscanCopyOps.push_back(CopyOp);
15428 InscanCopyArrayTemps.push_back(CopyArrayTemp);
15429 InscanCopyArrayElems.push_back(CopyArrayElem);
15430 } else {
15431 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15433, __PRETTY_FUNCTION__))
15432 CopyArrayElem == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15433, __PRETTY_FUNCTION__))
15433 "Copy operation must be used for inscan reductions only.")((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15433, __PRETTY_FUNCTION__))
;
15434 }
15435 }
15436};
15437} // namespace
15438
15439static bool checkOMPArraySectionConstantForReduction(
15440 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
15441 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
15442 const Expr *Length = OASE->getLength();
15443 if (Length == nullptr) {
15444 // For array sections of the form [1:] or [:], we would need to analyze
15445 // the lower bound...
15446 if (OASE->getColonLocFirst().isValid())
15447 return false;
15448
15449 // This is an array subscript which has implicit length 1!
15450 SingleElement = true;
15451 ArraySizes.push_back(llvm::APSInt::get(1));
15452 } else {
15453 Expr::EvalResult Result;
15454 if (!Length->EvaluateAsInt(Result, Context))
15455 return false;
15456
15457 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15458 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
15459 ArraySizes.push_back(ConstantLengthValue);
15460 }
15461
15462 // Get the base of this array section and walk up from there.
15463 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
15464
15465 // We require length = 1 for all array sections except the right-most to
15466 // guarantee that the memory region is contiguous and has no holes in it.
15467 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
15468 Length = TempOASE->getLength();
15469 if (Length == nullptr) {
15470 // For array sections of the form [1:] or [:], we would need to analyze
15471 // the lower bound...
15472 if (OASE->getColonLocFirst().isValid())
15473 return false;
15474
15475 // This is an array subscript which has implicit length 1!
15476 ArraySizes.push_back(llvm::APSInt::get(1));
15477 } else {
15478 Expr::EvalResult Result;
15479 if (!Length->EvaluateAsInt(Result, Context))
15480 return false;
15481
15482 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15483 if (ConstantLengthValue.getSExtValue() != 1)
15484 return false;
15485
15486 ArraySizes.push_back(ConstantLengthValue);
15487 }
15488 Base = TempOASE->getBase()->IgnoreParenImpCasts();
15489 }
15490
15491 // If we have a single element, we don't need to add the implicit lengths.
15492 if (!SingleElement) {
15493 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
15494 // Has implicit length 1!
15495 ArraySizes.push_back(llvm::APSInt::get(1));
15496 Base = TempASE->getBase()->IgnoreParenImpCasts();
15497 }
15498 }
15499
15500 // This array section can be privatized as a single value or as a constant
15501 // sized array.
15502 return true;
15503}
15504
15505static bool actOnOMPReductionKindClause(
15506 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
15507 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15508 SourceLocation ColonLoc, SourceLocation EndLoc,
15509 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15510 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
15511 DeclarationName DN = ReductionId.getName();
15512 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
15513 BinaryOperatorKind BOK = BO_Comma;
15514
15515 ASTContext &Context = S.Context;
15516 // OpenMP [2.14.3.6, reduction clause]
15517 // C
15518 // reduction-identifier is either an identifier or one of the following
15519 // operators: +, -, *, &, |, ^, && and ||
15520 // C++
15521 // reduction-identifier is either an id-expression or one of the following
15522 // operators: +, -, *, &, |, ^, && and ||
15523 switch (OOK) {
15524 case OO_Plus:
15525 case OO_Minus:
15526 BOK = BO_Add;
15527 break;
15528 case OO_Star:
15529 BOK = BO_Mul;
15530 break;
15531 case OO_Amp:
15532 BOK = BO_And;
15533 break;
15534 case OO_Pipe:
15535 BOK = BO_Or;
15536 break;
15537 case OO_Caret:
15538 BOK = BO_Xor;
15539 break;
15540 case OO_AmpAmp:
15541 BOK = BO_LAnd;
15542 break;
15543 case OO_PipePipe:
15544 BOK = BO_LOr;
15545 break;
15546 case OO_New:
15547 case OO_Delete:
15548 case OO_Array_New:
15549 case OO_Array_Delete:
15550 case OO_Slash:
15551 case OO_Percent:
15552 case OO_Tilde:
15553 case OO_Exclaim:
15554 case OO_Equal:
15555 case OO_Less:
15556 case OO_Greater:
15557 case OO_LessEqual:
15558 case OO_GreaterEqual:
15559 case OO_PlusEqual:
15560 case OO_MinusEqual:
15561 case OO_StarEqual:
15562 case OO_SlashEqual:
15563 case OO_PercentEqual:
15564 case OO_CaretEqual:
15565 case OO_AmpEqual:
15566 case OO_PipeEqual:
15567 case OO_LessLess:
15568 case OO_GreaterGreater:
15569 case OO_LessLessEqual:
15570 case OO_GreaterGreaterEqual:
15571 case OO_EqualEqual:
15572 case OO_ExclaimEqual:
15573 case OO_Spaceship:
15574 case OO_PlusPlus:
15575 case OO_MinusMinus:
15576 case OO_Comma:
15577 case OO_ArrowStar:
15578 case OO_Arrow:
15579 case OO_Call:
15580 case OO_Subscript:
15581 case OO_Conditional:
15582 case OO_Coawait:
15583 case NUM_OVERLOADED_OPERATORS:
15584 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15584)
;
15585 case OO_None:
15586 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
15587 if (II->isStr("max"))
15588 BOK = BO_GT;
15589 else if (II->isStr("min"))
15590 BOK = BO_LT;
15591 }
15592 break;
15593 }
15594 SourceRange ReductionIdRange;
15595 if (ReductionIdScopeSpec.isValid())
15596 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
15597 else
15598 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
15599 ReductionIdRange.setEnd(ReductionId.getEndLoc());
15600
15601 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
15602 bool FirstIter = true;
15603 for (Expr *RefExpr : VarList) {
15604 assert(RefExpr && "nullptr expr in OpenMP reduction clause.")((RefExpr && "nullptr expr in OpenMP reduction clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15604, __PRETTY_FUNCTION__))
;
15605 // OpenMP [2.1, C/C++]
15606 // A list item is a variable or array section, subject to the restrictions
15607 // specified in Section 2.4 on page 42 and in each of the sections
15608 // describing clauses and directives for which a list appears.
15609 // OpenMP [2.14.3.3, Restrictions, p.1]
15610 // A variable that is part of another variable (as an array or
15611 // structure element) cannot appear in a private clause.
15612 if (!FirstIter && IR != ER)
15613 ++IR;
15614 FirstIter = false;
15615 SourceLocation ELoc;
15616 SourceRange ERange;
15617 Expr *SimpleRefExpr = RefExpr;
15618 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
15619 /*AllowArraySection=*/true);
15620 if (Res.second) {
15621 // Try to find 'declare reduction' corresponding construct before using
15622 // builtin/overloaded operators.
15623 QualType Type = Context.DependentTy;
15624 CXXCastPath BasePath;
15625 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15626 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15627 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15628 Expr *ReductionOp = nullptr;
15629 if (S.CurContext->isDependentContext() &&
15630 (DeclareReductionRef.isUnset() ||
15631 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
15632 ReductionOp = DeclareReductionRef.get();
15633 // It will be analyzed later.
15634 RD.push(RefExpr, ReductionOp);
15635 }
15636 ValueDecl *D = Res.first;
15637 if (!D)
15638 continue;
15639
15640 Expr *TaskgroupDescriptor = nullptr;
15641 QualType Type;
15642 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
15643 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
15644 if (ASE) {
15645 Type = ASE->getType().getNonReferenceType();
15646 } else if (OASE) {
15647 QualType BaseType =
15648 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15649 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15650 Type = ATy->getElementType();
15651 else
15652 Type = BaseType->getPointeeType();
15653 Type = Type.getNonReferenceType();
15654 } else {
15655 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
15656 }
15657 auto *VD = dyn_cast<VarDecl>(D);
15658
15659 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15660 // A variable that appears in a private clause must not have an incomplete
15661 // type or a reference type.
15662 if (S.RequireCompleteType(ELoc, D->getType(),
15663 diag::err_omp_reduction_incomplete_type))
15664 continue;
15665 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15666 // A list item that appears in a reduction clause must not be
15667 // const-qualified.
15668 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
15669 /*AcceptIfMutable*/ false, ASE || OASE))
15670 continue;
15671
15672 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
15673 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
15674 // If a list-item is a reference type then it must bind to the same object
15675 // for all threads of the team.
15676 if (!ASE && !OASE) {
15677 if (VD) {
15678 VarDecl *VDDef = VD->getDefinition();
15679 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15680 DSARefChecker Check(Stack);
15681 if (Check.Visit(VDDef->getInit())) {
15682 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15683 << getOpenMPClauseName(ClauseKind) << ERange;
15684 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15685 continue;
15686 }
15687 }
15688 }
15689
15690 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15691 // in a Construct]
15692 // Variables with the predetermined data-sharing attributes may not be
15693 // listed in data-sharing attributes clauses, except for the cases
15694 // listed below. For these exceptions only, listing a predetermined
15695 // variable in a data-sharing attribute clause is allowed and overrides
15696 // the variable's predetermined data-sharing attributes.
15697 // OpenMP [2.14.3.6, Restrictions, p.3]
15698 // Any number of reduction clauses can be specified on the directive,
15699 // but a list item can appear only once in the reduction clauses for that
15700 // directive.
15701 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15702 if (DVar.CKind == OMPC_reduction) {
15703 S.Diag(ELoc, diag::err_omp_once_referenced)
15704 << getOpenMPClauseName(ClauseKind);
15705 if (DVar.RefExpr)
15706 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15707 continue;
15708 }
15709 if (DVar.CKind != OMPC_unknown) {
15710 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15711 << getOpenMPClauseName(DVar.CKind)
15712 << getOpenMPClauseName(OMPC_reduction);
15713 reportOriginalDsa(S, Stack, D, DVar);
15714 continue;
15715 }
15716
15717 // OpenMP [2.14.3.6, Restrictions, p.1]
15718 // A list item that appears in a reduction clause of a worksharing
15719 // construct must be shared in the parallel regions to which any of the
15720 // worksharing regions arising from the worksharing construct bind.
15721 if (isOpenMPWorksharingDirective(CurrDir) &&
15722 !isOpenMPParallelDirective(CurrDir) &&
15723 !isOpenMPTeamsDirective(CurrDir)) {
15724 DVar = Stack->getImplicitDSA(D, true);
15725 if (DVar.CKind != OMPC_shared) {
15726 S.Diag(ELoc, diag::err_omp_required_access)
15727 << getOpenMPClauseName(OMPC_reduction)
15728 << getOpenMPClauseName(OMPC_shared);
15729 reportOriginalDsa(S, Stack, D, DVar);
15730 continue;
15731 }
15732 }
15733 } else {
15734 // Threadprivates cannot be shared between threads, so dignose if the base
15735 // is a threadprivate variable.
15736 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15737 if (DVar.CKind == OMPC_threadprivate) {
15738 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15739 << getOpenMPClauseName(DVar.CKind)
15740 << getOpenMPClauseName(OMPC_reduction);
15741 reportOriginalDsa(S, Stack, D, DVar);
15742 continue;
15743 }
15744 }
15745
15746 // Try to find 'declare reduction' corresponding construct before using
15747 // builtin/overloaded operators.
15748 CXXCastPath BasePath;
15749 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15750 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15751 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15752 if (DeclareReductionRef.isInvalid())
15753 continue;
15754 if (S.CurContext->isDependentContext() &&
15755 (DeclareReductionRef.isUnset() ||
15756 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15757 RD.push(RefExpr, DeclareReductionRef.get());
15758 continue;
15759 }
15760 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15761 // Not allowed reduction identifier is found.
15762 S.Diag(ReductionId.getBeginLoc(),
15763 diag::err_omp_unknown_reduction_identifier)
15764 << Type << ReductionIdRange;
15765 continue;
15766 }
15767
15768 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15769 // The type of a list item that appears in a reduction clause must be valid
15770 // for the reduction-identifier. For a max or min reduction in C, the type
15771 // of the list item must be an allowed arithmetic data type: char, int,
15772 // float, double, or _Bool, possibly modified with long, short, signed, or
15773 // unsigned. For a max or min reduction in C++, the type of the list item
15774 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15775 // double, or bool, possibly modified with long, short, signed, or unsigned.
15776 if (DeclareReductionRef.isUnset()) {
15777 if ((BOK == BO_GT || BOK == BO_LT) &&
15778 !(Type->isScalarType() ||
15779 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15780 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15781 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15782 if (!ASE && !OASE) {
15783 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15784 VarDecl::DeclarationOnly;
15785 S.Diag(D->getLocation(),
15786 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15787 << D;
15788 }
15789 continue;
15790 }
15791 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15792 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15793 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15794 << getOpenMPClauseName(ClauseKind);
15795 if (!ASE && !OASE) {
15796 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15797 VarDecl::DeclarationOnly;
15798 S.Diag(D->getLocation(),
15799 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15800 << D;
15801 }
15802 continue;
15803 }
15804 }
15805
15806 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15807 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15808 D->hasAttrs() ? &D->getAttrs() : nullptr);
15809 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15810 D->hasAttrs() ? &D->getAttrs() : nullptr);
15811 QualType PrivateTy = Type;
15812
15813 // Try if we can determine constant lengths for all array sections and avoid
15814 // the VLA.
15815 bool ConstantLengthOASE = false;
15816 if (OASE) {
15817 bool SingleElement;
15818 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15819 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15820 Context, OASE, SingleElement, ArraySizes);
15821
15822 // If we don't have a single element, we must emit a constant array type.
15823 if (ConstantLengthOASE && !SingleElement) {
15824 for (llvm::APSInt &Size : ArraySizes)
15825 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15826 ArrayType::Normal,
15827 /*IndexTypeQuals=*/0);
15828 }
15829 }
15830
15831 if ((OASE && !ConstantLengthOASE) ||
15832 (!OASE && !ASE &&
15833 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15834 if (!Context.getTargetInfo().isVLASupported()) {
15835 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15836 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15837 S.Diag(ELoc, diag::note_vla_unsupported);
15838 continue;
15839 } else {
15840 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15841 S.targetDiag(ELoc, diag::note_vla_unsupported);
15842 }
15843 }
15844 // For arrays/array sections only:
15845 // Create pseudo array type for private copy. The size for this array will
15846 // be generated during codegen.
15847 // For array subscripts or single variables Private Ty is the same as Type
15848 // (type of the variable or single array element).
15849 PrivateTy = Context.getVariableArrayType(
15850 Type,
15851 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15852 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15853 } else if (!ASE && !OASE &&
15854 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15855 PrivateTy = D->getType().getNonReferenceType();
15856 }
15857 // Private copy.
15858 VarDecl *PrivateVD =
15859 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15860 D->hasAttrs() ? &D->getAttrs() : nullptr,
15861 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15862 // Add initializer for private variable.
15863 Expr *Init = nullptr;
15864 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15865 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15866 if (DeclareReductionRef.isUsable()) {
15867 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15868 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15869 if (DRD->getInitializer()) {
15870 S.ActOnUninitializedDecl(PrivateVD);
15871 Init = DRDRef;
15872 RHSVD->setInit(DRDRef);
15873 RHSVD->setInitStyle(VarDecl::CallInit);
15874 }
15875 } else {
15876 switch (BOK) {
15877 case BO_Add:
15878 case BO_Xor:
15879 case BO_Or:
15880 case BO_LOr:
15881 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15882 if (Type->isScalarType() || Type->isAnyComplexType())
15883 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15884 break;
15885 case BO_Mul:
15886 case BO_LAnd:
15887 if (Type->isScalarType() || Type->isAnyComplexType()) {
15888 // '*' and '&&' reduction ops - initializer is '1'.
15889 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15890 }
15891 break;
15892 case BO_And: {
15893 // '&' reduction op - initializer is '~0'.
15894 QualType OrigType = Type;
15895 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15896 Type = ComplexTy->getElementType();
15897 if (Type->isRealFloatingType()) {
15898 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15899 Context.getFloatTypeSemantics(Type),
15900 Context.getTypeSize(Type));
15901 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15902 Type, ELoc);
15903 } else if (Type->isScalarType()) {
15904 uint64_t Size = Context.getTypeSize(Type);
15905 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15906 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15907 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15908 }
15909 if (Init && OrigType->isAnyComplexType()) {
15910 // Init = 0xFFFF + 0xFFFFi;
15911 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15912 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15913 }
15914 Type = OrigType;
15915 break;
15916 }
15917 case BO_LT:
15918 case BO_GT: {
15919 // 'min' reduction op - initializer is 'Largest representable number in
15920 // the reduction list item type'.
15921 // 'max' reduction op - initializer is 'Least representable number in
15922 // the reduction list item type'.
15923 if (Type->isIntegerType() || Type->isPointerType()) {
15924 bool IsSigned = Type->hasSignedIntegerRepresentation();
15925 uint64_t Size = Context.getTypeSize(Type);
15926 QualType IntTy =
15927 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15928 llvm::APInt InitValue =
15929 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15930 : llvm::APInt::getMinValue(Size)
15931 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15932 : llvm::APInt::getMaxValue(Size);
15933 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15934 if (Type->isPointerType()) {
15935 // Cast to pointer type.
15936 ExprResult CastExpr = S.BuildCStyleCastExpr(
15937 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15938 if (CastExpr.isInvalid())
15939 continue;
15940 Init = CastExpr.get();
15941 }
15942 } else if (Type->isRealFloatingType()) {
15943 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15944 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15945 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15946 Type, ELoc);
15947 }
15948 break;
15949 }
15950 case BO_PtrMemD:
15951 case BO_PtrMemI:
15952 case BO_MulAssign:
15953 case BO_Div:
15954 case BO_Rem:
15955 case BO_Sub:
15956 case BO_Shl:
15957 case BO_Shr:
15958 case BO_LE:
15959 case BO_GE:
15960 case BO_EQ:
15961 case BO_NE:
15962 case BO_Cmp:
15963 case BO_AndAssign:
15964 case BO_XorAssign:
15965 case BO_OrAssign:
15966 case BO_Assign:
15967 case BO_AddAssign:
15968 case BO_SubAssign:
15969 case BO_DivAssign:
15970 case BO_RemAssign:
15971 case BO_ShlAssign:
15972 case BO_ShrAssign:
15973 case BO_Comma:
15974 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 15974)
;
15975 }
15976 }
15977 if (Init && DeclareReductionRef.isUnset()) {
15978 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15979 // Store initializer for single element in private copy. Will be used
15980 // during codegen.
15981 PrivateVD->setInit(RHSVD->getInit());
15982 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15983 } else if (!Init) {
15984 S.ActOnUninitializedDecl(RHSVD);
15985 // Store initializer for single element in private copy. Will be used
15986 // during codegen.
15987 PrivateVD->setInit(RHSVD->getInit());
15988 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15989 }
15990 if (RHSVD->isInvalidDecl())
15991 continue;
15992 if (!RHSVD->hasInit() &&
15993 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15994 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15995 << Type << ReductionIdRange;
15996 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15997 VarDecl::DeclarationOnly;
15998 S.Diag(D->getLocation(),
15999 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16000 << D;
16001 continue;
16002 }
16003 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
16004 ExprResult ReductionOp;
16005 if (DeclareReductionRef.isUsable()) {
16006 QualType RedTy = DeclareReductionRef.get()->getType();
16007 QualType PtrRedTy = Context.getPointerType(RedTy);
16008 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
16009 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
16010 if (!BasePath.empty()) {
16011 LHS = S.DefaultLvalueConversion(LHS.get());
16012 RHS = S.DefaultLvalueConversion(RHS.get());
16013 LHS = ImplicitCastExpr::Create(
16014 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
16015 LHS.get()->getValueKind(), FPOptionsOverride());
16016 RHS = ImplicitCastExpr::Create(
16017 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
16018 RHS.get()->getValueKind(), FPOptionsOverride());
16019 }
16020 FunctionProtoType::ExtProtoInfo EPI;
16021 QualType Params[] = {PtrRedTy, PtrRedTy};
16022 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
16023 auto *OVE = new (Context) OpaqueValueExpr(
16024 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
16025 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
16026 Expr *Args[] = {LHS.get(), RHS.get()};
16027 ReductionOp =
16028 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
16029 S.CurFPFeatureOverrides());
16030 } else {
16031 ReductionOp = S.BuildBinOp(
16032 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
16033 if (ReductionOp.isUsable()) {
16034 if (BOK != BO_LT && BOK != BO_GT) {
16035 ReductionOp =
16036 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16037 BO_Assign, LHSDRE, ReductionOp.get());
16038 } else {
16039 auto *ConditionalOp = new (Context)
16040 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
16041 Type, VK_LValue, OK_Ordinary);
16042 ReductionOp =
16043 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16044 BO_Assign, LHSDRE, ConditionalOp);
16045 }
16046 if (ReductionOp.isUsable())
16047 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
16048 /*DiscardedValue*/ false);
16049 }
16050 if (!ReductionOp.isUsable())
16051 continue;
16052 }
16053
16054 // Add copy operations for inscan reductions.
16055 // LHS = RHS;
16056 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
16057 if (ClauseKind == OMPC_reduction &&
16058 RD.RedModifier == OMPC_REDUCTION_inscan) {
16059 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
16060 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
16061 RHS.get());
16062 if (!CopyOpRes.isUsable())
16063 continue;
16064 CopyOpRes =
16065 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
16066 if (!CopyOpRes.isUsable())
16067 continue;
16068 // For simd directive and simd-based directives in simd mode no need to
16069 // construct temp array, need just a single temp element.
16070 if (Stack->getCurrentDirective() == OMPD_simd ||
16071 (S.getLangOpts().OpenMPSimd &&
16072 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
16073 VarDecl *TempArrayVD =
16074 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
16075 D->hasAttrs() ? &D->getAttrs() : nullptr);
16076 // Add a constructor to the temp decl.
16077 S.ActOnUninitializedDecl(TempArrayVD);
16078 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
16079 } else {
16080 // Build temp array for prefix sum.
16081 auto *Dim = new (S.Context)
16082 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16083 QualType ArrayTy =
16084 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
16085 /*IndexTypeQuals=*/0, {ELoc, ELoc});
16086 VarDecl *TempArrayVD =
16087 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
16088 D->hasAttrs() ? &D->getAttrs() : nullptr);
16089 // Add a constructor to the temp decl.
16090 S.ActOnUninitializedDecl(TempArrayVD);
16091 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
16092 TempArrayElem =
16093 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
16094 auto *Idx = new (S.Context)
16095 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16096 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
16097 ELoc, Idx, ELoc);
16098 }
16099 }
16100
16101 // OpenMP [2.15.4.6, Restrictions, p.2]
16102 // A list item that appears in an in_reduction clause of a task construct
16103 // must appear in a task_reduction clause of a construct associated with a
16104 // taskgroup region that includes the participating task in its taskgroup
16105 // set. The construct associated with the innermost region that meets this
16106 // condition must specify the same reduction-identifier as the in_reduction
16107 // clause.
16108 if (ClauseKind == OMPC_in_reduction) {
16109 SourceRange ParentSR;
16110 BinaryOperatorKind ParentBOK;
16111 const Expr *ParentReductionOp = nullptr;
16112 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
16113 DSAStackTy::DSAVarData ParentBOKDSA =
16114 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
16115 ParentBOKTD);
16116 DSAStackTy::DSAVarData ParentReductionOpDSA =
16117 Stack->getTopMostTaskgroupReductionData(
16118 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
16119 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
16120 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
16121 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
16122 (DeclareReductionRef.isUsable() && IsParentBOK) ||
16123 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
16124 bool EmitError = true;
16125 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
16126 llvm::FoldingSetNodeID RedId, ParentRedId;
16127 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
16128 DeclareReductionRef.get()->Profile(RedId, Context,
16129 /*Canonical=*/true);
16130 EmitError = RedId != ParentRedId;
16131 }
16132 if (EmitError) {
16133 S.Diag(ReductionId.getBeginLoc(),
16134 diag::err_omp_reduction_identifier_mismatch)
16135 << ReductionIdRange << RefExpr->getSourceRange();
16136 S.Diag(ParentSR.getBegin(),
16137 diag::note_omp_previous_reduction_identifier)
16138 << ParentSR
16139 << (IsParentBOK ? ParentBOKDSA.RefExpr
16140 : ParentReductionOpDSA.RefExpr)
16141 ->getSourceRange();
16142 continue;
16143 }
16144 }
16145 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
16146 }
16147
16148 DeclRefExpr *Ref = nullptr;
16149 Expr *VarsExpr = RefExpr->IgnoreParens();
16150 if (!VD && !S.CurContext->isDependentContext()) {
16151 if (ASE || OASE) {
16152 TransformExprToCaptures RebuildToCapture(S, D);
16153 VarsExpr =
16154 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
16155 Ref = RebuildToCapture.getCapturedExpr();
16156 } else {
16157 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
16158 }
16159 if (!S.isOpenMPCapturedDecl(D)) {
16160 RD.ExprCaptures.emplace_back(Ref->getDecl());
16161 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
16162 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
16163 if (!RefRes.isUsable())
16164 continue;
16165 ExprResult PostUpdateRes =
16166 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
16167 RefRes.get());
16168 if (!PostUpdateRes.isUsable())
16169 continue;
16170 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
16171 Stack->getCurrentDirective() == OMPD_taskgroup) {
16172 S.Diag(RefExpr->getExprLoc(),
16173 diag::err_omp_reduction_non_addressable_expression)
16174 << RefExpr->getSourceRange();
16175 continue;
16176 }
16177 RD.ExprPostUpdates.emplace_back(
16178 S.IgnoredValueConversions(PostUpdateRes.get()).get());
16179 }
16180 }
16181 }
16182 // All reduction items are still marked as reduction (to do not increase
16183 // code base size).
16184 unsigned Modifier = RD.RedModifier;
16185 // Consider task_reductions as reductions with task modifier. Required for
16186 // correct analysis of in_reduction clauses.
16187 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
16188 Modifier = OMPC_REDUCTION_task;
16189 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
16190 ASE || OASE);
16191 if (Modifier == OMPC_REDUCTION_task &&
16192 (CurrDir == OMPD_taskgroup ||
16193 ((isOpenMPParallelDirective(CurrDir) ||
16194 isOpenMPWorksharingDirective(CurrDir)) &&
16195 !isOpenMPSimdDirective(CurrDir)))) {
16196 if (DeclareReductionRef.isUsable())
16197 Stack->addTaskgroupReductionData(D, ReductionIdRange,
16198 DeclareReductionRef.get());
16199 else
16200 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
16201 }
16202 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
16203 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
16204 TempArrayElem.get());
16205 }
16206 return RD.Vars.empty();
16207}
16208
16209OMPClause *Sema::ActOnOpenMPReductionClause(
16210 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
16211 SourceLocation StartLoc, SourceLocation LParenLoc,
16212 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
16213 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16214 ArrayRef<Expr *> UnresolvedReductions) {
16215 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
16216 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
16217 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
16218 /*Last=*/OMPC_REDUCTION_unknown)
16219 << getOpenMPClauseName(OMPC_reduction);
16220 return nullptr;
16221 }
16222 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
16223 // A reduction clause with the inscan reduction-modifier may only appear on a
16224 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
16225 // construct, a parallel worksharing-loop construct or a parallel
16226 // worksharing-loop SIMD construct.
16227 if (Modifier == OMPC_REDUCTION_inscan &&
16228 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
16229 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
16230 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
16231 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
16232 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
16233 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
16234 return nullptr;
16235 }
16236
16237 ReductionData RD(VarList.size(), Modifier);
16238 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
16239 StartLoc, LParenLoc, ColonLoc, EndLoc,
16240 ReductionIdScopeSpec, ReductionId,
16241 UnresolvedReductions, RD))
16242 return nullptr;
16243
16244 return OMPReductionClause::Create(
16245 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
16246 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
16247 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
16248 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
16249 buildPreInits(Context, RD.ExprCaptures),
16250 buildPostUpdate(*this, RD.ExprPostUpdates));
16251}
16252
16253OMPClause *Sema::ActOnOpenMPTaskReductionClause(
16254 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16255 SourceLocation ColonLoc, SourceLocation EndLoc,
16256 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16257 ArrayRef<Expr *> UnresolvedReductions) {
16258 ReductionData RD(VarList.size());
16259 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
16260 StartLoc, LParenLoc, ColonLoc, EndLoc,
16261 ReductionIdScopeSpec, ReductionId,
16262 UnresolvedReductions, RD))
16263 return nullptr;
16264
16265 return OMPTaskReductionClause::Create(
16266 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
16267 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
16268 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
16269 buildPreInits(Context, RD.ExprCaptures),
16270 buildPostUpdate(*this, RD.ExprPostUpdates));
16271}
16272
16273OMPClause *Sema::ActOnOpenMPInReductionClause(
16274 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16275 SourceLocation ColonLoc, SourceLocation EndLoc,
16276 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16277 ArrayRef<Expr *> UnresolvedReductions) {
16278 ReductionData RD(VarList.size());
16279 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
16280 StartLoc, LParenLoc, ColonLoc, EndLoc,
16281 ReductionIdScopeSpec, ReductionId,
16282 UnresolvedReductions, RD))
16283 return nullptr;
16284
16285 return OMPInReductionClause::Create(
16286 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
16287 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
16288 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
16289 buildPreInits(Context, RD.ExprCaptures),
16290 buildPostUpdate(*this, RD.ExprPostUpdates));
16291}
16292
16293bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
16294 SourceLocation LinLoc) {
16295 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
16296 LinKind == OMPC_LINEAR_unknown) {
16297 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
16298 return true;
16299 }
16300 return false;
16301}
16302
16303bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
16304 OpenMPLinearClauseKind LinKind, QualType Type,
16305 bool IsDeclareSimd) {
16306 const auto *VD = dyn_cast_or_null<VarDecl>(D);
16307 // A variable must not have an incomplete type or a reference type.
16308 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
16309 return true;
16310 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
16311 !Type->isReferenceType()) {
16312 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
16313 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
16314 return true;
16315 }
16316 Type = Type.getNonReferenceType();
16317
16318 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
16319 // A variable that is privatized must not have a const-qualified type
16320 // unless it is of class type with a mutable member. This restriction does
16321 // not apply to the firstprivate clause, nor to the linear clause on
16322 // declarative directives (like declare simd).
16323 if (!IsDeclareSimd &&
16324 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
16325 return true;
16326
16327 // A list item must be of integral or pointer type.
16328 Type = Type.getUnqualifiedType().getCanonicalType();
16329 const auto *Ty = Type.getTypePtrOrNull();
16330 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
16331 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
16332 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
16333 if (D) {
16334 bool IsDecl =
16335 !VD ||
16336 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16337 Diag(D->getLocation(),
16338 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16339 << D;
16340 }
16341 return true;
16342 }
16343 return false;
16344}
16345
16346OMPClause *Sema::ActOnOpenMPLinearClause(
16347 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
16348 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
16349 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16350 SmallVector<Expr *, 8> Vars;
16351 SmallVector<Expr *, 8> Privates;
16352 SmallVector<Expr *, 8> Inits;
16353 SmallVector<Decl *, 4> ExprCaptures;
16354 SmallVector<Expr *, 4> ExprPostUpdates;
16355 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
16356 LinKind = OMPC_LINEAR_val;
16357 for (Expr *RefExpr : VarList) {
16358 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 16358, __PRETTY_FUNCTION__))
;
16359 SourceLocation ELoc;
16360 SourceRange ERange;
16361 Expr *SimpleRefExpr = RefExpr;
16362 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16363 if (Res.second) {
16364 // It will be analyzed later.
16365 Vars.push_back(RefExpr);
16366 Privates.push_back(nullptr);
16367 Inits.push_back(nullptr);
16368 }
16369 ValueDecl *D = Res.first;
16370 if (!D)
16371 continue;
16372
16373 QualType Type = D->getType();
16374 auto *VD = dyn_cast<VarDecl>(D);
16375
16376 // OpenMP [2.14.3.7, linear clause]
16377 // A list-item cannot appear in more than one linear clause.
16378 // A list-item that appears in a linear clause cannot appear in any
16379 // other data-sharing attribute clause.
16380 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16381 if (DVar.RefExpr) {
16382 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
16383 << getOpenMPClauseName(OMPC_linear);
16384 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16385 continue;
16386 }
16387
16388 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
16389 continue;
16390 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16391
16392 // Build private copy of original var.
16393 VarDecl *Private =
16394 buildVarDecl(*this, ELoc, Type, D->getName(),
16395 D->hasAttrs() ? &D->getAttrs() : nullptr,
16396 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
16397 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
16398 // Build var to save initial value.
16399 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
16400 Expr *InitExpr;
16401 DeclRefExpr *Ref = nullptr;
16402 if (!VD && !CurContext->isDependentContext()) {
16403 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16404 if (!isOpenMPCapturedDecl(D)) {
16405 ExprCaptures.push_back(Ref->getDecl());
16406 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
16407 ExprResult RefRes = DefaultLvalueConversion(Ref);
16408 if (!RefRes.isUsable())
16409 continue;
16410 ExprResult PostUpdateRes =
16411 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
16412 SimpleRefExpr, RefRes.get());
16413 if (!PostUpdateRes.isUsable())
16414 continue;
16415 ExprPostUpdates.push_back(
16416 IgnoredValueConversions(PostUpdateRes.get()).get());
16417 }
16418 }
16419 }
16420 if (LinKind == OMPC_LINEAR_uval)
16421 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
16422 else
16423 InitExpr = VD ? SimpleRefExpr : Ref;
16424 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
16425 /*DirectInit=*/false);
16426 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
16427
16428 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
16429 Vars.push_back((VD || CurContext->isDependentContext())
16430 ? RefExpr->IgnoreParens()
16431 : Ref);
16432 Privates.push_back(PrivateRef);
16433 Inits.push_back(InitRef);
16434 }
16435
16436 if (Vars.empty())
16437 return nullptr;
16438
16439 Expr *StepExpr = Step;
16440 Expr *CalcStepExpr = nullptr;
16441 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
16442 !Step->isInstantiationDependent() &&
16443 !Step->containsUnexpandedParameterPack()) {
16444 SourceLocation StepLoc = Step->getBeginLoc();
16445 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
16446 if (Val.isInvalid())
16447 return nullptr;
16448 StepExpr = Val.get();
16449
16450 // Build var to save the step value.
16451 VarDecl *SaveVar =
16452 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
16453 ExprResult SaveRef =
16454 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
16455 ExprResult CalcStep =
16456 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
16457 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
16458
16459 // Warn about zero linear step (it would be probably better specified as
16460 // making corresponding variables 'const').
16461 if (Optional<llvm::APSInt> Result =
16462 StepExpr->getIntegerConstantExpr(Context)) {
16463 if (!Result->isNegative() && !Result->isStrictlyPositive())
16464 Diag(StepLoc, diag::warn_omp_linear_step_zero)
16465 << Vars[0] << (Vars.size() > 1);
16466 } else if (CalcStep.isUsable()) {
16467 // Calculate the step beforehand instead of doing this on each iteration.
16468 // (This is not used if the number of iterations may be kfold-ed).
16469 CalcStepExpr = CalcStep.get();
16470 }
16471 }
16472
16473 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
16474 ColonLoc, EndLoc, Vars, Privates, Inits,
16475 StepExpr, CalcStepExpr,
16476 buildPreInits(Context, ExprCaptures),
16477 buildPostUpdate(*this, ExprPostUpdates));
16478}
16479
16480static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
16481 Expr *NumIterations, Sema &SemaRef,
16482 Scope *S, DSAStackTy *Stack) {
16483 // Walk the vars and build update/final expressions for the CodeGen.
16484 SmallVector<Expr *, 8> Updates;
16485 SmallVector<Expr *, 8> Finals;
16486 SmallVector<Expr *, 8> UsedExprs;
16487 Expr *Step = Clause.getStep();
16488 Expr *CalcStep = Clause.getCalcStep();
16489 // OpenMP [2.14.3.7, linear clause]
16490 // If linear-step is not specified it is assumed to be 1.
16491 if (!Step)
16492 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
16493 else if (CalcStep)
16494 Step = cast<BinaryOperator>(CalcStep)->getLHS();
16495 bool HasErrors = false;
16496 auto CurInit = Clause.inits().begin();
16497 auto CurPrivate = Clause.privates().begin();
16498 OpenMPLinearClauseKind LinKind = Clause.getModifier();
16499 for (Expr *RefExpr : Clause.varlists()) {
16500 SourceLocation ELoc;
16501 SourceRange ERange;
16502 Expr *SimpleRefExpr = RefExpr;
16503 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
16504 ValueDecl *D = Res.first;
16505 if (Res.second || !D) {
16506 Updates.push_back(nullptr);
16507 Finals.push_back(nullptr);
16508 HasErrors = true;
16509 continue;
16510 }
16511 auto &&Info = Stack->isLoopControlVariable(D);
16512 // OpenMP [2.15.11, distribute simd Construct]
16513 // A list item may not appear in a linear clause, unless it is the loop
16514 // iteration variable.
16515 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
16516 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
16517 SemaRef.Diag(ELoc,
16518 diag::err_omp_linear_distribute_var_non_loop_iteration);
16519 Updates.push_back(nullptr);
16520 Finals.push_back(nullptr);
16521 HasErrors = true;
16522 continue;
16523 }
16524 Expr *InitExpr = *CurInit;
16525
16526 // Build privatized reference to the current linear var.
16527 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
16528 Expr *CapturedRef;
16529 if (LinKind == OMPC_LINEAR_uval)
16530 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
16531 else
16532 CapturedRef =
16533 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
16534 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
16535 /*RefersToCapture=*/true);
16536
16537 // Build update: Var = InitExpr + IV * Step
16538 ExprResult Update;
16539 if (!Info.first)
16540 Update = buildCounterUpdate(
16541 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
16542 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
16543 else
16544 Update = *CurPrivate;
16545 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
16546 /*DiscardedValue*/ false);
16547
16548 // Build final: Var = InitExpr + NumIterations * Step
16549 ExprResult Final;
16550 if (!Info.first)
16551 Final =
16552 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
16553 InitExpr, NumIterations, Step, /*Subtract=*/false,
16554 /*IsNonRectangularLB=*/false);
16555 else
16556 Final = *CurPrivate;
16557 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
16558 /*DiscardedValue*/ false);
16559
16560 if (!Update.isUsable() || !Final.isUsable()) {
16561 Updates.push_back(nullptr);
16562 Finals.push_back(nullptr);
16563 UsedExprs.push_back(nullptr);
16564 HasErrors = true;
16565 } else {
16566 Updates.push_back(Update.get());
16567 Finals.push_back(Final.get());
16568 if (!Info.first)
16569 UsedExprs.push_back(SimpleRefExpr);
16570 }
16571 ++CurInit;
16572 ++CurPrivate;
16573 }
16574 if (Expr *S = Clause.getStep())
16575 UsedExprs.push_back(S);
16576 // Fill the remaining part with the nullptr.
16577 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
16578 Clause.setUpdates(Updates);
16579 Clause.setFinals(Finals);
16580 Clause.setUsedExprs(UsedExprs);
16581 return HasErrors;
16582}
16583
16584OMPClause *Sema::ActOnOpenMPAlignedClause(
16585 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
16586 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16587 SmallVector<Expr *, 8> Vars;
16588 for (Expr *RefExpr : VarList) {
16589 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 16589, __PRETTY_FUNCTION__))
;
16590 SourceLocation ELoc;
16591 SourceRange ERange;
16592 Expr *SimpleRefExpr = RefExpr;
16593 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16594 if (Res.second) {
16595 // It will be analyzed later.
16596 Vars.push_back(RefExpr);
16597 }
16598 ValueDecl *D = Res.first;
16599 if (!D)
16600 continue;
16601
16602 QualType QType = D->getType();
16603 auto *VD = dyn_cast<VarDecl>(D);
16604
16605 // OpenMP [2.8.1, simd construct, Restrictions]
16606 // The type of list items appearing in the aligned clause must be
16607 // array, pointer, reference to array, or reference to pointer.
16608 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16609 const Type *Ty = QType.getTypePtrOrNull();
16610 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
16611 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
16612 << QType << getLangOpts().CPlusPlus << ERange;
16613 bool IsDecl =
16614 !VD ||
16615 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16616 Diag(D->getLocation(),
16617 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16618 << D;
16619 continue;
16620 }
16621
16622 // OpenMP [2.8.1, simd construct, Restrictions]
16623 // A list-item cannot appear in more than one aligned clause.
16624 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
16625 Diag(ELoc, diag::err_omp_used_in_clause_twice)
16626 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
16627 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
16628 << getOpenMPClauseName(OMPC_aligned);
16629 continue;
16630 }
16631
16632 DeclRefExpr *Ref = nullptr;
16633 if (!VD && isOpenMPCapturedDecl(D))
16634 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16635 Vars.push_back(DefaultFunctionArrayConversion(
16636 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
16637 .get());
16638 }
16639
16640 // OpenMP [2.8.1, simd construct, Description]
16641 // The parameter of the aligned clause, alignment, must be a constant
16642 // positive integer expression.
16643 // If no optional parameter is specified, implementation-defined default
16644 // alignments for SIMD instructions on the target platforms are assumed.
16645 if (Alignment != nullptr) {
16646 ExprResult AlignResult =
16647 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
16648 if (AlignResult.isInvalid())
16649 return nullptr;
16650 Alignment = AlignResult.get();
16651 }
16652 if (Vars.empty())
16653 return nullptr;
16654
16655 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
16656 EndLoc, Vars, Alignment);
16657}
16658
16659OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
16660 SourceLocation StartLoc,
16661 SourceLocation LParenLoc,
16662 SourceLocation EndLoc) {
16663 SmallVector<Expr *, 8> Vars;
16664 SmallVector<Expr *, 8> SrcExprs;
16665 SmallVector<Expr *, 8> DstExprs;
16666 SmallVector<Expr *, 8> AssignmentOps;
16667 for (Expr *RefExpr : VarList) {
16668 assert(RefExpr && "NULL expr in OpenMP copyin clause.")((RefExpr && "NULL expr in OpenMP copyin clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 16668, __PRETTY_FUNCTION__))
;
16669 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16670 // It will be analyzed later.
16671 Vars.push_back(RefExpr);
16672 SrcExprs.push_back(nullptr);
16673 DstExprs.push_back(nullptr);
16674 AssignmentOps.push_back(nullptr);
16675 continue;
16676 }
16677
16678 SourceLocation ELoc = RefExpr->getExprLoc();
16679 // OpenMP [2.1, C/C++]
16680 // A list item is a variable name.
16681 // OpenMP [2.14.4.1, Restrictions, p.1]
16682 // A list item that appears in a copyin clause must be threadprivate.
16683 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
16684 if (!DE || !isa<VarDecl>(DE->getDecl())) {
16685 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
16686 << 0 << RefExpr->getSourceRange();
16687 continue;
16688 }
16689
16690 Decl *D = DE->getDecl();
16691 auto *VD = cast<VarDecl>(D);
16692
16693 QualType Type = VD->getType();
16694 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16695 // It will be analyzed later.
16696 Vars.push_back(DE);
16697 SrcExprs.push_back(nullptr);
16698 DstExprs.push_back(nullptr);
16699 AssignmentOps.push_back(nullptr);
16700 continue;
16701 }
16702
16703 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16704 // A list item that appears in a copyin clause must be threadprivate.
16705 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16706 Diag(ELoc, diag::err_omp_required_access)
16707 << getOpenMPClauseName(OMPC_copyin)
16708 << getOpenMPDirectiveName(OMPD_threadprivate);
16709 continue;
16710 }
16711
16712 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16713 // A variable of class type (or array thereof) that appears in a
16714 // copyin clause requires an accessible, unambiguous copy assignment
16715 // operator for the class type.
16716 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16717 VarDecl *SrcVD =
16718 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16719 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16720 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16721 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16722 VarDecl *DstVD =
16723 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16724 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16725 DeclRefExpr *PseudoDstExpr =
16726 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16727 // For arrays generate assignment operation for single element and replace
16728 // it by the original array element in CodeGen.
16729 ExprResult AssignmentOp =
16730 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16731 PseudoSrcExpr);
16732 if (AssignmentOp.isInvalid())
16733 continue;
16734 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16735 /*DiscardedValue*/ false);
16736 if (AssignmentOp.isInvalid())
16737 continue;
16738
16739 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
16740 Vars.push_back(DE);
16741 SrcExprs.push_back(PseudoSrcExpr);
16742 DstExprs.push_back(PseudoDstExpr);
16743 AssignmentOps.push_back(AssignmentOp.get());
16744 }
16745
16746 if (Vars.empty())
16747 return nullptr;
16748
16749 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16750 SrcExprs, DstExprs, AssignmentOps);
16751}
16752
16753OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16754 SourceLocation StartLoc,
16755 SourceLocation LParenLoc,
16756 SourceLocation EndLoc) {
16757 SmallVector<Expr *, 8> Vars;
16758 SmallVector<Expr *, 8> SrcExprs;
16759 SmallVector<Expr *, 8> DstExprs;
16760 SmallVector<Expr *, 8> AssignmentOps;
16761 for (Expr *RefExpr : VarList) {
16762 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 16762, __PRETTY_FUNCTION__))
;
16763 SourceLocation ELoc;
16764 SourceRange ERange;
16765 Expr *SimpleRefExpr = RefExpr;
16766 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16767 if (Res.second) {
16768 // It will be analyzed later.
16769 Vars.push_back(RefExpr);
16770 SrcExprs.push_back(nullptr);
16771 DstExprs.push_back(nullptr);
16772 AssignmentOps.push_back(nullptr);
16773 }
16774 ValueDecl *D = Res.first;
16775 if (!D)
16776 continue;
16777
16778 QualType Type = D->getType();
16779 auto *VD = dyn_cast<VarDecl>(D);
16780
16781 // OpenMP [2.14.4.2, Restrictions, p.2]
16782 // A list item that appears in a copyprivate clause may not appear in a
16783 // private or firstprivate clause on the single construct.
16784 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16785 DSAStackTy::DSAVarData DVar =
16786 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16787 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16788 DVar.RefExpr) {
16789 Diag(ELoc, diag::err_omp_wrong_dsa)
16790 << getOpenMPClauseName(DVar.CKind)
16791 << getOpenMPClauseName(OMPC_copyprivate);
16792 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16793 continue;
16794 }
16795
16796 // OpenMP [2.11.4.2, Restrictions, p.1]
16797 // All list items that appear in a copyprivate clause must be either
16798 // threadprivate or private in the enclosing context.
16799 if (DVar.CKind == OMPC_unknown) {
16800 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
16801 if (DVar.CKind == OMPC_shared) {
16802 Diag(ELoc, diag::err_omp_required_access)
16803 << getOpenMPClauseName(OMPC_copyprivate)
16804 << "threadprivate or private in the enclosing context";
16805 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16806 continue;
16807 }
16808 }
16809 }
16810
16811 // Variably modified types are not supported.
16812 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16813 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16814 << getOpenMPClauseName(OMPC_copyprivate) << Type
16815 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
16816 bool IsDecl =
16817 !VD ||
16818 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16819 Diag(D->getLocation(),
16820 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16821 << D;
16822 continue;
16823 }
16824
16825 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16826 // A variable of class type (or array thereof) that appears in a
16827 // copyin clause requires an accessible, unambiguous copy assignment
16828 // operator for the class type.
16829 Type = Context.getBaseElementType(Type.getNonReferenceType())
16830 .getUnqualifiedType();
16831 VarDecl *SrcVD =
16832 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16833 D->hasAttrs() ? &D->getAttrs() : nullptr);
16834 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16835 VarDecl *DstVD =
16836 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16837 D->hasAttrs() ? &D->getAttrs() : nullptr);
16838 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16839 ExprResult AssignmentOp = BuildBinOp(
16840 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16841 if (AssignmentOp.isInvalid())
16842 continue;
16843 AssignmentOp =
16844 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16845 if (AssignmentOp.isInvalid())
16846 continue;
16847
16848 // No need to mark vars as copyprivate, they are already threadprivate or
16849 // implicitly private.
16850 assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0
) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 16850, __PRETTY_FUNCTION__))
;
16851 Vars.push_back(
16852 VD ? RefExpr->IgnoreParens()
16853 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16854 SrcExprs.push_back(PseudoSrcExpr);
16855 DstExprs.push_back(PseudoDstExpr);
16856 AssignmentOps.push_back(AssignmentOp.get());
16857 }
16858
16859 if (Vars.empty())
16860 return nullptr;
16861
16862 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16863 Vars, SrcExprs, DstExprs, AssignmentOps);
16864}
16865
16866OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16867 SourceLocation StartLoc,
16868 SourceLocation LParenLoc,
16869 SourceLocation EndLoc) {
16870 if (VarList.empty())
16871 return nullptr;
16872
16873 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16874}
16875
16876/// Tries to find omp_depend_t. type.
16877static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16878 bool Diagnose = true) {
16879 QualType OMPDependT = Stack->getOMPDependT();
16880 if (!OMPDependT.isNull())
16881 return true;
16882 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16883 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16884 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16885 if (Diagnose)
16886 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16887 return false;
16888 }
16889 Stack->setOMPDependT(PT.get());
16890 return true;
16891}
16892
16893OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16894 SourceLocation LParenLoc,
16895 SourceLocation EndLoc) {
16896 if (!Depobj)
16897 return nullptr;
16898
16899 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
16900
16901 // OpenMP 5.0, 2.17.10.1 depobj Construct
16902 // depobj is an lvalue expression of type omp_depend_t.
16903 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16904 !Depobj->isInstantiationDependent() &&
16905 !Depobj->containsUnexpandedParameterPack() &&
16906 (OMPDependTFound &&
16907 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
16908 /*CompareUnqualified=*/true))) {
16909 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16910 << 0 << Depobj->getType() << Depobj->getSourceRange();
16911 }
16912
16913 if (!Depobj->isLValue()) {
16914 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16915 << 1 << Depobj->getSourceRange();
16916 }
16917
16918 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16919}
16920
16921OMPClause *
16922Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16923 SourceLocation DepLoc, SourceLocation ColonLoc,
16924 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16925 SourceLocation LParenLoc, SourceLocation EndLoc) {
16926 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
16927 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16928 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16929 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16930 return nullptr;
16931 }
16932 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
16933 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16934 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16935 DepKind == OMPC_DEPEND_sink ||
16936 ((LangOpts.OpenMP < 50 ||
16937 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16938 DepKind == OMPC_DEPEND_depobj))) {
16939 SmallVector<unsigned, 3> Except;
16940 Except.push_back(OMPC_DEPEND_source);
16941 Except.push_back(OMPC_DEPEND_sink);
16942 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
16943 Except.push_back(OMPC_DEPEND_depobj);
16944 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16945 ? "depend modifier(iterator) or "
16946 : "";
16947 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16948 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16949 /*Last=*/OMPC_DEPEND_unknown,
16950 Except)
16951 << getOpenMPClauseName(OMPC_depend);
16952 return nullptr;
16953 }
16954 if (DepModifier &&
16955 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16956 Diag(DepModifier->getExprLoc(),
16957 diag::err_omp_depend_sink_source_with_modifier);
16958 return nullptr;
16959 }
16960 if (DepModifier &&
16961 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16962 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16963
16964 SmallVector<Expr *, 8> Vars;
16965 DSAStackTy::OperatorOffsetTy OpsOffs;
16966 llvm::APSInt DepCounter(/*BitWidth=*/32);
16967 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16968 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16969 if (const Expr *OrderedCountExpr =
16970 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
16971 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16972 TotalDepCount.setIsUnsigned(/*Val=*/true);
16973 }
16974 }
16975 for (Expr *RefExpr : VarList) {
16976 assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 16976, __PRETTY_FUNCTION__))
;
16977 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16978 // It will be analyzed later.
16979 Vars.push_back(RefExpr);
16980 continue;
16981 }
16982
16983 SourceLocation ELoc = RefExpr->getExprLoc();
16984 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16985 if (DepKind == OMPC_DEPEND_sink) {
16986 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16987 DepCounter >= TotalDepCount) {
16988 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16989 continue;
16990 }
16991 ++DepCounter;
16992 // OpenMP [2.13.9, Summary]
16993 // depend(dependence-type : vec), where dependence-type is:
16994 // 'sink' and where vec is the iteration vector, which has the form:
16995 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16996 // where n is the value specified by the ordered clause in the loop
16997 // directive, xi denotes the loop iteration variable of the i-th nested
16998 // loop associated with the loop directive, and di is a constant
16999 // non-negative integer.
17000 if (CurContext->isDependentContext()) {
17001 // It will be analyzed later.
17002 Vars.push_back(RefExpr);
17003 continue;
17004 }
17005 SimpleExpr = SimpleExpr->IgnoreImplicit();
17006 OverloadedOperatorKind OOK = OO_None;
17007 SourceLocation OOLoc;
17008 Expr *LHS = SimpleExpr;
17009 Expr *RHS = nullptr;
17010 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
17011 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
17012 OOLoc = BO->getOperatorLoc();
17013 LHS = BO->getLHS()->IgnoreParenImpCasts();
17014 RHS = BO->getRHS()->IgnoreParenImpCasts();
17015 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
17016 OOK = OCE->getOperator();
17017 OOLoc = OCE->getOperatorLoc();
17018 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17019 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
17020 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
17021 OOK = MCE->getMethodDecl()
17022 ->getNameInfo()
17023 .getName()
17024 .getCXXOverloadedOperator();
17025 OOLoc = MCE->getCallee()->getExprLoc();
17026 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
17027 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17028 }
17029 SourceLocation ELoc;
17030 SourceRange ERange;
17031 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
17032 if (Res.second) {
17033 // It will be analyzed later.
17034 Vars.push_back(RefExpr);
17035 }
17036 ValueDecl *D = Res.first;
17037 if (!D)
17038 continue;
17039
17040 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
17041 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
17042 continue;
17043 }
17044 if (RHS) {
17045 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
17046 RHS, OMPC_depend, /*StrictlyPositive=*/false);
17047 if (RHSRes.isInvalid())
17048 continue;
17049 }
17050 if (!CurContext->isDependentContext() &&
17051 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
17052 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
17053 const ValueDecl *VD =
17054 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
17055 if (VD)
17056 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
17057 << 1 << VD;
17058 else
17059 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
17060 continue;
17061 }
17062 OpsOffs.emplace_back(RHS, OOK);
17063 } else {
17064 bool OMPDependTFound = LangOpts.OpenMP >= 50;
17065 if (OMPDependTFound)
17066 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
17067 DepKind == OMPC_DEPEND_depobj);
17068 if (DepKind == OMPC_DEPEND_depobj) {
17069 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17070 // List items used in depend clauses with the depobj dependence type
17071 // must be expressions of the omp_depend_t type.
17072 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17073 !RefExpr->isInstantiationDependent() &&
17074 !RefExpr->containsUnexpandedParameterPack() &&
17075 (OMPDependTFound &&
17076 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
17077 RefExpr->getType()))) {
17078 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17079 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
17080 continue;
17081 }
17082 if (!RefExpr->isLValue()) {
17083 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17084 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
17085 continue;
17086 }
17087 } else {
17088 // OpenMP 5.0 [2.17.11, Restrictions]
17089 // List items used in depend clauses cannot be zero-length array
17090 // sections.
17091 QualType ExprTy = RefExpr->getType().getNonReferenceType();
17092 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
17093 if (OASE) {
17094 QualType BaseType =
17095 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17096 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17097 ExprTy = ATy->getElementType();
17098 else
17099 ExprTy = BaseType->getPointeeType();
17100 ExprTy = ExprTy.getNonReferenceType();
17101 const Expr *Length = OASE->getLength();
17102 Expr::EvalResult Result;
17103 if (Length && !Length->isValueDependent() &&
17104 Length->EvaluateAsInt(Result, Context) &&
17105 Result.Val.getInt().isNullValue()) {
17106 Diag(ELoc,
17107 diag::err_omp_depend_zero_length_array_section_not_allowed)
17108 << SimpleExpr->getSourceRange();
17109 continue;
17110 }
17111 }
17112
17113 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17114 // List items used in depend clauses with the in, out, inout or
17115 // mutexinoutset dependence types cannot be expressions of the
17116 // omp_depend_t type.
17117 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17118 !RefExpr->isInstantiationDependent() &&
17119 !RefExpr->containsUnexpandedParameterPack() &&
17120 (OMPDependTFound &&
17121 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
17122 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17123 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
17124 << RefExpr->getSourceRange();
17125 continue;
17126 }
17127
17128 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
17129 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
17130 (ASE && !ASE->getBase()->isTypeDependent() &&
17131 !ASE->getBase()
17132 ->getType()
17133 .getNonReferenceType()
17134 ->isPointerType() &&
17135 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
17136 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17137 << (LangOpts.OpenMP >= 50 ? 1 : 0)
17138 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17139 continue;
17140 }
17141
17142 ExprResult Res;
17143 {
17144 Sema::TentativeAnalysisScope Trap(*this);
17145 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
17146 RefExpr->IgnoreParenImpCasts());
17147 }
17148 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
17149 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
17150 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17151 << (LangOpts.OpenMP >= 50 ? 1 : 0)
17152 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17153 continue;
17154 }
17155 }
17156 }
17157 Vars.push_back(RefExpr->IgnoreParenImpCasts());
17158 }
17159
17160 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
17161 TotalDepCount > VarList.size() &&
17162 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
17163 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
17164 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
17165 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
17166 }
17167 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
17168 Vars.empty())
17169 return nullptr;
17170
17171 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17172 DepModifier, DepKind, DepLoc, ColonLoc,
17173 Vars, TotalDepCount.getZExtValue());
17174 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
17175 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
17176 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
17177 return C;
17178}
17179
17180OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
17181 Expr *Device, SourceLocation StartLoc,
17182 SourceLocation LParenLoc,
17183 SourceLocation ModifierLoc,
17184 SourceLocation EndLoc) {
17185 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
"Unexpected device modifier in OpenMP < 50.") ? static_cast
<void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17186, __PRETTY_FUNCTION__))
17186 "Unexpected device modifier in OpenMP < 50.")(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
"Unexpected device modifier in OpenMP < 50.") ? static_cast
<void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17186, __PRETTY_FUNCTION__))
;
17187
17188 bool ErrorFound = false;
17189 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
17190 std::string Values =
17191 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
17192 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
17193 << Values << getOpenMPClauseName(OMPC_device);
17194 ErrorFound = true;
17195 }
17196
17197 Expr *ValExpr = Device;
17198 Stmt *HelperValStmt = nullptr;
17199
17200 // OpenMP [2.9.1, Restrictions]
17201 // The device expression must evaluate to a non-negative integer value.
17202 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
17203 /*StrictlyPositive=*/false) ||
17204 ErrorFound;
17205 if (ErrorFound)
17206 return nullptr;
17207
17208 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17209 OpenMPDirectiveKind CaptureRegion =
17210 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
17211 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17212 ValExpr = MakeFullExpr(ValExpr).get();
17213 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17214 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17215 HelperValStmt = buildPreInits(Context, Captures);
17216 }
17217
17218 return new (Context)
17219 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
17220 LParenLoc, ModifierLoc, EndLoc);
17221}
17222
17223static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
17224 DSAStackTy *Stack, QualType QTy,
17225 bool FullCheck = true) {
17226 NamedDecl *ND;
17227 if (QTy->isIncompleteType(&ND)) {
17228 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
17229 return false;
17230 }
17231 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
17232 !QTy.isTriviallyCopyableType(SemaRef.Context))
17233 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
17234 return true;
17235}
17236
17237/// Return true if it can be proven that the provided array expression
17238/// (array section or array subscript) does NOT specify the whole size of the
17239/// array whose base type is \a BaseQTy.
17240static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
17241 const Expr *E,
17242 QualType BaseQTy) {
17243 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
17244
17245 // If this is an array subscript, it refers to the whole size if the size of
17246 // the dimension is constant and equals 1. Also, an array section assumes the
17247 // format of an array subscript if no colon is used.
17248 if (isa<ArraySubscriptExpr>(E) ||
17249 (OASE && OASE->getColonLocFirst().isInvalid())) {
17250 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
17251 return ATy->getSize().getSExtValue() != 1;
17252 // Size can't be evaluated statically.
17253 return false;
17254 }
17255
17256 assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript."
) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17256, __PRETTY_FUNCTION__))
;
17257 const Expr *LowerBound = OASE->getLowerBound();
17258 const Expr *Length = OASE->getLength();
17259
17260 // If there is a lower bound that does not evaluates to zero, we are not
17261 // covering the whole dimension.
17262 if (LowerBound) {
17263 Expr::EvalResult Result;
17264 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
17265 return false; // Can't get the integer value as a constant.
17266
17267 llvm::APSInt ConstLowerBound = Result.Val.getInt();
17268 if (ConstLowerBound.getSExtValue())
17269 return true;
17270 }
17271
17272 // If we don't have a length we covering the whole dimension.
17273 if (!Length)
17274 return false;
17275
17276 // If the base is a pointer, we don't have a way to get the size of the
17277 // pointee.
17278 if (BaseQTy->isPointerType())
17279 return false;
17280
17281 // We can only check if the length is the same as the size of the dimension
17282 // if we have a constant array.
17283 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
17284 if (!CATy)
17285 return false;
17286
17287 Expr::EvalResult Result;
17288 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
17289 return false; // Can't get the integer value as a constant.
17290
17291 llvm::APSInt ConstLength = Result.Val.getInt();
17292 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
17293}
17294
17295// Return true if it can be proven that the provided array expression (array
17296// section or array subscript) does NOT specify a single element of the array
17297// whose base type is \a BaseQTy.
17298static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
17299 const Expr *E,
17300 QualType BaseQTy) {
17301 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
17302
17303 // An array subscript always refer to a single element. Also, an array section
17304 // assumes the format of an array subscript if no colon is used.
17305 if (isa<ArraySubscriptExpr>(E) ||
17306 (OASE && OASE->getColonLocFirst().isInvalid()))
17307 return false;
17308
17309 assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript."
) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17309, __PRETTY_FUNCTION__))
;
17310 const Expr *Length = OASE->getLength();
17311
17312 // If we don't have a length we have to check if the array has unitary size
17313 // for this dimension. Also, we should always expect a length if the base type
17314 // is pointer.
17315 if (!Length) {
17316 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
17317 return ATy->getSize().getSExtValue() != 1;
17318 // We cannot assume anything.
17319 return false;
17320 }
17321
17322 // Check if the length evaluates to 1.
17323 Expr::EvalResult Result;
17324 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
17325 return false; // Can't get the integer value as a constant.
17326
17327 llvm::APSInt ConstLength = Result.Val.getInt();
17328 return ConstLength.getSExtValue() != 1;
17329}
17330
17331// The base of elements of list in a map clause have to be either:
17332// - a reference to variable or field.
17333// - a member expression.
17334// - an array expression.
17335//
17336// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
17337// reference to 'r'.
17338//
17339// If we have:
17340//
17341// struct SS {
17342// Bla S;
17343// foo() {
17344// #pragma omp target map (S.Arr[:12]);
17345// }
17346// }
17347//
17348// We want to retrieve the member expression 'this->S';
17349
17350// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
17351// If a list item is an array section, it must specify contiguous storage.
17352//
17353// For this restriction it is sufficient that we make sure only references
17354// to variables or fields and array expressions, and that no array sections
17355// exist except in the rightmost expression (unless they cover the whole
17356// dimension of the array). E.g. these would be invalid:
17357//
17358// r.ArrS[3:5].Arr[6:7]
17359//
17360// r.ArrS[3:5].x
17361//
17362// but these would be valid:
17363// r.ArrS[3].Arr[6:7]
17364//
17365// r.ArrS[3].x
17366namespace {
17367class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
17368 Sema &SemaRef;
17369 OpenMPClauseKind CKind = OMPC_unknown;
17370 OpenMPDirectiveKind DKind = OMPD_unknown;
17371 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
17372 bool IsNonContiguous = false;
17373 bool NoDiagnose = false;
17374 const Expr *RelevantExpr = nullptr;
17375 bool AllowUnitySizeArraySection = true;
17376 bool AllowWholeSizeArraySection = true;
17377 bool AllowAnotherPtr = true;
17378 SourceLocation ELoc;
17379 SourceRange ERange;
17380
17381 void emitErrorMsg() {
17382 // If nothing else worked, this is not a valid map clause expression.
17383 if (SemaRef.getLangOpts().OpenMP < 50) {
17384 SemaRef.Diag(ELoc,
17385 diag::err_omp_expected_named_var_member_or_array_expression)
17386 << ERange;
17387 } else {
17388 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17389 << getOpenMPClauseName(CKind) << ERange;
17390 }
17391 }
17392
17393public:
17394 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
17395 if (!isa<VarDecl>(DRE->getDecl())) {
17396 emitErrorMsg();
17397 return false;
17398 }
17399 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17399, __PRETTY_FUNCTION__))
;
17400 RelevantExpr = DRE;
17401 // Record the component.
17402 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
17403 return true;
17404 }
17405
17406 bool VisitMemberExpr(MemberExpr *ME) {
17407 Expr *E = ME;
17408 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
17409
17410 if (isa<CXXThisExpr>(BaseE)) {
17411 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17411, __PRETTY_FUNCTION__))
;
17412 // We found a base expression: this->Val.
17413 RelevantExpr = ME;
17414 } else {
17415 E = BaseE;
17416 }
17417
17418 if (!isa<FieldDecl>(ME->getMemberDecl())) {
17419 if (!NoDiagnose) {
17420 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
17421 << ME->getSourceRange();
17422 return false;
17423 }
17424 if (RelevantExpr)
17425 return false;
17426 return Visit(E);
17427 }
17428
17429 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
17430
17431 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
17432 // A bit-field cannot appear in a map clause.
17433 //
17434 if (FD->isBitField()) {
17435 if (!NoDiagnose) {
17436 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
17437 << ME->getSourceRange() << getOpenMPClauseName(CKind);
17438 return false;
17439 }
17440 if (RelevantExpr)
17441 return false;
17442 return Visit(E);
17443 }
17444
17445 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17446 // If the type of a list item is a reference to a type T then the type
17447 // will be considered to be T for all purposes of this clause.
17448 QualType CurType = BaseE->getType().getNonReferenceType();
17449
17450 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
17451 // A list item cannot be a variable that is a member of a structure with
17452 // a union type.
17453 //
17454 if (CurType->isUnionType()) {
17455 if (!NoDiagnose) {
17456 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
17457 << ME->getSourceRange();
17458 return false;
17459 }
17460 return RelevantExpr || Visit(E);
17461 }
17462
17463 // If we got a member expression, we should not expect any array section
17464 // before that:
17465 //
17466 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
17467 // If a list item is an element of a structure, only the rightmost symbol
17468 // of the variable reference can be an array section.
17469 //
17470 AllowUnitySizeArraySection = false;
17471 AllowWholeSizeArraySection = false;
17472
17473 // Record the component.
17474 Components.emplace_back(ME, FD, IsNonContiguous);
17475 return RelevantExpr || Visit(E);
17476 }
17477
17478 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
17479 Expr *E = AE->getBase()->IgnoreParenImpCasts();
17480
17481 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
17482 if (!NoDiagnose) {
17483 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17484 << 0 << AE->getSourceRange();
17485 return false;
17486 }
17487 return RelevantExpr || Visit(E);
17488 }
17489
17490 // If we got an array subscript that express the whole dimension we
17491 // can have any array expressions before. If it only expressing part of
17492 // the dimension, we can only have unitary-size array expressions.
17493 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
17494 E->getType()))
17495 AllowWholeSizeArraySection = false;
17496
17497 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
17498 Expr::EvalResult Result;
17499 if (!AE->getIdx()->isValueDependent() &&
17500 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
17501 !Result.Val.getInt().isNullValue()) {
17502 SemaRef.Diag(AE->getIdx()->getExprLoc(),
17503 diag::err_omp_invalid_map_this_expr);
17504 SemaRef.Diag(AE->getIdx()->getExprLoc(),
17505 diag::note_omp_invalid_subscript_on_this_ptr_map);
17506 }
17507 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17507, __PRETTY_FUNCTION__))
;
17508 RelevantExpr = TE;
17509 }
17510
17511 // Record the component - we don't have any declaration associated.
17512 Components.emplace_back(AE, nullptr, IsNonContiguous);
17513
17514 return RelevantExpr || Visit(E);
17515 }
17516
17517 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
17518 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.")((!NoDiagnose && "Array sections cannot be implicitly mapped."
) ? static_cast<void> (0) : __assert_fail ("!NoDiagnose && \"Array sections cannot be implicitly mapped.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17518, __PRETTY_FUNCTION__))
;
17519 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17520 QualType CurType =
17521 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17522
17523 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17524 // If the type of a list item is a reference to a type T then the type
17525 // will be considered to be T for all purposes of this clause.
17526 if (CurType->isReferenceType())
17527 CurType = CurType->getPointeeType();
17528
17529 bool IsPointer = CurType->isAnyPointerType();
17530
17531 if (!IsPointer && !CurType->isArrayType()) {
17532 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17533 << 0 << OASE->getSourceRange();
17534 return false;
17535 }
17536
17537 bool NotWhole =
17538 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
17539 bool NotUnity =
17540 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
17541
17542 if (AllowWholeSizeArraySection) {
17543 // Any array section is currently allowed. Allowing a whole size array
17544 // section implies allowing a unity array section as well.
17545 //
17546 // If this array section refers to the whole dimension we can still
17547 // accept other array sections before this one, except if the base is a
17548 // pointer. Otherwise, only unitary sections are accepted.
17549 if (NotWhole || IsPointer)
17550 AllowWholeSizeArraySection = false;
17551 } else if (DKind == OMPD_target_update &&
17552 SemaRef.getLangOpts().OpenMP >= 50) {
17553 if (IsPointer && !AllowAnotherPtr)
17554 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
17555 << /*array of unknown bound */ 1;
17556 else
17557 IsNonContiguous = true;
17558 } else if (AllowUnitySizeArraySection && NotUnity) {
17559 // A unity or whole array section is not allowed and that is not
17560 // compatible with the properties of the current array section.
17561 SemaRef.Diag(
17562 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
17563 << OASE->getSourceRange();
17564 return false;
17565 }
17566
17567 if (IsPointer)
17568 AllowAnotherPtr = false;
17569
17570 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
17571 Expr::EvalResult ResultR;
17572 Expr::EvalResult ResultL;
17573 if (!OASE->getLength()->isValueDependent() &&
17574 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
17575 !ResultR.Val.getInt().isOneValue()) {
17576 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17577 diag::err_omp_invalid_map_this_expr);
17578 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17579 diag::note_omp_invalid_length_on_this_ptr_mapping);
17580 }
17581 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
17582 OASE->getLowerBound()->EvaluateAsInt(ResultL,
17583 SemaRef.getASTContext()) &&
17584 !ResultL.Val.getInt().isNullValue()) {
17585 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17586 diag::err_omp_invalid_map_this_expr);
17587 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17588 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
17589 }
17590 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17590, __PRETTY_FUNCTION__))
;
17591 RelevantExpr = TE;
17592 }
17593
17594 // Record the component - we don't have any declaration associated.
17595 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
17596 return RelevantExpr || Visit(E);
17597 }
17598 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
17599 Expr *Base = E->getBase();
17600
17601 // Record the component - we don't have any declaration associated.
17602 Components.emplace_back(E, nullptr, IsNonContiguous);
17603
17604 return Visit(Base->IgnoreParenImpCasts());
17605 }
17606
17607 bool VisitUnaryOperator(UnaryOperator *UO) {
17608 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
17609 UO->getOpcode() != UO_Deref) {
17610 emitErrorMsg();
17611 return false;
17612 }
17613 if (!RelevantExpr) {
17614 // Record the component if haven't found base decl.
17615 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
17616 }
17617 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
17618 }
17619 bool VisitBinaryOperator(BinaryOperator *BO) {
17620 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
17621 emitErrorMsg();
17622 return false;
17623 }
17624
17625 // Pointer arithmetic is the only thing we expect to happen here so after we
17626 // make sure the binary operator is a pointer type, the we only thing need
17627 // to to is to visit the subtree that has the same type as root (so that we
17628 // know the other subtree is just an offset)
17629 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
17630 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
17631 Components.emplace_back(BO, nullptr, false);
17632 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17634, __PRETTY_FUNCTION__))
17633 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17634, __PRETTY_FUNCTION__))
17634 "Either LHS or RHS have base decl inside")(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17634, __PRETTY_FUNCTION__))
;
17635 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
17636 return RelevantExpr || Visit(LE);
17637 return RelevantExpr || Visit(RE);
17638 }
17639 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
17640 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17640, __PRETTY_FUNCTION__))
;
17641 RelevantExpr = CTE;
17642 Components.emplace_back(CTE, nullptr, IsNonContiguous);
17643 return true;
17644 }
17645 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
17646 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17646, __PRETTY_FUNCTION__))
;
17647 Components.emplace_back(COCE, nullptr, IsNonContiguous);
17648 return true;
17649 }
17650 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
17651 Expr *Source = E->getSourceExpr();
17652 if (!Source) {
17653 emitErrorMsg();
17654 return false;
17655 }
17656 return Visit(Source);
17657 }
17658 bool VisitStmt(Stmt *) {
17659 emitErrorMsg();
17660 return false;
17661 }
17662 const Expr *getFoundBase() const {
17663 return RelevantExpr;
17664 }
17665 explicit MapBaseChecker(
17666 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
17667 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
17668 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
17669 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
17670 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
17671};
17672} // namespace
17673
17674/// Return the expression of the base of the mappable expression or null if it
17675/// cannot be determined and do all the necessary checks to see if the expression
17676/// is valid as a standalone mappable expression. In the process, record all the
17677/// components of the expression.
17678static const Expr *checkMapClauseExpressionBase(
17679 Sema &SemaRef, Expr *E,
17680 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
17681 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
17682 SourceLocation ELoc = E->getExprLoc();
17683 SourceRange ERange = E->getSourceRange();
17684 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
17685 ERange);
17686 if (Checker.Visit(E->IgnoreParens())) {
17687 // Check if the highest dimension array section has length specified
17688 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
17689 (CKind == OMPC_to || CKind == OMPC_from)) {
17690 auto CI = CurComponents.rbegin();
17691 auto CE = CurComponents.rend();
17692 for (; CI != CE; ++CI) {
17693 const auto *OASE =
17694 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
17695 if (!OASE)
17696 continue;
17697 if (OASE && OASE->getLength())
17698 break;
17699 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
17700 << ERange;
17701 }
17702 }
17703 return Checker.getFoundBase();
17704 }
17705 return nullptr;
17706}
17707
17708// Return true if expression E associated with value VD has conflicts with other
17709// map information.
17710static bool checkMapConflicts(
17711 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
17712 bool CurrentRegionOnly,
17713 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
17714 OpenMPClauseKind CKind) {
17715 assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail
("VD && E", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17715, __PRETTY_FUNCTION__))
;
17716 SourceLocation ELoc = E->getExprLoc();
17717 SourceRange ERange = E->getSourceRange();
17718
17719 // In order to easily check the conflicts we need to match each component of
17720 // the expression under test with the components of the expressions that are
17721 // already in the stack.
17722
17723 assert(!CurComponents.empty() && "Map clause expression with no components!")((!CurComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17723, __PRETTY_FUNCTION__))
;
17724 assert(CurComponents.back().getAssociatedDeclaration() == VD &&((CurComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17725, __PRETTY_FUNCTION__))
17725 "Map clause expression with unexpected base!")((CurComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17725, __PRETTY_FUNCTION__))
;
17726
17727 // Variables to help detecting enclosing problems in data environment nests.
17728 bool IsEnclosedByDataEnvironmentExpr = false;
17729 const Expr *EnclosingExpr = nullptr;
17730
17731 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17732 VD, CurrentRegionOnly,
17733 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17734 ERange, CKind, &EnclosingExpr,
17735 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17736 StackComponents,
17737 OpenMPClauseKind Kind) {
17738 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
17739 return false;
17740 assert(!StackComponents.empty() &&((!StackComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17741, __PRETTY_FUNCTION__))
17741 "Map clause expression with no components!")((!StackComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17741, __PRETTY_FUNCTION__))
;
17742 assert(StackComponents.back().getAssociatedDeclaration() == VD &&((StackComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17743, __PRETTY_FUNCTION__))
17743 "Map clause expression with unexpected base!")((StackComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17743, __PRETTY_FUNCTION__))
;
17744 (void)VD;
17745
17746 // The whole expression in the stack.
17747 const Expr *RE = StackComponents.front().getAssociatedExpression();
17748
17749 // Expressions must start from the same base. Here we detect at which
17750 // point both expressions diverge from each other and see if we can
17751 // detect if the memory referred to both expressions is contiguous and
17752 // do not overlap.
17753 auto CI = CurComponents.rbegin();
17754 auto CE = CurComponents.rend();
17755 auto SI = StackComponents.rbegin();
17756 auto SE = StackComponents.rend();
17757 for (; CI != CE && SI != SE; ++CI, ++SI) {
17758
17759 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17760 // At most one list item can be an array item derived from a given
17761 // variable in map clauses of the same construct.
17762 if (CurrentRegionOnly &&
17763 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17764 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17765 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17766 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17767 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17768 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17769 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17770 diag::err_omp_multiple_array_items_in_map_clause)
17771 << CI->getAssociatedExpression()->getSourceRange();
17772 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17773 diag::note_used_here)
17774 << SI->getAssociatedExpression()->getSourceRange();
17775 return true;
17776 }
17777
17778 // Do both expressions have the same kind?
17779 if (CI->getAssociatedExpression()->getStmtClass() !=
17780 SI->getAssociatedExpression()->getStmtClass())
17781 break;
17782
17783 // Are we dealing with different variables/fields?
17784 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17785 break;
17786 }
17787 // Check if the extra components of the expressions in the enclosing
17788 // data environment are redundant for the current base declaration.
17789 // If they are, the maps completely overlap, which is legal.
17790 for (; SI != SE; ++SI) {
17791 QualType Type;
17792 if (const auto *ASE =
17793 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17794 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17795 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17796 SI->getAssociatedExpression())) {
17797 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17798 Type =
17799 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17800 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17801 SI->getAssociatedExpression())) {
17802 Type = OASE->getBase()->getType()->getPointeeType();
17803 }
17804 if (Type.isNull() || Type->isAnyPointerType() ||
17805 checkArrayExpressionDoesNotReferToWholeSize(
17806 SemaRef, SI->getAssociatedExpression(), Type))
17807 break;
17808 }
17809
17810 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17811 // List items of map clauses in the same construct must not share
17812 // original storage.
17813 //
17814 // If the expressions are exactly the same or one is a subset of the
17815 // other, it means they are sharing storage.
17816 if (CI == CE && SI == SE) {
17817 if (CurrentRegionOnly) {
17818 if (CKind == OMPC_map) {
17819 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17820 } else {
17821 assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void
> (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17821, __PRETTY_FUNCTION__))
;
17822 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17823 << ERange;
17824 }
17825 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17826 << RE->getSourceRange();
17827 return true;
17828 }
17829 // If we find the same expression in the enclosing data environment,
17830 // that is legal.
17831 IsEnclosedByDataEnvironmentExpr = true;
17832 return false;
17833 }
17834
17835 QualType DerivedType =
17836 std::prev(CI)->getAssociatedDeclaration()->getType();
17837 SourceLocation DerivedLoc =
17838 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17839
17840 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17841 // If the type of a list item is a reference to a type T then the type
17842 // will be considered to be T for all purposes of this clause.
17843 DerivedType = DerivedType.getNonReferenceType();
17844
17845 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17846 // A variable for which the type is pointer and an array section
17847 // derived from that variable must not appear as list items of map
17848 // clauses of the same construct.
17849 //
17850 // Also, cover one of the cases in:
17851 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17852 // If any part of the original storage of a list item has corresponding
17853 // storage in the device data environment, all of the original storage
17854 // must have corresponding storage in the device data environment.
17855 //
17856 if (DerivedType->isAnyPointerType()) {
17857 if (CI == CE || SI == SE) {
17858 SemaRef.Diag(
17859 DerivedLoc,
17860 diag::err_omp_pointer_mapped_along_with_derived_section)
17861 << DerivedLoc;
17862 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17863 << RE->getSourceRange();
17864 return true;
17865 }
17866 if (CI->getAssociatedExpression()->getStmtClass() !=
17867 SI->getAssociatedExpression()->getStmtClass() ||
17868 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17869 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17870 assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0)
: __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17870, __PRETTY_FUNCTION__))
;
17871 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17872 << DerivedLoc;
17873 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17874 << RE->getSourceRange();
17875 return true;
17876 }
17877 }
17878
17879 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17880 // List items of map clauses in the same construct must not share
17881 // original storage.
17882 //
17883 // An expression is a subset of the other.
17884 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17885 if (CKind == OMPC_map) {
17886 if (CI != CE || SI != SE) {
17887 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17888 // a pointer.
17889 auto Begin =
17890 CI != CE ? CurComponents.begin() : StackComponents.begin();
17891 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17892 auto It = Begin;
17893 while (It != End && !It->getAssociatedDeclaration())
17894 std::advance(It, 1);
17895 assert(It != End &&((It != End && "Expected at least one component with the declaration."
) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17896, __PRETTY_FUNCTION__))
17896 "Expected at least one component with the declaration.")((It != End && "Expected at least one component with the declaration."
) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17896, __PRETTY_FUNCTION__))
;
17897 if (It != Begin && It->getAssociatedDeclaration()
17898 ->getType()
17899 .getCanonicalType()
17900 ->isAnyPointerType()) {
17901 IsEnclosedByDataEnvironmentExpr = false;
17902 EnclosingExpr = nullptr;
17903 return false;
17904 }
17905 }
17906 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17907 } else {
17908 assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void
> (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17908, __PRETTY_FUNCTION__))
;
17909 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17910 << ERange;
17911 }
17912 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17913 << RE->getSourceRange();
17914 return true;
17915 }
17916
17917 // The current expression uses the same base as other expression in the
17918 // data environment but does not contain it completely.
17919 if (!CurrentRegionOnly && SI != SE)
17920 EnclosingExpr = RE;
17921
17922 // The current expression is a subset of the expression in the data
17923 // environment.
17924 IsEnclosedByDataEnvironmentExpr |=
17925 (!CurrentRegionOnly && CI != CE && SI == SE);
17926
17927 return false;
17928 });
17929
17930 if (CurrentRegionOnly)
17931 return FoundError;
17932
17933 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17934 // If any part of the original storage of a list item has corresponding
17935 // storage in the device data environment, all of the original storage must
17936 // have corresponding storage in the device data environment.
17937 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17938 // If a list item is an element of a structure, and a different element of
17939 // the structure has a corresponding list item in the device data environment
17940 // prior to a task encountering the construct associated with the map clause,
17941 // then the list item must also have a corresponding list item in the device
17942 // data environment prior to the task encountering the construct.
17943 //
17944 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17945 SemaRef.Diag(ELoc,
17946 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17947 << ERange;
17948 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17949 << EnclosingExpr->getSourceRange();
17950 return true;
17951 }
17952
17953 return FoundError;
17954}
17955
17956// Look up the user-defined mapper given the mapper name and mapped type, and
17957// build a reference to it.
17958static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17959 CXXScopeSpec &MapperIdScopeSpec,
17960 const DeclarationNameInfo &MapperId,
17961 QualType Type,
17962 Expr *UnresolvedMapper) {
17963 if (MapperIdScopeSpec.isInvalid())
17964 return ExprError();
17965 // Get the actual type for the array type.
17966 if (Type->isArrayType()) {
17967 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")((Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"
) ? static_cast<void> (0) : __assert_fail ("Type->getAsArrayTypeUnsafe() && \"Expect to get a valid array type\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17967, __PRETTY_FUNCTION__))
;
17968 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17969 }
17970 // Find all user-defined mappers with the given MapperId.
17971 SmallVector<UnresolvedSet<8>, 4> Lookups;
17972 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17973 Lookup.suppressDiagnostics();
17974 if (S) {
17975 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17976 NamedDecl *D = Lookup.getRepresentativeDecl();
17977 while (S && !S->isDeclScope(D))
17978 S = S->getParent();
17979 if (S)
17980 S = S->getParent();
17981 Lookups.emplace_back();
17982 Lookups.back().append(Lookup.begin(), Lookup.end());
17983 Lookup.clear();
17984 }
17985 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17986 // Extract the user-defined mappers with the given MapperId.
17987 Lookups.push_back(UnresolvedSet<8>());
17988 for (NamedDecl *D : ULE->decls()) {
17989 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17990 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")((DMD && "Expect valid OMPDeclareMapperDecl during instantiation."
) ? static_cast<void> (0) : __assert_fail ("DMD && \"Expect valid OMPDeclareMapperDecl during instantiation.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 17990, __PRETTY_FUNCTION__))
;
17991 Lookups.back().addDecl(DMD);
17992 }
17993 }
17994 // Defer the lookup for dependent types. The results will be passed through
17995 // UnresolvedMapper on instantiation.
17996 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17997 Type->isInstantiationDependentType() ||
17998 Type->containsUnexpandedParameterPack() ||
17999 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18000 return !D->isInvalidDecl() &&
18001 (D->getType()->isDependentType() ||
18002 D->getType()->isInstantiationDependentType() ||
18003 D->getType()->containsUnexpandedParameterPack());
18004 })) {
18005 UnresolvedSet<8> URS;
18006 for (const UnresolvedSet<8> &Set : Lookups) {
18007 if (Set.empty())
18008 continue;
18009 URS.append(Set.begin(), Set.end());
18010 }
18011 return UnresolvedLookupExpr::Create(
18012 SemaRef.Context, /*NamingClass=*/nullptr,
18013 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
18014 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
18015 }
18016 SourceLocation Loc = MapperId.getLoc();
18017 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18018 // The type must be of struct, union or class type in C and C++
18019 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
18020 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
18021 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
18022 return ExprError();
18023 }
18024 // Perform argument dependent lookup.
18025 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
18026 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
18027 // Return the first user-defined mapper with the desired type.
18028 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18029 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
18030 if (!D->isInvalidDecl() &&
18031 SemaRef.Context.hasSameType(D->getType(), Type))
18032 return D;
18033 return nullptr;
18034 }))
18035 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18036 // Find the first user-defined mapper with a type derived from the desired
18037 // type.
18038 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18039 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
18040 if (!D->isInvalidDecl() &&
18041 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
18042 !Type.isMoreQualifiedThan(D->getType()))
18043 return D;
18044 return nullptr;
18045 })) {
18046 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18047 /*DetectVirtual=*/false);
18048 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
18049 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18050 VD->getType().getUnqualifiedType()))) {
18051 if (SemaRef.CheckBaseClassAccess(
18052 Loc, VD->getType(), Type, Paths.front(),
18053 /*DiagID=*/0) != Sema::AR_inaccessible) {
18054 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18055 }
18056 }
18057 }
18058 }
18059 // Report error if a mapper is specified, but cannot be found.
18060 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
18061 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
18062 << Type << MapperId.getName();
18063 return ExprError();
18064 }
18065 return ExprEmpty();
18066}
18067
18068namespace {
18069// Utility struct that gathers all the related lists associated with a mappable
18070// expression.
18071struct MappableVarListInfo {
18072 // The list of expressions.
18073 ArrayRef<Expr *> VarList;
18074 // The list of processed expressions.
18075 SmallVector<Expr *, 16> ProcessedVarList;
18076 // The mappble components for each expression.
18077 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
18078 // The base declaration of the variable.
18079 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
18080 // The reference to the user-defined mapper associated with every expression.
18081 SmallVector<Expr *, 16> UDMapperList;
18082
18083 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
18084 // We have a list of components and base declarations for each entry in the
18085 // variable list.
18086 VarComponents.reserve(VarList.size());
18087 VarBaseDeclarations.reserve(VarList.size());
18088 }
18089};
18090}
18091
18092// Check the validity of the provided variable list for the provided clause kind
18093// \a CKind. In the check process the valid expressions, mappable expression
18094// components, variables, and user-defined mappers are extracted and used to
18095// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
18096// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
18097// and \a MapperId are expected to be valid if the clause kind is 'map'.
18098static void checkMappableExpressionList(
18099 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
18100 MappableVarListInfo &MVLI, SourceLocation StartLoc,
18101 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
18102 ArrayRef<Expr *> UnresolvedMappers,
18103 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
18104 bool IsMapTypeImplicit = false) {
18105 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
18106 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from
) && "Unexpected clause kind with mappable expressions!"
) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18107, __PRETTY_FUNCTION__))
18107 "Unexpected clause kind with mappable expressions!")(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from
) && "Unexpected clause kind with mappable expressions!"
) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18107, __PRETTY_FUNCTION__))
;
18108
18109 // If the identifier of user-defined mapper is not specified, it is "default".
18110 // We do not change the actual name in this clause to distinguish whether a
18111 // mapper is specified explicitly, i.e., it is not explicitly specified when
18112 // MapperId.getName() is empty.
18113 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
18114 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
18115 MapperId.setName(DeclNames.getIdentifier(
18116 &SemaRef.getASTContext().Idents.get("default")));
18117 MapperId.setLoc(StartLoc);
18118 }
18119
18120 // Iterators to find the current unresolved mapper expression.
18121 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
18122 bool UpdateUMIt = false;
18123 Expr *UnresolvedMapper = nullptr;
18124
18125 // Keep track of the mappable components and base declarations in this clause.
18126 // Each entry in the list is going to have a list of components associated. We
18127 // record each set of the components so that we can build the clause later on.
18128 // In the end we should have the same amount of declarations and component
18129 // lists.
18130
18131 for (Expr *RE : MVLI.VarList) {
18132 assert(RE && "Null expr in omp to/from/map clause")((RE && "Null expr in omp to/from/map clause") ? static_cast
<void> (0) : __assert_fail ("RE && \"Null expr in omp to/from/map clause\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18132, __PRETTY_FUNCTION__))
;
18133 SourceLocation ELoc = RE->getExprLoc();
18134
18135 // Find the current unresolved mapper expression.
18136 if (UpdateUMIt && UMIt != UMEnd) {
18137 UMIt++;
18138 assert(((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18140, __PRETTY_FUNCTION__))
18139 UMIt != UMEnd &&((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18140, __PRETTY_FUNCTION__))
18140 "Expect the size of UnresolvedMappers to match with that of VarList")((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18140, __PRETTY_FUNCTION__))
;
18141 }
18142 UpdateUMIt = true;
18143 if (UMIt != UMEnd)
18144 UnresolvedMapper = *UMIt;
18145
18146 const Expr *VE = RE->IgnoreParenLValueCasts();
18147
18148 if (VE->isValueDependent() || VE->isTypeDependent() ||
18149 VE->isInstantiationDependent() ||
18150 VE->containsUnexpandedParameterPack()) {
18151 // Try to find the associated user-defined mapper.
18152 ExprResult ER = buildUserDefinedMapperRef(
18153 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
18154 VE->getType().getCanonicalType(), UnresolvedMapper);
18155 if (ER.isInvalid())
18156 continue;
18157 MVLI.UDMapperList.push_back(ER.get());
18158 // We can only analyze this information once the missing information is
18159 // resolved.
18160 MVLI.ProcessedVarList.push_back(RE);
18161 continue;
18162 }
18163
18164 Expr *SimpleExpr = RE->IgnoreParenCasts();
18165
18166 if (!RE->isLValue()) {
18167 if (SemaRef.getLangOpts().OpenMP < 50) {
18168 SemaRef.Diag(
18169 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
18170 << RE->getSourceRange();
18171 } else {
18172 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18173 << getOpenMPClauseName(CKind) << RE->getSourceRange();
18174 }
18175 continue;
18176 }
18177
18178 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
18179 ValueDecl *CurDeclaration = nullptr;
18180
18181 // Obtain the array or member expression bases if required. Also, fill the
18182 // components array with all the components identified in the process.
18183 const Expr *BE = checkMapClauseExpressionBase(
18184 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
18185 /*NoDiagnose=*/false);
18186 if (!BE)
18187 continue;
18188
18189 assert(!CurComponents.empty() &&((!CurComponents.empty() && "Invalid mappable expression information."
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18190, __PRETTY_FUNCTION__))
18190 "Invalid mappable expression information.")((!CurComponents.empty() && "Invalid mappable expression information."
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18190, __PRETTY_FUNCTION__))
;
18191
18192 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
18193 // Add store "this" pointer to class in DSAStackTy for future checking
18194 DSAS->addMappedClassesQualTypes(TE->getType());
18195 // Try to find the associated user-defined mapper.
18196 ExprResult ER = buildUserDefinedMapperRef(
18197 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
18198 VE->getType().getCanonicalType(), UnresolvedMapper);
18199 if (ER.isInvalid())
18200 continue;
18201 MVLI.UDMapperList.push_back(ER.get());
18202 // Skip restriction checking for variable or field declarations
18203 MVLI.ProcessedVarList.push_back(RE);
18204 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18205 MVLI.VarComponents.back().append(CurComponents.begin(),
18206 CurComponents.end());
18207 MVLI.VarBaseDeclarations.push_back(nullptr);
18208 continue;
18209 }
18210
18211 // For the following checks, we rely on the base declaration which is
18212 // expected to be associated with the last component. The declaration is
18213 // expected to be a variable or a field (if 'this' is being mapped).
18214 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
18215 assert(CurDeclaration && "Null decl on map clause.")((CurDeclaration && "Null decl on map clause.") ? static_cast
<void> (0) : __assert_fail ("CurDeclaration && \"Null decl on map clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18215, __PRETTY_FUNCTION__))
;
18216 assert(((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18218, __PRETTY_FUNCTION__))
18217 CurDeclaration->isCanonicalDecl() &&((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18218, __PRETTY_FUNCTION__))
18218 "Expecting components to have associated only canonical declarations.")((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18218, __PRETTY_FUNCTION__))
;
18219
18220 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
18221 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
18222
18223 assert((VD || FD) && "Only variables or fields are expected here!")(((VD || FD) && "Only variables or fields are expected here!"
) ? static_cast<void> (0) : __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18223, __PRETTY_FUNCTION__))
;
18224 (void)FD;
18225
18226 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
18227 // threadprivate variables cannot appear in a map clause.
18228 // OpenMP 4.5 [2.10.5, target update Construct]
18229 // threadprivate variables cannot appear in a from clause.
18230 if (VD && DSAS->isThreadPrivate(VD)) {
18231 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
18232 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
18233 << getOpenMPClauseName(CKind);
18234 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
18235 continue;
18236 }
18237
18238 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
18239 // A list item cannot appear in both a map clause and a data-sharing
18240 // attribute clause on the same construct.
18241
18242 // Check conflicts with other map clause expressions. We check the conflicts
18243 // with the current construct separately from the enclosing data
18244 // environment, because the restrictions are different. We only have to
18245 // check conflicts across regions for the map clauses.
18246 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
18247 /*CurrentRegionOnly=*/true, CurComponents, CKind))
18248 break;
18249 if (CKind == OMPC_map &&
18250 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
18251 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
18252 /*CurrentRegionOnly=*/false, CurComponents, CKind))
18253 break;
18254
18255 // OpenMP 4.5 [2.10.5, target update Construct]
18256 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18257 // If the type of a list item is a reference to a type T then the type will
18258 // be considered to be T for all purposes of this clause.
18259 auto I = llvm::find_if(
18260 CurComponents,
18261 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
18262 return MC.getAssociatedDeclaration();
18263 });
18264 assert(I != CurComponents.end() && "Null decl on map clause.")((I != CurComponents.end() && "Null decl on map clause."
) ? static_cast<void> (0) : __assert_fail ("I != CurComponents.end() && \"Null decl on map clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18264, __PRETTY_FUNCTION__))
;
18265 (void)I;
18266 QualType Type;
18267 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
18268 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
18269 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
18270 if (ASE) {
18271 Type = ASE->getType().getNonReferenceType();
18272 } else if (OASE) {
18273 QualType BaseType =
18274 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18275 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18276 Type = ATy->getElementType();
18277 else
18278 Type = BaseType->getPointeeType();
18279 Type = Type.getNonReferenceType();
18280 } else if (OAShE) {
18281 Type = OAShE->getBase()->getType()->getPointeeType();
18282 } else {
18283 Type = VE->getType();
18284 }
18285
18286 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
18287 // A list item in a to or from clause must have a mappable type.
18288 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
18289 // A list item must have a mappable type.
18290 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
18291 DSAS, Type))
18292 continue;
18293
18294 if (CKind == OMPC_map) {
18295 // target enter data
18296 // OpenMP [2.10.2, Restrictions, p. 99]
18297 // A map-type must be specified in all map clauses and must be either
18298 // to or alloc.
18299 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
18300 if (DKind == OMPD_target_enter_data &&
18301 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
18302 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
18303 << (IsMapTypeImplicit ? 1 : 0)
18304 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
18305 << getOpenMPDirectiveName(DKind);
18306 continue;
18307 }
18308
18309 // target exit_data
18310 // OpenMP [2.10.3, Restrictions, p. 102]
18311 // A map-type must be specified in all map clauses and must be either
18312 // from, release, or delete.
18313 if (DKind == OMPD_target_exit_data &&
18314 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
18315 MapType == OMPC_MAP_delete)) {
18316 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
18317 << (IsMapTypeImplicit ? 1 : 0)
18318 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
18319 << getOpenMPDirectiveName(DKind);
18320 continue;
18321 }
18322
18323 // target, target data
18324 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
18325 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
18326 // A map-type in a map clause must be to, from, tofrom or alloc
18327 if ((DKind == OMPD_target_data ||
18328 isOpenMPTargetExecutionDirective(DKind)) &&
18329 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
18330 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
18331 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
18332 << (IsMapTypeImplicit ? 1 : 0)
18333 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
18334 << getOpenMPDirectiveName(DKind);
18335 continue;
18336 }
18337
18338 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18339 // A list item cannot appear in both a map clause and a data-sharing
18340 // attribute clause on the same construct
18341 //
18342 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18343 // A list item cannot appear in both a map clause and a data-sharing
18344 // attribute clause on the same construct unless the construct is a
18345 // combined construct.
18346 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
18347 isOpenMPTargetExecutionDirective(DKind)) ||
18348 DKind == OMPD_target)) {
18349 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
18350 if (isOpenMPPrivate(DVar.CKind)) {
18351 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18352 << getOpenMPClauseName(DVar.CKind)
18353 << getOpenMPClauseName(OMPC_map)
18354 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
18355 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
18356 continue;
18357 }
18358 }
18359 }
18360
18361 // Try to find the associated user-defined mapper.
18362 ExprResult ER = buildUserDefinedMapperRef(
18363 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
18364 Type.getCanonicalType(), UnresolvedMapper);
18365 if (ER.isInvalid())
18366 continue;
18367 MVLI.UDMapperList.push_back(ER.get());
18368
18369 // Save the current expression.
18370 MVLI.ProcessedVarList.push_back(RE);
18371
18372 // Store the components in the stack so that they can be used to check
18373 // against other clauses later on.
18374 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
18375 /*WhereFoundClauseKind=*/OMPC_map);
18376
18377 // Save the components and declaration to create the clause. For purposes of
18378 // the clause creation, any component list that has has base 'this' uses
18379 // null as base declaration.
18380 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18381 MVLI.VarComponents.back().append(CurComponents.begin(),
18382 CurComponents.end());
18383 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
18384 : CurDeclaration);
18385 }
18386}
18387
18388OMPClause *Sema::ActOnOpenMPMapClause(
18389 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
18390 ArrayRef<SourceLocation> MapTypeModifiersLoc,
18391 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18392 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
18393 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18394 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18395 OpenMPMapModifierKind Modifiers[] = {
18396 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
18397 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
18398 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
18399
18400 // Process map-type-modifiers, flag errors for duplicate modifiers.
18401 unsigned Count = 0;
18402 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
18403 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
18404 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
18405 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
18406 continue;
18407 }
18408 assert(Count < NumberOfOMPMapClauseModifiers &&((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18409, __PRETTY_FUNCTION__))
18409 "Modifiers exceed the allowed number of map type modifiers")((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18409, __PRETTY_FUNCTION__))
;
18410 Modifiers[Count] = MapTypeModifiers[I];
18411 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
18412 ++Count;
18413 }
18414
18415 MappableVarListInfo MVLI(VarList);
18416 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
18417 MapperIdScopeSpec, MapperId, UnresolvedMappers,
18418 MapType, IsMapTypeImplicit);
18419
18420 // We need to produce a map clause even if we don't have variables so that
18421 // other diagnostics related with non-existing map clauses are accurate.
18422 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
18423 MVLI.VarBaseDeclarations, MVLI.VarComponents,
18424 MVLI.UDMapperList, Modifiers, ModifiersLoc,
18425 MapperIdScopeSpec.getWithLocInContext(Context),
18426 MapperId, MapType, IsMapTypeImplicit, MapLoc);
18427}
18428
18429QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
18430 TypeResult ParsedType) {
18431 assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail
("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18431, __PRETTY_FUNCTION__))
;
18432
18433 QualType ReductionType = GetTypeFromParser(ParsedType.get());
18434 if (ReductionType.isNull())
18435 return QualType();
18436
18437 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
18438 // A type name in a declare reduction directive cannot be a function type, an
18439 // array type, a reference type, or a type qualified with const, volatile or
18440 // restrict.
18441 if (ReductionType.hasQualifiers()) {
18442 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
18443 return QualType();
18444 }
18445
18446 if (ReductionType->isFunctionType()) {
18447 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
18448 return QualType();
18449 }
18450 if (ReductionType->isReferenceType()) {
18451 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
18452 return QualType();
18453 }
18454 if (ReductionType->isArrayType()) {
18455 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
18456 return QualType();
18457 }
18458 return ReductionType;
18459}
18460
18461Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
18462 Scope *S, DeclContext *DC, DeclarationName Name,
18463 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
18464 AccessSpecifier AS, Decl *PrevDeclInScope) {
18465 SmallVector<Decl *, 8> Decls;
18466 Decls.reserve(ReductionTypes.size());
18467
18468 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
18469 forRedeclarationInCurContext());
18470 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
18471 // A reduction-identifier may not be re-declared in the current scope for the
18472 // same type or for a type that is compatible according to the base language
18473 // rules.
18474 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18475 OMPDeclareReductionDecl *PrevDRD = nullptr;
18476 bool InCompoundScope = true;
18477 if (S != nullptr) {
18478 // Find previous declaration with the same name not referenced in other
18479 // declarations.
18480 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18481 InCompoundScope =
18482 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18483 LookupName(Lookup, S);
18484 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18485 /*AllowInlineNamespace=*/false);
18486 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
18487 LookupResult::Filter Filter = Lookup.makeFilter();
18488 while (Filter.hasNext()) {
18489 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
18490 if (InCompoundScope) {
18491 auto I = UsedAsPrevious.find(PrevDecl);
18492 if (I == UsedAsPrevious.end())
18493 UsedAsPrevious[PrevDecl] = false;
18494 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
18495 UsedAsPrevious[D] = true;
18496 }
18497 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18498 PrevDecl->getLocation();
18499 }
18500 Filter.done();
18501 if (InCompoundScope) {
18502 for (const auto &PrevData : UsedAsPrevious) {
18503 if (!PrevData.second) {
18504 PrevDRD = PrevData.first;
18505 break;
18506 }
18507 }
18508 }
18509 } else if (PrevDeclInScope != nullptr) {
18510 auto *PrevDRDInScope = PrevDRD =
18511 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
18512 do {
18513 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
18514 PrevDRDInScope->getLocation();
18515 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
18516 } while (PrevDRDInScope != nullptr);
18517 }
18518 for (const auto &TyData : ReductionTypes) {
18519 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
18520 bool Invalid = false;
18521 if (I != PreviousRedeclTypes.end()) {
18522 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
18523 << TyData.first;
18524 Diag(I->second, diag::note_previous_definition);
18525 Invalid = true;
18526 }
18527 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
18528 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
18529 Name, TyData.first, PrevDRD);
18530 DC->addDecl(DRD);
18531 DRD->setAccess(AS);
18532 Decls.push_back(DRD);
18533 if (Invalid)
18534 DRD->setInvalidDecl();
18535 else
18536 PrevDRD = DRD;
18537 }
18538
18539 return DeclGroupPtrTy::make(
18540 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
18541}
18542
18543void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
18544 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18545
18546 // Enter new function scope.
18547 PushFunctionScope();
18548 setFunctionHasBranchProtectedScope();
18549 getCurFunction()->setHasOMPDeclareReductionCombiner();
18550
18551 if (S != nullptr)
18552 PushDeclContext(S, DRD);
18553 else
18554 CurContext = DRD;
18555
18556 PushExpressionEvaluationContext(
18557 ExpressionEvaluationContext::PotentiallyEvaluated);
18558
18559 QualType ReductionType = DRD->getType();
18560 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
18561 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
18562 // uses semantics of argument handles by value, but it should be passed by
18563 // reference. C lang does not support references, so pass all parameters as
18564 // pointers.
18565 // Create 'T omp_in;' variable.
18566 VarDecl *OmpInParm =
18567 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
18568 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
18569 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
18570 // uses semantics of argument handles by value, but it should be passed by
18571 // reference. C lang does not support references, so pass all parameters as
18572 // pointers.
18573 // Create 'T omp_out;' variable.
18574 VarDecl *OmpOutParm =
18575 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
18576 if (S != nullptr) {
18577 PushOnScopeChains(OmpInParm, S);
18578 PushOnScopeChains(OmpOutParm, S);
18579 } else {
18580 DRD->addDecl(OmpInParm);
18581 DRD->addDecl(OmpOutParm);
18582 }
18583 Expr *InE =
18584 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
18585 Expr *OutE =
18586 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
18587 DRD->setCombinerData(InE, OutE);
18588}
18589
18590void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
18591 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18592 DiscardCleanupsInEvaluationContext();
18593 PopExpressionEvaluationContext();
18594
18595 PopDeclContext();
18596 PopFunctionScopeInfo();
18597
18598 if (Combiner != nullptr)
18599 DRD->setCombiner(Combiner);
18600 else
18601 DRD->setInvalidDecl();
18602}
18603
18604VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
18605 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18606
18607 // Enter new function scope.
18608 PushFunctionScope();
18609 setFunctionHasBranchProtectedScope();
18610
18611 if (S != nullptr)
18612 PushDeclContext(S, DRD);
18613 else
18614 CurContext = DRD;
18615
18616 PushExpressionEvaluationContext(
18617 ExpressionEvaluationContext::PotentiallyEvaluated);
18618
18619 QualType ReductionType = DRD->getType();
18620 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
18621 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
18622 // uses semantics of argument handles by value, but it should be passed by
18623 // reference. C lang does not support references, so pass all parameters as
18624 // pointers.
18625 // Create 'T omp_priv;' variable.
18626 VarDecl *OmpPrivParm =
18627 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
18628 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
18629 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
18630 // uses semantics of argument handles by value, but it should be passed by
18631 // reference. C lang does not support references, so pass all parameters as
18632 // pointers.
18633 // Create 'T omp_orig;' variable.
18634 VarDecl *OmpOrigParm =
18635 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
18636 if (S != nullptr) {
18637 PushOnScopeChains(OmpPrivParm, S);
18638 PushOnScopeChains(OmpOrigParm, S);
18639 } else {
18640 DRD->addDecl(OmpPrivParm);
18641 DRD->addDecl(OmpOrigParm);
18642 }
18643 Expr *OrigE =
18644 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
18645 Expr *PrivE =
18646 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
18647 DRD->setInitializerData(OrigE, PrivE);
18648 return OmpPrivParm;
18649}
18650
18651void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
18652 VarDecl *OmpPrivParm) {
18653 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18654 DiscardCleanupsInEvaluationContext();
18655 PopExpressionEvaluationContext();
18656
18657 PopDeclContext();
18658 PopFunctionScopeInfo();
18659
18660 if (Initializer != nullptr) {
18661 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
18662 } else if (OmpPrivParm->hasInit()) {
18663 DRD->setInitializer(OmpPrivParm->getInit(),
18664 OmpPrivParm->isDirectInit()
18665 ? OMPDeclareReductionDecl::DirectInit
18666 : OMPDeclareReductionDecl::CopyInit);
18667 } else {
18668 DRD->setInvalidDecl();
18669 }
18670}
18671
18672Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
18673 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
18674 for (Decl *D : DeclReductions.get()) {
18675 if (IsValid) {
18676 if (S)
18677 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
18678 /*AddToContext=*/false);
18679 } else {
18680 D->setInvalidDecl();
18681 }
18682 }
18683 return DeclReductions;
18684}
18685
18686TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
18687 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
18688 QualType T = TInfo->getType();
18689 if (D.isInvalidType())
18690 return true;
18691
18692 if (getLangOpts().CPlusPlus) {
18693 // Check that there are no default arguments (C++ only).
18694 CheckExtraCXXDefaultArguments(D);
18695 }
18696
18697 return CreateParsedType(T, TInfo);
18698}
18699
18700QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
18701 TypeResult ParsedType) {
18702 assert(ParsedType.isUsable() && "Expect usable parsed mapper type")((ParsedType.isUsable() && "Expect usable parsed mapper type"
) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable() && \"Expect usable parsed mapper type\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18702, __PRETTY_FUNCTION__))
;
18703
18704 QualType MapperType = GetTypeFromParser(ParsedType.get());
18705 assert(!MapperType.isNull() && "Expect valid mapper type")((!MapperType.isNull() && "Expect valid mapper type")
? static_cast<void> (0) : __assert_fail ("!MapperType.isNull() && \"Expect valid mapper type\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18705, __PRETTY_FUNCTION__))
;
18706
18707 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18708 // The type must be of struct, union or class type in C and C++
18709 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
18710 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
18711 return QualType();
18712 }
18713 return MapperType;
18714}
18715
18716Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
18717 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
18718 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
18719 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
18720 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
18721 forRedeclarationInCurContext());
18722 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18723 // A mapper-identifier may not be redeclared in the current scope for the
18724 // same type or for a type that is compatible according to the base language
18725 // rules.
18726 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18727 OMPDeclareMapperDecl *PrevDMD = nullptr;
18728 bool InCompoundScope = true;
18729 if (S != nullptr) {
18730 // Find previous declaration with the same name not referenced in other
18731 // declarations.
18732 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18733 InCompoundScope =
18734 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18735 LookupName(Lookup, S);
18736 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18737 /*AllowInlineNamespace=*/false);
18738 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18739 LookupResult::Filter Filter = Lookup.makeFilter();
18740 while (Filter.hasNext()) {
18741 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18742 if (InCompoundScope) {
18743 auto I = UsedAsPrevious.find(PrevDecl);
18744 if (I == UsedAsPrevious.end())
18745 UsedAsPrevious[PrevDecl] = false;
18746 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18747 UsedAsPrevious[D] = true;
18748 }
18749 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18750 PrevDecl->getLocation();
18751 }
18752 Filter.done();
18753 if (InCompoundScope) {
18754 for (const auto &PrevData : UsedAsPrevious) {
18755 if (!PrevData.second) {
18756 PrevDMD = PrevData.first;
18757 break;
18758 }
18759 }
18760 }
18761 } else if (PrevDeclInScope) {
18762 auto *PrevDMDInScope = PrevDMD =
18763 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18764 do {
18765 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18766 PrevDMDInScope->getLocation();
18767 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18768 } while (PrevDMDInScope != nullptr);
18769 }
18770 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18771 bool Invalid = false;
18772 if (I != PreviousRedeclTypes.end()) {
18773 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18774 << MapperType << Name;
18775 Diag(I->second, diag::note_previous_definition);
18776 Invalid = true;
18777 }
18778 // Build expressions for implicit maps of data members with 'default'
18779 // mappers.
18780 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
18781 Clauses.end());
18782 if (LangOpts.OpenMP >= 50)
18783 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ClausesWithImplicit);
18784 auto *DMD =
18785 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
18786 ClausesWithImplicit, PrevDMD);
18787 if (S)
18788 PushOnScopeChains(DMD, S);
18789 else
18790 DC->addDecl(DMD);
18791 DMD->setAccess(AS);
18792 if (Invalid)
18793 DMD->setInvalidDecl();
18794
18795 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
18796 VD->setDeclContext(DMD);
18797 VD->setLexicalDeclContext(DMD);
18798 DMD->addDecl(VD);
18799 DMD->setMapperVarRef(MapperVarRef);
18800
18801 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
18802}
18803
18804ExprResult
18805Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
18806 SourceLocation StartLoc,
18807 DeclarationName VN) {
18808 TypeSourceInfo *TInfo =
18809 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
18810 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
18811 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
18812 MapperType, TInfo, SC_None);
18813 if (S)
18814 PushOnScopeChains(VD, S, /*AddToContext=*/false);
18815 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18816 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
18817 return E;
18818}
18819
18820bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
18821 assert(LangOpts.OpenMP && "Expected OpenMP mode.")((LangOpts.OpenMP && "Expected OpenMP mode.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18821, __PRETTY_FUNCTION__))
;
18822 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
18823 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
18824 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
18825 return true;
18826}
18827
18828const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
18829 assert(LangOpts.OpenMP && "Expected OpenMP mode.")((LangOpts.OpenMP && "Expected OpenMP mode.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 18829, __PRETTY_FUNCTION__))
;
18830 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
18831}
18832
18833OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18834 SourceLocation StartLoc,
18835 SourceLocation LParenLoc,
18836 SourceLocation EndLoc) {
18837 Expr *ValExpr = NumTeams;
18838 Stmt *HelperValStmt = nullptr;
18839
18840 // OpenMP [teams Constrcut, Restrictions]
18841 // The num_teams expression must evaluate to a positive integer value.
18842 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18843 /*StrictlyPositive=*/true))
18844 return nullptr;
18845
18846 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18847 OpenMPDirectiveKind CaptureRegion =
18848 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18849 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18850 ValExpr = MakeFullExpr(ValExpr).get();
18851 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18852 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18853 HelperValStmt = buildPreInits(Context, Captures);
18854 }
18855
18856 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18857 StartLoc, LParenLoc, EndLoc);
18858}
18859
18860OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18861 SourceLocation StartLoc,
18862 SourceLocation LParenLoc,
18863 SourceLocation EndLoc) {
18864 Expr *ValExpr = ThreadLimit;
18865 Stmt *HelperValStmt = nullptr;
18866
18867 // OpenMP [teams Constrcut, Restrictions]
18868 // The thread_limit expression must evaluate to a positive integer value.
18869 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18870 /*StrictlyPositive=*/true))
18871 return nullptr;
18872
18873 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18874 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18875 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18876 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18877 ValExpr = MakeFullExpr(ValExpr).get();
18878 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18879 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18880 HelperValStmt = buildPreInits(Context, Captures);
18881 }
18882
18883 return new (Context) OMPThreadLimitClause(
18884 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18885}
18886
18887OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18888 SourceLocation StartLoc,
18889 SourceLocation LParenLoc,
18890 SourceLocation EndLoc) {
18891 Expr *ValExpr = Priority;
18892 Stmt *HelperValStmt = nullptr;
18893 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18894
18895 // OpenMP [2.9.1, task Constrcut]
18896 // The priority-value is a non-negative numerical scalar expression.
18897 if (!isNonNegativeIntegerValue(
18898 ValExpr, *this, OMPC_priority,
18899 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18900 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18901 return nullptr;
18902
18903 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18904 StartLoc, LParenLoc, EndLoc);
18905}
18906
18907OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18908 SourceLocation StartLoc,
18909 SourceLocation LParenLoc,
18910 SourceLocation EndLoc) {
18911 Expr *ValExpr = Grainsize;
18912 Stmt *HelperValStmt = nullptr;
18913 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18914
18915 // OpenMP [2.9.2, taskloop Constrcut]
18916 // The parameter of the grainsize clause must be a positive integer
18917 // expression.
18918 if (!isNonNegativeIntegerValue(
18919 ValExpr, *this, OMPC_grainsize,
18920 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18921 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18922 return nullptr;
18923
18924 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18925 StartLoc, LParenLoc, EndLoc);
18926}
18927
18928OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18929 SourceLocation StartLoc,
18930 SourceLocation LParenLoc,
18931 SourceLocation EndLoc) {
18932 Expr *ValExpr = NumTasks;
18933 Stmt *HelperValStmt = nullptr;
18934 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18935
18936 // OpenMP [2.9.2, taskloop Constrcut]
18937 // The parameter of the num_tasks clause must be a positive integer
18938 // expression.
18939 if (!isNonNegativeIntegerValue(
18940 ValExpr, *this, OMPC_num_tasks,
18941 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18942 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18943 return nullptr;
18944
18945 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18946 StartLoc, LParenLoc, EndLoc);
18947}
18948
18949OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18950 SourceLocation LParenLoc,
18951 SourceLocation EndLoc) {
18952 // OpenMP [2.13.2, critical construct, Description]
18953 // ... where hint-expression is an integer constant expression that evaluates
18954 // to a valid lock hint.
18955 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18956 if (HintExpr.isInvalid())
18957 return nullptr;
18958 return new (Context)
18959 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18960}
18961
18962/// Tries to find omp_event_handle_t type.
18963static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18964 DSAStackTy *Stack) {
18965 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18966 if (!OMPEventHandleT.isNull())
18967 return true;
18968 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18969 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18970 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18971 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18972 return false;
18973 }
18974 Stack->setOMPEventHandleT(PT.get());
18975 return true;
18976}
18977
18978OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18979 SourceLocation LParenLoc,
18980 SourceLocation EndLoc) {
18981 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18982 !Evt->isInstantiationDependent() &&
18983 !Evt->containsUnexpandedParameterPack()) {
18984 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
18985 return nullptr;
18986 // OpenMP 5.0, 2.10.1 task Construct.
18987 // event-handle is a variable of the omp_event_handle_t type.
18988 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18989 if (!Ref) {
18990 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18991 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18992 return nullptr;
18993 }
18994 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18995 if (!VD) {
18996 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18997 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18998 return nullptr;
18999 }
19000 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
19001 VD->getType()) ||
19002 VD->getType().isConstant(Context)) {
19003 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19004 << "omp_event_handle_t" << 1 << VD->getType()
19005 << Evt->getSourceRange();
19006 return nullptr;
19007 }
19008 // OpenMP 5.0, 2.10.1 task Construct
19009 // [detach clause]... The event-handle will be considered as if it was
19010 // specified on a firstprivate clause.
19011 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
19012 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
19013 DVar.RefExpr) {
19014 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
19015 << getOpenMPClauseName(DVar.CKind)
19016 << getOpenMPClauseName(OMPC_firstprivate);
19017 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
19018 return nullptr;
19019 }
19020 }
19021
19022 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
19023}
19024
19025OMPClause *Sema::ActOnOpenMPDistScheduleClause(
19026 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
19027 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
19028 SourceLocation EndLoc) {
19029 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
19030 std::string Values;
19031 Values += "'";
19032 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
19033 Values += "'";
19034 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19035 << Values << getOpenMPClauseName(OMPC_dist_schedule);
19036 return nullptr;
19037 }
19038 Expr *ValExpr = ChunkSize;
19039 Stmt *HelperValStmt = nullptr;
19040 if (ChunkSize) {
19041 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
19042 !ChunkSize->isInstantiationDependent() &&
19043 !ChunkSize->containsUnexpandedParameterPack()) {
19044 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
19045 ExprResult Val =
19046 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
19047 if (Val.isInvalid())
19048 return nullptr;
19049
19050 ValExpr = Val.get();
19051
19052 // OpenMP [2.7.1, Restrictions]
19053 // chunk_size must be a loop invariant integer expression with a positive
19054 // value.
19055 if (Optional<llvm::APSInt> Result =
19056 ValExpr->getIntegerConstantExpr(Context)) {
19057 if (Result->isSigned() && !Result->isStrictlyPositive()) {
19058 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
19059 << "dist_schedule" << ChunkSize->getSourceRange();
19060 return nullptr;
19061 }
19062 } else if (getOpenMPCaptureRegionForClause(
19063 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
19064 LangOpts.OpenMP) != OMPD_unknown &&
19065 !CurContext->isDependentContext()) {
19066 ValExpr = MakeFullExpr(ValExpr).get();
19067 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19068 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19069 HelperValStmt = buildPreInits(Context, Captures);
19070 }
19071 }
19072 }
19073
19074 return new (Context)
19075 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
19076 Kind, ValExpr, HelperValStmt);
19077}
19078
19079OMPClause *Sema::ActOnOpenMPDefaultmapClause(
19080 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
19081 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
19082 SourceLocation KindLoc, SourceLocation EndLoc) {
19083 if (getLangOpts().OpenMP < 50) {
19084 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
19085 Kind != OMPC_DEFAULTMAP_scalar) {
19086 std::string Value;
19087 SourceLocation Loc;
19088 Value += "'";
19089 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
19090 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19091 OMPC_DEFAULTMAP_MODIFIER_tofrom);
19092 Loc = MLoc;
19093 } else {
19094 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19095 OMPC_DEFAULTMAP_scalar);
19096 Loc = KindLoc;
19097 }
19098 Value += "'";
19099 Diag(Loc, diag::err_omp_unexpected_clause_value)
19100 << Value << getOpenMPClauseName(OMPC_defaultmap);
19101 return nullptr;
19102 }
19103 } else {
19104 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
19105 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
19106 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
19107 if (!isDefaultmapKind || !isDefaultmapModifier) {
19108 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
19109 if (LangOpts.OpenMP == 50) {
19110 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
19111 "'firstprivate', 'none', 'default'";
19112 if (!isDefaultmapKind && isDefaultmapModifier) {
19113 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19114 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19115 } else if (isDefaultmapKind && !isDefaultmapModifier) {
19116 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19117 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19118 } else {
19119 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19120 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19121 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19122 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19123 }
19124 } else {
19125 StringRef ModifierValue =
19126 "'alloc', 'from', 'to', 'tofrom', "
19127 "'firstprivate', 'none', 'default', 'present'";
19128 if (!isDefaultmapKind && isDefaultmapModifier) {
19129 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19130 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19131 } else if (isDefaultmapKind && !isDefaultmapModifier) {
19132 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19133 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19134 } else {
19135 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19136 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19137 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19138 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19139 }
19140 }
19141 return nullptr;
19142 }
19143
19144 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
19145 // At most one defaultmap clause for each category can appear on the
19146 // directive.
19147 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
19148 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
19149 return nullptr;
19150 }
19151 }
19152 if (Kind == OMPC_DEFAULTMAP_unknown) {
19153 // Variable category is not specified - mark all categories.
19154 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
19155 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
19156 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
19157 } else {
19158 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
19159 }
19160
19161 return new (Context)
19162 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
19163}
19164
19165bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
19166 DeclContext *CurLexicalContext = getCurLexicalContext();
19167 if (!CurLexicalContext->isFileContext() &&
19168 !CurLexicalContext->isExternCContext() &&
19169 !CurLexicalContext->isExternCXXContext() &&
19170 !isa<CXXRecordDecl>(CurLexicalContext) &&
19171 !isa<ClassTemplateDecl>(CurLexicalContext) &&
19172 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
19173 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
19174 Diag(Loc, diag::err_omp_region_not_file_context);
19175 return false;
19176 }
19177 DeclareTargetNesting.push_back(Loc);
19178 return true;
19179}
19180
19181void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
19182 assert(!DeclareTargetNesting.empty() &&((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19183, __PRETTY_FUNCTION__))
19183 "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19183, __PRETTY_FUNCTION__))
;
19184 DeclareTargetNesting.pop_back();
19185}
19186
19187NamedDecl *
19188Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
19189 const DeclarationNameInfo &Id,
19190 NamedDeclSetType &SameDirectiveDecls) {
19191 LookupResult Lookup(*this, Id, LookupOrdinaryName);
19192 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
19193
19194 if (Lookup.isAmbiguous())
19195 return nullptr;
19196 Lookup.suppressDiagnostics();
19197
19198 if (!Lookup.isSingleResult()) {
19199 VarOrFuncDeclFilterCCC CCC(*this);
19200 if (TypoCorrection Corrected =
19201 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
19202 CTK_ErrorRecovery)) {
19203 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
19204 << Id.getName());
19205 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
19206 return nullptr;
19207 }
19208
19209 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
19210 return nullptr;
19211 }
19212
19213 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
19214 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
19215 !isa<FunctionTemplateDecl>(ND)) {
19216 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
19217 return nullptr;
19218 }
19219 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
19220 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
19221 return ND;
19222}
19223
19224void Sema::ActOnOpenMPDeclareTargetName(
19225 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
19226 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
19227 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19229, __PRETTY_FUNCTION__))
19228 isa<FunctionTemplateDecl>(ND)) &&(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19229, __PRETTY_FUNCTION__))
19229 "Expected variable, function or function template.")(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19229, __PRETTY_FUNCTION__))
;
19230
19231 // Diagnose marking after use as it may lead to incorrect diagnosis and
19232 // codegen.
19233 if (LangOpts.OpenMP >= 50 &&
19234 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
19235 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
19236
19237 auto *VD = cast<ValueDecl>(ND);
19238 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
19239 OMPDeclareTargetDeclAttr::getDeviceType(VD);
19240 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
19241 if (DevTy.hasValue() && *DevTy != DT &&
19242 (DeclareTargetNesting.empty() ||
19243 *AttrLoc != DeclareTargetNesting.back())) {
19244 Diag(Loc, diag::err_omp_device_type_mismatch)
19245 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
19246 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
19247 return;
19248 }
19249 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
19250 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
19251 if (!Res || (!DeclareTargetNesting.empty() &&
19252 *AttrLoc == DeclareTargetNesting.back())) {
19253 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
19254 Context, MT, DT, DeclareTargetNesting.size() + 1,
19255 SourceRange(Loc, Loc));
19256 ND->addAttr(A);
19257 if (ASTMutationListener *ML = Context.getASTMutationListener())
19258 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
19259 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
19260 } else if (*Res != MT) {
19261 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
19262 }
19263}
19264
19265static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
19266 Sema &SemaRef, Decl *D) {
19267 if (!D || !isa<VarDecl>(D))
19268 return;
19269 auto *VD = cast<VarDecl>(D);
19270 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
19271 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
19272 if (SemaRef.LangOpts.OpenMP >= 50 &&
19273 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
19274 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
19275 VD->hasGlobalStorage()) {
19276 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
19277 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
19278 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
19279 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
19280 // If a lambda declaration and definition appears between a
19281 // declare target directive and the matching end declare target
19282 // directive, all variables that are captured by the lambda
19283 // expression must also appear in a to clause.
19284 SemaRef.Diag(VD->getLocation(),
19285 diag::err_omp_lambda_capture_in_declare_target_not_to);
19286 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
19287 << VD << 0 << SR;
19288 return;
19289 }
19290 }
19291 if (MapTy.hasValue())
19292 return;
19293 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
19294 SemaRef.Diag(SL, diag::note_used_here) << SR;
19295}
19296
19297static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
19298 Sema &SemaRef, DSAStackTy *Stack,
19299 ValueDecl *VD) {
19300 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
19301 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
19302 /*FullCheck=*/false);
19303}
19304
19305void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
19306 SourceLocation IdLoc) {
19307 if (!D || D->isInvalidDecl())
19308 return;
19309 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
19310 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
19311 if (auto *VD = dyn_cast<VarDecl>(D)) {
19312 // Only global variables can be marked as declare target.
19313 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
19314 !VD->isStaticDataMember())
19315 return;
19316 // 2.10.6: threadprivate variable cannot appear in a declare target
19317 // directive.
19318 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
19319 Diag(SL, diag::err_omp_threadprivate_in_target);
19320 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
19321 return;
19322 }
19323 }
19324 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
19325 D = FTD->getTemplatedDecl();
19326 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
19327 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
19328 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
19329 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
19330 Diag(IdLoc, diag::err_omp_function_in_link_clause);
19331 Diag(FD->getLocation(), diag::note_defined_here) << FD;
19332 return;
19333 }
19334 }
19335 if (auto *VD = dyn_cast<ValueDecl>(D)) {
19336 // Problem if any with var declared with incomplete type will be reported
19337 // as normal, so no need to check it here.
19338 if ((E || !VD->getType()->isIncompleteType()) &&
19339 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
19340 return;
19341 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
19342 // Checking declaration inside declare target region.
19343 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
19344 isa<FunctionTemplateDecl>(D)) {
19345 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
19346 Context, OMPDeclareTargetDeclAttr::MT_To,
19347 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
19348 SourceRange(DeclareTargetNesting.back(),
19349 DeclareTargetNesting.back()));
19350 D->addAttr(A);
19351 if (ASTMutationListener *ML = Context.getASTMutationListener())
19352 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
19353 }
19354 return;
19355 }
19356 }
19357 if (!E)
19358 return;
19359 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
19360}
19361
19362OMPClause *Sema::ActOnOpenMPToClause(
19363 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
19364 ArrayRef<SourceLocation> MotionModifiersLoc,
19365 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19366 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19367 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
19368 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
19369 OMPC_MOTION_MODIFIER_unknown};
19370 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
19371
19372 // Process motion-modifiers, flag errors for duplicate modifiers.
19373 unsigned Count = 0;
19374 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
19375 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
19376 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
19377 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
19378 continue;
19379 }
19380 assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19381, __PRETTY_FUNCTION__))
19381 "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19381, __PRETTY_FUNCTION__))
;
19382 Modifiers[Count] = MotionModifiers[I];
19383 ModifiersLoc[Count] = MotionModifiersLoc[I];
19384 ++Count;
19385 }
19386
19387 MappableVarListInfo MVLI(VarList);
19388 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
19389 MapperIdScopeSpec, MapperId, UnresolvedMappers);
19390 if (MVLI.ProcessedVarList.empty())
19391 return nullptr;
19392
19393 return OMPToClause::Create(
19394 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
19395 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
19396 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
19397}
19398
19399OMPClause *Sema::ActOnOpenMPFromClause(
19400 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
19401 ArrayRef<SourceLocation> MotionModifiersLoc,
19402 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19403 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19404 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
19405 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
19406 OMPC_MOTION_MODIFIER_unknown};
19407 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
19408
19409 // Process motion-modifiers, flag errors for duplicate modifiers.
19410 unsigned Count = 0;
19411 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
19412 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
19413 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
19414 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
19415 continue;
19416 }
19417 assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19418, __PRETTY_FUNCTION__))
19418 "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19418, __PRETTY_FUNCTION__))
;
19419 Modifiers[Count] = MotionModifiers[I];
19420 ModifiersLoc[Count] = MotionModifiersLoc[I];
19421 ++Count;
19422 }
19423
19424 MappableVarListInfo MVLI(VarList);
19425 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
19426 MapperIdScopeSpec, MapperId, UnresolvedMappers);
19427 if (MVLI.ProcessedVarList.empty())
19428 return nullptr;
19429
19430 return OMPFromClause::Create(
19431 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
19432 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
19433 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
19434}
19435
19436OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
19437 const OMPVarListLocTy &Locs) {
19438 MappableVarListInfo MVLI(VarList);
19439 SmallVector<Expr *, 8> PrivateCopies;
19440 SmallVector<Expr *, 8> Inits;
19441
19442 for (Expr *RefExpr : VarList) {
19443 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")((RefExpr && "NULL expr in OpenMP use_device_ptr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19443, __PRETTY_FUNCTION__))
;
19444 SourceLocation ELoc;
19445 SourceRange ERange;
19446 Expr *SimpleRefExpr = RefExpr;
19447 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19448 if (Res.second) {
19449 // It will be analyzed later.
19450 MVLI.ProcessedVarList.push_back(RefExpr);
19451 PrivateCopies.push_back(nullptr);
19452 Inits.push_back(nullptr);
19453 }
19454 ValueDecl *D = Res.first;
19455 if (!D)
19456 continue;
19457
19458 QualType Type = D->getType();
19459 Type = Type.getNonReferenceType().getUnqualifiedType();
19460
19461 auto *VD = dyn_cast<VarDecl>(D);
19462
19463 // Item should be a pointer or reference to pointer.
19464 if (!Type->isPointerType()) {
19465 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
19466 << 0 << RefExpr->getSourceRange();
19467 continue;
19468 }
19469
19470 // Build the private variable and the expression that refers to it.
19471 auto VDPrivate =
19472 buildVarDecl(*this, ELoc, Type, D->getName(),
19473 D->hasAttrs() ? &D->getAttrs() : nullptr,
19474 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19475 if (VDPrivate->isInvalidDecl())
19476 continue;
19477
19478 CurContext->addDecl(VDPrivate);
19479 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
19480 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
19481
19482 // Add temporary variable to initialize the private copy of the pointer.
19483 VarDecl *VDInit =
19484 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
19485 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
19486 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
19487 AddInitializerToDecl(VDPrivate,
19488 DefaultLvalueConversion(VDInitRefExpr).get(),
19489 /*DirectInit=*/false);
19490
19491 // If required, build a capture to implement the privatization initialized
19492 // with the current list item value.
19493 DeclRefExpr *Ref = nullptr;
19494 if (!VD)
19495 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19496 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19497 PrivateCopies.push_back(VDPrivateRefExpr);
19498 Inits.push_back(VDInitRefExpr);
19499
19500 // We need to add a data sharing attribute for this variable to make sure it
19501 // is correctly captured. A variable that shows up in a use_device_ptr has
19502 // similar properties of a first private variable.
19503 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19504
19505 // Create a mappable component for the list item. List items in this clause
19506 // only need a component.
19507 MVLI.VarBaseDeclarations.push_back(D);
19508 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19509 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
19510 /*IsNonContiguous=*/false);
19511 }
19512
19513 if (MVLI.ProcessedVarList.empty())
19514 return nullptr;
19515
19516 return OMPUseDevicePtrClause::Create(
19517 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
19518 MVLI.VarBaseDeclarations, MVLI.VarComponents);
19519}
19520
19521OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
19522 const OMPVarListLocTy &Locs) {
19523 MappableVarListInfo MVLI(VarList);
19524
19525 for (Expr *RefExpr : VarList) {
19526 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")((RefExpr && "NULL expr in OpenMP use_device_addr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_addr clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19526, __PRETTY_FUNCTION__))
;
19527 SourceLocation ELoc;
19528 SourceRange ERange;
19529 Expr *SimpleRefExpr = RefExpr;
19530 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19531 /*AllowArraySection=*/true);
19532 if (Res.second) {
19533 // It will be analyzed later.
19534 MVLI.ProcessedVarList.push_back(RefExpr);
19535 }
19536 ValueDecl *D = Res.first;
19537 if (!D)
19538 continue;
19539 auto *VD = dyn_cast<VarDecl>(D);
19540
19541 // If required, build a capture to implement the privatization initialized
19542 // with the current list item value.
19543 DeclRefExpr *Ref = nullptr;
19544 if (!VD)
19545 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19546 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19547
19548 // We need to add a data sharing attribute for this variable to make sure it
19549 // is correctly captured. A variable that shows up in a use_device_addr has
19550 // similar properties of a first private variable.
19551 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19552
19553 // Create a mappable component for the list item. List items in this clause
19554 // only need a component.
19555 MVLI.VarBaseDeclarations.push_back(D);
19556 MVLI.VarComponents.emplace_back();
19557 Expr *Component = SimpleRefExpr;
19558 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
19559 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
19560 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
19561 MVLI.VarComponents.back().emplace_back(Component, D,
19562 /*IsNonContiguous=*/false);
19563 }
19564
19565 if (MVLI.ProcessedVarList.empty())
19566 return nullptr;
19567
19568 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19569 MVLI.VarBaseDeclarations,
19570 MVLI.VarComponents);
19571}
19572
19573OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
19574 const OMPVarListLocTy &Locs) {
19575 MappableVarListInfo MVLI(VarList);
19576 for (Expr *RefExpr : VarList) {
19577 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")((RefExpr && "NULL expr in OpenMP is_device_ptr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19577, __PRETTY_FUNCTION__))
;
19578 SourceLocation ELoc;
19579 SourceRange ERange;
19580 Expr *SimpleRefExpr = RefExpr;
19581 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19582 if (Res.second) {
19583 // It will be analyzed later.
19584 MVLI.ProcessedVarList.push_back(RefExpr);
19585 }
19586 ValueDecl *D = Res.first;
19587 if (!D)
19588 continue;
19589
19590 QualType Type = D->getType();
19591 // item should be a pointer or array or reference to pointer or array
19592 if (!Type.getNonReferenceType()->isPointerType() &&
19593 !Type.getNonReferenceType()->isArrayType()) {
19594 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
19595 << 0 << RefExpr->getSourceRange();
19596 continue;
19597 }
19598
19599 // Check if the declaration in the clause does not show up in any data
19600 // sharing attribute.
19601 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
19602 if (isOpenMPPrivate(DVar.CKind)) {
19603 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19604 << getOpenMPClauseName(DVar.CKind)
19605 << getOpenMPClauseName(OMPC_is_device_ptr)
19606 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
19607 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
19608 continue;
19609 }
19610
19611 const Expr *ConflictExpr;
19612 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
19613 D, /*CurrentRegionOnly=*/true,
19614 [&ConflictExpr](
19615 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
19616 OpenMPClauseKind) -> bool {
19617 ConflictExpr = R.front().getAssociatedExpression();
19618 return true;
19619 })) {
19620 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
19621 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
19622 << ConflictExpr->getSourceRange();
19623 continue;
19624 }
19625
19626 // Store the components in the stack so that they can be used to check
19627 // against other clauses later on.
19628 OMPClauseMappableExprCommon::MappableComponent MC(
19629 SimpleRefExpr, D, /*IsNonContiguous=*/false);
19630 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
19631 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
19632
19633 // Record the expression we've just processed.
19634 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
19635
19636 // Create a mappable component for the list item. List items in this clause
19637 // only need a component. We use a null declaration to signal fields in
19638 // 'this'.
19639 assert((isa<DeclRefExpr>(SimpleRefExpr) ||(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19641, __PRETTY_FUNCTION__))
19640 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19641, __PRETTY_FUNCTION__))
19641 "Unexpected device pointer expression!")(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19641, __PRETTY_FUNCTION__))
;
19642 MVLI.VarBaseDeclarations.push_back(
19643 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
19644 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19645 MVLI.VarComponents.back().push_back(MC);
19646 }
19647
19648 if (MVLI.ProcessedVarList.empty())
19649 return nullptr;
19650
19651 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19652 MVLI.VarBaseDeclarations,
19653 MVLI.VarComponents);
19654}
19655
19656OMPClause *Sema::ActOnOpenMPAllocateClause(
19657 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19658 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
19659 if (Allocator) {
19660 // OpenMP [2.11.4 allocate Clause, Description]
19661 // allocator is an expression of omp_allocator_handle_t type.
19662 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19663 return nullptr;
19664
19665 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
19666 if (AllocatorRes.isInvalid())
19667 return nullptr;
19668 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
19669 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
19670 Sema::AA_Initializing,
19671 /*AllowExplicit=*/true);
19672 if (AllocatorRes.isInvalid())
19673 return nullptr;
19674 Allocator = AllocatorRes.get();
19675 } else {
19676 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
19677 // allocate clauses that appear on a target construct or on constructs in a
19678 // target region must specify an allocator expression unless a requires
19679 // directive with the dynamic_allocators clause is present in the same
19680 // compilation unit.
19681 if (LangOpts.OpenMPIsDevice &&
19682 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
19683 targetDiag(StartLoc, diag::err_expected_allocator_expression);
19684 }
19685 // Analyze and build list of variables.
19686 SmallVector<Expr *, 8> Vars;
19687 for (Expr *RefExpr : VarList) {
19688 assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ?
static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19688, __PRETTY_FUNCTION__))
;
19689 SourceLocation ELoc;
19690 SourceRange ERange;
19691 Expr *SimpleRefExpr = RefExpr;
19692 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19693 if (Res.second) {
19694 // It will be analyzed later.
19695 Vars.push_back(RefExpr);
19696 }
19697 ValueDecl *D = Res.first;
19698 if (!D)
19699 continue;
19700
19701 auto *VD = dyn_cast<VarDecl>(D);
19702 DeclRefExpr *Ref = nullptr;
19703 if (!VD && !CurContext->isDependentContext())
19704 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19705 Vars.push_back((VD || CurContext->isDependentContext())
19706 ? RefExpr->IgnoreParens()
19707 : Ref);
19708 }
19709
19710 if (Vars.empty())
19711 return nullptr;
19712
19713 if (Allocator)
19714 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
19715 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
19716 ColonLoc, EndLoc, Vars);
19717}
19718
19719OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
19720 SourceLocation StartLoc,
19721 SourceLocation LParenLoc,
19722 SourceLocation EndLoc) {
19723 SmallVector<Expr *, 8> Vars;
19724 for (Expr *RefExpr : VarList) {
19725 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19725, __PRETTY_FUNCTION__))
;
19726 SourceLocation ELoc;
19727 SourceRange ERange;
19728 Expr *SimpleRefExpr = RefExpr;
19729 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19730 if (Res.second)
19731 // It will be analyzed later.
19732 Vars.push_back(RefExpr);
19733 ValueDecl *D = Res.first;
19734 if (!D)
19735 continue;
19736
19737 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
19738 // A list-item cannot appear in more than one nontemporal clause.
19739 if (const Expr *PrevRef =
19740 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
19741 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19742 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
19743 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19744 << getOpenMPClauseName(OMPC_nontemporal);
19745 continue;
19746 }
19747
19748 Vars.push_back(RefExpr);
19749 }
19750
19751 if (Vars.empty())
19752 return nullptr;
19753
19754 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19755 Vars);
19756}
19757
19758OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
19759 SourceLocation StartLoc,
19760 SourceLocation LParenLoc,
19761 SourceLocation EndLoc) {
19762 SmallVector<Expr *, 8> Vars;
19763 for (Expr *RefExpr : VarList) {
19764 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19764, __PRETTY_FUNCTION__))
;
19765 SourceLocation ELoc;
19766 SourceRange ERange;
19767 Expr *SimpleRefExpr = RefExpr;
19768 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19769 /*AllowArraySection=*/true);
19770 if (Res.second)
19771 // It will be analyzed later.
19772 Vars.push_back(RefExpr);
19773 ValueDecl *D = Res.first;
19774 if (!D)
19775 continue;
19776
19777 const DSAStackTy::DSAVarData DVar =
19778 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19779 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19780 // A list item that appears in the inclusive or exclusive clause must appear
19781 // in a reduction clause with the inscan modifier on the enclosing
19782 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19783 if (DVar.CKind != OMPC_reduction ||
19784 DVar.Modifier != OMPC_REDUCTION_inscan)
19785 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19786 << RefExpr->getSourceRange();
19787
19788 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
19789 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19790 Vars.push_back(RefExpr);
19791 }
19792
19793 if (Vars.empty())
19794 return nullptr;
19795
19796 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19797}
19798
19799OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19800 SourceLocation StartLoc,
19801 SourceLocation LParenLoc,
19802 SourceLocation EndLoc) {
19803 SmallVector<Expr *, 8> Vars;
19804 for (Expr *RefExpr : VarList) {
19805 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-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19805, __PRETTY_FUNCTION__))
;
19806 SourceLocation ELoc;
19807 SourceRange ERange;
19808 Expr *SimpleRefExpr = RefExpr;
19809 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19810 /*AllowArraySection=*/true);
19811 if (Res.second)
19812 // It will be analyzed later.
19813 Vars.push_back(RefExpr);
19814 ValueDecl *D = Res.first;
19815 if (!D)
19816 continue;
19817
19818 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
19819 DSAStackTy::DSAVarData DVar;
19820 if (ParentDirective != OMPD_unknown)
19821 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19822 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19823 // A list item that appears in the inclusive or exclusive clause must appear
19824 // in a reduction clause with the inscan modifier on the enclosing
19825 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19826 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19827 DVar.Modifier != OMPC_REDUCTION_inscan) {
19828 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19829 << RefExpr->getSourceRange();
19830 } else {
19831 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19832 }
19833 Vars.push_back(RefExpr);
19834 }
19835
19836 if (Vars.empty())
19837 return nullptr;
19838
19839 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19840}
19841
19842/// Tries to find omp_alloctrait_t type.
19843static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19844 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19845 if (!OMPAlloctraitT.isNull())
19846 return true;
19847 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19848 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19849 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19850 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19851 return false;
19852 }
19853 Stack->setOMPAlloctraitT(PT.get());
19854 return true;
19855}
19856
19857OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19858 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19859 ArrayRef<UsesAllocatorsData> Data) {
19860 // OpenMP [2.12.5, target Construct]
19861 // allocator is an identifier of omp_allocator_handle_t type.
19862 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19863 return nullptr;
19864 // OpenMP [2.12.5, target Construct]
19865 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19866 if (llvm::any_of(
19867 Data,
19868 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19869 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19870 return nullptr;
19871 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19872 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19873 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19874 StringRef Allocator =
19875 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19876 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19877 PredefinedAllocators.insert(LookupSingleName(
19878 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19879 }
19880
19881 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19882 for (const UsesAllocatorsData &D : Data) {
19883 Expr *AllocatorExpr = nullptr;
19884 // Check allocator expression.
19885 if (D.Allocator->isTypeDependent()) {
19886 AllocatorExpr = D.Allocator;
19887 } else {
19888 // Traits were specified - need to assign new allocator to the specified
19889 // allocator, so it must be an lvalue.
19890 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19891 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19892 bool IsPredefinedAllocator = false;
19893 if (DRE)
19894 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19895 if (!DRE ||
19896 !(Context.hasSameUnqualifiedType(
19897 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
19898 Context.typesAreCompatible(AllocatorExpr->getType(),
19899 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
19900 /*CompareUnqualified=*/true)) ||
19901 (!IsPredefinedAllocator &&
19902 (AllocatorExpr->getType().isConstant(Context) ||
19903 !AllocatorExpr->isLValue()))) {
19904 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19905 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19906 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19907 continue;
19908 }
19909 // OpenMP [2.12.5, target Construct]
19910 // Predefined allocators appearing in a uses_allocators clause cannot have
19911 // traits specified.
19912 if (IsPredefinedAllocator && D.AllocatorTraits) {
19913 Diag(D.AllocatorTraits->getExprLoc(),
19914 diag::err_omp_predefined_allocator_with_traits)
19915 << D.AllocatorTraits->getSourceRange();
19916 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19917 << cast<NamedDecl>(DRE->getDecl())->getName()
19918 << D.Allocator->getSourceRange();
19919 continue;
19920 }
19921 // OpenMP [2.12.5, target Construct]
19922 // Non-predefined allocators appearing in a uses_allocators clause must
19923 // have traits specified.
19924 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19925 Diag(D.Allocator->getExprLoc(),
19926 diag::err_omp_nonpredefined_allocator_without_traits);
19927 continue;
19928 }
19929 // No allocator traits - just convert it to rvalue.
19930 if (!D.AllocatorTraits)
19931 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19932 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19933 DRE->getDecl(),
19934 IsPredefinedAllocator
19935 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19936 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19937 }
19938 Expr *AllocatorTraitsExpr = nullptr;
19939 if (D.AllocatorTraits) {
19940 if (D.AllocatorTraits->isTypeDependent()) {
19941 AllocatorTraitsExpr = D.AllocatorTraits;
19942 } else {
19943 // OpenMP [2.12.5, target Construct]
19944 // Arrays that contain allocator traits that appear in a uses_allocators
19945 // clause must be constant arrays, have constant values and be defined
19946 // in the same scope as the construct in which the clause appears.
19947 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19948 // Check that traits expr is a constant array.
19949 QualType TraitTy;
19950 if (const ArrayType *Ty =
19951 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19952 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19953 TraitTy = ConstArrayTy->getElementType();
19954 if (TraitTy.isNull() ||
19955 !(Context.hasSameUnqualifiedType(TraitTy,
19956 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
19957 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
19958 /*CompareUnqualified=*/true))) {
19959 Diag(D.AllocatorTraits->getExprLoc(),
19960 diag::err_omp_expected_array_alloctraits)
19961 << AllocatorTraitsExpr->getType();
19962 continue;
19963 }
19964 // Do not map by default allocator traits if it is a standalone
19965 // variable.
19966 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19967 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19968 DRE->getDecl(),
19969 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19970 }
19971 }
19972 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19973 NewD.Allocator = AllocatorExpr;
19974 NewD.AllocatorTraits = AllocatorTraitsExpr;
19975 NewD.LParenLoc = D.LParenLoc;
19976 NewD.RParenLoc = D.RParenLoc;
19977 }
19978 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19979 NewData);
19980}
19981
19982OMPClause *Sema::ActOnOpenMPAffinityClause(
19983 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19984 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19985 SmallVector<Expr *, 8> Vars;
19986 for (Expr *RefExpr : Locators) {
19987 assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210304100658+2f37cdd5699f/clang/lib/Sema/SemaOpenMP.cpp"
, 19987, __PRETTY_FUNCTION__))
;
19988 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19989 // It will be analyzed later.
19990 Vars.push_back(RefExpr);
19991 continue;
19992 }
19993
19994 SourceLocation ELoc = RefExpr->getExprLoc();
19995 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19996
19997 if (!SimpleExpr->isLValue()) {
19998 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19999 << 1 << 0 << RefExpr->getSourceRange();
20000 continue;
20001 }
20002
20003 ExprResult Res;
20004 {
20005 Sema::TentativeAnalysisScope Trap(*this);
20006 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
20007 }
20008 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20009 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20010 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20011 << 1 << 0 << RefExpr->getSourceRange();
20012 continue;
20013 }
20014 Vars.push_back(SimpleExpr);
20015 }
20016
20017 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20018 EndLoc, Modifier, Vars);
20019}