Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/tools/clang/lib/Sema -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D CLANG_ROUND_TRIP_CC1_ARGS=ON -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/include -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/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/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../x86_64-linux-gnu/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~++20210405022414+5f57793c4fe4/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4=. -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 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-04-05-202135-9119-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 1941, __PRETTY_FUNCTION__))
;
1942
1943 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944 if (FD) {
1945 FunctionEmissionStatus FES = getEmissionStatus(FD);
1946 switch (FES) {
1947 case FunctionEmissionStatus::Emitted:
1948 Kind = SemaDiagnosticBuilder::K_Immediate;
1949 break;
1950 case FunctionEmissionStatus::Unknown:
1951 Kind = SemaDiagnosticBuilder::K_Deferred;
1952 break;
1953 case FunctionEmissionStatus::TemplateDiscarded:
1954 case FunctionEmissionStatus::OMPDiscarded:
1955 case FunctionEmissionStatus::CUDADiscarded:
1956 Kind = SemaDiagnosticBuilder::K_Nop;
1957 break;
1958 }
1959 }
1960
1961 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1962}
1963
1964static OpenMPDefaultmapClauseKind
1965getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1966 if (LO.OpenMP <= 45) {
1967 if (VD->getType().getNonReferenceType()->isScalarType())
1968 return OMPC_DEFAULTMAP_scalar;
1969 return OMPC_DEFAULTMAP_aggregate;
1970 }
1971 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1972 return OMPC_DEFAULTMAP_pointer;
1973 if (VD->getType().getNonReferenceType()->isScalarType())
1974 return OMPC_DEFAULTMAP_scalar;
1975 return OMPC_DEFAULTMAP_aggregate;
1976}
1977
1978bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1979 unsigned OpenMPCaptureLevel) const {
1980 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 1980, __PRETTY_FUNCTION__))
;
1981
1982 ASTContext &Ctx = getASTContext();
1983 bool IsByRef = true;
1984
1985 // Find the directive that is associated with the provided scope.
1986 D = cast<ValueDecl>(D->getCanonicalDecl());
1987 QualType Ty = D->getType();
1988
1989 bool IsVariableUsedInMapClause = false;
1990 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1991 // This table summarizes how a given variable should be passed to the device
1992 // given its type and the clauses where it appears. This table is based on
1993 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1994 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1995 //
1996 // =========================================================================
1997 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1998 // | |(tofrom:scalar)| | pvt | | | |
1999 // =========================================================================
2000 // | scl | | | | - | | bycopy|
2001 // | scl | | - | x | - | - | bycopy|
2002 // | scl | | x | - | - | - | null |
2003 // | scl | x | | | - | | byref |
2004 // | scl | x | - | x | - | - | bycopy|
2005 // | scl | x | x | - | - | - | null |
2006 // | scl | | - | - | - | x | byref |
2007 // | scl | x | - | - | - | x | byref |
2008 //
2009 // | agg | n.a. | | | - | | byref |
2010 // | agg | n.a. | - | x | - | - | byref |
2011 // | agg | n.a. | x | - | - | - | null |
2012 // | agg | n.a. | - | - | - | x | byref |
2013 // | agg | n.a. | - | - | - | x[] | byref |
2014 //
2015 // | ptr | n.a. | | | - | | bycopy|
2016 // | ptr | n.a. | - | x | - | - | bycopy|
2017 // | ptr | n.a. | x | - | - | - | null |
2018 // | ptr | n.a. | - | - | - | x | byref |
2019 // | ptr | n.a. | - | - | - | x[] | bycopy|
2020 // | ptr | n.a. | - | - | x | | bycopy|
2021 // | ptr | n.a. | - | - | x | x | bycopy|
2022 // | ptr | n.a. | - | - | x | x[] | bycopy|
2023 // =========================================================================
2024 // Legend:
2025 // scl - scalar
2026 // ptr - pointer
2027 // agg - aggregate
2028 // x - applies
2029 // - - invalid in this combination
2030 // [] - mapped with an array section
2031 // byref - should be mapped by reference
2032 // byval - should be mapped by value
2033 // null - initialize a local variable to null on the device
2034 //
2035 // Observations:
2036 // - All scalar declarations that show up in a map clause have to be passed
2037 // by reference, because they may have been mapped in the enclosing data
2038 // environment.
2039 // - If the scalar value does not fit the size of uintptr, it has to be
2040 // passed by reference, regardless the result in the table above.
2041 // - For pointers mapped by value that have either an implicit map or an
2042 // array section, the runtime library may pass the NULL value to the
2043 // device instead of the value passed to it by the compiler.
2044
2045 if (Ty->isReferenceType())
2046 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2047
2048 // Locate map clauses and see if the variable being captured is referred to
2049 // in any of those clauses. Here we only care about variables, not fields,
2050 // because fields are part of aggregates.
2051 bool IsVariableAssociatedWithSection = false;
2052
2053 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2054 D, Level,
2055 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2056 OMPClauseMappableExprCommon::MappableExprComponentListRef
2057 MapExprComponents,
2058 OpenMPClauseKind WhereFoundClauseKind) {
2059 // Only the map clause information influences how a variable is
2060 // captured. E.g. is_device_ptr does not require changing the default
2061 // behavior.
2062 if (WhereFoundClauseKind != OMPC_map)
2063 return false;
2064
2065 auto EI = MapExprComponents.rbegin();
2066 auto EE = MapExprComponents.rend();
2067
2068 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2068, __PRETTY_FUNCTION__))
;
2069
2070 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2071 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2072
2073 ++EI;
2074 if (EI == EE)
2075 return false;
2076
2077 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2078 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2079 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2080 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2081 IsVariableAssociatedWithSection = true;
2082 // There is nothing more we need to know about this variable.
2083 return true;
2084 }
2085
2086 // Keep looking for more map info.
2087 return false;
2088 });
2089
2090 if (IsVariableUsedInMapClause) {
2091 // If variable is identified in a map clause it is always captured by
2092 // reference except if it is a pointer that is dereferenced somehow.
2093 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2094 } else {
2095 // By default, all the data that has a scalar type is mapped by copy
2096 // (except for reduction variables).
2097 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2098 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2099 !Ty->isAnyPointerType()) ||
2100 !Ty->isScalarType() ||
2101 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2102 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2103 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2104 D,
2105 [](OpenMPClauseKind K, bool AppliedToPointee) {
2106 return K == OMPC_reduction && !AppliedToPointee;
2107 },
2108 Level);
2109 }
2110 }
2111
2112 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2113 IsByRef =
2114 ((IsVariableUsedInMapClause &&
2115 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2116 OMPD_target) ||
2117 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2118 D,
2119 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2120 return K == OMPC_firstprivate ||
2121 (K == OMPC_reduction && AppliedToPointee);
2122 },
2123 Level, /*NotLastprivate=*/true) ||
2124 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2125 // If the variable is artificial and must be captured by value - try to
2126 // capture by value.
2127 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2128 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2129 // If the variable is implicitly firstprivate and scalar - capture by
2130 // copy
2131 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2132 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2133 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2134 Level) &&
2135 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2136 }
2137
2138 // When passing data by copy, we need to make sure it fits the uintptr size
2139 // and alignment, because the runtime library only deals with uintptr types.
2140 // If it does not fit the uintptr size, we need to pass the data by reference
2141 // instead.
2142 if (!IsByRef &&
2143 (Ctx.getTypeSizeInChars(Ty) >
2144 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2145 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2146 IsByRef = true;
2147 }
2148
2149 return IsByRef;
2150}
2151
2152unsigned Sema::getOpenMPNestingLevel() const {
2153 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2153, __PRETTY_FUNCTION__))
;
2154 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2155}
2156
2157bool Sema::isInOpenMPTargetExecutionDirective() const {
2158 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2159 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2160 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2161 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2162 SourceLocation) -> bool {
2163 return isOpenMPTargetExecutionDirective(K);
2164 },
2165 false);
2166}
2167
2168VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2169 unsigned StopAt) {
2170 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2170, __PRETTY_FUNCTION__))
;
2171 D = getCanonicalDecl(D);
2172
2173 auto *VD = dyn_cast<VarDecl>(D);
2174 // Do not capture constexpr variables.
2175 if (VD && VD->isConstexpr())
2176 return nullptr;
2177
2178 // If we want to determine whether the variable should be captured from the
2179 // perspective of the current capturing scope, and we've already left all the
2180 // capturing scopes of the top directive on the stack, check from the
2181 // perspective of its parent directive (if any) instead.
2182 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2183 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2184
2185 // If we are attempting to capture a global variable in a directive with
2186 // 'target' we return true so that this global is also mapped to the device.
2187 //
2188 if (VD && !VD->hasLocalStorage() &&
2189 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2190 if (isInOpenMPDeclareTargetContext()) {
2191 // Try to mark variable as declare target if it is used in capturing
2192 // regions.
2193 if (LangOpts.OpenMP <= 45 &&
2194 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2195 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2196 return nullptr;
2197 }
2198 if (isInOpenMPTargetExecutionDirective()) {
2199 // If the declaration is enclosed in a 'declare target' directive,
2200 // then it should not be captured.
2201 //
2202 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2203 return nullptr;
2204 CapturedRegionScopeInfo *CSI = nullptr;
2205 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2206 llvm::reverse(FunctionScopes),
2207 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2208 if (!isa<CapturingScopeInfo>(FSI))
2209 return nullptr;
2210 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2211 if (RSI->CapRegionKind == CR_OpenMP) {
2212 CSI = RSI;
2213 break;
2214 }
2215 }
2216 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2216, __PRETTY_FUNCTION__))
;
2217 SmallVector<OpenMPDirectiveKind, 4> Regions;
2218 getOpenMPCaptureRegions(Regions,
2219 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2220 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2221 return VD;
2222 }
2223 }
2224
2225 if (CheckScopeInfo) {
2226 bool OpenMPFound = false;
2227 for (unsigned I = StopAt + 1; I > 0; --I) {
2228 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2229 if(!isa<CapturingScopeInfo>(FSI))
2230 return nullptr;
2231 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2232 if (RSI->CapRegionKind == CR_OpenMP) {
2233 OpenMPFound = true;
2234 break;
2235 }
2236 }
2237 if (!OpenMPFound)
2238 return nullptr;
2239 }
2240
2241 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2242 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2243 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2244 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2245 if (Info.first ||
2246 (VD && VD->hasLocalStorage() &&
2247 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2248 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2249 return VD ? VD : Info.second;
2250 DSAStackTy::DSAVarData DVarTop =
2251 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2252 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2253 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2254 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2255 // Threadprivate variables must not be captured.
2256 if (isOpenMPThreadPrivate(DVarTop.CKind))
2257 return nullptr;
2258 // The variable is not private or it is the variable in the directive with
2259 // default(none) clause and not used in any clause.
2260 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2261 D,
2262 [](OpenMPClauseKind C, bool AppliedToPointee) {
2263 return isOpenMPPrivate(C) && !AppliedToPointee;
2264 },
2265 [](OpenMPDirectiveKind) { return true; },
2266 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2267 // Global shared must not be captured.
2268 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2269 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2271 DVarTop.CKind == OMPC_shared))
2272 return nullptr;
2273 if (DVarPrivate.CKind != OMPC_unknown ||
2274 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2275 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2276 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2277 }
2278 return nullptr;
2279}
2280
2281void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2282 unsigned Level) const {
2283 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2284}
2285
2286void Sema::startOpenMPLoop() {
2287 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2287, __PRETTY_FUNCTION__))
;
2288 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2289 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2290}
2291
2292void Sema::startOpenMPCXXRangeFor() {
2293 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2293, __PRETTY_FUNCTION__))
;
2294 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2295 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2296 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2297 }
2298}
2299
2300OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2301 unsigned CapLevel) const {
2302 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2302, __PRETTY_FUNCTION__))
;
2303 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2304 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2305 Level)) {
2306 bool IsTriviallyCopyable =
2307 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2308 !D->getType()
2309 .getNonReferenceType()
2310 .getCanonicalType()
2311 ->getAsCXXRecordDecl();
2312 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2313 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2314 getOpenMPCaptureRegions(CaptureRegions, DKind);
2315 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2316 (IsTriviallyCopyable ||
2317 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2318 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2319 D,
2320 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2321 Level, /*NotLastprivate=*/true))
2322 return OMPC_firstprivate;
2323 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2324 if (DVar.CKind != OMPC_shared &&
2325 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2326 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2327 return OMPC_firstprivate;
2328 }
2329 }
2330 }
2331 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2332 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2333 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2334 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2335 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2336 return OMPC_private;
2337 }
2338 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2339 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2340 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2341 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2342 Level) &&
2343 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2344 return OMPC_private;
2345 }
2346 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2347 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2348 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2349 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2350 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2351 Level))
2352 return OMPC_private;
2353 }
2354 // User-defined allocators are private since they must be defined in the
2355 // context of target region.
2356 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2357 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2358 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2359 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2360 return OMPC_private;
2361 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2362 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2363 Level) ||
2364 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2365 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2366 // Consider taskgroup reduction descriptor variable a private
2367 // to avoid possible capture in the region.
2368 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2369 [](OpenMPDirectiveKind K) {
2370 return K == OMPD_taskgroup ||
2371 ((isOpenMPParallelDirective(K) ||
2372 isOpenMPWorksharingDirective(K)) &&
2373 !isOpenMPSimdDirective(K));
2374 },
2375 Level) &&
2376 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2377 ? OMPC_private
2378 : OMPC_unknown;
2379}
2380
2381void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2382 unsigned Level) {
2383 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2383, __PRETTY_FUNCTION__))
;
2384 D = getCanonicalDecl(D);
2385 OpenMPClauseKind OMPC = OMPC_unknown;
2386 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2387 const unsigned NewLevel = I - 1;
2388 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2389 D,
2390 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2391 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2392 OMPC = K;
2393 return true;
2394 }
2395 return false;
2396 },
2397 NewLevel))
2398 break;
2399 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2400 D, NewLevel,
2401 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2402 OpenMPClauseKind) { return true; })) {
2403 OMPC = OMPC_map;
2404 break;
2405 }
2406 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2407 NewLevel)) {
2408 OMPC = OMPC_map;
2409 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2410 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2411 OMPC = OMPC_firstprivate;
2412 break;
2413 }
2414 }
2415 if (OMPC != OMPC_unknown)
2416 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2417}
2418
2419bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2420 unsigned CaptureLevel) const {
2421 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2421, __PRETTY_FUNCTION__))
;
2422 // Return true if the current level is no longer enclosed in a target region.
2423
2424 SmallVector<OpenMPDirectiveKind, 4> Regions;
2425 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2426 const auto *VD = dyn_cast<VarDecl>(D);
2427 return VD && !VD->hasLocalStorage() &&
2428 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2429 Level) &&
2430 Regions[CaptureLevel] != OMPD_task;
2431}
2432
2433bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2434 unsigned CaptureLevel) const {
2435 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2435, __PRETTY_FUNCTION__))
;
2436 // Return true if the current level is no longer enclosed in a target region.
2437
2438 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2439 if (!VD->hasLocalStorage()) {
2440 if (isInOpenMPTargetExecutionDirective())
2441 return true;
2442 DSAStackTy::DSAVarData TopDVar =
2443 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2444 unsigned NumLevels =
2445 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2446 if (Level == 0)
2447 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2448 do {
2449 --Level;
2450 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2451 if (DVar.CKind != OMPC_shared)
2452 return true;
2453 } while (Level > 0);
2454 }
2455 }
2456 return true;
2457}
2458
2459void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2460
2461void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2462 OMPTraitInfo &TI) {
2463 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2464}
2465
2466void Sema::ActOnOpenMPEndDeclareVariant() {
2467 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2468, __PRETTY_FUNCTION__))
2468 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2468, __PRETTY_FUNCTION__))
;
2469
2470 OMPDeclareVariantScopes.pop_back();
2471}
2472
2473void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2474 const FunctionDecl *Callee,
2475 SourceLocation Loc) {
2476 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2476, __PRETTY_FUNCTION__))
;
2477 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2478 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2479 // Ignore host functions during device analyzis.
2480 if (LangOpts.OpenMPIsDevice && DevTy &&
2481 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2482 return;
2483 // Ignore nohost functions during host analyzis.
2484 if (!LangOpts.OpenMPIsDevice && DevTy &&
2485 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2486 return;
2487 const FunctionDecl *FD = Callee->getMostRecentDecl();
2488 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2489 if (LangOpts.OpenMPIsDevice && DevTy &&
2490 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2491 // Diagnose host function called during device codegen.
2492 StringRef HostDevTy =
2493 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2494 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2495 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2496 diag::note_omp_marked_device_type_here)
2497 << HostDevTy;
2498 return;
2499 }
2500 if (!LangOpts.OpenMPIsDevice && DevTy &&
2501 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2502 // Diagnose nohost function called during host codegen.
2503 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2504 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2505 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2506 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2507 diag::note_omp_marked_device_type_here)
2508 << NoHostDevTy;
2509 }
2510}
2511
2512void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2513 const DeclarationNameInfo &DirName,
2514 Scope *CurScope, SourceLocation Loc) {
2515 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2516 PushExpressionEvaluationContext(
2517 ExpressionEvaluationContext::PotentiallyEvaluated);
2518}
2519
2520void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2521 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2522}
2523
2524void Sema::EndOpenMPClause() {
2525 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2526}
2527
2528static std::pair<ValueDecl *, bool>
2529getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2530 SourceRange &ERange, bool AllowArraySection = false);
2531
2532/// Check consistency of the reduction clauses.
2533static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2534 ArrayRef<OMPClause *> Clauses) {
2535 bool InscanFound = false;
2536 SourceLocation InscanLoc;
2537 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2538 // A reduction clause without the inscan reduction-modifier may not appear on
2539 // a construct on which a reduction clause with the inscan reduction-modifier
2540 // appears.
2541 for (OMPClause *C : Clauses) {
2542 if (C->getClauseKind() != OMPC_reduction)
2543 continue;
2544 auto *RC = cast<OMPReductionClause>(C);
2545 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2546 InscanFound = true;
2547 InscanLoc = RC->getModifierLoc();
2548 continue;
2549 }
2550 if (RC->getModifier() == OMPC_REDUCTION_task) {
2551 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2552 // A reduction clause with the task reduction-modifier may only appear on
2553 // a parallel construct, a worksharing construct or a combined or
2554 // composite construct for which any of the aforementioned constructs is a
2555 // constituent construct and simd or loop are not constituent constructs.
2556 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2557 if (!(isOpenMPParallelDirective(CurDir) ||
2558 isOpenMPWorksharingDirective(CurDir)) ||
2559 isOpenMPSimdDirective(CurDir))
2560 S.Diag(RC->getModifierLoc(),
2561 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2562 continue;
2563 }
2564 }
2565 if (InscanFound) {
2566 for (OMPClause *C : Clauses) {
2567 if (C->getClauseKind() != OMPC_reduction)
2568 continue;
2569 auto *RC = cast<OMPReductionClause>(C);
2570 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2571 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2572 ? RC->getBeginLoc()
2573 : RC->getModifierLoc(),
2574 diag::err_omp_inscan_reduction_expected);
2575 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2576 continue;
2577 }
2578 for (Expr *Ref : RC->varlists()) {
2579 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2579, __PRETTY_FUNCTION__))
;
2580 SourceLocation ELoc;
2581 SourceRange ERange;
2582 Expr *SimpleRefExpr = Ref;
2583 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2584 /*AllowArraySection=*/true);
2585 ValueDecl *D = Res.first;
2586 if (!D)
2587 continue;
2588 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2589 S.Diag(Ref->getExprLoc(),
2590 diag::err_omp_reduction_not_inclusive_exclusive)
2591 << Ref->getSourceRange();
2592 }
2593 }
2594 }
2595 }
2596}
2597
2598static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2599 ArrayRef<OMPClause *> Clauses);
2600static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2601 bool WithInit);
2602
2603static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2604 const ValueDecl *D,
2605 const DSAStackTy::DSAVarData &DVar,
2606 bool IsLoopIterVar = false);
2607
2608void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2609 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2610 // A variable of class type (or array thereof) that appears in a lastprivate
2611 // clause requires an accessible, unambiguous default constructor for the
2612 // class type, unless the list item is also specified in a firstprivate
2613 // clause.
2614 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2615 for (OMPClause *C : D->clauses()) {
2616 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2617 SmallVector<Expr *, 8> PrivateCopies;
2618 for (Expr *DE : Clause->varlists()) {
2619 if (DE->isValueDependent() || DE->isTypeDependent()) {
2620 PrivateCopies.push_back(nullptr);
2621 continue;
2622 }
2623 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2624 auto *VD = cast<VarDecl>(DRE->getDecl());
2625 QualType Type = VD->getType().getNonReferenceType();
2626 const DSAStackTy::DSAVarData DVar =
2627 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2628 if (DVar.CKind == OMPC_lastprivate) {
2629 // Generate helper private variable and initialize it with the
2630 // default value. The address of the original variable is replaced
2631 // by the address of the new private variable in CodeGen. This new
2632 // variable is not added to IdResolver, so the code in the OpenMP
2633 // region uses original variable for proper diagnostics.
2634 VarDecl *VDPrivate = buildVarDecl(
2635 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2636 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2637 ActOnUninitializedDecl(VDPrivate);
2638 if (VDPrivate->isInvalidDecl()) {
2639 PrivateCopies.push_back(nullptr);
2640 continue;
2641 }
2642 PrivateCopies.push_back(buildDeclRefExpr(
2643 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2644 } else {
2645 // The variable is also a firstprivate, so initialization sequence
2646 // for private copy is generated already.
2647 PrivateCopies.push_back(nullptr);
2648 }
2649 }
2650 Clause->setPrivateCopies(PrivateCopies);
2651 continue;
2652 }
2653 // Finalize nontemporal clause by handling private copies, if any.
2654 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2655 SmallVector<Expr *, 8> PrivateRefs;
2656 for (Expr *RefExpr : Clause->varlists()) {
2657 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 2657, __PRETTY_FUNCTION__))
;
2658 SourceLocation ELoc;
2659 SourceRange ERange;
2660 Expr *SimpleRefExpr = RefExpr;
2661 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2662 if (Res.second)
2663 // It will be analyzed later.
2664 PrivateRefs.push_back(RefExpr);
2665 ValueDecl *D = Res.first;
2666 if (!D)
2667 continue;
2668
2669 const DSAStackTy::DSAVarData DVar =
2670 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2671 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2672 : SimpleRefExpr);
2673 }
2674 Clause->setPrivateRefs(PrivateRefs);
2675 continue;
2676 }
2677 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2678 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2679 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2680 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2681 if (!DRE)
2682 continue;
2683 ValueDecl *VD = DRE->getDecl();
2684 if (!VD || !isa<VarDecl>(VD))
2685 continue;
2686 DSAStackTy::DSAVarData DVar =
2687 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2688 // OpenMP [2.12.5, target Construct]
2689 // Memory allocators that appear in a uses_allocators clause cannot
2690 // appear in other data-sharing attribute clauses or data-mapping
2691 // attribute clauses in the same construct.
2692 Expr *MapExpr = nullptr;
2693 if (DVar.RefExpr ||
2694 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2695 VD, /*CurrentRegionOnly=*/true,
2696 [VD, &MapExpr](
2697 OMPClauseMappableExprCommon::MappableExprComponentListRef
2698 MapExprComponents,
2699 OpenMPClauseKind C) {
2700 auto MI = MapExprComponents.rbegin();
2701 auto ME = MapExprComponents.rend();
2702 if (MI != ME &&
2703 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2704 VD->getCanonicalDecl()) {
2705 MapExpr = MI->getAssociatedExpression();
2706 return true;
2707 }
2708 return false;
2709 })) {
2710 Diag(D.Allocator->getExprLoc(),
2711 diag::err_omp_allocator_used_in_clauses)
2712 << D.Allocator->getSourceRange();
2713 if (DVar.RefExpr)
2714 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2715 else
2716 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2717 << MapExpr->getSourceRange();
2718 }
2719 }
2720 continue;
2721 }
2722 }
2723 // Check allocate clauses.
2724 if (!CurContext->isDependentContext())
2725 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2726 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2727 }
2728
2729 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2730 DiscardCleanupsInEvaluationContext();
2731 PopExpressionEvaluationContext();
2732}
2733
2734static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2735 Expr *NumIterations, Sema &SemaRef,
2736 Scope *S, DSAStackTy *Stack);
2737
2738namespace {
2739
2740class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2741private:
2742 Sema &SemaRef;
2743
2744public:
2745 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2746 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2747 NamedDecl *ND = Candidate.getCorrectionDecl();
2748 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2749 return VD->hasGlobalStorage() &&
2750 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2751 SemaRef.getCurScope());
2752 }
2753 return false;
2754 }
2755
2756 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2757 return std::make_unique<VarDeclFilterCCC>(*this);
2758 }
2759
2760};
2761
2762class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2763private:
2764 Sema &SemaRef;
2765
2766public:
2767 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2768 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2769 NamedDecl *ND = Candidate.getCorrectionDecl();
2770 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2771 isa<FunctionDecl>(ND))) {
2772 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2773 SemaRef.getCurScope());
2774 }
2775 return false;
2776 }
2777
2778 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2779 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2780 }
2781};
2782
2783} // namespace
2784
2785ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2786 CXXScopeSpec &ScopeSpec,
2787 const DeclarationNameInfo &Id,
2788 OpenMPDirectiveKind Kind) {
2789 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2790 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2791
2792 if (Lookup.isAmbiguous())
2793 return ExprError();
2794
2795 VarDecl *VD;
2796 if (!Lookup.isSingleResult()) {
2797 VarDeclFilterCCC CCC(*this);
2798 if (TypoCorrection Corrected =
2799 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2800 CTK_ErrorRecovery)) {
2801 diagnoseTypo(Corrected,
2802 PDiag(Lookup.empty()
2803 ? diag::err_undeclared_var_use_suggest
2804 : diag::err_omp_expected_var_arg_suggest)
2805 << Id.getName());
2806 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2807 } else {
2808 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2809 : diag::err_omp_expected_var_arg)
2810 << Id.getName();
2811 return ExprError();
2812 }
2813 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2814 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2815 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2816 return ExprError();
2817 }
2818 Lookup.suppressDiagnostics();
2819
2820 // OpenMP [2.9.2, Syntax, C/C++]
2821 // Variables must be file-scope, namespace-scope, or static block-scope.
2822 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2823 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2824 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2825 bool IsDecl =
2826 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2827 Diag(VD->getLocation(),
2828 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2829 << VD;
2830 return ExprError();
2831 }
2832
2833 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2834 NamedDecl *ND = CanonicalVD;
2835 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2836 // A threadprivate directive for file-scope variables must appear outside
2837 // any definition or declaration.
2838 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2839 !getCurLexicalContext()->isTranslationUnit()) {
2840 Diag(Id.getLoc(), diag::err_omp_var_scope)
2841 << getOpenMPDirectiveName(Kind) << VD;
2842 bool IsDecl =
2843 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2844 Diag(VD->getLocation(),
2845 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2846 << VD;
2847 return ExprError();
2848 }
2849 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2850 // A threadprivate directive for static class member variables must appear
2851 // in the class definition, in the same scope in which the member
2852 // variables are declared.
2853 if (CanonicalVD->isStaticDataMember() &&
2854 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2855 Diag(Id.getLoc(), diag::err_omp_var_scope)
2856 << getOpenMPDirectiveName(Kind) << VD;
2857 bool IsDecl =
2858 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2859 Diag(VD->getLocation(),
2860 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2861 << VD;
2862 return ExprError();
2863 }
2864 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2865 // A threadprivate directive for namespace-scope variables must appear
2866 // outside any definition or declaration other than the namespace
2867 // definition itself.
2868 if (CanonicalVD->getDeclContext()->isNamespace() &&
2869 (!getCurLexicalContext()->isFileContext() ||
2870 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2871 Diag(Id.getLoc(), diag::err_omp_var_scope)
2872 << getOpenMPDirectiveName(Kind) << VD;
2873 bool IsDecl =
2874 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2875 Diag(VD->getLocation(),
2876 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2877 << VD;
2878 return ExprError();
2879 }
2880 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2881 // A threadprivate directive for static block-scope variables must appear
2882 // in the scope of the variable and not in a nested scope.
2883 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2884 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2885 Diag(Id.getLoc(), diag::err_omp_var_scope)
2886 << getOpenMPDirectiveName(Kind) << VD;
2887 bool IsDecl =
2888 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2889 Diag(VD->getLocation(),
2890 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2891 << VD;
2892 return ExprError();
2893 }
2894
2895 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2896 // A threadprivate directive must lexically precede all references to any
2897 // of the variables in its list.
2898 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2899 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2900 Diag(Id.getLoc(), diag::err_omp_var_used)
2901 << getOpenMPDirectiveName(Kind) << VD;
2902 return ExprError();
2903 }
2904
2905 QualType ExprType = VD->getType().getNonReferenceType();
2906 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2907 SourceLocation(), VD,
2908 /*RefersToEnclosingVariableOrCapture=*/false,
2909 Id.getLoc(), ExprType, VK_LValue);
2910}
2911
2912Sema::DeclGroupPtrTy
2913Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2914 ArrayRef<Expr *> VarList) {
2915 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2916 CurContext->addDecl(D);
2917 return DeclGroupPtrTy::make(DeclGroupRef(D));
2918 }
2919 return nullptr;
2920}
2921
2922namespace {
2923class LocalVarRefChecker final
2924 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2925 Sema &SemaRef;
2926
2927public:
2928 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2929 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2930 if (VD->hasLocalStorage()) {
2931 SemaRef.Diag(E->getBeginLoc(),
2932 diag::err_omp_local_var_in_threadprivate_init)
2933 << E->getSourceRange();
2934 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2935 << VD << VD->getSourceRange();
2936 return true;
2937 }
2938 }
2939 return false;
2940 }
2941 bool VisitStmt(const Stmt *S) {
2942 for (const Stmt *Child : S->children()) {
2943 if (Child && Visit(Child))
2944 return true;
2945 }
2946 return false;
2947 }
2948 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2949};
2950} // namespace
2951
2952OMPThreadPrivateDecl *
2953Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2954 SmallVector<Expr *, 8> Vars;
2955 for (Expr *RefExpr : VarList) {
2956 auto *DE = cast<DeclRefExpr>(RefExpr);
2957 auto *VD = cast<VarDecl>(DE->getDecl());
2958 SourceLocation ILoc = DE->getExprLoc();
2959
2960 // Mark variable as used.
2961 VD->setReferenced();
2962 VD->markUsed(Context);
2963
2964 QualType QType = VD->getType();
2965 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2966 // It will be analyzed later.
2967 Vars.push_back(DE);
2968 continue;
2969 }
2970
2971 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2972 // A threadprivate variable must not have an incomplete type.
2973 if (RequireCompleteType(ILoc, VD->getType(),
2974 diag::err_omp_threadprivate_incomplete_type)) {
2975 continue;
2976 }
2977
2978 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2979 // A threadprivate variable must not have a reference type.
2980 if (VD->getType()->isReferenceType()) {
2981 Diag(ILoc, diag::err_omp_ref_type_arg)
2982 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2983 bool IsDecl =
2984 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2985 Diag(VD->getLocation(),
2986 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2987 << VD;
2988 continue;
2989 }
2990
2991 // Check if this is a TLS variable. If TLS is not being supported, produce
2992 // the corresponding diagnostic.
2993 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2994 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2995 getLangOpts().OpenMPUseTLS &&
2996 getASTContext().getTargetInfo().isTLSSupported())) ||
2997 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2998 !VD->isLocalVarDecl())) {
2999 Diag(ILoc, diag::err_omp_var_thread_local)
3000 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3001 bool IsDecl =
3002 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3003 Diag(VD->getLocation(),
3004 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3005 << VD;
3006 continue;
3007 }
3008
3009 // Check if initial value of threadprivate variable reference variable with
3010 // local storage (it is not supported by runtime).
3011 if (const Expr *Init = VD->getAnyInitializer()) {
3012 LocalVarRefChecker Checker(*this);
3013 if (Checker.Visit(Init))
3014 continue;
3015 }
3016
3017 Vars.push_back(RefExpr);
3018 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3019 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3020 Context, SourceRange(Loc, Loc)));
3021 if (ASTMutationListener *ML = Context.getASTMutationListener())
3022 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3023 }
3024 OMPThreadPrivateDecl *D = nullptr;
3025 if (!Vars.empty()) {
3026 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3027 Vars);
3028 D->setAccess(AS_public);
3029 }
3030 return D;
3031}
3032
3033static OMPAllocateDeclAttr::AllocatorTypeTy
3034getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3035 if (!Allocator)
3036 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3037 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3038 Allocator->isInstantiationDependent() ||
3039 Allocator->containsUnexpandedParameterPack())
3040 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3041 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3042 const Expr *AE = Allocator->IgnoreParenImpCasts();
3043 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3044 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3045 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3046 llvm::FoldingSetNodeID AEId, DAEId;
3047 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3048 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3049 if (AEId == DAEId) {
3050 AllocatorKindRes = AllocatorKind;
3051 break;
3052 }
3053 }
3054 return AllocatorKindRes;
3055}
3056
3057static bool checkPreviousOMPAllocateAttribute(
3058 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3059 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3060 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3061 return false;
3062 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3063 Expr *PrevAllocator = A->getAllocator();
3064 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3065 getAllocatorKind(S, Stack, PrevAllocator);
3066 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3067 if (AllocatorsMatch &&
3068 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3069 Allocator && PrevAllocator) {
3070 const Expr *AE = Allocator->IgnoreParenImpCasts();
3071 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3072 llvm::FoldingSetNodeID AEId, PAEId;
3073 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3074 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3075 AllocatorsMatch = AEId == PAEId;
3076 }
3077 if (!AllocatorsMatch) {
3078 SmallString<256> AllocatorBuffer;
3079 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3080 if (Allocator)
3081 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3082 SmallString<256> PrevAllocatorBuffer;
3083 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3084 if (PrevAllocator)
3085 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3086 S.getPrintingPolicy());
3087
3088 SourceLocation AllocatorLoc =
3089 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3090 SourceRange AllocatorRange =
3091 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3092 SourceLocation PrevAllocatorLoc =
3093 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3094 SourceRange PrevAllocatorRange =
3095 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3096 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3097 << (Allocator ? 1 : 0) << AllocatorStream.str()
3098 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3099 << AllocatorRange;
3100 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3101 << PrevAllocatorRange;
3102 return true;
3103 }
3104 return false;
3105}
3106
3107static void
3108applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3109 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3110 Expr *Allocator, SourceRange SR) {
3111 if (VD->hasAttr<OMPAllocateDeclAttr>())
3112 return;
3113 if (Allocator &&
3114 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3115 Allocator->isInstantiationDependent() ||
3116 Allocator->containsUnexpandedParameterPack()))
3117 return;
3118 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3119 Allocator, SR);
3120 VD->addAttr(A);
3121 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3122 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3123}
3124
3125Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3126 SourceLocation Loc, ArrayRef<Expr *> VarList,
3127 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3128 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 3128, __PRETTY_FUNCTION__))
;
3129 Expr *Allocator = nullptr;
3130 if (Clauses.empty()) {
3131 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3132 // allocate directives that appear in a target region must specify an
3133 // allocator clause unless a requires directive with the dynamic_allocators
3134 // clause is present in the same compilation unit.
3135 if (LangOpts.OpenMPIsDevice &&
3136 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3137 targetDiag(Loc, diag::err_expected_allocator_clause);
3138 } else {
3139 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3140 }
3141 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3142 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3143 SmallVector<Expr *, 8> Vars;
3144 for (Expr *RefExpr : VarList) {
3145 auto *DE = cast<DeclRefExpr>(RefExpr);
3146 auto *VD = cast<VarDecl>(DE->getDecl());
3147
3148 // Check if this is a TLS variable or global register.
3149 if (VD->getTLSKind() != VarDecl::TLS_None ||
3150 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3151 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3152 !VD->isLocalVarDecl()))
3153 continue;
3154
3155 // If the used several times in the allocate directive, the same allocator
3156 // must be used.
3157 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3158 AllocatorKind, Allocator))
3159 continue;
3160
3161 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3162 // If a list item has a static storage type, the allocator expression in the
3163 // allocator clause must be a constant expression that evaluates to one of
3164 // the predefined memory allocator values.
3165 if (Allocator && VD->hasGlobalStorage()) {
3166 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3167 Diag(Allocator->getExprLoc(),
3168 diag::err_omp_expected_predefined_allocator)
3169 << Allocator->getSourceRange();
3170 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3171 VarDecl::DeclarationOnly;
3172 Diag(VD->getLocation(),
3173 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3174 << VD;
3175 continue;
3176 }
3177 }
3178
3179 Vars.push_back(RefExpr);
3180 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3181 DE->getSourceRange());
3182 }
3183 if (Vars.empty())
3184 return nullptr;
3185 if (!Owner)
3186 Owner = getCurLexicalContext();
3187 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3188 D->setAccess(AS_public);
3189 Owner->addDecl(D);
3190 return DeclGroupPtrTy::make(DeclGroupRef(D));
3191}
3192
3193Sema::DeclGroupPtrTy
3194Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3195 ArrayRef<OMPClause *> ClauseList) {
3196 OMPRequiresDecl *D = nullptr;
3197 if (!CurContext->isFileContext()) {
3198 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3199 } else {
3200 D = CheckOMPRequiresDecl(Loc, ClauseList);
3201 if (D) {
3202 CurContext->addDecl(D);
3203 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3204 }
3205 }
3206 return DeclGroupPtrTy::make(DeclGroupRef(D));
3207}
3208
3209void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3210 OpenMPDirectiveKind DKind,
3211 ArrayRef<StringRef> Assumptions,
3212 bool SkippedClauses) {
3213 if (!SkippedClauses && Assumptions.empty())
3214 Diag(Loc, diag::err_omp_no_clause_for_directive)
3215 << llvm::omp::getAllAssumeClauseOptions()
3216 << llvm::omp::getOpenMPDirectiveName(DKind);
3217
3218 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3219 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3220 OMPAssumeScoped.push_back(AA);
3221 return;
3222 }
3223
3224 // Global assumes without assumption clauses are ignored.
3225 if (Assumptions.empty())
3226 return;
3227
3228 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 3229, __PRETTY_FUNCTION__))
3229 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 3229, __PRETTY_FUNCTION__))
;
3230 OMPAssumeGlobal.push_back(AA);
3231
3232 // The OMPAssumeGlobal scope above will take care of new declarations but
3233 // we also want to apply the assumption to existing ones, e.g., to
3234 // declarations in included headers. To this end, we traverse all existing
3235 // declaration contexts and annotate function declarations here.
3236 SmallVector<DeclContext *, 8> DeclContexts;
3237 auto *Ctx = CurContext;
3238 while (Ctx->getLexicalParent())
3239 Ctx = Ctx->getLexicalParent();
3240 DeclContexts.push_back(Ctx);
3241 while (!DeclContexts.empty()) {
3242 DeclContext *DC = DeclContexts.pop_back_val();
3243 for (auto *SubDC : DC->decls()) {
3244 if (SubDC->isInvalidDecl())
3245 continue;
3246 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3247 DeclContexts.push_back(CTD->getTemplatedDecl());
3248 for (auto *S : CTD->specializations())
3249 DeclContexts.push_back(S);
3250 continue;
3251 }
3252 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3253 DeclContexts.push_back(DC);
3254 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3255 F->addAttr(AA);
3256 continue;
3257 }
3258 }
3259 }
3260}
3261
3262void Sema::ActOnOpenMPEndAssumesDirective() {
3263 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 3263, __PRETTY_FUNCTION__))
;
3264 OMPAssumeScoped.pop_back();
3265}
3266
3267OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3268 ArrayRef<OMPClause *> ClauseList) {
3269 /// For target specific clauses, the requires directive cannot be
3270 /// specified after the handling of any of the target regions in the
3271 /// current compilation unit.
3272 ArrayRef<SourceLocation> TargetLocations =
3273 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3274 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3275 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3276 for (const OMPClause *CNew : ClauseList) {
3277 // Check if any of the requires clauses affect target regions.
3278 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3279 isa<OMPUnifiedAddressClause>(CNew) ||
3280 isa<OMPReverseOffloadClause>(CNew) ||
3281 isa<OMPDynamicAllocatorsClause>(CNew)) {
3282 Diag(Loc, diag::err_omp_directive_before_requires)
3283 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3284 for (SourceLocation TargetLoc : TargetLocations) {
3285 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3286 << "target";
3287 }
3288 } else if (!AtomicLoc.isInvalid() &&
3289 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3290 Diag(Loc, diag::err_omp_directive_before_requires)
3291 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3292 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3293 << "atomic";
3294 }
3295 }
3296 }
3297
3298 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3299 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3300 ClauseList);
3301 return nullptr;
3302}
3303
3304static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3305 const ValueDecl *D,
3306 const DSAStackTy::DSAVarData &DVar,
3307 bool IsLoopIterVar) {
3308 if (DVar.RefExpr) {
3309 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3310 << getOpenMPClauseName(DVar.CKind);
3311 return;
3312 }
3313 enum {
3314 PDSA_StaticMemberShared,
3315 PDSA_StaticLocalVarShared,
3316 PDSA_LoopIterVarPrivate,
3317 PDSA_LoopIterVarLinear,
3318 PDSA_LoopIterVarLastprivate,
3319 PDSA_ConstVarShared,
3320 PDSA_GlobalVarShared,
3321 PDSA_TaskVarFirstprivate,
3322 PDSA_LocalVarPrivate,
3323 PDSA_Implicit
3324 } Reason = PDSA_Implicit;
3325 bool ReportHint = false;
3326 auto ReportLoc = D->getLocation();
3327 auto *VD = dyn_cast<VarDecl>(D);
3328 if (IsLoopIterVar) {
3329 if (DVar.CKind == OMPC_private)
3330 Reason = PDSA_LoopIterVarPrivate;
3331 else if (DVar.CKind == OMPC_lastprivate)
3332 Reason = PDSA_LoopIterVarLastprivate;
3333 else
3334 Reason = PDSA_LoopIterVarLinear;
3335 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3336 DVar.CKind == OMPC_firstprivate) {
3337 Reason = PDSA_TaskVarFirstprivate;
3338 ReportLoc = DVar.ImplicitDSALoc;
3339 } else if (VD && VD->isStaticLocal())
3340 Reason = PDSA_StaticLocalVarShared;
3341 else if (VD && VD->isStaticDataMember())
3342 Reason = PDSA_StaticMemberShared;
3343 else if (VD && VD->isFileVarDecl())
3344 Reason = PDSA_GlobalVarShared;
3345 else if (D->getType().isConstant(SemaRef.getASTContext()))
3346 Reason = PDSA_ConstVarShared;
3347 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3348 ReportHint = true;
3349 Reason = PDSA_LocalVarPrivate;
3350 }
3351 if (Reason != PDSA_Implicit) {
3352 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3353 << Reason << ReportHint
3354 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3355 } else if (DVar.ImplicitDSALoc.isValid()) {
3356 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3357 << getOpenMPClauseName(DVar.CKind);
3358 }
3359}
3360
3361static OpenMPMapClauseKind
3362getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3363 bool IsAggregateOrDeclareTarget) {
3364 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3365 switch (M) {
3366 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3367 Kind = OMPC_MAP_alloc;
3368 break;
3369 case OMPC_DEFAULTMAP_MODIFIER_to:
3370 Kind = OMPC_MAP_to;
3371 break;
3372 case OMPC_DEFAULTMAP_MODIFIER_from:
3373 Kind = OMPC_MAP_from;
3374 break;
3375 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3376 Kind = OMPC_MAP_tofrom;
3377 break;
3378 case OMPC_DEFAULTMAP_MODIFIER_present:
3379 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3380 // If implicit-behavior is present, each variable referenced in the
3381 // construct in the category specified by variable-category is treated as if
3382 // it had been listed in a map clause with the map-type of alloc and
3383 // map-type-modifier of present.
3384 Kind = OMPC_MAP_alloc;
3385 break;
3386 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3387 case OMPC_DEFAULTMAP_MODIFIER_last:
3388 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 3388)
;
3389 case OMPC_DEFAULTMAP_MODIFIER_none:
3390 case OMPC_DEFAULTMAP_MODIFIER_default:
3391 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3392 // IsAggregateOrDeclareTarget could be true if:
3393 // 1. the implicit behavior for aggregate is tofrom
3394 // 2. it's a declare target link
3395 if (IsAggregateOrDeclareTarget) {
3396 Kind = OMPC_MAP_tofrom;
3397 break;
3398 }
3399 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 3399)
;
3400 }
3401 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 3401, __PRETTY_FUNCTION__))
;
3402 return Kind;
3403}
3404
3405namespace {
3406class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3407 DSAStackTy *Stack;
3408 Sema &SemaRef;
3409 bool ErrorFound = false;
3410 bool TryCaptureCXXThisMembers = false;
3411 CapturedStmt *CS = nullptr;
3412 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3413 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3414 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3415 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3416 ImplicitMapModifier[DefaultmapKindNum];
3417 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3418 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3419
3420 void VisitSubCaptures(OMPExecutableDirective *S) {
3421 // Check implicitly captured variables.
3422 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3423 return;
3424 if (S->getDirectiveKind() == OMPD_atomic ||
3425 S->getDirectiveKind() == OMPD_critical ||
3426 S->getDirectiveKind() == OMPD_section ||
3427 S->getDirectiveKind() == OMPD_master ||
3428 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3429 Visit(S->getAssociatedStmt());
3430 return;
3431 }
3432 visitSubCaptures(S->getInnermostCapturedStmt());
3433 // Try to capture inner this->member references to generate correct mappings
3434 // and diagnostics.
3435 if (TryCaptureCXXThisMembers ||
3436 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3437 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3438 [](const CapturedStmt::Capture &C) {
3439 return C.capturesThis();
3440 }))) {
3441 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3442 TryCaptureCXXThisMembers = true;
3443 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3444 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3445 }
3446 // In tasks firstprivates are not captured anymore, need to analyze them
3447 // explicitly.
3448 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3449 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3450 for (OMPClause *C : S->clauses())
3451 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3452 for (Expr *Ref : FC->varlists())
3453 Visit(Ref);
3454 }
3455 }
3456 }
3457
3458public:
3459 void VisitDeclRefExpr(DeclRefExpr *E) {
3460 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3461 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3462 E->isInstantiationDependent())
3463 return;
3464 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3465 // Check the datasharing rules for the expressions in the clauses.
3466 if (!CS) {
3467 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3468 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3469 Visit(CED->getInit());
3470 return;
3471 }
3472 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3473 // Do not analyze internal variables and do not enclose them into
3474 // implicit clauses.
3475 return;
3476 VD = VD->getCanonicalDecl();
3477 // Skip internally declared variables.
3478 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3479 !Stack->isImplicitTaskFirstprivate(VD))
3480 return;
3481 // Skip allocators in uses_allocators clauses.
3482 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3483 return;
3484
3485 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3486 // Check if the variable has explicit DSA set and stop analysis if it so.
3487 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3488 return;
3489
3490 // Skip internally declared static variables.
3491 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3492 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3493 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3494 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3495 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3496 !Stack->isImplicitTaskFirstprivate(VD))
3497 return;
3498
3499 SourceLocation ELoc = E->getExprLoc();
3500 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3501 // The default(none) clause requires that each variable that is referenced
3502 // in the construct, and does not have a predetermined data-sharing
3503 // attribute, must have its data-sharing attribute explicitly determined
3504 // by being listed in a data-sharing attribute clause.
3505 if (DVar.CKind == OMPC_unknown &&
3506 (Stack->getDefaultDSA() == DSA_none ||
3507 Stack->getDefaultDSA() == DSA_firstprivate) &&
3508 isImplicitOrExplicitTaskingRegion(DKind) &&
3509 VarsWithInheritedDSA.count(VD) == 0) {
3510 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3511 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3512 DSAStackTy::DSAVarData DVar =
3513 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3514 InheritedDSA = DVar.CKind == OMPC_unknown;
3515 }
3516 if (InheritedDSA)
3517 VarsWithInheritedDSA[VD] = E;
3518 return;
3519 }
3520
3521 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3522 // If implicit-behavior is none, each variable referenced in the
3523 // construct that does not have a predetermined data-sharing attribute
3524 // and does not appear in a to or link clause on a declare target
3525 // directive must be listed in a data-mapping attribute clause, a
3526 // data-haring attribute clause (including a data-sharing attribute
3527 // clause on a combined construct where target. is one of the
3528 // constituent constructs), or an is_device_ptr clause.
3529 OpenMPDefaultmapClauseKind ClauseKind =
3530 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3531 if (SemaRef.getLangOpts().OpenMP >= 50) {
3532 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3533 OMPC_DEFAULTMAP_MODIFIER_none;
3534 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3535 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3536 // Only check for data-mapping attribute and is_device_ptr here
3537 // since we have already make sure that the declaration does not
3538 // have a data-sharing attribute above
3539 if (!Stack->checkMappableExprComponentListsForDecl(
3540 VD, /*CurrentRegionOnly=*/true,
3541 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3542 MapExprComponents,
3543 OpenMPClauseKind) {
3544 auto MI = MapExprComponents.rbegin();
3545 auto ME = MapExprComponents.rend();
3546 return MI != ME && MI->getAssociatedDeclaration() == VD;
3547 })) {
3548 VarsWithInheritedDSA[VD] = E;
3549 return;
3550 }
3551 }
3552 }
3553 if (SemaRef.getLangOpts().OpenMP > 50) {
3554 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3555 OMPC_DEFAULTMAP_MODIFIER_present;
3556 if (IsModifierPresent) {
3557 if (llvm::find(ImplicitMapModifier[ClauseKind],
3558 OMPC_MAP_MODIFIER_present) ==
3559 std::end(ImplicitMapModifier[ClauseKind])) {
3560 ImplicitMapModifier[ClauseKind].push_back(
3561 OMPC_MAP_MODIFIER_present);
3562 }
3563 }
3564 }
3565
3566 if (isOpenMPTargetExecutionDirective(DKind) &&
3567 !Stack->isLoopControlVariable(VD).first) {
3568 if (!Stack->checkMappableExprComponentListsForDecl(
3569 VD, /*CurrentRegionOnly=*/true,
3570 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3571 StackComponents,
3572 OpenMPClauseKind) {
3573 if (SemaRef.LangOpts.OpenMP >= 50)
3574 return !StackComponents.empty();
3575 // Variable is used if it has been marked as an array, array
3576 // section, array shaping or the variable iself.
3577 return StackComponents.size() == 1 ||
3578 std::all_of(
3579 std::next(StackComponents.rbegin()),
3580 StackComponents.rend(),
3581 [](const OMPClauseMappableExprCommon::
3582 MappableComponent &MC) {
3583 return MC.getAssociatedDeclaration() ==
3584 nullptr &&
3585 (isa<OMPArraySectionExpr>(
3586 MC.getAssociatedExpression()) ||
3587 isa<OMPArrayShapingExpr>(
3588 MC.getAssociatedExpression()) ||
3589 isa<ArraySubscriptExpr>(
3590 MC.getAssociatedExpression()));
3591 });
3592 })) {
3593 bool IsFirstprivate = false;
3594 // By default lambdas are captured as firstprivates.
3595 if (const auto *RD =
3596 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3597 IsFirstprivate = RD->isLambda();
3598 IsFirstprivate =
3599 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3600 if (IsFirstprivate) {
3601 ImplicitFirstprivate.emplace_back(E);
3602 } else {
3603 OpenMPDefaultmapClauseModifier M =
3604 Stack->getDefaultmapModifier(ClauseKind);
3605 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3606 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3607 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3608 }
3609 return;
3610 }
3611 }
3612
3613 // OpenMP [2.9.3.6, Restrictions, p.2]
3614 // A list item that appears in a reduction clause of the innermost
3615 // enclosing worksharing or parallel construct may not be accessed in an
3616 // explicit task.
3617 DVar = Stack->hasInnermostDSA(
3618 VD,
3619 [](OpenMPClauseKind C, bool AppliedToPointee) {
3620 return C == OMPC_reduction && !AppliedToPointee;
3621 },
3622 [](OpenMPDirectiveKind K) {
3623 return isOpenMPParallelDirective(K) ||
3624 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3625 },
3626 /*FromParent=*/true);
3627 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3628 ErrorFound = true;
3629 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3630 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3631 return;
3632 }
3633
3634 // Define implicit data-sharing attributes for task.
3635 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3636 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3637 (Stack->getDefaultDSA() == DSA_firstprivate &&
3638 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3639 !Stack->isLoopControlVariable(VD).first) {
3640 ImplicitFirstprivate.push_back(E);
3641 return;
3642 }
3643
3644 // Store implicitly used globals with declare target link for parent
3645 // target.
3646 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3647 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3648 Stack->addToParentTargetRegionLinkGlobals(E);
3649 return;
3650 }
3651 }
3652 }
3653 void VisitMemberExpr(MemberExpr *E) {
3654 if (E->isTypeDependent() || E->isValueDependent() ||
3655 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3656 return;
3657 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3658 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3659 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3660 if (!FD)
3661 return;
3662 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3663 // Check if the variable has explicit DSA set and stop analysis if it
3664 // so.
3665 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3666 return;
3667
3668 if (isOpenMPTargetExecutionDirective(DKind) &&
3669 !Stack->isLoopControlVariable(FD).first &&
3670 !Stack->checkMappableExprComponentListsForDecl(
3671 FD, /*CurrentRegionOnly=*/true,
3672 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3673 StackComponents,
3674 OpenMPClauseKind) {
3675 return isa<CXXThisExpr>(
3676 cast<MemberExpr>(
3677 StackComponents.back().getAssociatedExpression())
3678 ->getBase()
3679 ->IgnoreParens());
3680 })) {
3681 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3682 // A bit-field cannot appear in a map clause.
3683 //
3684 if (FD->isBitField())
3685 return;
3686
3687 // Check to see if the member expression is referencing a class that
3688 // has already been explicitly mapped
3689 if (Stack->isClassPreviouslyMapped(TE->getType()))
3690 return;
3691
3692 OpenMPDefaultmapClauseModifier Modifier =
3693 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3694 OpenMPDefaultmapClauseKind ClauseKind =
3695 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3696 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3697 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3698 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3699 return;
3700 }
3701
3702 SourceLocation ELoc = E->getExprLoc();
3703 // OpenMP [2.9.3.6, Restrictions, p.2]
3704 // A list item that appears in a reduction clause of the innermost
3705 // enclosing worksharing or parallel construct may not be accessed in
3706 // an explicit task.
3707 DVar = Stack->hasInnermostDSA(
3708 FD,
3709 [](OpenMPClauseKind C, bool AppliedToPointee) {
3710 return C == OMPC_reduction && !AppliedToPointee;
3711 },
3712 [](OpenMPDirectiveKind K) {
3713 return isOpenMPParallelDirective(K) ||
3714 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3715 },
3716 /*FromParent=*/true);
3717 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3718 ErrorFound = true;
3719 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3720 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3721 return;
3722 }
3723
3724 // Define implicit data-sharing attributes for task.
3725 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3726 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3727 !Stack->isLoopControlVariable(FD).first) {
3728 // Check if there is a captured expression for the current field in the
3729 // region. Do not mark it as firstprivate unless there is no captured
3730 // expression.
3731 // TODO: try to make it firstprivate.
3732 if (DVar.CKind != OMPC_unknown)
3733 ImplicitFirstprivate.push_back(E);
3734 }
3735 return;
3736 }
3737 if (isOpenMPTargetExecutionDirective(DKind)) {
3738 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3739 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3740 Stack->getCurrentDirective(),
3741 /*NoDiagnose=*/true))
3742 return;
3743 const auto *VD = cast<ValueDecl>(
3744 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3745 if (!Stack->checkMappableExprComponentListsForDecl(
3746 VD, /*CurrentRegionOnly=*/true,
3747 [&CurComponents](
3748 OMPClauseMappableExprCommon::MappableExprComponentListRef
3749 StackComponents,
3750 OpenMPClauseKind) {
3751 auto CCI = CurComponents.rbegin();
3752 auto CCE = CurComponents.rend();
3753 for (const auto &SC : llvm::reverse(StackComponents)) {
3754 // Do both expressions have the same kind?
3755 if (CCI->getAssociatedExpression()->getStmtClass() !=
3756 SC.getAssociatedExpression()->getStmtClass())
3757 if (!((isa<OMPArraySectionExpr>(
3758 SC.getAssociatedExpression()) ||
3759 isa<OMPArrayShapingExpr>(
3760 SC.getAssociatedExpression())) &&
3761 isa<ArraySubscriptExpr>(
3762 CCI->getAssociatedExpression())))
3763 return false;
3764
3765 const Decl *CCD = CCI->getAssociatedDeclaration();
3766 const Decl *SCD = SC.getAssociatedDeclaration();
3767 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3768 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3769 if (SCD != CCD)
3770 return false;
3771 std::advance(CCI, 1);
3772 if (CCI == CCE)
3773 break;
3774 }
3775 return true;
3776 })) {
3777 Visit(E->getBase());
3778 }
3779 } else if (!TryCaptureCXXThisMembers) {
3780 Visit(E->getBase());
3781 }
3782 }
3783 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3784 for (OMPClause *C : S->clauses()) {
3785 // Skip analysis of arguments of implicitly defined firstprivate clause
3786 // for task|target directives.
3787 // Skip analysis of arguments of implicitly defined map clause for target
3788 // directives.
3789 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3790 C->isImplicit() &&
3791 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3792 for (Stmt *CC : C->children()) {
3793 if (CC)
3794 Visit(CC);
3795 }
3796 }
3797 }
3798 // Check implicitly captured variables.
3799 VisitSubCaptures(S);
3800 }
3801
3802 void VisitOMPTileDirective(OMPTileDirective *S) {
3803 // #pragma omp tile does not introduce data sharing.
3804 VisitStmt(S);
3805 }
3806
3807 void VisitStmt(Stmt *S) {
3808 for (Stmt *C : S->children()) {
3809 if (C) {
3810 // Check implicitly captured variables in the task-based directives to
3811 // check if they must be firstprivatized.
3812 Visit(C);
3813 }
3814 }
3815 }
3816
3817 void visitSubCaptures(CapturedStmt *S) {
3818 for (const CapturedStmt::Capture &Cap : S->captures()) {
3819 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3820 continue;
3821 VarDecl *VD = Cap.getCapturedVar();
3822 // Do not try to map the variable if it or its sub-component was mapped
3823 // already.
3824 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3825 Stack->checkMappableExprComponentListsForDecl(
3826 VD, /*CurrentRegionOnly=*/true,
3827 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3828 OpenMPClauseKind) { return true; }))
3829 continue;
3830 DeclRefExpr *DRE = buildDeclRefExpr(
3831 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3832 Cap.getLocation(), /*RefersToCapture=*/true);
3833 Visit(DRE);
3834 }
3835 }
3836 bool isErrorFound() const { return ErrorFound; }
3837 ArrayRef<Expr *> getImplicitFirstprivate() const {
3838 return ImplicitFirstprivate;
3839 }
3840 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3841 OpenMPMapClauseKind MK) const {
3842 return ImplicitMap[DK][MK];
3843 }
3844 ArrayRef<OpenMPMapModifierKind>
3845 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3846 return ImplicitMapModifier[Kind];
3847 }
3848 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3849 return VarsWithInheritedDSA;
3850 }
3851
3852 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3853 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3854 // Process declare target link variables for the target directives.
3855 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3856 for (DeclRefExpr *E : Stack->getLinkGlobals())
3857 Visit(E);
3858 }
3859 }
3860};
3861} // namespace
3862
3863void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3864 switch (DKind) {
3865 case OMPD_parallel:
3866 case OMPD_parallel_for:
3867 case OMPD_parallel_for_simd:
3868 case OMPD_parallel_sections:
3869 case OMPD_parallel_master:
3870 case OMPD_teams:
3871 case OMPD_teams_distribute:
3872 case OMPD_teams_distribute_simd: {
3873 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3874 QualType KmpInt32PtrTy =
3875 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3876 Sema::CapturedParamNameType Params[] = {
3877 std::make_pair(".global_tid.", KmpInt32PtrTy),
3878 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3879 std::make_pair(StringRef(), QualType()) // __context with shared vars
3880 };
3881 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3882 Params);
3883 break;
3884 }
3885 case OMPD_target_teams:
3886 case OMPD_target_parallel:
3887 case OMPD_target_parallel_for:
3888 case OMPD_target_parallel_for_simd:
3889 case OMPD_target_teams_distribute:
3890 case OMPD_target_teams_distribute_simd: {
3891 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3892 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3893 QualType KmpInt32PtrTy =
3894 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3895 QualType Args[] = {VoidPtrTy};
3896 FunctionProtoType::ExtProtoInfo EPI;
3897 EPI.Variadic = true;
3898 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3899 Sema::CapturedParamNameType Params[] = {
3900 std::make_pair(".global_tid.", KmpInt32Ty),
3901 std::make_pair(".part_id.", KmpInt32PtrTy),
3902 std::make_pair(".privates.", VoidPtrTy),
3903 std::make_pair(
3904 ".copy_fn.",
3905 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3906 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3907 std::make_pair(StringRef(), QualType()) // __context with shared vars
3908 };
3909 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3910 Params, /*OpenMPCaptureLevel=*/0);
3911 // Mark this captured region as inlined, because we don't use outlined
3912 // function directly.
3913 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3914 AlwaysInlineAttr::CreateImplicit(
3915 Context, {}, AttributeCommonInfo::AS_Keyword,
3916 AlwaysInlineAttr::Keyword_forceinline));
3917 Sema::CapturedParamNameType ParamsTarget[] = {
3918 std::make_pair(StringRef(), QualType()) // __context with shared vars
3919 };
3920 // Start a captured region for 'target' with no implicit parameters.
3921 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3922 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3923 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3924 std::make_pair(".global_tid.", KmpInt32PtrTy),
3925 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3926 std::make_pair(StringRef(), QualType()) // __context with shared vars
3927 };
3928 // Start a captured region for 'teams' or 'parallel'. Both regions have
3929 // the same implicit parameters.
3930 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3931 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3932 break;
3933 }
3934 case OMPD_target:
3935 case OMPD_target_simd: {
3936 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3937 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3938 QualType KmpInt32PtrTy =
3939 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3940 QualType Args[] = {VoidPtrTy};
3941 FunctionProtoType::ExtProtoInfo EPI;
3942 EPI.Variadic = true;
3943 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3944 Sema::CapturedParamNameType Params[] = {
3945 std::make_pair(".global_tid.", KmpInt32Ty),
3946 std::make_pair(".part_id.", KmpInt32PtrTy),
3947 std::make_pair(".privates.", VoidPtrTy),
3948 std::make_pair(
3949 ".copy_fn.",
3950 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3951 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3952 std::make_pair(StringRef(), QualType()) // __context with shared vars
3953 };
3954 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3955 Params, /*OpenMPCaptureLevel=*/0);
3956 // Mark this captured region as inlined, because we don't use outlined
3957 // function directly.
3958 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3959 AlwaysInlineAttr::CreateImplicit(
3960 Context, {}, AttributeCommonInfo::AS_Keyword,
3961 AlwaysInlineAttr::Keyword_forceinline));
3962 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3963 std::make_pair(StringRef(), QualType()),
3964 /*OpenMPCaptureLevel=*/1);
3965 break;
3966 }
3967 case OMPD_atomic:
3968 case OMPD_critical:
3969 case OMPD_section:
3970 case OMPD_master:
3971 case OMPD_tile:
3972 break;
3973 case OMPD_simd:
3974 case OMPD_for:
3975 case OMPD_for_simd:
3976 case OMPD_sections:
3977 case OMPD_single:
3978 case OMPD_taskgroup:
3979 case OMPD_distribute:
3980 case OMPD_distribute_simd:
3981 case OMPD_ordered:
3982 case OMPD_target_data:
3983 case OMPD_dispatch: {
3984 Sema::CapturedParamNameType Params[] = {
3985 std::make_pair(StringRef(), QualType()) // __context with shared vars
3986 };
3987 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3988 Params);
3989 break;
3990 }
3991 case OMPD_task: {
3992 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3993 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3994 QualType KmpInt32PtrTy =
3995 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3996 QualType Args[] = {VoidPtrTy};
3997 FunctionProtoType::ExtProtoInfo EPI;
3998 EPI.Variadic = true;
3999 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4000 Sema::CapturedParamNameType Params[] = {
4001 std::make_pair(".global_tid.", KmpInt32Ty),
4002 std::make_pair(".part_id.", KmpInt32PtrTy),
4003 std::make_pair(".privates.", VoidPtrTy),
4004 std::make_pair(
4005 ".copy_fn.",
4006 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4007 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4008 std::make_pair(StringRef(), QualType()) // __context with shared vars
4009 };
4010 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4011 Params);
4012 // Mark this captured region as inlined, because we don't use outlined
4013 // function directly.
4014 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4015 AlwaysInlineAttr::CreateImplicit(
4016 Context, {}, AttributeCommonInfo::AS_Keyword,
4017 AlwaysInlineAttr::Keyword_forceinline));
4018 break;
4019 }
4020 case OMPD_taskloop:
4021 case OMPD_taskloop_simd:
4022 case OMPD_master_taskloop:
4023 case OMPD_master_taskloop_simd: {
4024 QualType KmpInt32Ty =
4025 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4026 .withConst();
4027 QualType KmpUInt64Ty =
4028 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4029 .withConst();
4030 QualType KmpInt64Ty =
4031 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4032 .withConst();
4033 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4034 QualType KmpInt32PtrTy =
4035 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4036 QualType Args[] = {VoidPtrTy};
4037 FunctionProtoType::ExtProtoInfo EPI;
4038 EPI.Variadic = true;
4039 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4040 Sema::CapturedParamNameType Params[] = {
4041 std::make_pair(".global_tid.", KmpInt32Ty),
4042 std::make_pair(".part_id.", KmpInt32PtrTy),
4043 std::make_pair(".privates.", VoidPtrTy),
4044 std::make_pair(
4045 ".copy_fn.",
4046 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4047 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4048 std::make_pair(".lb.", KmpUInt64Ty),
4049 std::make_pair(".ub.", KmpUInt64Ty),
4050 std::make_pair(".st.", KmpInt64Ty),
4051 std::make_pair(".liter.", KmpInt32Ty),
4052 std::make_pair(".reductions.", VoidPtrTy),
4053 std::make_pair(StringRef(), QualType()) // __context with shared vars
4054 };
4055 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4056 Params);
4057 // Mark this captured region as inlined, because we don't use outlined
4058 // function directly.
4059 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4060 AlwaysInlineAttr::CreateImplicit(
4061 Context, {}, AttributeCommonInfo::AS_Keyword,
4062 AlwaysInlineAttr::Keyword_forceinline));
4063 break;
4064 }
4065 case OMPD_parallel_master_taskloop:
4066 case OMPD_parallel_master_taskloop_simd: {
4067 QualType KmpInt32Ty =
4068 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4069 .withConst();
4070 QualType KmpUInt64Ty =
4071 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4072 .withConst();
4073 QualType KmpInt64Ty =
4074 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4075 .withConst();
4076 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4077 QualType KmpInt32PtrTy =
4078 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4079 Sema::CapturedParamNameType ParamsParallel[] = {
4080 std::make_pair(".global_tid.", KmpInt32PtrTy),
4081 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4082 std::make_pair(StringRef(), QualType()) // __context with shared vars
4083 };
4084 // Start a captured region for 'parallel'.
4085 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4086 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4087 QualType Args[] = {VoidPtrTy};
4088 FunctionProtoType::ExtProtoInfo EPI;
4089 EPI.Variadic = true;
4090 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4091 Sema::CapturedParamNameType Params[] = {
4092 std::make_pair(".global_tid.", KmpInt32Ty),
4093 std::make_pair(".part_id.", KmpInt32PtrTy),
4094 std::make_pair(".privates.", VoidPtrTy),
4095 std::make_pair(
4096 ".copy_fn.",
4097 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4098 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4099 std::make_pair(".lb.", KmpUInt64Ty),
4100 std::make_pair(".ub.", KmpUInt64Ty),
4101 std::make_pair(".st.", KmpInt64Ty),
4102 std::make_pair(".liter.", KmpInt32Ty),
4103 std::make_pair(".reductions.", VoidPtrTy),
4104 std::make_pair(StringRef(), QualType()) // __context with shared vars
4105 };
4106 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4107 Params, /*OpenMPCaptureLevel=*/1);
4108 // Mark this captured region as inlined, because we don't use outlined
4109 // function directly.
4110 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4111 AlwaysInlineAttr::CreateImplicit(
4112 Context, {}, AttributeCommonInfo::AS_Keyword,
4113 AlwaysInlineAttr::Keyword_forceinline));
4114 break;
4115 }
4116 case OMPD_distribute_parallel_for_simd:
4117 case OMPD_distribute_parallel_for: {
4118 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4119 QualType KmpInt32PtrTy =
4120 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4121 Sema::CapturedParamNameType Params[] = {
4122 std::make_pair(".global_tid.", KmpInt32PtrTy),
4123 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4124 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4125 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4126 std::make_pair(StringRef(), QualType()) // __context with shared vars
4127 };
4128 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4129 Params);
4130 break;
4131 }
4132 case OMPD_target_teams_distribute_parallel_for:
4133 case OMPD_target_teams_distribute_parallel_for_simd: {
4134 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4135 QualType KmpInt32PtrTy =
4136 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4137 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4138
4139 QualType Args[] = {VoidPtrTy};
4140 FunctionProtoType::ExtProtoInfo EPI;
4141 EPI.Variadic = true;
4142 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4143 Sema::CapturedParamNameType Params[] = {
4144 std::make_pair(".global_tid.", KmpInt32Ty),
4145 std::make_pair(".part_id.", KmpInt32PtrTy),
4146 std::make_pair(".privates.", VoidPtrTy),
4147 std::make_pair(
4148 ".copy_fn.",
4149 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4150 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4151 std::make_pair(StringRef(), QualType()) // __context with shared vars
4152 };
4153 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4154 Params, /*OpenMPCaptureLevel=*/0);
4155 // Mark this captured region as inlined, because we don't use outlined
4156 // function directly.
4157 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4158 AlwaysInlineAttr::CreateImplicit(
4159 Context, {}, AttributeCommonInfo::AS_Keyword,
4160 AlwaysInlineAttr::Keyword_forceinline));
4161 Sema::CapturedParamNameType ParamsTarget[] = {
4162 std::make_pair(StringRef(), QualType()) // __context with shared vars
4163 };
4164 // Start a captured region for 'target' with no implicit parameters.
4165 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4166 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4167
4168 Sema::CapturedParamNameType ParamsTeams[] = {
4169 std::make_pair(".global_tid.", KmpInt32PtrTy),
4170 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4171 std::make_pair(StringRef(), QualType()) // __context with shared vars
4172 };
4173 // Start a captured region for 'target' with no implicit parameters.
4174 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4175 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4176
4177 Sema::CapturedParamNameType ParamsParallel[] = {
4178 std::make_pair(".global_tid.", KmpInt32PtrTy),
4179 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4180 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4181 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4182 std::make_pair(StringRef(), QualType()) // __context with shared vars
4183 };
4184 // Start a captured region for 'teams' or 'parallel'. Both regions have
4185 // the same implicit parameters.
4186 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4187 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4188 break;
4189 }
4190
4191 case OMPD_teams_distribute_parallel_for:
4192 case OMPD_teams_distribute_parallel_for_simd: {
4193 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4194 QualType KmpInt32PtrTy =
4195 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4196
4197 Sema::CapturedParamNameType ParamsTeams[] = {
4198 std::make_pair(".global_tid.", KmpInt32PtrTy),
4199 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4200 std::make_pair(StringRef(), QualType()) // __context with shared vars
4201 };
4202 // Start a captured region for 'target' with no implicit parameters.
4203 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4204 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4205
4206 Sema::CapturedParamNameType ParamsParallel[] = {
4207 std::make_pair(".global_tid.", KmpInt32PtrTy),
4208 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4209 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4210 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4211 std::make_pair(StringRef(), QualType()) // __context with shared vars
4212 };
4213 // Start a captured region for 'teams' or 'parallel'. Both regions have
4214 // the same implicit parameters.
4215 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4216 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4217 break;
4218 }
4219 case OMPD_target_update:
4220 case OMPD_target_enter_data:
4221 case OMPD_target_exit_data: {
4222 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4223 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4224 QualType KmpInt32PtrTy =
4225 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4226 QualType Args[] = {VoidPtrTy};
4227 FunctionProtoType::ExtProtoInfo EPI;
4228 EPI.Variadic = true;
4229 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4230 Sema::CapturedParamNameType Params[] = {
4231 std::make_pair(".global_tid.", KmpInt32Ty),
4232 std::make_pair(".part_id.", KmpInt32PtrTy),
4233 std::make_pair(".privates.", VoidPtrTy),
4234 std::make_pair(
4235 ".copy_fn.",
4236 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4237 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4238 std::make_pair(StringRef(), QualType()) // __context with shared vars
4239 };
4240 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4241 Params);
4242 // Mark this captured region as inlined, because we don't use outlined
4243 // function directly.
4244 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4245 AlwaysInlineAttr::CreateImplicit(
4246 Context, {}, AttributeCommonInfo::AS_Keyword,
4247 AlwaysInlineAttr::Keyword_forceinline));
4248 break;
4249 }
4250 case OMPD_threadprivate:
4251 case OMPD_allocate:
4252 case OMPD_taskyield:
4253 case OMPD_barrier:
4254 case OMPD_taskwait:
4255 case OMPD_cancellation_point:
4256 case OMPD_cancel:
4257 case OMPD_flush:
4258 case OMPD_depobj:
4259 case OMPD_scan:
4260 case OMPD_declare_reduction:
4261 case OMPD_declare_mapper:
4262 case OMPD_declare_simd:
4263 case OMPD_declare_target:
4264 case OMPD_end_declare_target:
4265 case OMPD_requires:
4266 case OMPD_declare_variant:
4267 case OMPD_begin_declare_variant:
4268 case OMPD_end_declare_variant:
4269 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 4269)
;
4270 case OMPD_unknown:
4271 default:
4272 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 4272)
;
4273 }
4274 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setContext(CurContext);
4275}
4276
4277int Sema::getNumberOfConstructScopes(unsigned Level) const {
4278 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4279}
4280
4281int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4282 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4283 getOpenMPCaptureRegions(CaptureRegions, DKind);
4284 return CaptureRegions.size();
4285}
4286
4287static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4288 Expr *CaptureExpr, bool WithInit,
4289 bool AsExpression) {
4290 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 4290, __PRETTY_FUNCTION__))
;
4291 ASTContext &C = S.getASTContext();
4292 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4293 QualType Ty = Init->getType();
4294 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4295 if (S.getLangOpts().CPlusPlus) {
4296 Ty = C.getLValueReferenceType(Ty);
4297 } else {
4298 Ty = C.getPointerType(Ty);
4299 ExprResult Res =
4300 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4301 if (!Res.isUsable())
4302 return nullptr;
4303 Init = Res.get();
4304 }
4305 WithInit = true;
4306 }
4307 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4308 CaptureExpr->getBeginLoc());
4309 if (!WithInit)
4310 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4311 S.CurContext->addHiddenDecl(CED);
4312 Sema::TentativeAnalysisScope Trap(S);
4313 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4314 return CED;
4315}
4316
4317static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4318 bool WithInit) {
4319 OMPCapturedExprDecl *CD;
4320 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4321 CD = cast<OMPCapturedExprDecl>(VD);
4322 else
4323 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4324 /*AsExpression=*/false);
4325 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4326 CaptureExpr->getExprLoc());
4327}
4328
4329static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4330 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4331 if (!Ref) {
4332 OMPCapturedExprDecl *CD = buildCaptureDecl(
4333 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4334 /*WithInit=*/true, /*AsExpression=*/true);
4335 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4336 CaptureExpr->getExprLoc());
4337 }
4338 ExprResult Res = Ref;
4339 if (!S.getLangOpts().CPlusPlus &&
4340 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4341 Ref->getType()->isPointerType()) {
4342 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4343 if (!Res.isUsable())
4344 return ExprError();
4345 }
4346 return S.DefaultLvalueConversion(Res.get());
4347}
4348
4349namespace {
4350// OpenMP directives parsed in this section are represented as a
4351// CapturedStatement with an associated statement. If a syntax error
4352// is detected during the parsing of the associated statement, the
4353// compiler must abort processing and close the CapturedStatement.
4354//
4355// Combined directives such as 'target parallel' have more than one
4356// nested CapturedStatements. This RAII ensures that we unwind out
4357// of all the nested CapturedStatements when an error is found.
4358class CaptureRegionUnwinderRAII {
4359private:
4360 Sema &S;
4361 bool &ErrorFound;
4362 OpenMPDirectiveKind DKind = OMPD_unknown;
4363
4364public:
4365 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4366 OpenMPDirectiveKind DKind)
4367 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4368 ~CaptureRegionUnwinderRAII() {
4369 if (ErrorFound) {
4370 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4371 while (--ThisCaptureLevel >= 0)
4372 S.ActOnCapturedRegionError();
4373 }
4374 }
4375};
4376} // namespace
4377
4378void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4379 // Capture variables captured by reference in lambdas for target-based
4380 // directives.
4381 if (!CurContext->isDependentContext() &&
4382 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4383 isOpenMPTargetDataManagementDirective(
4384 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4385 QualType Type = V->getType();
4386 if (const auto *RD = Type.getCanonicalType()
4387 .getNonReferenceType()
4388 ->getAsCXXRecordDecl()) {
4389 bool SavedForceCaptureByReferenceInTargetExecutable =
4390 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4391 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4392 /*V=*/true);
4393 if (RD->isLambda()) {
4394 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4395 FieldDecl *ThisCapture;
4396 RD->getCaptureFields(Captures, ThisCapture);
4397 for (const LambdaCapture &LC : RD->captures()) {
4398 if (LC.getCaptureKind() == LCK_ByRef) {
4399 VarDecl *VD = LC.getCapturedVar();
4400 DeclContext *VDC = VD->getDeclContext();
4401 if (!VDC->Encloses(CurContext))
4402 continue;
4403 MarkVariableReferenced(LC.getLocation(), VD);
4404 } else if (LC.getCaptureKind() == LCK_This) {
4405 QualType ThisTy = getCurrentThisType();
4406 if (!ThisTy.isNull() &&
4407 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4408 CheckCXXThisCapture(LC.getLocation());
4409 }
4410 }
4411 }
4412 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4413 SavedForceCaptureByReferenceInTargetExecutable);
4414 }
4415 }
4416}
4417
4418static bool checkOrderedOrderSpecified(Sema &S,
4419 const ArrayRef<OMPClause *> Clauses) {
4420 const OMPOrderedClause *Ordered = nullptr;
4421 const OMPOrderClause *Order = nullptr;
4422
4423 for (const OMPClause *Clause : Clauses) {
4424 if (Clause->getClauseKind() == OMPC_ordered)
4425 Ordered = cast<OMPOrderedClause>(Clause);
4426 else if (Clause->getClauseKind() == OMPC_order) {
4427 Order = cast<OMPOrderClause>(Clause);
4428 if (Order->getKind() != OMPC_ORDER_concurrent)
4429 Order = nullptr;
4430 }
4431 if (Ordered && Order)
4432 break;
4433 }
4434
4435 if (Ordered && Order) {
4436 S.Diag(Order->getKindKwLoc(),
4437 diag::err_omp_simple_clause_incompatible_with_ordered)
4438 << getOpenMPClauseName(OMPC_order)
4439 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4440 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4441 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4442 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4443 return true;
4444 }
4445 return false;
4446}
4447
4448StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4449 ArrayRef<OMPClause *> Clauses) {
4450 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4451 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4452 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4453 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master)
4454 return S;
4455
4456 bool ErrorFound = false;
4457 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4458 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4459 if (!S.isUsable()) {
4460 ErrorFound = true;
Value stored to 'ErrorFound' is never read
4461 return StmtError();
4462 }
4463
4464 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4465 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4466 OMPOrderedClause *OC = nullptr;
4467 OMPScheduleClause *SC = nullptr;
4468 SmallVector<const OMPLinearClause *, 4> LCs;
4469 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4470 // This is required for proper codegen.
4471 for (OMPClause *Clause : Clauses) {
4472 if (!LangOpts.OpenMPSimd &&
4473 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4474 Clause->getClauseKind() == OMPC_in_reduction) {
4475 // Capture taskgroup task_reduction descriptors inside the tasking regions
4476 // with the corresponding in_reduction items.
4477 auto *IRC = cast<OMPInReductionClause>(Clause);
4478 for (Expr *E : IRC->taskgroup_descriptors())
4479 if (E)
4480 MarkDeclarationsReferencedInExpr(E);
4481 }
4482 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4483 Clause->getClauseKind() == OMPC_copyprivate ||
4484 (getLangOpts().OpenMPUseTLS &&
4485 getASTContext().getTargetInfo().isTLSSupported() &&
4486 Clause->getClauseKind() == OMPC_copyin)) {
4487 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4488 // Mark all variables in private list clauses as used in inner region.
4489 for (Stmt *VarRef : Clause->children()) {
4490 if (auto *E = cast_or_null<Expr>(VarRef)) {
4491 MarkDeclarationsReferencedInExpr(E);
4492 }
4493 }
4494 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4495 } else if (isOpenMPLoopTransformationDirective(
4496 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4497 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 4498, __PRETTY_FUNCTION__))
4498 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 4498, __PRETTY_FUNCTION__))
;
4499 } else if (CaptureRegions.size() > 1 ||
4500 CaptureRegions.back() != OMPD_unknown) {
4501 if (auto *C = OMPClauseWithPreInit::get(Clause))
4502 PICs.push_back(C);
4503 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4504 if (Expr *E = C->getPostUpdateExpr())
4505 MarkDeclarationsReferencedInExpr(E);
4506 }
4507 }
4508 if (Clause->getClauseKind() == OMPC_schedule)
4509 SC = cast<OMPScheduleClause>(Clause);
4510 else if (Clause->getClauseKind() == OMPC_ordered)
4511 OC = cast<OMPOrderedClause>(Clause);
4512 else if (Clause->getClauseKind() == OMPC_linear)
4513 LCs.push_back(cast<OMPLinearClause>(Clause));
4514 }
4515 // Capture allocator expressions if used.
4516 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4517 MarkDeclarationsReferencedInExpr(E);
4518 // OpenMP, 2.7.1 Loop Construct, Restrictions
4519 // The nonmonotonic modifier cannot be specified if an ordered clause is
4520 // specified.
4521 if (SC &&
4522 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4523 SC->getSecondScheduleModifier() ==
4524 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4525 OC) {
4526 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4527 ? SC->getFirstScheduleModifierLoc()
4528 : SC->getSecondScheduleModifierLoc(),
4529 diag::err_omp_simple_clause_incompatible_with_ordered)
4530 << getOpenMPClauseName(OMPC_schedule)
4531 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4532 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4533 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4534 ErrorFound = true;
4535 }
4536 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4537 // If an order(concurrent) clause is present, an ordered clause may not appear
4538 // on the same directive.
4539 if (checkOrderedOrderSpecified(*this, Clauses))
4540 ErrorFound = true;
4541 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4542 for (const OMPLinearClause *C : LCs) {
4543 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4544 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4545 }
4546 ErrorFound = true;
4547 }
4548 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4549 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4550 OC->getNumForLoops()) {
4551 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4552 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4553 ErrorFound = true;
4554 }
4555 if (ErrorFound) {
4556 return StmtError();
4557 }
4558 StmtResult SR = S;
4559 unsigned CompletedRegions = 0;
4560 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4561 // Mark all variables in private list clauses as used in inner region.
4562 // Required for proper codegen of combined directives.
4563 // TODO: add processing for other clauses.
4564 if (ThisCaptureRegion != OMPD_unknown) {
4565 for (const clang::OMPClauseWithPreInit *C : PICs) {
4566 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4567 // Find the particular capture region for the clause if the
4568 // directive is a combined one with multiple capture regions.
4569 // If the directive is not a combined one, the capture region
4570 // associated with the clause is OMPD_unknown and is generated
4571 // only once.
4572 if (CaptureRegion == ThisCaptureRegion ||
4573 CaptureRegion == OMPD_unknown) {
4574 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4575 for (Decl *D : DS->decls())
4576 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4577 }
4578 }
4579 }
4580 }
4581 if (ThisCaptureRegion == OMPD_target) {
4582 // Capture allocator traits in the target region. They are used implicitly
4583 // and, thus, are not captured by default.
4584 for (OMPClause *C : Clauses) {
4585 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4586 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4587 ++I) {
4588 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4589 if (Expr *E = D.AllocatorTraits)
4590 MarkDeclarationsReferencedInExpr(E);
4591 }
4592 continue;
4593 }
4594 }
4595 }
4596 if (++CompletedRegions == CaptureRegions.size())
4597 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4598 SR = ActOnCapturedRegionEnd(SR.get());
4599 }
4600 return SR;
4601}
4602
4603static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4604 OpenMPDirectiveKind CancelRegion,
4605 SourceLocation StartLoc) {
4606 // CancelRegion is only needed for cancel and cancellation_point.
4607 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4608 return false;
4609
4610 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4611 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4612 return false;
4613
4614 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4615 << getOpenMPDirectiveName(CancelRegion);
4616 return true;
4617}
4618
4619static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4620 OpenMPDirectiveKind CurrentRegion,
4621 const DeclarationNameInfo &CurrentName,
4622 OpenMPDirectiveKind CancelRegion,
4623 SourceLocation StartLoc) {
4624 if (Stack->getCurScope()) {
4625 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4626 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4627 bool NestingProhibited = false;
4628 bool CloseNesting = true;
4629 bool OrphanSeen = false;
4630 enum {
4631 NoRecommend,
4632 ShouldBeInParallelRegion,
4633 ShouldBeInOrderedRegion,
4634 ShouldBeInTargetRegion,
4635 ShouldBeInTeamsRegion,
4636 ShouldBeInLoopSimdRegion,
4637 } Recommend = NoRecommend;
4638 if (isOpenMPSimdDirective(ParentRegion) &&
4639 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4640 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4641 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4642 CurrentRegion != OMPD_scan))) {
4643 // OpenMP [2.16, Nesting of Regions]
4644 // OpenMP constructs may not be nested inside a simd region.
4645 // OpenMP [2.8.1,simd Construct, Restrictions]
4646 // An ordered construct with the simd clause is the only OpenMP
4647 // construct that can appear in the simd region.
4648 // Allowing a SIMD construct nested in another SIMD construct is an
4649 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4650 // message.
4651 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4652 // The only OpenMP constructs that can be encountered during execution of
4653 // a simd region are the atomic construct, the loop construct, the simd
4654 // construct and the ordered construct with the simd clause.
4655 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4656 ? diag::err_omp_prohibited_region_simd
4657 : diag::warn_omp_nesting_simd)
4658 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4659 return CurrentRegion != OMPD_simd;
4660 }
4661 if (ParentRegion == OMPD_atomic) {
4662 // OpenMP [2.16, Nesting of Regions]
4663 // OpenMP constructs may not be nested inside an atomic region.
4664 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4665 return true;
4666 }
4667 if (CurrentRegion == OMPD_section) {
4668 // OpenMP [2.7.2, sections Construct, Restrictions]
4669 // Orphaned section directives are prohibited. That is, the section
4670 // directives must appear within the sections construct and must not be
4671 // encountered elsewhere in the sections region.
4672 if (ParentRegion != OMPD_sections &&
4673 ParentRegion != OMPD_parallel_sections) {
4674 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4675 << (ParentRegion != OMPD_unknown)
4676 << getOpenMPDirectiveName(ParentRegion);
4677 return true;
4678 }
4679 return false;
4680 }
4681 // Allow some constructs (except teams and cancellation constructs) to be
4682 // orphaned (they could be used in functions, called from OpenMP regions
4683 // with the required preconditions).
4684 if (ParentRegion == OMPD_unknown &&
4685 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4686 CurrentRegion != OMPD_cancellation_point &&
4687 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4688 return false;
4689 if (CurrentRegion == OMPD_cancellation_point ||
4690 CurrentRegion == OMPD_cancel) {
4691 // OpenMP [2.16, Nesting of Regions]
4692 // A cancellation point construct for which construct-type-clause is
4693 // taskgroup must be nested inside a task construct. A cancellation
4694 // point construct for which construct-type-clause is not taskgroup must
4695 // be closely nested inside an OpenMP construct that matches the type
4696 // specified in construct-type-clause.
4697 // A cancel construct for which construct-type-clause is taskgroup must be
4698 // nested inside a task construct. A cancel construct for which
4699 // construct-type-clause is not taskgroup must be closely nested inside an
4700 // OpenMP construct that matches the type specified in
4701 // construct-type-clause.
4702 NestingProhibited =
4703 !((CancelRegion == OMPD_parallel &&
4704 (ParentRegion == OMPD_parallel ||
4705 ParentRegion == OMPD_target_parallel)) ||
4706 (CancelRegion == OMPD_for &&
4707 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4708 ParentRegion == OMPD_target_parallel_for ||
4709 ParentRegion == OMPD_distribute_parallel_for ||
4710 ParentRegion == OMPD_teams_distribute_parallel_for ||
4711 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4712 (CancelRegion == OMPD_taskgroup &&
4713 (ParentRegion == OMPD_task ||
4714 (SemaRef.getLangOpts().OpenMP >= 50 &&
4715 (ParentRegion == OMPD_taskloop ||
4716 ParentRegion == OMPD_master_taskloop ||
4717 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4718 (CancelRegion == OMPD_sections &&
4719 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4720 ParentRegion == OMPD_parallel_sections)));
4721 OrphanSeen = ParentRegion == OMPD_unknown;
4722 } else if (CurrentRegion == OMPD_master) {
4723 // OpenMP [2.16, Nesting of Regions]
4724 // A master region may not be closely nested inside a worksharing,
4725 // atomic, or explicit task region.
4726 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4727 isOpenMPTaskingDirective(ParentRegion);
4728 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4729 // OpenMP [2.16, Nesting of Regions]
4730 // A critical region may not be nested (closely or otherwise) inside a
4731 // critical region with the same name. Note that this restriction is not
4732 // sufficient to prevent deadlock.
4733 SourceLocation PreviousCriticalLoc;
4734 bool DeadLock = Stack->hasDirective(
4735 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4736 const DeclarationNameInfo &DNI,
4737 SourceLocation Loc) {
4738 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4739 PreviousCriticalLoc = Loc;
4740 return true;
4741 }
4742 return false;
4743 },
4744 false /* skip top directive */);
4745 if (DeadLock) {
4746 SemaRef.Diag(StartLoc,
4747 diag::err_omp_prohibited_region_critical_same_name)
4748 << CurrentName.getName();
4749 if (PreviousCriticalLoc.isValid())
4750 SemaRef.Diag(PreviousCriticalLoc,
4751 diag::note_omp_previous_critical_region);
4752 return true;
4753 }
4754 } else if (CurrentRegion == OMPD_barrier) {
4755 // OpenMP [2.16, Nesting of Regions]
4756 // A barrier region may not be closely nested inside a worksharing,
4757 // explicit task, critical, ordered, atomic, or master region.
4758 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4759 isOpenMPTaskingDirective(ParentRegion) ||
4760 ParentRegion == OMPD_master ||
4761 ParentRegion == OMPD_parallel_master ||
4762 ParentRegion == OMPD_critical ||
4763 ParentRegion == OMPD_ordered;
4764 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4765 !isOpenMPParallelDirective(CurrentRegion) &&
4766 !isOpenMPTeamsDirective(CurrentRegion)) {
4767 // OpenMP [2.16, Nesting of Regions]
4768 // A worksharing region may not be closely nested inside a worksharing,
4769 // explicit task, critical, ordered, atomic, or master region.
4770 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4771 isOpenMPTaskingDirective(ParentRegion) ||
4772 ParentRegion == OMPD_master ||
4773 ParentRegion == OMPD_parallel_master ||
4774 ParentRegion == OMPD_critical ||
4775 ParentRegion == OMPD_ordered;
4776 Recommend = ShouldBeInParallelRegion;
4777 } else if (CurrentRegion == OMPD_ordered) {
4778 // OpenMP [2.16, Nesting of Regions]
4779 // An ordered region may not be closely nested inside a critical,
4780 // atomic, or explicit task region.
4781 // An ordered region must be closely nested inside a loop region (or
4782 // parallel loop region) with an ordered clause.
4783 // OpenMP [2.8.1,simd Construct, Restrictions]
4784 // An ordered construct with the simd clause is the only OpenMP construct
4785 // that can appear in the simd region.
4786 NestingProhibited = ParentRegion == OMPD_critical ||
4787 isOpenMPTaskingDirective(ParentRegion) ||
4788 !(isOpenMPSimdDirective(ParentRegion) ||
4789 Stack->isParentOrderedRegion());
4790 Recommend = ShouldBeInOrderedRegion;
4791 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4792 // OpenMP [2.16, Nesting of Regions]
4793 // If specified, a teams construct must be contained within a target
4794 // construct.
4795 NestingProhibited =
4796 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4797 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4798 ParentRegion != OMPD_target);
4799 OrphanSeen = ParentRegion == OMPD_unknown;
4800 Recommend = ShouldBeInTargetRegion;
4801 } else if (CurrentRegion == OMPD_scan) {
4802 // OpenMP [2.16, Nesting of Regions]
4803 // If specified, a teams construct must be contained within a target
4804 // construct.
4805 NestingProhibited =
4806 SemaRef.LangOpts.OpenMP < 50 ||
4807 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4808 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4809 ParentRegion != OMPD_parallel_for_simd);
4810 OrphanSeen = ParentRegion == OMPD_unknown;
4811 Recommend = ShouldBeInLoopSimdRegion;
4812 }
4813 if (!NestingProhibited &&
4814 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4815 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4816 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4817 // OpenMP [2.16, Nesting of Regions]
4818 // distribute, parallel, parallel sections, parallel workshare, and the
4819 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4820 // constructs that can be closely nested in the teams region.
4821 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4822 !isOpenMPDistributeDirective(CurrentRegion);
4823 Recommend = ShouldBeInParallelRegion;
4824 }
4825 if (!NestingProhibited &&
4826 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4827 // OpenMP 4.5 [2.17 Nesting of Regions]
4828 // The region associated with the distribute construct must be strictly
4829 // nested inside a teams region
4830 NestingProhibited =
4831 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4832 Recommend = ShouldBeInTeamsRegion;
4833 }
4834 if (!NestingProhibited &&
4835 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4836 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4837 // OpenMP 4.5 [2.17 Nesting of Regions]
4838 // If a target, target update, target data, target enter data, or
4839 // target exit data construct is encountered during execution of a
4840 // target region, the behavior is unspecified.
4841 NestingProhibited = Stack->hasDirective(
4842 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4843 SourceLocation) {
4844 if (isOpenMPTargetExecutionDirective(K)) {
4845 OffendingRegion = K;
4846 return true;
4847 }
4848 return false;
4849 },
4850 false /* don't skip top directive */);
4851 CloseNesting = false;
4852 }
4853 if (NestingProhibited) {
4854 if (OrphanSeen) {
4855 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4856 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4857 } else {
4858 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4859 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4860 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4861 }
4862 return true;
4863 }
4864 }
4865 return false;
4866}
4867
4868struct Kind2Unsigned {
4869 using argument_type = OpenMPDirectiveKind;
4870 unsigned operator()(argument_type DK) { return unsigned(DK); }
4871};
4872static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4873 ArrayRef<OMPClause *> Clauses,
4874 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4875 bool ErrorFound = false;
4876 unsigned NamedModifiersNumber = 0;
4877 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4878 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4879 SmallVector<SourceLocation, 4> NameModifierLoc;
4880 for (const OMPClause *C : Clauses) {
4881 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4882 // At most one if clause without a directive-name-modifier can appear on
4883 // the directive.
4884 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4885 if (FoundNameModifiers[CurNM]) {
4886 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4887 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4888 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4889 ErrorFound = true;
4890 } else if (CurNM != OMPD_unknown) {
4891 NameModifierLoc.push_back(IC->getNameModifierLoc());
4892 ++NamedModifiersNumber;
4893 }
4894 FoundNameModifiers[CurNM] = IC;
4895 if (CurNM == OMPD_unknown)
4896 continue;
4897 // Check if the specified name modifier is allowed for the current
4898 // directive.
4899 // At most one if clause with the particular directive-name-modifier can
4900 // appear on the directive.
4901 bool MatchFound = false;
4902 for (auto NM : AllowedNameModifiers) {
4903 if (CurNM == NM) {
4904 MatchFound = true;
4905 break;
4906 }
4907 }
4908 if (!MatchFound) {
4909 S.Diag(IC->getNameModifierLoc(),
4910 diag::err_omp_wrong_if_directive_name_modifier)
4911 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4912 ErrorFound = true;
4913 }
4914 }
4915 }
4916 // If any if clause on the directive includes a directive-name-modifier then
4917 // all if clauses on the directive must include a directive-name-modifier.
4918 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4919 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4920 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4921 diag::err_omp_no_more_if_clause);
4922 } else {
4923 std::string Values;
4924 std::string Sep(", ");
4925 unsigned AllowedCnt = 0;
4926 unsigned TotalAllowedNum =
4927 AllowedNameModifiers.size() - NamedModifiersNumber;
4928 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4929 ++Cnt) {
4930 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4931 if (!FoundNameModifiers[NM]) {
4932 Values += "'";
4933 Values += getOpenMPDirectiveName(NM);
4934 Values += "'";
4935 if (AllowedCnt + 2 == TotalAllowedNum)
4936 Values += " or ";
4937 else if (AllowedCnt + 1 != TotalAllowedNum)
4938 Values += Sep;
4939 ++AllowedCnt;
4940 }
4941 }
4942 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4943 diag::err_omp_unnamed_if_clause)
4944 << (TotalAllowedNum > 1) << Values;
4945 }
4946 for (SourceLocation Loc : NameModifierLoc) {
4947 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4948 }
4949 ErrorFound = true;
4950 }
4951 return ErrorFound;
4952}
4953
4954static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4955 SourceLocation &ELoc,
4956 SourceRange &ERange,
4957 bool AllowArraySection) {
4958 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4959 RefExpr->containsUnexpandedParameterPack())
4960 return std::make_pair(nullptr, true);
4961
4962 // OpenMP [3.1, C/C++]
4963 // A list item is a variable name.
4964 // OpenMP [2.9.3.3, Restrictions, p.1]
4965 // A variable that is part of another variable (as an array or
4966 // structure element) cannot appear in a private clause.
4967 RefExpr = RefExpr->IgnoreParens();
4968 enum {
4969 NoArrayExpr = -1,
4970 ArraySubscript = 0,
4971 OMPArraySection = 1
4972 } IsArrayExpr = NoArrayExpr;
4973 if (AllowArraySection) {
4974 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4975 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4976 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4977 Base = TempASE->getBase()->IgnoreParenImpCasts();
4978 RefExpr = Base;
4979 IsArrayExpr = ArraySubscript;
4980 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4981 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4982 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4983 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4984 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4985 Base = TempASE->getBase()->IgnoreParenImpCasts();
4986 RefExpr = Base;
4987 IsArrayExpr = OMPArraySection;
4988 }
4989 }
4990 ELoc = RefExpr->getExprLoc();
4991 ERange = RefExpr->getSourceRange();
4992 RefExpr = RefExpr->IgnoreParenImpCasts();
4993 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4994 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4995 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4996 (S.getCurrentThisType().isNull() || !ME ||
4997 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4998 !isa<FieldDecl>(ME->getMemberDecl()))) {
4999 if (IsArrayExpr != NoArrayExpr) {
5000 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
5001 << ERange;
5002 } else {
5003 S.Diag(ELoc,
5004 AllowArraySection
5005 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5006 : diag::err_omp_expected_var_name_member_expr)
5007 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5008 }
5009 return std::make_pair(nullptr, false);
5010 }
5011 return std::make_pair(
5012 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5013}
5014
5015namespace {
5016/// Checks if the allocator is used in uses_allocators clause to be allowed in
5017/// target regions.
5018class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5019 DSAStackTy *S = nullptr;
5020
5021public:
5022 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5023 return S->isUsesAllocatorsDecl(E->getDecl())
5024 .getValueOr(
5025 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5026 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5027 }
5028 bool VisitStmt(const Stmt *S) {
5029 for (const Stmt *Child : S->children()) {
5030 if (Child && Visit(Child))
5031 return true;
5032 }
5033 return false;
5034 }
5035 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5036};
5037} // namespace
5038
5039static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5040 ArrayRef<OMPClause *> Clauses) {
5041 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5042, __PRETTY_FUNCTION__))
5042 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5042, __PRETTY_FUNCTION__))
;
5043 auto AllocateRange =
5044 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5045 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5046 DeclToCopy;
5047 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5048 return isOpenMPPrivate(C->getClauseKind());
5049 });
5050 for (OMPClause *Cl : PrivateRange) {
5051 MutableArrayRef<Expr *>::iterator I, It, Et;
5052 if (Cl->getClauseKind() == OMPC_private) {
5053 auto *PC = cast<OMPPrivateClause>(Cl);
5054 I = PC->private_copies().begin();
5055 It = PC->varlist_begin();
5056 Et = PC->varlist_end();
5057 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5058 auto *PC = cast<OMPFirstprivateClause>(Cl);
5059 I = PC->private_copies().begin();
5060 It = PC->varlist_begin();
5061 Et = PC->varlist_end();
5062 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5063 auto *PC = cast<OMPLastprivateClause>(Cl);
5064 I = PC->private_copies().begin();
5065 It = PC->varlist_begin();
5066 Et = PC->varlist_end();
5067 } else if (Cl->getClauseKind() == OMPC_linear) {
5068 auto *PC = cast<OMPLinearClause>(Cl);
5069 I = PC->privates().begin();
5070 It = PC->varlist_begin();
5071 Et = PC->varlist_end();
5072 } else if (Cl->getClauseKind() == OMPC_reduction) {
5073 auto *PC = cast<OMPReductionClause>(Cl);
5074 I = PC->privates().begin();
5075 It = PC->varlist_begin();
5076 Et = PC->varlist_end();
5077 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5078 auto *PC = cast<OMPTaskReductionClause>(Cl);
5079 I = PC->privates().begin();
5080 It = PC->varlist_begin();
5081 Et = PC->varlist_end();
5082 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5083 auto *PC = cast<OMPInReductionClause>(Cl);
5084 I = PC->privates().begin();
5085 It = PC->varlist_begin();
5086 Et = PC->varlist_end();
5087 } else {
5088 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5088)
;
5089 }
5090 for (Expr *E : llvm::make_range(It, Et)) {
5091 if (!*I) {
5092 ++I;
5093 continue;
5094 }
5095 SourceLocation ELoc;
5096 SourceRange ERange;
5097 Expr *SimpleRefExpr = E;
5098 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5099 /*AllowArraySection=*/true);
5100 DeclToCopy.try_emplace(Res.first,
5101 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5102 ++I;
5103 }
5104 }
5105 for (OMPClause *C : AllocateRange) {
5106 auto *AC = cast<OMPAllocateClause>(C);
5107 if (S.getLangOpts().OpenMP >= 50 &&
5108 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5109 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5110 AC->getAllocator()) {
5111 Expr *Allocator = AC->getAllocator();
5112 // OpenMP, 2.12.5 target Construct
5113 // Memory allocators that do not appear in a uses_allocators clause cannot
5114 // appear as an allocator in an allocate clause or be used in the target
5115 // region unless a requires directive with the dynamic_allocators clause
5116 // is present in the same compilation unit.
5117 AllocatorChecker Checker(Stack);
5118 if (Checker.Visit(Allocator))
5119 S.Diag(Allocator->getExprLoc(),
5120 diag::err_omp_allocator_not_in_uses_allocators)
5121 << Allocator->getSourceRange();
5122 }
5123 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5124 getAllocatorKind(S, Stack, AC->getAllocator());
5125 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5126 // For task, taskloop or target directives, allocation requests to memory
5127 // allocators with the trait access set to thread result in unspecified
5128 // behavior.
5129 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5130 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5131 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5132 S.Diag(AC->getAllocator()->getExprLoc(),
5133 diag::warn_omp_allocate_thread_on_task_target_directive)
5134 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5135 }
5136 for (Expr *E : AC->varlists()) {
5137 SourceLocation ELoc;
5138 SourceRange ERange;
5139 Expr *SimpleRefExpr = E;
5140 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5141 ValueDecl *VD = Res.first;
5142 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5143 if (!isOpenMPPrivate(Data.CKind)) {
5144 S.Diag(E->getExprLoc(),
5145 diag::err_omp_expected_private_copy_for_allocate);
5146 continue;
5147 }
5148 VarDecl *PrivateVD = DeclToCopy[VD];
5149 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5150 AllocatorKind, AC->getAllocator()))
5151 continue;
5152 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5153 E->getSourceRange());
5154 }
5155 }
5156}
5157
5158namespace {
5159/// Rewrite statements and expressions for Sema \p Actions CurContext.
5160///
5161/// Used to wrap already parsed statements/expressions into a new CapturedStmt
5162/// context. DeclRefExpr used inside the new context are changed to refer to the
5163/// captured variable instead.
5164class CaptureVars : public TreeTransform<CaptureVars> {
5165 using BaseTransform = TreeTransform<CaptureVars>;
5166
5167public:
5168 CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5169
5170 bool AlwaysRebuild() { return true; }
5171};
5172} // namespace
5173
5174static VarDecl *precomputeExpr(Sema &Actions,
5175 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5176 StringRef Name) {
5177 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5178 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5179 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5180 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5181 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5182 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5183 BodyStmts.push_back(NewDeclStmt);
5184 return NewVar;
5185}
5186
5187/// Create a closure that computes the number of iterations of a loop.
5188///
5189/// \param Actions The Sema object.
5190/// \param LogicalTy Type for the logical iteration number.
5191/// \param Rel Comparison operator of the loop condition.
5192/// \param StartExpr Value of the loop counter at the first iteration.
5193/// \param StopExpr Expression the loop counter is compared against in the loop
5194/// condition. \param StepExpr Amount of increment after each iteration.
5195///
5196/// \return Closure (CapturedStmt) of the distance calculation.
5197static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5198 BinaryOperator::Opcode Rel,
5199 Expr *StartExpr, Expr *StopExpr,
5200 Expr *StepExpr) {
5201 ASTContext &Ctx = Actions.getASTContext();
5202 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5203
5204 // Captured regions currently don't support return values, we use an
5205 // out-parameter instead. All inputs are implicit captures.
5206 // TODO: Instead of capturing each DeclRefExpr occurring in
5207 // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5208 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5209 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5210 {StringRef(), QualType()}};
5211 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5212
5213 Stmt *Body;
5214 {
5215 Sema::CompoundScopeRAII CompoundScope(Actions);
5216 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5217
5218 // Get the LValue expression for the result.
5219 ImplicitParamDecl *DistParam = CS->getParam(0);
5220 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5221 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5222
5223 SmallVector<Stmt *, 4> BodyStmts;
5224
5225 // Capture all referenced variable references.
5226 // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5227 // CapturedStmt, we could compute them before and capture the result, to be
5228 // used jointly with the LoopVar function.
5229 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5230 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5231 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5232 auto BuildVarRef = [&](VarDecl *VD) {
5233 return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5234 };
5235
5236 IntegerLiteral *Zero = IntegerLiteral::Create(
5237 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5238 Expr *Dist;
5239 if (Rel == BO_NE) {
5240 // When using a != comparison, the increment can be +1 or -1. This can be
5241 // dynamic at runtime, so we need to check for the direction.
5242 Expr *IsNegStep = AssertSuccess(
5243 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5244
5245 // Positive increment.
5246 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5247 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5248 ForwardRange = AssertSuccess(
5249 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5250 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5251 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5252
5253 // Negative increment.
5254 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5255 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5256 BackwardRange = AssertSuccess(
5257 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5258 Expr *NegIncAmount = AssertSuccess(
5259 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5260 Expr *BackwardDist = AssertSuccess(
5261 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5262
5263 // Use the appropriate case.
5264 Dist = AssertSuccess(Actions.ActOnConditionalOp(
5265 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5266 } else {
5267 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&(((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT
) && "Expected one of these relational operators") ? static_cast
<void> (0) : __assert_fail ("(Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && \"Expected one of these relational operators\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5268, __PRETTY_FUNCTION__))
5268 "Expected one of these relational operators")(((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT
) && "Expected one of these relational operators") ? static_cast
<void> (0) : __assert_fail ("(Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && \"Expected one of these relational operators\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5268, __PRETTY_FUNCTION__))
;
5269
5270 // We can derive the direction from any other comparison operator. It is
5271 // non well-formed OpenMP if Step increments/decrements in the other
5272 // directions. Whether at least the first iteration passes the loop
5273 // condition.
5274 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5275 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5276
5277 // Compute the range between first and last counter value.
5278 Expr *Range;
5279 if (Rel == BO_GE || Rel == BO_GT)
5280 Range = AssertSuccess(Actions.BuildBinOp(
5281 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5282 else
5283 Range = AssertSuccess(Actions.BuildBinOp(
5284 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5285
5286 // Ensure unsigned range space.
5287 Range =
5288 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5289
5290 if (Rel == BO_LE || Rel == BO_GE) {
5291 // Add one to the range if the relational operator is inclusive.
5292 Range =
5293 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_PreInc, Range));
5294 }
5295
5296 // Divide by the absolute step amount.
5297 Expr *Divisor = BuildVarRef(NewStep);
5298 if (Rel == BO_GE || Rel == BO_GT)
5299 Divisor =
5300 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5301 Dist = AssertSuccess(
5302 Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
5303
5304 // If there is not at least one iteration, the range contains garbage. Fix
5305 // to zero in this case.
5306 Dist = AssertSuccess(
5307 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5308 }
5309
5310 // Assign the result to the out-parameter.
5311 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5312 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5313 BodyStmts.push_back(ResultAssign);
5314
5315 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5316 }
5317
5318 return cast<CapturedStmt>(
5319 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5320}
5321
5322/// Create a closure that computes the loop variable from the logical iteration
5323/// number.
5324///
5325/// \param Actions The Sema object.
5326/// \param LoopVarTy Type for the loop variable used for result value.
5327/// \param LogicalTy Type for the logical iteration number.
5328/// \param StartExpr Value of the loop counter at the first iteration.
5329/// \param Step Amount of increment after each iteration.
5330/// \param Deref Whether the loop variable is a dereference of the loop
5331/// counter variable.
5332///
5333/// \return Closure (CapturedStmt) of the loop value calculation.
5334static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5335 QualType LogicalTy,
5336 DeclRefExpr *StartExpr, Expr *Step,
5337 bool Deref) {
5338 ASTContext &Ctx = Actions.getASTContext();
5339
5340 // Pass the result as an out-parameter. Passing as return value would require
5341 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5342 // invoke a copy constructor.
5343 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5344 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5345 {"Logical", LogicalTy},
5346 {StringRef(), QualType()}};
5347 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5348
5349 // Capture the initial iterator which represents the LoopVar value at the
5350 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5351 // it in every iteration, capture it by value before it is modified.
5352 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5353 bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5354 Sema::TryCapture_ExplicitByVal, {});
5355 (void)Invalid;
5356 assert(!Invalid && "Expecting capture-by-value to work.")((!Invalid && "Expecting capture-by-value to work.") ?
static_cast<void> (0) : __assert_fail ("!Invalid && \"Expecting capture-by-value to work.\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5356, __PRETTY_FUNCTION__))
;
5357
5358 Expr *Body;
5359 {
5360 Sema::CompoundScopeRAII CompoundScope(Actions);
5361 auto *CS = cast<CapturedDecl>(Actions.CurContext);
5362
5363 ImplicitParamDecl *TargetParam = CS->getParam(0);
5364 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5365 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5366 ImplicitParamDecl *IndvarParam = CS->getParam(1);
5367 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5368 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5369
5370 // Capture the Start expression.
5371 CaptureVars Recap(Actions);
5372 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5373 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5374
5375 Expr *Skip = AssertSuccess(
5376 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5377 // TODO: Explicitly cast to the iterator's difference_type instead of
5378 // relying on implicit conversion.
5379 Expr *Advanced =
5380 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5381
5382 if (Deref) {
5383 // For range-based for-loops convert the loop counter value to a concrete
5384 // loop variable value by dereferencing the iterator.
5385 Advanced =
5386 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5387 }
5388
5389 // Assign the result to the output parameter.
5390 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5391 BO_Assign, TargetRef, Advanced));
5392 }
5393 return cast<CapturedStmt>(
5394 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5395}
5396
5397StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5398 ASTContext &Ctx = getASTContext();
5399
5400 // Extract the common elements of ForStmt and CXXForRangeStmt:
5401 // Loop variable, repeat condition, increment
5402 Expr *Cond, *Inc;
5403 VarDecl *LIVDecl, *LUVDecl;
5404 if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5405 Stmt *Init = For->getInit();
5406 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5407 // For statement declares loop variable.
5408 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5409 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5410 // For statement reuses variable.
5411 assert(LCAssign->getOpcode() == BO_Assign &&((LCAssign->getOpcode() == BO_Assign && "init part must be a loop variable assignment"
) ? static_cast<void> (0) : __assert_fail ("LCAssign->getOpcode() == BO_Assign && \"init part must be a loop variable assignment\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5412, __PRETTY_FUNCTION__))
5412 "init part must be a loop variable assignment")((LCAssign->getOpcode() == BO_Assign && "init part must be a loop variable assignment"
) ? static_cast<void> (0) : __assert_fail ("LCAssign->getOpcode() == BO_Assign && \"init part must be a loop variable assignment\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5412, __PRETTY_FUNCTION__))
;
5413 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5414 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5415 } else
5416 llvm_unreachable("Cannot determine loop variable")::llvm::llvm_unreachable_internal("Cannot determine loop variable"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5416)
;
5417 LUVDecl = LIVDecl;
5418
5419 Cond = For->getCond();
5420 Inc = For->getInc();
5421 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5422 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5423 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5424 LUVDecl = RangeFor->getLoopVariable();
5425
5426 Cond = RangeFor->getCond();
5427 Inc = RangeFor->getInc();
5428 } else
5429 llvm_unreachable("unhandled kind of loop")::llvm::llvm_unreachable_internal("unhandled kind of loop", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5429)
;
5430
5431 QualType CounterTy = LIVDecl->getType();
5432 QualType LVTy = LUVDecl->getType();
5433
5434 // Analyze the loop condition.
5435 Expr *LHS, *RHS;
5436 BinaryOperator::Opcode CondRel;
5437 Cond = Cond->IgnoreImplicit();
5438 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5439 LHS = CondBinExpr->getLHS();
5440 RHS = CondBinExpr->getRHS();
5441 CondRel = CondBinExpr->getOpcode();
5442 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5443 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands")((CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"
) ? static_cast<void> (0) : __assert_fail ("CondCXXOp->getNumArgs() == 2 && \"Comparison should have 2 operands\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5443, __PRETTY_FUNCTION__))
;
5444 LHS = CondCXXOp->getArg(0);
5445 RHS = CondCXXOp->getArg(1);
5446 switch (CondCXXOp->getOperator()) {
5447 case OO_ExclaimEqual:
5448 CondRel = BO_NE;
5449 break;
5450 case OO_Less:
5451 CondRel = BO_LT;
5452 break;
5453 case OO_LessEqual:
5454 CondRel = BO_LE;
5455 break;
5456 case OO_Greater:
5457 CondRel = BO_GT;
5458 break;
5459 case OO_GreaterEqual:
5460 CondRel = BO_GE;
5461 break;
5462 default:
5463 llvm_unreachable("unexpected iterator operator")::llvm::llvm_unreachable_internal("unexpected iterator operator"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5463)
;
5464 }
5465 } else
5466 llvm_unreachable("unexpected loop condition")::llvm::llvm_unreachable_internal("unexpected loop condition"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5466)
;
5467
5468 // Normalize such that the loop counter is on the LHS.
5469 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5470 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5471 std::swap(LHS, RHS);
5472 CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5473 }
5474 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5475
5476 // Decide the bit width for the logical iteration counter. By default use the
5477 // unsigned ptrdiff_t integer size (for iterators and pointers).
5478 // TODO: For iterators, use iterator::difference_type,
5479 // std::iterator_traits<>::difference_type or decltype(it - end).
5480 QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5481 if (CounterTy->isIntegerType()) {
5482 unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5483 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5484 }
5485
5486 // Analyze the loop increment.
5487 Expr *Step;
5488 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5489 int Direction;
5490 switch (IncUn->getOpcode()) {
5491 case UO_PreInc:
5492 case UO_PostInc:
5493 Direction = 1;
5494 break;
5495 case UO_PreDec:
5496 case UO_PostDec:
5497 Direction = -1;
5498 break;
5499 default:
5500 llvm_unreachable("unhandled unary increment operator")::llvm::llvm_unreachable_internal("unhandled unary increment operator"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5500)
;
5501 }
5502 Step = IntegerLiteral::Create(
5503 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5504 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5505 if (IncBin->getOpcode() == BO_AddAssign) {
5506 Step = IncBin->getRHS();
5507 } else if (IncBin->getOpcode() == BO_SubAssign) {
5508 Step =
5509 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5510 } else
5511 llvm_unreachable("unhandled binary increment operator")::llvm::llvm_unreachable_internal("unhandled binary increment operator"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5511)
;
5512 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5513 switch (CondCXXOp->getOperator()) {
5514 case OO_PlusPlus:
5515 Step = IntegerLiteral::Create(
5516 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5517 break;
5518 case OO_MinusMinus:
5519 Step = IntegerLiteral::Create(
5520 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5521 break;
5522 case OO_PlusEqual:
5523 Step = CondCXXOp->getArg(1);
5524 break;
5525 case OO_MinusEqual:
5526 Step = AssertSuccess(
5527 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5528 break;
5529 default:
5530 llvm_unreachable("unhandled overloaded increment operator")::llvm::llvm_unreachable_internal("unhandled overloaded increment operator"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5530)
;
5531 }
5532 } else
5533 llvm_unreachable("unknown increment expression")::llvm::llvm_unreachable_internal("unknown increment expression"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5533)
;
5534
5535 CapturedStmt *DistanceFunc =
5536 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5537 CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5538 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5539 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5540 {}, nullptr, nullptr, {}, nullptr);
5541 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5542 LoopVarFunc, LVRef);
5543}
5544
5545static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5546 CXXScopeSpec &MapperIdScopeSpec,
5547 const DeclarationNameInfo &MapperId,
5548 QualType Type,
5549 Expr *UnresolvedMapper);
5550
5551/// Perform DFS through the structure/class data members trying to find
5552/// member(s) with user-defined 'default' mapper and generate implicit map
5553/// clauses for such members with the found 'default' mapper.
5554static void
5555processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5556 SmallVectorImpl<OMPClause *> &Clauses) {
5557 // Check for the deault mapper for data members.
5558 if (S.getLangOpts().OpenMP < 50)
5559 return;
5560 SmallVector<OMPClause *, 4> ImplicitMaps;
5561 DeclarationNameInfo DefaultMapperId;
5562 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5563 &S.Context.Idents.get("default")));
5564 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5565 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5566 if (!C)
5567 continue;
5568 SmallVector<Expr *, 4> SubExprs;
5569 auto *MI = C->mapperlist_begin();
5570 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5571 ++I, ++MI) {
5572 // Expression is mapped using mapper - skip it.
5573 if (*MI)
5574 continue;
5575 Expr *E = *I;
5576 // Expression is dependent - skip it, build the mapper when it gets
5577 // instantiated.
5578 if (E->isTypeDependent() || E->isValueDependent() ||
5579 E->containsUnexpandedParameterPack())
5580 continue;
5581 // Array section - need to check for the mapping of the array section
5582 // element.
5583 QualType CanonType = E->getType().getCanonicalType();
5584 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5585 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5586 QualType BaseType =
5587 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5588 QualType ElemType;
5589 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5590 ElemType = ATy->getElementType();
5591 else
5592 ElemType = BaseType->getPointeeType();
5593 CanonType = ElemType;
5594 }
5595
5596 // DFS over data members in structures/classes.
5597 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5598 1, {CanonType, nullptr});
5599 llvm::DenseMap<const Type *, Expr *> Visited;
5600 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5601 1, {nullptr, 1});
5602 while (!Types.empty()) {
5603 QualType BaseType;
5604 FieldDecl *CurFD;
5605 std::tie(BaseType, CurFD) = Types.pop_back_val();
5606 while (ParentChain.back().second == 0)
5607 ParentChain.pop_back();
5608 --ParentChain.back().second;
5609 if (BaseType.isNull())
5610 continue;
5611 // Only structs/classes are allowed to have mappers.
5612 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5613 if (!RD)
5614 continue;
5615 auto It = Visited.find(BaseType.getTypePtr());
5616 if (It == Visited.end()) {
5617 // Try to find the associated user-defined mapper.
5618 CXXScopeSpec MapperIdScopeSpec;
5619 ExprResult ER = buildUserDefinedMapperRef(
5620 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5621 BaseType, /*UnresolvedMapper=*/nullptr);
5622 if (ER.isInvalid())
5623 continue;
5624 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5625 }
5626 // Found default mapper.
5627 if (It->second) {
5628 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5629 VK_LValue, OK_Ordinary, E);
5630 OE->setIsUnique(/*V=*/true);
5631 Expr *BaseExpr = OE;
5632 for (const auto &P : ParentChain) {
5633 if (P.first) {
5634 BaseExpr = S.BuildMemberExpr(
5635 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5636 NestedNameSpecifierLoc(), SourceLocation(), P.first,
5637 DeclAccessPair::make(P.first, P.first->getAccess()),
5638 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5639 P.first->getType(), VK_LValue, OK_Ordinary);
5640 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5641 }
5642 }
5643 if (CurFD)
5644 BaseExpr = S.BuildMemberExpr(
5645 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5646 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5647 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5648 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5649 CurFD->getType(), VK_LValue, OK_Ordinary);
5650 SubExprs.push_back(BaseExpr);
5651 continue;
5652 }
5653 // Check for the "default" mapper for data memebers.
5654 bool FirstIter = true;
5655 for (FieldDecl *FD : RD->fields()) {
5656 if (!FD)
5657 continue;
5658 QualType FieldTy = FD->getType();
5659 if (FieldTy.isNull() ||
5660 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5661 continue;
5662 if (FirstIter) {
5663 FirstIter = false;
5664 ParentChain.emplace_back(CurFD, 1);
5665 } else {
5666 ++ParentChain.back().second;
5667 }
5668 Types.emplace_back(FieldTy, FD);
5669 }
5670 }
5671 }
5672 if (SubExprs.empty())
5673 continue;
5674 CXXScopeSpec MapperIdScopeSpec;
5675 DeclarationNameInfo MapperId;
5676 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5677 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5678 MapperIdScopeSpec, MapperId, C->getMapType(),
5679 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5680 SubExprs, OMPVarListLocTy()))
5681 Clauses.push_back(NewClause);
5682 }
5683}
5684
5685StmtResult Sema::ActOnOpenMPExecutableDirective(
5686 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5687 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5688 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5689 StmtResult Res = StmtError();
5690 // First check CancelRegion which is then used in checkNestingOfRegions.
5691 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5692 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5693 StartLoc))
5694 return StmtError();
5695
5696 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5697 VarsWithInheritedDSAType VarsWithInheritedDSA;
5698 bool ErrorFound = false;
5699 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5700 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5701 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5702 !isOpenMPLoopTransformationDirective(Kind)) {
5703 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5703, __PRETTY_FUNCTION__))
;
5704
5705 // Check default data sharing attributes for referenced variables.
5706 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5707 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5708 Stmt *S = AStmt;
5709 while (--ThisCaptureLevel >= 0)
5710 S = cast<CapturedStmt>(S)->getCapturedStmt();
5711 DSAChecker.Visit(S);
5712 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5713 !isOpenMPTaskingDirective(Kind)) {
5714 // Visit subcaptures to generate implicit clauses for captured vars.
5715 auto *CS = cast<CapturedStmt>(AStmt);
5716 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5717 getOpenMPCaptureRegions(CaptureRegions, Kind);
5718 // Ignore outer tasking regions for target directives.
5719 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5720 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5721 DSAChecker.visitSubCaptures(CS);
5722 }
5723 if (DSAChecker.isErrorFound())
5724 return StmtError();
5725 // Generate list of implicitly defined firstprivate variables.
5726 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5727
5728 SmallVector<Expr *, 4> ImplicitFirstprivates(
5729 DSAChecker.getImplicitFirstprivate().begin(),
5730 DSAChecker.getImplicitFirstprivate().end());
5731 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5732 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5733 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5734 ImplicitMapModifiers[DefaultmapKindNum];
5735 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5736 ImplicitMapModifiersLoc[DefaultmapKindNum];
5737 // Get the original location of present modifier from Defaultmap clause.
5738 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5739 for (OMPClause *C : Clauses) {
5740 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5741 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5742 PresentModifierLocs[DMC->getDefaultmapKind()] =
5743 DMC->getDefaultmapModifierLoc();
5744 }
5745 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5746 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5747 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5748 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5749 Kind, static_cast<OpenMPMapClauseKind>(I));
5750 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5751 }
5752 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5753 DSAChecker.getImplicitMapModifier(Kind);
5754 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5755 ImplicitModifier.end());
5756 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5757 ImplicitModifier.size(), PresentModifierLocs[VC]);
5758 }
5759 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5760 for (OMPClause *C : Clauses) {
5761 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5762 for (Expr *E : IRC->taskgroup_descriptors())
5763 if (E)
5764 ImplicitFirstprivates.emplace_back(E);
5765 }
5766 // OpenMP 5.0, 2.10.1 task Construct
5767 // [detach clause]... The event-handle will be considered as if it was
5768 // specified on a firstprivate clause.
5769 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5770 ImplicitFirstprivates.push_back(DC->getEventHandler());
5771 }
5772 if (!ImplicitFirstprivates.empty()) {
5773 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5774 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5775 SourceLocation())) {
5776 ClausesWithImplicit.push_back(Implicit);
5777 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5778 ImplicitFirstprivates.size();
5779 } else {
5780 ErrorFound = true;
5781 }
5782 }
5783 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5784 int ClauseKindCnt = -1;
5785 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5786 ++ClauseKindCnt;
5787 if (ImplicitMap.empty())
5788 continue;
5789 CXXScopeSpec MapperIdScopeSpec;
5790 DeclarationNameInfo MapperId;
5791 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5792 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5793 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5794 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5795 SourceLocation(), SourceLocation(), ImplicitMap,
5796 OMPVarListLocTy())) {
5797 ClausesWithImplicit.emplace_back(Implicit);
5798 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5799 ImplicitMap.size();
5800 } else {
5801 ErrorFound = true;
5802 }
5803 }
5804 }
5805 // Build expressions for implicit maps of data members with 'default'
5806 // mappers.
5807 if (LangOpts.OpenMP >= 50)
5808 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5809 ClausesWithImplicit);
5810 }
5811
5812 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5813 switch (Kind) {
5814 case OMPD_parallel:
5815 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5816 EndLoc);
5817 AllowedNameModifiers.push_back(OMPD_parallel);
5818 break;
5819 case OMPD_simd:
5820 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5821 VarsWithInheritedDSA);
5822 if (LangOpts.OpenMP >= 50)
5823 AllowedNameModifiers.push_back(OMPD_simd);
5824 break;
5825 case OMPD_tile:
5826 Res =
5827 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5828 break;
5829 case OMPD_for:
5830 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5831 VarsWithInheritedDSA);
5832 break;
5833 case OMPD_for_simd:
5834 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5835 EndLoc, VarsWithInheritedDSA);
5836 if (LangOpts.OpenMP >= 50)
5837 AllowedNameModifiers.push_back(OMPD_simd);
5838 break;
5839 case OMPD_sections:
5840 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5841 EndLoc);
5842 break;
5843 case OMPD_section:
5844 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5845, __PRETTY_FUNCTION__))
5845 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5845, __PRETTY_FUNCTION__))
;
5846 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5847 break;
5848 case OMPD_single:
5849 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5850 EndLoc);
5851 break;
5852 case OMPD_master:
5853 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5854, __PRETTY_FUNCTION__))
5854 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5854, __PRETTY_FUNCTION__))
;
5855 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5856 break;
5857 case OMPD_critical:
5858 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5859 StartLoc, EndLoc);
5860 break;
5861 case OMPD_parallel_for:
5862 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5863 EndLoc, VarsWithInheritedDSA);
5864 AllowedNameModifiers.push_back(OMPD_parallel);
5865 break;
5866 case OMPD_parallel_for_simd:
5867 Res = ActOnOpenMPParallelForSimdDirective(
5868 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5869 AllowedNameModifiers.push_back(OMPD_parallel);
5870 if (LangOpts.OpenMP >= 50)
5871 AllowedNameModifiers.push_back(OMPD_simd);
5872 break;
5873 case OMPD_parallel_master:
5874 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5875 StartLoc, EndLoc);
5876 AllowedNameModifiers.push_back(OMPD_parallel);
5877 break;
5878 case OMPD_parallel_sections:
5879 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5880 StartLoc, EndLoc);
5881 AllowedNameModifiers.push_back(OMPD_parallel);
5882 break;
5883 case OMPD_task:
5884 Res =
5885 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5886 AllowedNameModifiers.push_back(OMPD_task);
5887 break;
5888 case OMPD_taskyield:
5889 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5890, __PRETTY_FUNCTION__))
5890 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5890, __PRETTY_FUNCTION__))
;
5891 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5892, __PRETTY_FUNCTION__))
5892 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5892, __PRETTY_FUNCTION__))
;
5893 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5894 break;
5895 case OMPD_barrier:
5896 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5897, __PRETTY_FUNCTION__))
5897 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5897, __PRETTY_FUNCTION__))
;
5898 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5899, __PRETTY_FUNCTION__))
5899 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5899, __PRETTY_FUNCTION__))
;
5900 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5901 break;
5902 case OMPD_taskwait:
5903 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5904, __PRETTY_FUNCTION__))
5904 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5904, __PRETTY_FUNCTION__))
;
5905 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5906, __PRETTY_FUNCTION__))
5906 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5906, __PRETTY_FUNCTION__))
;
5907 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5908 break;
5909 case OMPD_taskgroup:
5910 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5911 EndLoc);
5912 break;
5913 case OMPD_flush:
5914 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5915, __PRETTY_FUNCTION__))
5915 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5915, __PRETTY_FUNCTION__))
;
5916 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5917 break;
5918 case OMPD_depobj:
5919 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5920, __PRETTY_FUNCTION__))
5920 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5920, __PRETTY_FUNCTION__))
;
5921 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5922 break;
5923 case OMPD_scan:
5924 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5925, __PRETTY_FUNCTION__))
5925 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5925, __PRETTY_FUNCTION__))
;
5926 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5927 break;
5928 case OMPD_ordered:
5929 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5930 EndLoc);
5931 break;
5932 case OMPD_atomic:
5933 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5934 EndLoc);
5935 break;
5936 case OMPD_teams:
5937 Res =
5938 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5939 break;
5940 case OMPD_target:
5941 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5942 EndLoc);
5943 AllowedNameModifiers.push_back(OMPD_target);
5944 break;
5945 case OMPD_target_parallel:
5946 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5947 StartLoc, EndLoc);
5948 AllowedNameModifiers.push_back(OMPD_target);
5949 AllowedNameModifiers.push_back(OMPD_parallel);
5950 break;
5951 case OMPD_target_parallel_for:
5952 Res = ActOnOpenMPTargetParallelForDirective(
5953 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5954 AllowedNameModifiers.push_back(OMPD_target);
5955 AllowedNameModifiers.push_back(OMPD_parallel);
5956 break;
5957 case OMPD_cancellation_point:
5958 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5959, __PRETTY_FUNCTION__))
5959 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5959, __PRETTY_FUNCTION__))
;
5960 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5961, __PRETTY_FUNCTION__))
5961 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5961, __PRETTY_FUNCTION__))
;
5962 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5963 break;
5964 case OMPD_cancel:
5965 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5966, __PRETTY_FUNCTION__))
5966 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 5966, __PRETTY_FUNCTION__))
;
5967 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5968 CancelRegion);
5969 AllowedNameModifiers.push_back(OMPD_cancel);
5970 break;
5971 case OMPD_target_data:
5972 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5973 EndLoc);
5974 AllowedNameModifiers.push_back(OMPD_target_data);
5975 break;
5976 case OMPD_target_enter_data:
5977 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5978 EndLoc, AStmt);
5979 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5980 break;
5981 case OMPD_target_exit_data:
5982 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5983 EndLoc, AStmt);
5984 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5985 break;
5986 case OMPD_taskloop:
5987 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5988 EndLoc, VarsWithInheritedDSA);
5989 AllowedNameModifiers.push_back(OMPD_taskloop);
5990 break;
5991 case OMPD_taskloop_simd:
5992 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5993 EndLoc, VarsWithInheritedDSA);
5994 AllowedNameModifiers.push_back(OMPD_taskloop);
5995 if (LangOpts.OpenMP >= 50)
5996 AllowedNameModifiers.push_back(OMPD_simd);
5997 break;
5998 case OMPD_master_taskloop:
5999 Res = ActOnOpenMPMasterTaskLoopDirective(
6000 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6001 AllowedNameModifiers.push_back(OMPD_taskloop);
6002 break;
6003 case OMPD_master_taskloop_simd:
6004 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6005 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6006 AllowedNameModifiers.push_back(OMPD_taskloop);
6007 if (LangOpts.OpenMP >= 50)
6008 AllowedNameModifiers.push_back(OMPD_simd);
6009 break;
6010 case OMPD_parallel_master_taskloop:
6011 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6012 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6013 AllowedNameModifiers.push_back(OMPD_taskloop);
6014 AllowedNameModifiers.push_back(OMPD_parallel);
6015 break;
6016 case OMPD_parallel_master_taskloop_simd:
6017 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6018 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6019 AllowedNameModifiers.push_back(OMPD_taskloop);
6020 AllowedNameModifiers.push_back(OMPD_parallel);
6021 if (LangOpts.OpenMP >= 50)
6022 AllowedNameModifiers.push_back(OMPD_simd);
6023 break;
6024 case OMPD_distribute:
6025 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6026 EndLoc, VarsWithInheritedDSA);
6027 break;
6028 case OMPD_target_update:
6029 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6030 EndLoc, AStmt);
6031 AllowedNameModifiers.push_back(OMPD_target_update);
6032 break;
6033 case OMPD_distribute_parallel_for:
6034 Res = ActOnOpenMPDistributeParallelForDirective(
6035 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6036 AllowedNameModifiers.push_back(OMPD_parallel);
6037 break;
6038 case OMPD_distribute_parallel_for_simd:
6039 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6040 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6041 AllowedNameModifiers.push_back(OMPD_parallel);
6042 if (LangOpts.OpenMP >= 50)
6043 AllowedNameModifiers.push_back(OMPD_simd);
6044 break;
6045 case OMPD_distribute_simd:
6046 Res = ActOnOpenMPDistributeSimdDirective(
6047 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6048 if (LangOpts.OpenMP >= 50)
6049 AllowedNameModifiers.push_back(OMPD_simd);
6050 break;
6051 case OMPD_target_parallel_for_simd:
6052 Res = ActOnOpenMPTargetParallelForSimdDirective(
6053 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6054 AllowedNameModifiers.push_back(OMPD_target);
6055 AllowedNameModifiers.push_back(OMPD_parallel);
6056 if (LangOpts.OpenMP >= 50)
6057 AllowedNameModifiers.push_back(OMPD_simd);
6058 break;
6059 case OMPD_target_simd:
6060 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6061 EndLoc, VarsWithInheritedDSA);
6062 AllowedNameModifiers.push_back(OMPD_target);
6063 if (LangOpts.OpenMP >= 50)
6064 AllowedNameModifiers.push_back(OMPD_simd);
6065 break;
6066 case OMPD_teams_distribute:
6067 Res = ActOnOpenMPTeamsDistributeDirective(
6068 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6069 break;
6070 case OMPD_teams_distribute_simd:
6071 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6072 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6073 if (LangOpts.OpenMP >= 50)
6074 AllowedNameModifiers.push_back(OMPD_simd);
6075 break;
6076 case OMPD_teams_distribute_parallel_for_simd:
6077 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6078 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6079 AllowedNameModifiers.push_back(OMPD_parallel);
6080 if (LangOpts.OpenMP >= 50)
6081 AllowedNameModifiers.push_back(OMPD_simd);
6082 break;
6083 case OMPD_teams_distribute_parallel_for:
6084 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6085 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6086 AllowedNameModifiers.push_back(OMPD_parallel);
6087 break;
6088 case OMPD_target_teams:
6089 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6090 EndLoc);
6091 AllowedNameModifiers.push_back(OMPD_target);
6092 break;
6093 case OMPD_target_teams_distribute:
6094 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6095 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6096 AllowedNameModifiers.push_back(OMPD_target);
6097 break;
6098 case OMPD_target_teams_distribute_parallel_for:
6099 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6100 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6101 AllowedNameModifiers.push_back(OMPD_target);
6102 AllowedNameModifiers.push_back(OMPD_parallel);
6103 break;
6104 case OMPD_target_teams_distribute_parallel_for_simd:
6105 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6106 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6107 AllowedNameModifiers.push_back(OMPD_target);
6108 AllowedNameModifiers.push_back(OMPD_parallel);
6109 if (LangOpts.OpenMP >= 50)
6110 AllowedNameModifiers.push_back(OMPD_simd);
6111 break;
6112 case OMPD_target_teams_distribute_simd:
6113 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6114 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6115 AllowedNameModifiers.push_back(OMPD_target);
6116 if (LangOpts.OpenMP >= 50)
6117 AllowedNameModifiers.push_back(OMPD_simd);
6118 break;
6119 case OMPD_interop:
6120 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp interop' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp interop' directive\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6121, __PRETTY_FUNCTION__))
6121 "No associated statement allowed for 'omp interop' directive")((AStmt == nullptr && "No associated statement allowed for 'omp interop' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp interop' directive\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6121, __PRETTY_FUNCTION__))
;
6122 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6123 break;
6124 case OMPD_dispatch:
6125 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6126 EndLoc);
6127 break;
6128 case OMPD_declare_target:
6129 case OMPD_end_declare_target:
6130 case OMPD_threadprivate:
6131 case OMPD_allocate:
6132 case OMPD_declare_reduction:
6133 case OMPD_declare_mapper:
6134 case OMPD_declare_simd:
6135 case OMPD_requires:
6136 case OMPD_declare_variant:
6137 case OMPD_begin_declare_variant:
6138 case OMPD_end_declare_variant:
6139 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6139)
;
6140 case OMPD_unknown:
6141 default:
6142 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6142)
;
6143 }
6144
6145 ErrorFound = Res.isInvalid() || ErrorFound;
6146
6147 // Check variables in the clauses if default(none) or
6148 // default(firstprivate) was specified.
6149 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6150 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6151 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
6152 for (OMPClause *C : Clauses) {
6153 switch (C->getClauseKind()) {
6154 case OMPC_num_threads:
6155 case OMPC_dist_schedule:
6156 // Do not analyse if no parent teams directive.
6157 if (isOpenMPTeamsDirective(Kind))
6158 break;
6159 continue;
6160 case OMPC_if:
6161 if (isOpenMPTeamsDirective(Kind) &&
6162 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6163 break;
6164 if (isOpenMPParallelDirective(Kind) &&
6165 isOpenMPTaskLoopDirective(Kind) &&
6166 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6167 break;
6168 continue;
6169 case OMPC_schedule:
6170 case OMPC_detach:
6171 break;
6172 case OMPC_grainsize:
6173 case OMPC_num_tasks:
6174 case OMPC_final:
6175 case OMPC_priority:
6176 case OMPC_novariants:
6177 // Do not analyze if no parent parallel directive.
6178 if (isOpenMPParallelDirective(Kind))
6179 break;
6180 continue;
6181 case OMPC_ordered:
6182 case OMPC_device:
6183 case OMPC_num_teams:
6184 case OMPC_thread_limit:
6185 case OMPC_hint:
6186 case OMPC_collapse:
6187 case OMPC_safelen:
6188 case OMPC_simdlen:
6189 case OMPC_sizes:
6190 case OMPC_default:
6191 case OMPC_proc_bind:
6192 case OMPC_private:
6193 case OMPC_firstprivate:
6194 case OMPC_lastprivate:
6195 case OMPC_shared:
6196 case OMPC_reduction:
6197 case OMPC_task_reduction:
6198 case OMPC_in_reduction:
6199 case OMPC_linear:
6200 case OMPC_aligned:
6201 case OMPC_copyin:
6202 case OMPC_copyprivate:
6203 case OMPC_nowait:
6204 case OMPC_untied:
6205 case OMPC_mergeable:
6206 case OMPC_allocate:
6207 case OMPC_read:
6208 case OMPC_write:
6209 case OMPC_update:
6210 case OMPC_capture:
6211 case OMPC_seq_cst:
6212 case OMPC_acq_rel:
6213 case OMPC_acquire:
6214 case OMPC_release:
6215 case OMPC_relaxed:
6216 case OMPC_depend:
6217 case OMPC_threads:
6218 case OMPC_simd:
6219 case OMPC_map:
6220 case OMPC_nogroup:
6221 case OMPC_defaultmap:
6222 case OMPC_to:
6223 case OMPC_from:
6224 case OMPC_use_device_ptr:
6225 case OMPC_use_device_addr:
6226 case OMPC_is_device_ptr:
6227 case OMPC_nontemporal:
6228 case OMPC_order:
6229 case OMPC_destroy:
6230 case OMPC_inclusive:
6231 case OMPC_exclusive:
6232 case OMPC_uses_allocators:
6233 case OMPC_affinity:
6234 continue;
6235 case OMPC_allocator:
6236 case OMPC_flush:
6237 case OMPC_depobj:
6238 case OMPC_threadprivate:
6239 case OMPC_uniform:
6240 case OMPC_unknown:
6241 case OMPC_unified_address:
6242 case OMPC_unified_shared_memory:
6243 case OMPC_reverse_offload:
6244 case OMPC_dynamic_allocators:
6245 case OMPC_atomic_default_mem_order:
6246 case OMPC_device_type:
6247 case OMPC_match:
6248 default:
6249 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6249)
;
6250 }
6251 for (Stmt *CC : C->children()) {
6252 if (CC)
6253 DSAChecker.Visit(CC);
6254 }
6255 }
6256 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6257 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6258 }
6259 for (const auto &P : VarsWithInheritedDSA) {
6260 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6261 continue;
6262 ErrorFound = true;
6263 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6264 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6265 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6266 << P.first << P.second->getSourceRange();
6267 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6268 } else if (getLangOpts().OpenMP >= 50) {
6269 Diag(P.second->getExprLoc(),
6270 diag::err_omp_defaultmap_no_attr_for_variable)
6271 << P.first << P.second->getSourceRange();
6272 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
6273 diag::note_omp_defaultmap_attr_none);
6274 }
6275 }
6276
6277 if (!AllowedNameModifiers.empty())
6278 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6279 ErrorFound;
6280
6281 if (ErrorFound)
6282 return StmtError();
6283
6284 if (!CurContext->isDependentContext() &&
6285 isOpenMPTargetExecutionDirective(Kind) &&
6286 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6287 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6288 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6289 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6290 // Register target to DSA Stack.
6291 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
6292 }
6293
6294 return Res;
6295}
6296
6297Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6298 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6299 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6300 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6301 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6302 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6302, __PRETTY_FUNCTION__))
;
6303 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6303, __PRETTY_FUNCTION__))
;
6304 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6304, __PRETTY_FUNCTION__))
;
6305 if (!DG || DG.get().isNull())
6306 return DeclGroupPtrTy();
6307
6308 const int SimdId = 0;
6309 if (!DG.get().isSingleDecl()) {
6310 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6311 << SimdId;
6312 return DG;
6313 }
6314 Decl *ADecl = DG.get().getSingleDecl();
6315 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6316 ADecl = FTD->getTemplatedDecl();
6317
6318 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6319 if (!FD) {
6320 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6321 return DeclGroupPtrTy();
6322 }
6323
6324 // OpenMP [2.8.2, declare simd construct, Description]
6325 // The parameter of the simdlen clause must be a constant positive integer
6326 // expression.
6327 ExprResult SL;
6328 if (Simdlen)
6329 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6330 // OpenMP [2.8.2, declare simd construct, Description]
6331 // The special this pointer can be used as if was one of the arguments to the
6332 // function in any of the linear, aligned, or uniform clauses.
6333 // The uniform clause declares one or more arguments to have an invariant
6334 // value for all concurrent invocations of the function in the execution of a
6335 // single SIMD loop.
6336 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6337 const Expr *UniformedLinearThis = nullptr;
6338 for (const Expr *E : Uniforms) {
6339 E = E->IgnoreParenImpCasts();
6340 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6341 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6342 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6343 FD->getParamDecl(PVD->getFunctionScopeIndex())
6344 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6345 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6346 continue;
6347 }
6348 if (isa<CXXThisExpr>(E)) {
6349 UniformedLinearThis = E;
6350 continue;
6351 }
6352 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6353 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6354 }
6355 // OpenMP [2.8.2, declare simd construct, Description]
6356 // The aligned clause declares that the object to which each list item points
6357 // is aligned to the number of bytes expressed in the optional parameter of
6358 // the aligned clause.
6359 // The special this pointer can be used as if was one of the arguments to the
6360 // function in any of the linear, aligned, or uniform clauses.
6361 // The type of list items appearing in the aligned clause must be array,
6362 // pointer, reference to array, or reference to pointer.
6363 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6364 const Expr *AlignedThis = nullptr;
6365 for (const Expr *E : Aligneds) {
6366 E = E->IgnoreParenImpCasts();
6367 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6368 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6369 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6370 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6371 FD->getParamDecl(PVD->getFunctionScopeIndex())
6372 ->getCanonicalDecl() == CanonPVD) {
6373 // OpenMP [2.8.1, simd construct, Restrictions]
6374 // A list-item cannot appear in more than one aligned clause.
6375 if (AlignedArgs.count(CanonPVD) > 0) {
6376 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6377 << 1 << getOpenMPClauseName(OMPC_aligned)
6378 << E->getSourceRange();
6379 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6380 diag::note_omp_explicit_dsa)
6381 << getOpenMPClauseName(OMPC_aligned);
6382 continue;
6383 }
6384 AlignedArgs[CanonPVD] = E;
6385 QualType QTy = PVD->getType()
6386 .getNonReferenceType()
6387 .getUnqualifiedType()
6388 .getCanonicalType();
6389 const Type *Ty = QTy.getTypePtrOrNull();
6390 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6391 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6392 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6393 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6394 }
6395 continue;
6396 }
6397 }
6398 if (isa<CXXThisExpr>(E)) {
6399 if (AlignedThis) {
6400 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6401 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6402 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6403 << getOpenMPClauseName(OMPC_aligned);
6404 }
6405 AlignedThis = E;
6406 continue;
6407 }
6408 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6409 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6410 }
6411 // The optional parameter of the aligned clause, alignment, must be a constant
6412 // positive integer expression. If no optional parameter is specified,
6413 // implementation-defined default alignments for SIMD instructions on the
6414 // target platforms are assumed.
6415 SmallVector<const Expr *, 4> NewAligns;
6416 for (Expr *E : Alignments) {
6417 ExprResult Align;
6418 if (E)
6419 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6420 NewAligns.push_back(Align.get());
6421 }
6422 // OpenMP [2.8.2, declare simd construct, Description]
6423 // The linear clause declares one or more list items to be private to a SIMD
6424 // lane and to have a linear relationship with respect to the iteration space
6425 // of a loop.
6426 // The special this pointer can be used as if was one of the arguments to the
6427 // function in any of the linear, aligned, or uniform clauses.
6428 // When a linear-step expression is specified in a linear clause it must be
6429 // either a constant integer expression or an integer-typed parameter that is
6430 // specified in a uniform clause on the directive.
6431 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6432 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6433 auto MI = LinModifiers.begin();
6434 for (const Expr *E : Linears) {
6435 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6436 ++MI;
6437 E = E->IgnoreParenImpCasts();
6438 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6439 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6440 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6441 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6442 FD->getParamDecl(PVD->getFunctionScopeIndex())
6443 ->getCanonicalDecl() == CanonPVD) {
6444 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6445 // A list-item cannot appear in more than one linear clause.
6446 if (LinearArgs.count(CanonPVD) > 0) {
6447 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6448 << getOpenMPClauseName(OMPC_linear)
6449 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6450 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6451 diag::note_omp_explicit_dsa)
6452 << getOpenMPClauseName(OMPC_linear);
6453 continue;
6454 }
6455 // Each argument can appear in at most one uniform or linear clause.
6456 if (UniformedArgs.count(CanonPVD) > 0) {
6457 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6458 << getOpenMPClauseName(OMPC_linear)
6459 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6460 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6461 diag::note_omp_explicit_dsa)
6462 << getOpenMPClauseName(OMPC_uniform);
6463 continue;
6464 }
6465 LinearArgs[CanonPVD] = E;
6466 if (E->isValueDependent() || E->isTypeDependent() ||
6467 E->isInstantiationDependent() ||
6468 E->containsUnexpandedParameterPack())
6469 continue;
6470 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6471 PVD->getOriginalType(),
6472 /*IsDeclareSimd=*/true);
6473 continue;
6474 }
6475 }
6476 if (isa<CXXThisExpr>(E)) {
6477 if (UniformedLinearThis) {
6478 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6479 << getOpenMPClauseName(OMPC_linear)
6480 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6481 << E->getSourceRange();
6482 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6483 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6484 : OMPC_linear);
6485 continue;
6486 }
6487 UniformedLinearThis = E;
6488 if (E->isValueDependent() || E->isTypeDependent() ||
6489 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6490 continue;
6491 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6492 E->getType(), /*IsDeclareSimd=*/true);
6493 continue;
6494 }
6495 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6496 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6497 }
6498 Expr *Step = nullptr;
6499 Expr *NewStep = nullptr;
6500 SmallVector<Expr *, 4> NewSteps;
6501 for (Expr *E : Steps) {
6502 // Skip the same step expression, it was checked already.
6503 if (Step == E || !E) {
6504 NewSteps.push_back(E ? NewStep : nullptr);
6505 continue;
6506 }
6507 Step = E;
6508 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6509 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6510 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6511 if (UniformedArgs.count(CanonPVD) == 0) {
6512 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6513 << Step->getSourceRange();
6514 } else if (E->isValueDependent() || E->isTypeDependent() ||
6515 E->isInstantiationDependent() ||
6516 E->containsUnexpandedParameterPack() ||
6517 CanonPVD->getType()->hasIntegerRepresentation()) {
6518 NewSteps.push_back(Step);
6519 } else {
6520 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6521 << Step->getSourceRange();
6522 }
6523 continue;
6524 }
6525 NewStep = Step;
6526 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6527 !Step->isInstantiationDependent() &&
6528 !Step->containsUnexpandedParameterPack()) {
6529 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6530 .get();
6531 if (NewStep)
6532 NewStep =
6533 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6534 }
6535 NewSteps.push_back(NewStep);
6536 }
6537 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6538 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6539 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6540 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6541 const_cast<Expr **>(Linears.data()), Linears.size(),
6542 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6543 NewSteps.data(), NewSteps.size(), SR);
6544 ADecl->addAttr(NewAttr);
6545 return DG;
6546}
6547
6548static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6549 QualType NewType) {
6550 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6551, __PRETTY_FUNCTION__))
6551 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6551, __PRETTY_FUNCTION__))
;
6552 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6553, __PRETTY_FUNCTION__))
6553 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6553, __PRETTY_FUNCTION__))
;
6554 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6555, __PRETTY_FUNCTION__))
6555 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6555, __PRETTY_FUNCTION__))
;
6556 // Synthesize parameters with the same types.
6557 FD->setType(NewType);
6558 SmallVector<ParmVarDecl *, 16> Params;
6559 for (const ParmVarDecl *P : FDWithProto->parameters()) {
6560 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6561 SourceLocation(), nullptr, P->getType(),
6562 /*TInfo=*/nullptr, SC_None, nullptr);
6563 Param->setScopeInfo(0, Params.size());
6564 Param->setImplicit();
6565 Params.push_back(Param);
6566 }
6567
6568 FD->setParams(Params);
6569}
6570
6571void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6572 if (D->isInvalidDecl())
6573 return;
6574 FunctionDecl *FD = nullptr;
6575 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6576 FD = UTemplDecl->getTemplatedDecl();
6577 else
6578 FD = cast<FunctionDecl>(D);
6579 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 6579, __PRETTY_FUNCTION__))
;
6580
6581 // If we are intantiating templates we do *not* apply scoped assumptions but
6582 // only global ones. We apply scoped assumption to the template definition
6583 // though.
6584 if (!inTemplateInstantiation()) {
6585 for (AssumptionAttr *AA : OMPAssumeScoped)
6586 FD->addAttr(AA);
6587 }
6588 for (AssumptionAttr *AA : OMPAssumeGlobal)
6589 FD->addAttr(AA);
6590}
6591
6592Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6593 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6594
6595void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6596 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6597 SmallVectorImpl<FunctionDecl *> &Bases) {
6598 if (!D.getIdentifier())
6599 return;
6600
6601 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6602
6603 // Template specialization is an extension, check if we do it.
6604 bool IsTemplated = !TemplateParamLists.empty();
6605 if (IsTemplated &
6606 !DVScope.TI->isExtensionActive(
6607 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6608 return;
6609
6610 IdentifierInfo *BaseII = D.getIdentifier();
6611 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6612 LookupOrdinaryName);
6613 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6614
6615 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6616 QualType FType = TInfo->getType();
6617
6618 bool IsConstexpr =
6619 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6620 bool IsConsteval =
6621 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6622
6623 for (auto *Candidate : Lookup) {
6624 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6625 FunctionDecl *UDecl = nullptr;
6626 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6627 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6628 else if (!IsTemplated)
6629 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6630 if (!UDecl)
6631 continue;
6632
6633 // Don't specialize constexpr/consteval functions with
6634 // non-constexpr/consteval functions.
6635 if (UDecl->isConstexpr() && !IsConstexpr)
6636 continue;
6637 if (UDecl->isConsteval() && !IsConsteval)
6638 continue;
6639
6640 QualType UDeclTy = UDecl->getType();
6641 if (!UDeclTy->isDependentType()) {
6642 QualType NewType = Context.mergeFunctionTypes(
6643 FType, UDeclTy, /* OfBlockPointer */ false,
6644 /* Unqualified */ false, /* AllowCXX */ true);
6645 if (NewType.isNull())
6646 continue;
6647 }
6648
6649 // Found a base!
6650 Bases.push_back(UDecl);
6651 }
6652
6653 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6654 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6655 // If no base was found we create a declaration that we use as base.
6656 if (Bases.empty() && UseImplicitBase) {
6657 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6658 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6659 BaseD->setImplicit(true);
6660 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6661 Bases.push_back(BaseTemplD->getTemplatedDecl());
6662 else
6663 Bases.push_back(cast<FunctionDecl>(BaseD));
6664 }
6665
6666 std::string MangledName;
6667 MangledName += D.getIdentifier()->getName();
6668 MangledName += getOpenMPVariantManglingSeparatorStr();
6669 MangledName += DVScope.NameSuffix;
6670 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6671
6672 VariantII.setMangledOpenMPVariantName(true);
6673 D.SetIdentifier(&VariantII, D.getBeginLoc());
6674}
6675
6676void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6677 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6678 // Do not mark function as is used to prevent its emission if this is the
6679 // only place where it is used.
6680 EnterExpressionEvaluationContext Unevaluated(
6681 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6682
6683 FunctionDecl *FD = nullptr;
6684 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6685 FD = UTemplDecl->getTemplatedDecl();
6686 else
6687 FD = cast<FunctionDecl>(D);
6688 auto *VariantFuncRef = DeclRefExpr::Create(
6689 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6690 /* RefersToEnclosingVariableOrCapture */ false,
6691 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
6692
6693 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6694 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6695 Context, VariantFuncRef, DVScope.TI);
6696 for (FunctionDecl *BaseFD : Bases)
6697 BaseFD->addAttr(OMPDeclareVariantA);
6698}
6699
6700ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6701 SourceLocation LParenLoc,
6702 MultiExprArg ArgExprs,
6703 SourceLocation RParenLoc, Expr *ExecConfig) {
6704 // The common case is a regular call we do not want to specialize at all. Try
6705 // to make that case fast by bailing early.
6706 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6707 if (!CE)
6708 return Call;
6709
6710 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6711 if (!CalleeFnDecl)
6712 return Call;
6713
6714 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6715 return Call;
6716
6717 ASTContext &Context = getASTContext();
6718 std::function<void(StringRef)> DiagUnknownTrait = [this,
6719 CE](StringRef ISATrait) {
6720 // TODO Track the selector locations in a way that is accessible here to
6721 // improve the diagnostic location.
6722 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6723 << ISATrait;
6724 };
6725 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6726 getCurFunctionDecl());
6727
6728 QualType CalleeFnType = CalleeFnDecl->getType();
6729
6730 SmallVector<Expr *, 4> Exprs;
6731 SmallVector<VariantMatchInfo, 4> VMIs;
6732 while (CalleeFnDecl) {
6733 for (OMPDeclareVariantAttr *A :
6734 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6735 Expr *VariantRef = A->getVariantFuncRef();
6736
6737 VariantMatchInfo VMI;
6738 OMPTraitInfo &TI = A->getTraitInfo();
6739 TI.getAsVariantMatchInfo(Context, VMI);
6740 if (!isVariantApplicableInContext(VMI, OMPCtx,
6741 /* DeviceSetOnly */ false))
6742 continue;
6743
6744 VMIs.push_back(VMI);
6745 Exprs.push_back(VariantRef);
6746 }
6747
6748 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6749 }
6750
6751 ExprResult NewCall;
6752 do {
6753 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6754 if (BestIdx < 0)
6755 return Call;
6756 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6757 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6758
6759 {
6760 // Try to build a (member) call expression for the current best applicable
6761 // variant expression. We allow this to fail in which case we continue
6762 // with the next best variant expression. The fail case is part of the
6763 // implementation defined behavior in the OpenMP standard when it talks
6764 // about what differences in the function prototypes: "Any differences
6765 // that the specific OpenMP context requires in the prototype of the
6766 // variant from the base function prototype are implementation defined."
6767 // This wording is there to allow the specialized variant to have a
6768 // different type than the base function. This is intended and OK but if
6769 // we cannot create a call the difference is not in the "implementation
6770 // defined range" we allow.
6771 Sema::TentativeAnalysisScope Trap(*this);
6772
6773 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6774 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6775 BestExpr = MemberExpr::CreateImplicit(
6776 Context, MemberCall->getImplicitObjectArgument(),
6777 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6778 MemberCall->getValueKind(), MemberCall->getObjectKind());
6779 }
6780 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6781 ExecConfig);
6782 if (NewCall.isUsable()) {
6783 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6784 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6785 QualType NewType = Context.mergeFunctionTypes(
6786 CalleeFnType, NewCalleeFnDecl->getType(),
6787 /* OfBlockPointer */ false,
6788 /* Unqualified */ false, /* AllowCXX */ true);
6789 if (!NewType.isNull())
6790 break;
6791 // Don't use the call if the function type was not compatible.
6792 NewCall = nullptr;
6793 }
6794 }
6795 }
6796
6797 VMIs.erase(VMIs.begin() + BestIdx);
6798 Exprs.erase(Exprs.begin() + BestIdx);
6799 } while (!VMIs.empty());
6800
6801 if (!NewCall.isUsable())
6802 return Call;
6803 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6804}
6805
6806Optional<std::pair<FunctionDecl *, Expr *>>
6807Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6808 Expr *VariantRef, OMPTraitInfo &TI,
6809 SourceRange SR) {
6810 if (!DG || DG.get().isNull())
6811 return None;
6812
6813 const int VariantId = 1;
6814 // Must be applied only to single decl.
6815 if (!DG.get().isSingleDecl()) {
6816 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6817 << VariantId << SR;
6818 return None;
6819 }
6820 Decl *ADecl = DG.get().getSingleDecl();
6821 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6822 ADecl = FTD->getTemplatedDecl();
6823
6824 // Decl must be a function.
6825 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6826 if (!FD) {
6827 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6828 << VariantId << SR;
6829 return None;
6830 }
6831
6832 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6833 return FD->hasAttrs() &&
6834 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6835 FD->hasAttr<TargetAttr>());
6836 };
6837 // OpenMP is not compatible with CPU-specific attributes.
6838 if (HasMultiVersionAttributes(FD)) {
6839 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6840 << SR;
6841 return None;
6842 }
6843
6844 // Allow #pragma omp declare variant only if the function is not used.
6845 if (FD->isUsed(false))
6846 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6847 << FD->getLocation();
6848
6849 // Check if the function was emitted already.
6850 const FunctionDecl *Definition;
6851 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6852 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6853 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6854 << FD->getLocation();
6855
6856 // The VariantRef must point to function.
6857 if (!VariantRef) {
6858 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6859 return None;
6860 }
6861
6862 auto ShouldDelayChecks = [](Expr *&E, bool) {
6863 return E && (E->isTypeDependent() || E->isValueDependent() ||
6864 E->containsUnexpandedParameterPack() ||
6865 E->isInstantiationDependent());
6866 };
6867 // Do not check templates, wait until instantiation.
6868 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6869 TI.anyScoreOrCondition(ShouldDelayChecks))
6870 return std::make_pair(FD, VariantRef);
6871
6872 // Deal with non-constant score and user condition expressions.
6873 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6874 bool IsScore) -> bool {
6875 if (!E || E->isIntegerConstantExpr(Context))
6876 return false;
6877
6878 if (IsScore) {
6879 // We warn on non-constant scores and pretend they were not present.
6880 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6881 << E;
6882 E = nullptr;
6883 } else {
6884 // We could replace a non-constant user condition with "false" but we
6885 // will soon need to handle these anyway for the dynamic version of
6886 // OpenMP context selectors.
6887 Diag(E->getExprLoc(),
6888 diag::err_omp_declare_variant_user_condition_not_constant)
6889 << E;
6890 }
6891 return true;
6892 };
6893 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6894 return None;
6895
6896 // Convert VariantRef expression to the type of the original function to
6897 // resolve possible conflicts.
6898 ExprResult VariantRefCast = VariantRef;
6899 if (LangOpts.CPlusPlus) {
6900 QualType FnPtrType;
6901 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6902 if (Method && !Method->isStatic()) {
6903 const Type *ClassType =
6904 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6905 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6906 ExprResult ER;
6907 {
6908 // Build adrr_of unary op to correctly handle type checks for member
6909 // functions.
6910 Sema::TentativeAnalysisScope Trap(*this);
6911 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6912 VariantRef);
6913 }
6914 if (!ER.isUsable()) {
6915 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6916 << VariantId << VariantRef->getSourceRange();
6917 return None;
6918 }
6919 VariantRef = ER.get();
6920 } else {
6921 FnPtrType = Context.getPointerType(FD->getType());
6922 }
6923 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6924 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6925 ImplicitConversionSequence ICS = TryImplicitConversion(
6926 VariantRef, FnPtrType.getUnqualifiedType(),
6927 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6928 /*InOverloadResolution=*/false,
6929 /*CStyle=*/false,
6930 /*AllowObjCWritebackConversion=*/false);
6931 if (ICS.isFailure()) {
6932 Diag(VariantRef->getExprLoc(),
6933 diag::err_omp_declare_variant_incompat_types)
6934 << VariantRef->getType()
6935 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6936 << VariantRef->getSourceRange();
6937 return None;
6938 }
6939 VariantRefCast = PerformImplicitConversion(
6940 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6941 if (!VariantRefCast.isUsable())
6942 return None;
6943 }
6944 // Drop previously built artificial addr_of unary op for member functions.
6945 if (Method && !Method->isStatic()) {
6946 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6947 if (auto *UO = dyn_cast<UnaryOperator>(
6948 PossibleAddrOfVariantRef->IgnoreImplicit()))
6949 VariantRefCast = UO->getSubExpr();
6950 }
6951 }
6952
6953 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6954 if (!ER.isUsable() ||
6955 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6956 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6957 << VariantId << VariantRef->getSourceRange();
6958 return None;
6959 }
6960
6961 // The VariantRef must point to function.
6962 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6963 if (!DRE) {
6964 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6965 << VariantId << VariantRef->getSourceRange();
6966 return None;
6967 }
6968 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6969 if (!NewFD) {
6970 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6971 << VariantId << VariantRef->getSourceRange();
6972 return None;
6973 }
6974
6975 // Check if function types are compatible in C.
6976 if (!LangOpts.CPlusPlus) {
6977 QualType NewType =
6978 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6979 if (NewType.isNull()) {
6980 Diag(VariantRef->getExprLoc(),
6981 diag::err_omp_declare_variant_incompat_types)
6982 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6983 return None;
6984 }
6985 if (NewType->isFunctionProtoType()) {
6986 if (FD->getType()->isFunctionNoProtoType())
6987 setPrototype(*this, FD, NewFD, NewType);
6988 else if (NewFD->getType()->isFunctionNoProtoType())
6989 setPrototype(*this, NewFD, FD, NewType);
6990 }
6991 }
6992
6993 // Check if variant function is not marked with declare variant directive.
6994 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6995 Diag(VariantRef->getExprLoc(),
6996 diag::warn_omp_declare_variant_marked_as_declare_variant)
6997 << VariantRef->getSourceRange();
6998 SourceRange SR =
6999 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7000 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7001 return None;
7002 }
7003
7004 enum DoesntSupport {
7005 VirtFuncs = 1,
7006 Constructors = 3,
7007 Destructors = 4,
7008 DeletedFuncs = 5,
7009 DefaultedFuncs = 6,
7010 ConstexprFuncs = 7,
7011 ConstevalFuncs = 8,
7012 };
7013 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7014 if (CXXFD->isVirtual()) {
7015 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7016 << VirtFuncs;
7017 return None;
7018 }
7019
7020 if (isa<CXXConstructorDecl>(FD)) {
7021 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7022 << Constructors;
7023 return None;
7024 }
7025
7026 if (isa<CXXDestructorDecl>(FD)) {
7027 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7028 << Destructors;
7029 return None;
7030 }
7031 }
7032
7033 if (FD->isDeleted()) {
7034 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7035 << DeletedFuncs;
7036 return None;
7037 }
7038
7039 if (FD->isDefaulted()) {
7040 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7041 << DefaultedFuncs;
7042 return None;
7043 }
7044
7045 if (FD->isConstexpr()) {
7046 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7047 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7048 return None;
7049 }
7050
7051 // Check general compatibility.
7052 if (areMultiversionVariantFunctionsCompatible(
7053 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7054 PartialDiagnosticAt(SourceLocation(),
7055 PartialDiagnostic::NullDiagnostic()),
7056 PartialDiagnosticAt(
7057 VariantRef->getExprLoc(),
7058 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7059 PartialDiagnosticAt(VariantRef->getExprLoc(),
7060 PDiag(diag::err_omp_declare_variant_diff)
7061 << FD->getLocation()),
7062 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7063 /*CLinkageMayDiffer=*/true))
7064 return None;
7065 return std::make_pair(FD, cast<Expr>(DRE));
7066}
7067
7068void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
7069 Expr *VariantRef,
7070 OMPTraitInfo &TI,
7071 SourceRange SR) {
7072 auto *NewAttr =
7073 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
7074 FD->addAttr(NewAttr);
7075}
7076
7077StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7078 Stmt *AStmt,
7079 SourceLocation StartLoc,
7080 SourceLocation EndLoc) {
7081 if (!AStmt)
7082 return StmtError();
7083
7084 auto *CS = cast<CapturedStmt>(AStmt);
7085 // 1.2.2 OpenMP Language Terminology
7086 // Structured block - An executable statement with a single entry at the
7087 // top and a single exit at the bottom.
7088 // The point of exit cannot be a branch out of the structured block.
7089 // longjmp() and throw() must not violate the entry/exit criteria.
7090 CS->getCapturedDecl()->setNothrow();
7091
7092 setFunctionHasBranchProtectedScope();
7093
7094 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7095 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
7096 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7097}
7098
7099namespace {
7100/// Iteration space of a single for loop.
7101struct LoopIterationSpace final {
7102 /// True if the condition operator is the strict compare operator (<, > or
7103 /// !=).
7104 bool IsStrictCompare = false;
7105 /// Condition of the loop.
7106 Expr *PreCond = nullptr;
7107 /// This expression calculates the number of iterations in the loop.
7108 /// It is always possible to calculate it before starting the loop.
7109 Expr *NumIterations = nullptr;
7110 /// The loop counter variable.
7111 Expr *CounterVar = nullptr;
7112 /// Private loop counter variable.
7113 Expr *PrivateCounterVar = nullptr;
7114 /// This is initializer for the initial value of #CounterVar.
7115 Expr *CounterInit = nullptr;
7116 /// This is step for the #CounterVar used to generate its update:
7117 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7118 Expr *CounterStep = nullptr;
7119 /// Should step be subtracted?
7120 bool Subtract = false;
7121 /// Source range of the loop init.
7122 SourceRange InitSrcRange;
7123 /// Source range of the loop condition.
7124 SourceRange CondSrcRange;
7125 /// Source range of the loop increment.
7126 SourceRange IncSrcRange;
7127 /// Minimum value that can have the loop control variable. Used to support
7128 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7129 /// since only such variables can be used in non-loop invariant expressions.
7130 Expr *MinValue = nullptr;
7131 /// Maximum value that can have the loop control variable. Used to support
7132 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7133 /// since only such variables can be used in non-loop invariant expressions.
7134 Expr *MaxValue = nullptr;
7135 /// true, if the lower bound depends on the outer loop control var.
7136 bool IsNonRectangularLB = false;
7137 /// true, if the upper bound depends on the outer loop control var.
7138 bool IsNonRectangularUB = false;
7139 /// Index of the loop this loop depends on and forms non-rectangular loop
7140 /// nest.
7141 unsigned LoopDependentIdx = 0;
7142 /// Final condition for the non-rectangular loop nest support. It is used to
7143 /// check that the number of iterations for this particular counter must be
7144 /// finished.
7145 Expr *FinalCondition = nullptr;
7146};
7147
7148/// Helper class for checking canonical form of the OpenMP loops and
7149/// extracting iteration space of each loop in the loop nest, that will be used
7150/// for IR generation.
7151class OpenMPIterationSpaceChecker {
7152 /// Reference to Sema.
7153 Sema &SemaRef;
7154 /// Does the loop associated directive support non-rectangular loops?
7155 bool SupportsNonRectangular;
7156 /// Data-sharing stack.
7157 DSAStackTy &Stack;
7158 /// A location for diagnostics (when there is no some better location).
7159 SourceLocation DefaultLoc;
7160 /// A location for diagnostics (when increment is not compatible).
7161 SourceLocation ConditionLoc;
7162 /// A source location for referring to loop init later.
7163 SourceRange InitSrcRange;
7164 /// A source location for referring to condition later.
7165 SourceRange ConditionSrcRange;
7166 /// A source location for referring to increment later.
7167 SourceRange IncrementSrcRange;
7168 /// Loop variable.
7169 ValueDecl *LCDecl = nullptr;
7170 /// Reference to loop variable.
7171 Expr *LCRef = nullptr;
7172 /// Lower bound (initializer for the var).
7173 Expr *LB = nullptr;
7174 /// Upper bound.
7175 Expr *UB = nullptr;
7176 /// Loop step (increment).
7177 Expr *Step = nullptr;
7178 /// This flag is true when condition is one of:
7179 /// Var < UB
7180 /// Var <= UB
7181 /// UB > Var
7182 /// UB >= Var
7183 /// This will have no value when the condition is !=
7184 llvm::Optional<bool> TestIsLessOp;
7185 /// This flag is true when condition is strict ( < or > ).
7186 bool TestIsStrictOp = false;
7187 /// This flag is true when step is subtracted on each iteration.
7188 bool SubtractStep = false;
7189 /// The outer loop counter this loop depends on (if any).
7190 const ValueDecl *DepDecl = nullptr;
7191 /// Contains number of loop (starts from 1) on which loop counter init
7192 /// expression of this loop depends on.
7193 Optional<unsigned> InitDependOnLC;
7194 /// Contains number of loop (starts from 1) on which loop counter condition
7195 /// expression of this loop depends on.
7196 Optional<unsigned> CondDependOnLC;
7197 /// Checks if the provide statement depends on the loop counter.
7198 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7199 /// Original condition required for checking of the exit condition for
7200 /// non-rectangular loop.
7201 Expr *Condition = nullptr;
7202
7203public:
7204 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7205 DSAStackTy &Stack, SourceLocation DefaultLoc)
7206 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7207 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7208 /// Check init-expr for canonical loop form and save loop counter
7209 /// variable - #Var and its initialization value - #LB.
7210 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7211 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7212 /// for less/greater and for strict/non-strict comparison.
7213 bool checkAndSetCond(Expr *S);
7214 /// Check incr-expr for canonical loop form and return true if it
7215 /// does not conform, otherwise save loop step (#Step).
7216 bool checkAndSetInc(Expr *S);
7217 /// Return the loop counter variable.
7218 ValueDecl *getLoopDecl() const { return LCDecl; }
7219 /// Return the reference expression to loop counter variable.
7220 Expr *getLoopDeclRefExpr() const { return LCRef; }
7221 /// Source range of the loop init.
7222 SourceRange getInitSrcRange() const { return InitSrcRange; }
7223 /// Source range of the loop condition.
7224 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7225 /// Source range of the loop increment.
7226 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7227 /// True if the step should be subtracted.
7228 bool shouldSubtractStep() const { return SubtractStep; }
7229 /// True, if the compare operator is strict (<, > or !=).
7230 bool isStrictTestOp() const { return TestIsStrictOp; }
7231 /// Build the expression to calculate the number of iterations.
7232 Expr *buildNumIterations(
7233 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7234 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7235 /// Build the precondition expression for the loops.
7236 Expr *
7237 buildPreCond(Scope *S, Expr *Cond,
7238 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7239 /// Build reference expression to the counter be used for codegen.
7240 DeclRefExpr *
7241 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7242 DSAStackTy &DSA) const;
7243 /// Build reference expression to the private counter be used for
7244 /// codegen.
7245 Expr *buildPrivateCounterVar() const;
7246 /// Build initialization of the counter be used for codegen.
7247 Expr *buildCounterInit() const;
7248 /// Build step of the counter be used for codegen.
7249 Expr *buildCounterStep() const;
7250 /// Build loop data with counter value for depend clauses in ordered
7251 /// directives.
7252 Expr *
7253 buildOrderedLoopData(Scope *S, Expr *Counter,
7254 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7255 SourceLocation Loc, Expr *Inc = nullptr,
7256 OverloadedOperatorKind OOK = OO_Amp);
7257 /// Builds the minimum value for the loop counter.
7258 std::pair<Expr *, Expr *> buildMinMaxValues(
7259 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7260 /// Builds final condition for the non-rectangular loops.
7261 Expr *buildFinalCondition(Scope *S) const;
7262 /// Return true if any expression is dependent.
7263 bool dependent() const;
7264 /// Returns true if the initializer forms non-rectangular loop.
7265 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7266 /// Returns true if the condition forms non-rectangular loop.
7267 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7268 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7269 unsigned getLoopDependentIdx() const {
7270 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7271 }
7272
7273private:
7274 /// Check the right-hand side of an assignment in the increment
7275 /// expression.
7276 bool checkAndSetIncRHS(Expr *RHS);
7277 /// Helper to set loop counter variable and its initializer.
7278 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7279 bool EmitDiags);
7280 /// Helper to set upper bound.
7281 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7282 SourceRange SR, SourceLocation SL);
7283 /// Helper to set loop increment.
7284 bool setStep(Expr *NewStep, bool Subtract);
7285};
7286
7287bool OpenMPIterationSpaceChecker::dependent() const {
7288 if (!LCDecl) {
7289 assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void>
(0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7289, __PRETTY_FUNCTION__))
;
7290 return false;
7291 }
7292 return LCDecl->getType()->isDependentType() ||
7293 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7294 (Step && Step->isValueDependent());
7295}
7296
7297bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7298 Expr *NewLCRefExpr,
7299 Expr *NewLB, bool EmitDiags) {
7300 // State consistency checking to ensure correct usage.
7301 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7302, __PRETTY_FUNCTION__))
7302 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7302, __PRETTY_FUNCTION__))
;
7303 if (!NewLCDecl || !NewLB)
7304 return true;
7305 LCDecl = getCanonicalDecl(NewLCDecl);
7306 LCRef = NewLCRefExpr;
7307 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7308 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7309 if ((Ctor->isCopyOrMoveConstructor() ||
7310 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7311 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7312 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7313 LB = NewLB;
7314 if (EmitDiags)
7315 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7316 return false;
7317}
7318
7319bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7320 llvm::Optional<bool> LessOp,
7321 bool StrictOp, SourceRange SR,
7322 SourceLocation SL) {
7323 // State consistency checking to ensure correct usage.
7324 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7325, __PRETTY_FUNCTION__))
7325 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7325, __PRETTY_FUNCTION__))
;
7326 if (!NewUB)
7327 return true;
7328 UB = NewUB;
7329 if (LessOp)
7330 TestIsLessOp = LessOp;
7331 TestIsStrictOp = StrictOp;
7332 ConditionSrcRange = SR;
7333 ConditionLoc = SL;
7334 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7335 return false;
7336}
7337
7338bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7339 // State consistency checking to ensure correct usage.
7340 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7340, __PRETTY_FUNCTION__))
;
7341 if (!NewStep)
7342 return true;
7343 if (!NewStep->isValueDependent()) {
7344 // Check that the step is integer expression.
7345 SourceLocation StepLoc = NewStep->getBeginLoc();
7346 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7347 StepLoc, getExprAsWritten(NewStep));
7348 if (Val.isInvalid())
7349 return true;
7350 NewStep = Val.get();
7351
7352 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7353 // If test-expr is of form var relational-op b and relational-op is < or
7354 // <= then incr-expr must cause var to increase on each iteration of the
7355 // loop. If test-expr is of form var relational-op b and relational-op is
7356 // > or >= then incr-expr must cause var to decrease on each iteration of
7357 // the loop.
7358 // If test-expr is of form b relational-op var and relational-op is < or
7359 // <= then incr-expr must cause var to decrease on each iteration of the
7360 // loop. If test-expr is of form b relational-op var and relational-op is
7361 // > or >= then incr-expr must cause var to increase on each iteration of
7362 // the loop.
7363 Optional<llvm::APSInt> Result =
7364 NewStep->getIntegerConstantExpr(SemaRef.Context);
7365 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7366 bool IsConstNeg =
7367 Result && Result->isSigned() && (Subtract != Result->isNegative());
7368 bool IsConstPos =
7369 Result && Result->isSigned() && (Subtract == Result->isNegative());
7370 bool IsConstZero = Result && !Result->getBoolValue();
7371
7372 // != with increment is treated as <; != with decrement is treated as >
7373 if (!TestIsLessOp.hasValue())
7374 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7375 if (UB && (IsConstZero ||
7376 (TestIsLessOp.getValue() ?
7377 (IsConstNeg || (IsUnsigned && Subtract)) :
7378 (IsConstPos || (IsUnsigned && !Subtract))))) {
7379 SemaRef.Diag(NewStep->getExprLoc(),
7380 diag::err_omp_loop_incr_not_compatible)
7381 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7382 SemaRef.Diag(ConditionLoc,
7383 diag::note_omp_loop_cond_requres_compatible_incr)
7384 << TestIsLessOp.getValue() << ConditionSrcRange;
7385 return true;
7386 }
7387 if (TestIsLessOp.getValue() == Subtract) {
7388 NewStep =
7389 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7390 .get();
7391 Subtract = !Subtract;
7392 }
7393 }
7394
7395 Step = NewStep;
7396 SubtractStep = Subtract;
7397 return false;
7398}
7399
7400namespace {
7401/// Checker for the non-rectangular loops. Checks if the initializer or
7402/// condition expression references loop counter variable.
7403class LoopCounterRefChecker final
7404 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7405 Sema &SemaRef;
7406 DSAStackTy &Stack;
7407 const ValueDecl *CurLCDecl = nullptr;
7408 const ValueDecl *DepDecl = nullptr;
7409 const ValueDecl *PrevDepDecl = nullptr;
7410 bool IsInitializer = true;
7411 bool SupportsNonRectangular;
7412 unsigned BaseLoopId = 0;
7413 bool checkDecl(const Expr *E, const ValueDecl *VD) {
7414 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7415 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7416 << (IsInitializer ? 0 : 1);
7417 return false;
7418 }
7419 const auto &&Data = Stack.isLoopControlVariable(VD);
7420 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7421 // The type of the loop iterator on which we depend may not have a random
7422 // access iterator type.
7423 if (Data.first && VD->getType()->isRecordType()) {
7424 SmallString<128> Name;
7425 llvm::raw_svector_ostream OS(Name);
7426 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7427 /*Qualified=*/true);
7428 SemaRef.Diag(E->getExprLoc(),
7429 diag::err_omp_wrong_dependency_iterator_type)
7430 << OS.str();
7431 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7432 return false;
7433 }
7434 if (Data.first && !SupportsNonRectangular) {
7435 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7436 return false;
7437 }
7438 if (Data.first &&
7439 (DepDecl || (PrevDepDecl &&
7440 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7441 if (!DepDecl && PrevDepDecl)
7442 DepDecl = PrevDepDecl;
7443 SmallString<128> Name;
7444 llvm::raw_svector_ostream OS(Name);
7445 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7446 /*Qualified=*/true);
7447 SemaRef.Diag(E->getExprLoc(),
7448 diag::err_omp_invariant_or_linear_dependency)
7449 << OS.str();
7450 return false;
7451 }
7452 if (Data.first) {
7453 DepDecl = VD;
7454 BaseLoopId = Data.first;
7455 }
7456 return Data.first;
7457 }
7458
7459public:
7460 bool VisitDeclRefExpr(const DeclRefExpr *E) {
7461 const ValueDecl *VD = E->getDecl();
7462 if (isa<VarDecl>(VD))
7463 return checkDecl(E, VD);
7464 return false;
7465 }
7466 bool VisitMemberExpr(const MemberExpr *E) {
7467 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7468 const ValueDecl *VD = E->getMemberDecl();
7469 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7470 return checkDecl(E, VD);
7471 }
7472 return false;
7473 }
7474 bool VisitStmt(const Stmt *S) {
7475 bool Res = false;
7476 for (const Stmt *Child : S->children())
7477 Res = (Child && Visit(Child)) || Res;
7478 return Res;
7479 }
7480 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7481 const ValueDecl *CurLCDecl, bool IsInitializer,
7482 const ValueDecl *PrevDepDecl = nullptr,
7483 bool SupportsNonRectangular = true)
7484 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7485 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7486 SupportsNonRectangular(SupportsNonRectangular) {}
7487 unsigned getBaseLoopId() const {
7488 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7488, __PRETTY_FUNCTION__))
;
7489 return BaseLoopId;
7490 }
7491 const ValueDecl *getDepDecl() const {
7492 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 7492, __PRETTY_FUNCTION__))
;
7493 return DepDecl;
7494 }
7495};
7496} // namespace
7497
7498Optional<unsigned>
7499OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7500 bool IsInitializer) {
7501 // Check for the non-rectangular loops.
7502 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7503 DepDecl, SupportsNonRectangular);
7504 if (LoopStmtChecker.Visit(S)) {
7505 DepDecl = LoopStmtChecker.getDepDecl();
7506 return LoopStmtChecker.getBaseLoopId();
7507 }
7508 return llvm::None;
7509}
7510
7511bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7512 // Check init-expr for canonical loop form and save loop counter
7513 // variable - #Var and its initialization value - #LB.
7514 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7515 // var = lb
7516 // integer-type var = lb
7517 // random-access-iterator-type var = lb
7518 // pointer-type var = lb
7519 //
7520 if (!S) {
7521 if (EmitDiags) {
7522 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7523 }
7524 return true;
7525 }
7526 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7527 if (!ExprTemp->cleanupsHaveSideEffects())
7528 S = ExprTemp->getSubExpr();
7529
7530 InitSrcRange = S->getSourceRange();
7531 if (Expr *E = dyn_cast<Expr>(S))
7532 S = E->IgnoreParens();
7533 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7534 if (BO->getOpcode() == BO_Assign) {
7535 Expr *LHS = BO->getLHS()->IgnoreParens();
7536 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7537 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7538 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7539 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7540 EmitDiags);
7541 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7542 }
7543 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7544 if (ME->isArrow() &&
7545 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7546 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7547 EmitDiags);
7548 }
7549 }
7550 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7551 if (DS->isSingleDecl()) {
7552 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7553 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7554 // Accept non-canonical init form here but emit ext. warning.
7555 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7556 SemaRef.Diag(S->getBeginLoc(),
7557 diag::ext_omp_loop_not_canonical_init)
7558 << S->getSourceRange();
7559 return setLCDeclAndLB(
7560 Var,
7561 buildDeclRefExpr(SemaRef, Var,
7562 Var->getType().getNonReferenceType(),
7563 DS->getBeginLoc()),
7564 Var->getInit(), EmitDiags);
7565 }
7566 }
7567 }
7568 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7569 if (CE->getOperator() == OO_Equal) {
7570 Expr *LHS = CE->getArg(0);
7571 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7572 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7573 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7574 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7575 EmitDiags);
7576 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7577 }
7578 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7579 if (ME->isArrow() &&
7580 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7581 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7582 EmitDiags);
7583 }
7584 }
7585 }
7586
7587 if (dependent() || SemaRef.CurContext->isDependentContext())
7588 return false;
7589 if (EmitDiags) {
7590 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7591 << S->getSourceRange();
7592 }
7593 return true;
7594}
7595
7596/// Ignore parenthesizes, implicit casts, copy constructor and return the
7597/// variable (which may be the loop variable) if possible.
7598static const ValueDecl *getInitLCDecl(const Expr *E) {
7599 if (!E)
7600 return nullptr;
7601 E = getExprAsWritten(E);
7602 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7603 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7604 if ((Ctor->isCopyOrMoveConstructor() ||
7605 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7606 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7607 E = CE->getArg(0)->IgnoreParenImpCasts();
7608 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7609 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7610 return getCanonicalDecl(VD);
7611 }
7612 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7613 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7614 return getCanonicalDecl(ME->getMemberDecl());
7615 return nullptr;
7616}
7617
7618bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7619 // Check test-expr for canonical form, save upper-bound UB, flags for
7620 // less/greater and for strict/non-strict comparison.
7621 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7622 // var relational-op b
7623 // b relational-op var
7624 //
7625 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7626 if (!S) {
7627 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7628 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7629 return true;
7630 }
7631 Condition = S;
7632 S = getExprAsWritten(S);
7633 SourceLocation CondLoc = S->getBeginLoc();
7634 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7635 if (BO->isRelationalOp()) {
7636 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7637 return setUB(BO->getRHS(),
7638 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
7639 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7640 BO->getSourceRange(), BO->getOperatorLoc());
7641 if (getInitLCDecl(BO->getRHS()) == LCDecl)
7642 return setUB(BO->getLHS(),
7643 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
7644 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7645 BO->getSourceRange(), BO->getOperatorLoc());
7646 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
7647 return setUB(
7648 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
7649 /*LessOp=*/llvm::None,
7650 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
7651 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7652 if (CE->getNumArgs() == 2) {
7653 auto Op = CE->getOperator();
7654 switch (Op) {
7655 case OO_Greater:
7656 case OO_GreaterEqual:
7657 case OO_Less:
7658 case OO_LessEqual:
7659 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7660 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
7661 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7662 CE->getOperatorLoc());
7663 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
7664 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
7665 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7666 CE->getOperatorLoc());
7667 break;
7668 case OO_ExclaimEqual:
7669 if (IneqCondIsCanonical)
7670 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
7671 : CE->getArg(0),
7672 /*LessOp=*/llvm::None,
7673 /*StrictOp=*/true, CE->getSourceRange(),
7674 CE->getOperatorLoc());
7675 break;
7676 default:
7677 break;
7678 }
7679 }
7680 }
7681 if (dependent() || SemaRef.CurContext->isDependentContext())
7682 return false;
7683 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7684 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7685 return true;
7686}
7687
7688bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7689 // RHS of canonical loop form increment can be:
7690 // var + incr
7691 // incr + var
7692 // var - incr
7693 //
7694 RHS = RHS->IgnoreParenImpCasts();
7695 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7696 if (BO->isAdditiveOp()) {
7697 bool IsAdd = BO->getOpcode() == BO_Add;
7698 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7699 return setStep(BO->getRHS(), !IsAdd);
7700 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7701 return setStep(BO->getLHS(), /*Subtract=*/false);
7702 }
7703 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7704 bool IsAdd = CE->getOperator() == OO_Plus;
7705 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7706 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7707 return setStep(CE->getArg(1), !IsAdd);
7708 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7709 return setStep(CE->getArg(0), /*Subtract=*/false);
7710 }
7711 }
7712 if (dependent() || SemaRef.CurContext->isDependentContext())
7713 return false;
7714 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7715 << RHS->getSourceRange() << LCDecl;
7716 return true;
7717}
7718
7719bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7720 // Check incr-expr for canonical loop form and return true if it
7721 // does not conform.
7722 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7723 // ++var
7724 // var++
7725 // --var
7726 // var--
7727 // var += incr
7728 // var -= incr
7729 // var = var + incr
7730 // var = incr + var
7731 // var = var - incr
7732 //
7733 if (!S) {
7734 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7735 return true;
7736 }
7737 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7738 if (!ExprTemp->cleanupsHaveSideEffects())
7739 S = ExprTemp->getSubExpr();
7740
7741 IncrementSrcRange = S->getSourceRange();
7742 S = S->IgnoreParens();
7743 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7744 if (UO->isIncrementDecrementOp() &&
7745 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7746 return setStep(SemaRef
7747 .ActOnIntegerConstant(UO->getBeginLoc(),
7748 (UO->isDecrementOp() ? -1 : 1))
7749 .get(),
7750 /*Subtract=*/false);
7751 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7752 switch (BO->getOpcode()) {
7753 case BO_AddAssign:
7754 case BO_SubAssign:
7755 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7756 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7757 break;
7758 case BO_Assign:
7759 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7760 return checkAndSetIncRHS(BO->getRHS());
7761 break;
7762 default:
7763 break;
7764 }
7765 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7766 switch (CE->getOperator()) {
7767 case OO_PlusPlus:
7768 case OO_MinusMinus:
7769 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7770 return setStep(SemaRef
7771 .ActOnIntegerConstant(
7772 CE->getBeginLoc(),
7773 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7774 .get(),
7775 /*Subtract=*/false);
7776 break;
7777 case OO_PlusEqual:
7778 case OO_MinusEqual:
7779 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7780 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7781 break;
7782 case OO_Equal:
7783 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7784 return checkAndSetIncRHS(CE->getArg(1));
7785 break;
7786 default:
7787 break;
7788 }
7789 }
7790 if (dependent() || SemaRef.CurContext->isDependentContext())
7791 return false;
7792 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7793 << S->getSourceRange() << LCDecl;
7794 return true;
7795}
7796
7797static ExprResult
7798tryBuildCapture(Sema &SemaRef, Expr *Capture,
7799 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7800 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7801 return Capture;
7802 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7803 return SemaRef.PerformImplicitConversion(
7804 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7805 /*AllowExplicit=*/true);
7806 auto I = Captures.find(Capture);
7807 if (I != Captures.end())
7808 return buildCapture(SemaRef, Capture, I->second);
7809 DeclRefExpr *Ref = nullptr;
7810 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7811 Captures[Capture] = Ref;
7812 return Res;
7813}
7814
7815/// Calculate number of iterations, transforming to unsigned, if number of
7816/// iterations may be larger than the original type.
7817static Expr *
7818calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7819 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7820 bool TestIsStrictOp, bool RoundToStep,
7821 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7822 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7823 if (!NewStep.isUsable())
7824 return nullptr;
7825 llvm::APSInt LRes, SRes;
7826 bool IsLowerConst = false, IsStepConst = false;
7827 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7828 LRes = *Res;
7829 IsLowerConst = true;
7830 }
7831 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7832 SRes = *Res;
7833 IsStepConst = true;
7834 }
7835 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7836 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7837 (TestIsStrictOp && LRes.isStrictlyPositive()));
7838 bool NeedToReorganize = false;
7839 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7840 if (!NoNeedToConvert && IsLowerConst &&
7841 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7842 NoNeedToConvert = true;
7843 if (RoundToStep) {
7844 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7845 ? LRes.getBitWidth()
7846 : SRes.getBitWidth();
7847 LRes = LRes.extend(BW + 1);
7848 LRes.setIsSigned(true);
7849 SRes = SRes.extend(BW + 1);
7850 SRes.setIsSigned(true);
7851 LRes -= SRes;
7852 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7853 LRes = LRes.trunc(BW);
7854 }
7855 if (TestIsStrictOp) {
7856 unsigned BW = LRes.getBitWidth();
7857 LRes = LRes.extend(BW + 1);
7858 LRes.setIsSigned(true);
7859 ++LRes;
7860 NoNeedToConvert =
7861 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7862 // truncate to the original bitwidth.
7863 LRes = LRes.trunc(BW);
7864 }
7865 NeedToReorganize = NoNeedToConvert;
7866 }
7867 llvm::APSInt URes;
7868 bool IsUpperConst = false;
7869 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7870 URes = *Res;
7871 IsUpperConst = true;
7872 }
7873 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7874 (!RoundToStep || IsStepConst)) {
7875 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7876 : URes.getBitWidth();
7877 LRes = LRes.extend(BW + 1);
7878 LRes.setIsSigned(true);
7879 URes = URes.extend(BW + 1);
7880 URes.setIsSigned(true);
7881 URes -= LRes;
7882 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7883 NeedToReorganize = NoNeedToConvert;
7884 }
7885 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7886 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7887 // unsigned.
7888 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7889 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7890 QualType LowerTy = Lower->getType();
7891 QualType UpperTy = Upper->getType();
7892 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7893 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7894 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7895 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7896 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7897 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7898 Upper =
7899 SemaRef
7900 .PerformImplicitConversion(
7901 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7902 CastType, Sema::AA_Converting)
7903 .get();
7904 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7905 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7906 }
7907 }
7908 if (!Lower || !Upper || NewStep.isInvalid())
7909 return nullptr;
7910
7911 ExprResult Diff;
7912 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7913 // 1]).
7914 if (NeedToReorganize) {
7915 Diff = Lower;
7916
7917 if (RoundToStep) {
7918 // Lower - Step
7919 Diff =
7920 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7921 if (!Diff.isUsable())
7922 return nullptr;
7923 }
7924
7925 // Lower - Step [+ 1]
7926 if (TestIsStrictOp)
7927 Diff = SemaRef.BuildBinOp(
7928 S, DefaultLoc, BO_Add, Diff.get(),
7929 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7930 if (!Diff.isUsable())
7931 return nullptr;
7932
7933 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7934 if (!Diff.isUsable())
7935 return nullptr;
7936
7937 // Upper - (Lower - Step [+ 1]).
7938 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7939 if (!Diff.isUsable())
7940 return nullptr;
7941 } else {
7942 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7943
7944 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7945 // BuildBinOp already emitted error, this one is to point user to upper
7946 // and lower bound, and to tell what is passed to 'operator-'.
7947 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7948 << Upper->getSourceRange() << Lower->getSourceRange();
7949 return nullptr;
7950 }
7951
7952 if (!Diff.isUsable())
7953 return nullptr;
7954
7955 // Upper - Lower [- 1]
7956 if (TestIsStrictOp)
7957 Diff = SemaRef.BuildBinOp(
7958 S, DefaultLoc, BO_Sub, Diff.get(),
7959 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7960 if (!Diff.isUsable())
7961 return nullptr;
7962
7963 if (RoundToStep) {
7964 // Upper - Lower [- 1] + Step
7965 Diff =
7966 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7967 if (!Diff.isUsable())
7968 return nullptr;
7969 }
7970 }
7971
7972 // Parentheses (for dumping/debugging purposes only).
7973 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7974 if (!Diff.isUsable())
7975 return nullptr;
7976
7977 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7978 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7979 if (!Diff.isUsable())
7980 return nullptr;
7981
7982 return Diff.get();
7983}
7984
7985/// Build the expression to calculate the number of iterations.
7986Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7987 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7988 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7989 QualType VarType = LCDecl->getType().getNonReferenceType();
7990 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7991 !SemaRef.getLangOpts().CPlusPlus)
7992 return nullptr;
7993 Expr *LBVal = LB;
7994 Expr *UBVal = UB;
7995 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7996 // max(LB(MinVal), LB(MaxVal))
7997 if (InitDependOnLC) {
7998 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
7999 if (!IS.MinValue || !IS.MaxValue)
8000 return nullptr;
8001 // OuterVar = Min
8002 ExprResult MinValue =
8003 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8004 if (!MinValue.isUsable())
8005 return nullptr;
8006
8007 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8008 IS.CounterVar, MinValue.get());
8009 if (!LBMinVal.isUsable())
8010 return nullptr;
8011 // OuterVar = Min, LBVal
8012 LBMinVal =
8013 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8014 if (!LBMinVal.isUsable())
8015 return nullptr;
8016 // (OuterVar = Min, LBVal)
8017 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8018 if (!LBMinVal.isUsable())
8019 return nullptr;
8020
8021 // OuterVar = Max
8022 ExprResult MaxValue =
8023 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8024 if (!MaxValue.isUsable())
8025 return nullptr;
8026
8027 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8028 IS.CounterVar, MaxValue.get());
8029 if (!LBMaxVal.isUsable())
8030 return nullptr;
8031 // OuterVar = Max, LBVal
8032 LBMaxVal =
8033 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8034 if (!LBMaxVal.isUsable())
8035 return nullptr;
8036 // (OuterVar = Max, LBVal)
8037 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8038 if (!LBMaxVal.isUsable())
8039 return nullptr;
8040
8041 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8042 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8043 if (!LBMin || !LBMax)
8044 return nullptr;
8045 // LB(MinVal) < LB(MaxVal)
8046 ExprResult MinLessMaxRes =
8047 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8048 if (!MinLessMaxRes.isUsable())
8049 return nullptr;
8050 Expr *MinLessMax =
8051 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8052 if (!MinLessMax)
8053 return nullptr;
8054 if (TestIsLessOp.getValue()) {
8055 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8056 // LB(MaxVal))
8057 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8058 MinLessMax, LBMin, LBMax);
8059 if (!MinLB.isUsable())
8060 return nullptr;
8061 LBVal = MinLB.get();
8062 } else {
8063 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8064 // LB(MaxVal))
8065 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8066 MinLessMax, LBMax, LBMin);
8067 if (!MaxLB.isUsable())
8068 return nullptr;
8069 LBVal = MaxLB.get();
8070 }
8071 }
8072 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8073 // min(UB(MinVal), UB(MaxVal))
8074 if (CondDependOnLC) {
8075 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8076 if (!IS.MinValue || !IS.MaxValue)
8077 return nullptr;
8078 // OuterVar = Min
8079 ExprResult MinValue =
8080 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8081 if (!MinValue.isUsable())
8082 return nullptr;
8083
8084 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8085 IS.CounterVar, MinValue.get());
8086 if (!UBMinVal.isUsable())
8087 return nullptr;
8088 // OuterVar = Min, UBVal
8089 UBMinVal =
8090 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8091 if (!UBMinVal.isUsable())
8092 return nullptr;
8093 // (OuterVar = Min, UBVal)
8094 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8095 if (!UBMinVal.isUsable())
8096 return nullptr;
8097
8098 // OuterVar = Max
8099 ExprResult MaxValue =
8100 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8101 if (!MaxValue.isUsable())
8102 return nullptr;
8103
8104 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8105 IS.CounterVar, MaxValue.get());
8106 if (!UBMaxVal.isUsable())
8107 return nullptr;
8108 // OuterVar = Max, UBVal
8109 UBMaxVal =
8110 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8111 if (!UBMaxVal.isUsable())
8112 return nullptr;
8113 // (OuterVar = Max, UBVal)
8114 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8115 if (!UBMaxVal.isUsable())
8116 return nullptr;
8117
8118 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8119 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8120 if (!UBMin || !UBMax)
8121 return nullptr;
8122 // UB(MinVal) > UB(MaxVal)
8123 ExprResult MinGreaterMaxRes =
8124 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8125 if (!MinGreaterMaxRes.isUsable())
8126 return nullptr;
8127 Expr *MinGreaterMax =
8128 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8129 if (!MinGreaterMax)
8130 return nullptr;
8131 if (TestIsLessOp.getValue()) {
8132 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8133 // UB(MaxVal))
8134 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8135 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8136 if (!MaxUB.isUsable())
8137 return nullptr;
8138 UBVal = MaxUB.get();
8139 } else {
8140 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8141 // UB(MaxVal))
8142 ExprResult MinUB = SemaRef.ActOnConditionalOp(
8143 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8144 if (!MinUB.isUsable())
8145 return nullptr;
8146 UBVal = MinUB.get();
8147 }
8148 }
8149 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8150 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8151 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8152 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8153 if (!Upper || !Lower)
8154 return nullptr;
8155
8156 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8157 Step, VarType, TestIsStrictOp,
8158 /*RoundToStep=*/true, Captures);
8159 if (!Diff.isUsable())
8160 return nullptr;
8161
8162 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8163 QualType Type = Diff.get()->getType();
8164 ASTContext &C = SemaRef.Context;
8165 bool UseVarType = VarType->hasIntegerRepresentation() &&
8166 C.getTypeSize(Type) > C.getTypeSize(VarType);
8167 if (!Type->isIntegerType() || UseVarType) {
8168 unsigned NewSize =
8169 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8170 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8171 : Type->hasSignedIntegerRepresentation();
8172 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8173 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8174 Diff = SemaRef.PerformImplicitConversion(
8175 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8176 if (!Diff.isUsable())
8177 return nullptr;
8178 }
8179 }
8180 if (LimitedType) {
8181 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8182 if (NewSize != C.getTypeSize(Type)) {
8183 if (NewSize < C.getTypeSize(Type)) {
8184 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8184, __PRETTY_FUNCTION__))
;
8185 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8186 << InitSrcRange << ConditionSrcRange;
8187 }
8188 QualType NewType = C.getIntTypeForBitwidth(
8189 NewSize, Type->hasSignedIntegerRepresentation() ||
8190 C.getTypeSize(Type) < NewSize);
8191 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8192 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8193 Sema::AA_Converting, true);
8194 if (!Diff.isUsable())
8195 return nullptr;
8196 }
8197 }
8198 }
8199
8200 return Diff.get();
8201}
8202
8203std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8204 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8205 // Do not build for iterators, they cannot be used in non-rectangular loop
8206 // nests.
8207 if (LCDecl->getType()->isRecordType())
8208 return std::make_pair(nullptr, nullptr);
8209 // If we subtract, the min is in the condition, otherwise the min is in the
8210 // init value.
8211 Expr *MinExpr = nullptr;
8212 Expr *MaxExpr = nullptr;
8213 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8214 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8215 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8216 : CondDependOnLC.hasValue();
8217 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8218 : InitDependOnLC.hasValue();
8219 Expr *Lower =
8220 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8221 Expr *Upper =
8222 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8223 if (!Upper || !Lower)
8224 return std::make_pair(nullptr, nullptr);
8225
8226 if (TestIsLessOp.getValue())
8227 MinExpr = Lower;
8228 else
8229 MaxExpr = Upper;
8230
8231 // Build minimum/maximum value based on number of iterations.
8232 QualType VarType = LCDecl->getType().getNonReferenceType();
8233
8234 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8235 Step, VarType, TestIsStrictOp,
8236 /*RoundToStep=*/false, Captures);
8237 if (!Diff.isUsable())
8238 return std::make_pair(nullptr, nullptr);
8239
8240 // ((Upper - Lower [- 1]) / Step) * Step
8241 // Parentheses (for dumping/debugging purposes only).
8242 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8243 if (!Diff.isUsable())
8244 return std::make_pair(nullptr, nullptr);
8245
8246 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8247 if (!NewStep.isUsable())
8248 return std::make_pair(nullptr, nullptr);
8249 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8250 if (!Diff.isUsable())
8251 return std::make_pair(nullptr, nullptr);
8252
8253 // Parentheses (for dumping/debugging purposes only).
8254 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8255 if (!Diff.isUsable())
8256 return std::make_pair(nullptr, nullptr);
8257
8258 // Convert to the ptrdiff_t, if original type is pointer.
8259 if (VarType->isAnyPointerType() &&
8260 !SemaRef.Context.hasSameType(
8261 Diff.get()->getType(),
8262 SemaRef.Context.getUnsignedPointerDiffType())) {
8263 Diff = SemaRef.PerformImplicitConversion(
8264 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8265 Sema::AA_Converting, /*AllowExplicit=*/true);
8266 }
8267 if (!Diff.isUsable())
8268 return std::make_pair(nullptr, nullptr);
8269
8270 if (TestIsLessOp.getValue()) {
8271 // MinExpr = Lower;
8272 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8273 Diff = SemaRef.BuildBinOp(
8274 S, DefaultLoc, BO_Add,
8275 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8276 Diff.get());
8277 if (!Diff.isUsable())
8278 return std::make_pair(nullptr, nullptr);
8279 } else {
8280 // MaxExpr = Upper;
8281 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8282 Diff = SemaRef.BuildBinOp(
8283 S, DefaultLoc, BO_Sub,
8284 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8285 Diff.get());
8286 if (!Diff.isUsable())
8287 return std::make_pair(nullptr, nullptr);
8288 }
8289
8290 // Convert to the original type.
8291 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8292 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8293 Sema::AA_Converting,
8294 /*AllowExplicit=*/true);
8295 if (!Diff.isUsable())
8296 return std::make_pair(nullptr, nullptr);
8297
8298 Sema::TentativeAnalysisScope Trap(SemaRef);
8299 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8300 if (!Diff.isUsable())
8301 return std::make_pair(nullptr, nullptr);
8302
8303 if (TestIsLessOp.getValue())
8304 MaxExpr = Diff.get();
8305 else
8306 MinExpr = Diff.get();
8307
8308 return std::make_pair(MinExpr, MaxExpr);
8309}
8310
8311Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8312 if (InitDependOnLC || CondDependOnLC)
8313 return Condition;
8314 return nullptr;
8315}
8316
8317Expr *OpenMPIterationSpaceChecker::buildPreCond(
8318 Scope *S, Expr *Cond,
8319 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8320 // Do not build a precondition when the condition/initialization is dependent
8321 // to prevent pessimistic early loop exit.
8322 // TODO: this can be improved by calculating min/max values but not sure that
8323 // it will be very effective.
8324 if (CondDependOnLC || InitDependOnLC)
8325 return SemaRef.PerformImplicitConversion(
8326 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8327 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8328 /*AllowExplicit=*/true).get();
8329
8330 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8331 Sema::TentativeAnalysisScope Trap(SemaRef);
8332
8333 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8334 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8335 if (!NewLB.isUsable() || !NewUB.isUsable())
8336 return nullptr;
8337
8338 ExprResult CondExpr =
8339 SemaRef.BuildBinOp(S, DefaultLoc,
8340 TestIsLessOp.getValue() ?
8341 (TestIsStrictOp ? BO_LT : BO_LE) :
8342 (TestIsStrictOp ? BO_GT : BO_GE),
8343 NewLB.get(), NewUB.get());
8344 if (CondExpr.isUsable()) {
8345 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8346 SemaRef.Context.BoolTy))
8347 CondExpr = SemaRef.PerformImplicitConversion(
8348 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8349 /*AllowExplicit=*/true);
8350 }
8351
8352 // Otherwise use original loop condition and evaluate it in runtime.
8353 return CondExpr.isUsable() ? CondExpr.get() : Cond;
8354}
8355
8356/// Build reference expression to the counter be used for codegen.
8357DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8358 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8359 DSAStackTy &DSA) const {
8360 auto *VD = dyn_cast<VarDecl>(LCDecl);
8361 if (!VD) {
8362 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8363 DeclRefExpr *Ref = buildDeclRefExpr(
8364 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8365 const DSAStackTy::DSAVarData Data =
8366 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8367 // If the loop control decl is explicitly marked as private, do not mark it
8368 // as captured again.
8369 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8370 Captures.insert(std::make_pair(LCRef, Ref));
8371 return Ref;
8372 }
8373 return cast<DeclRefExpr>(LCRef);
8374}
8375
8376Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8377 if (LCDecl && !LCDecl->isInvalidDecl()) {
8378 QualType Type = LCDecl->getType().getNonReferenceType();
8379 VarDecl *PrivateVar = buildVarDecl(
8380 SemaRef, DefaultLoc, Type, LCDecl->getName(),
8381 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8382 isa<VarDecl>(LCDecl)
8383 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8384 : nullptr);
8385 if (PrivateVar->isInvalidDecl())
8386 return nullptr;
8387 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8388 }
8389 return nullptr;
8390}
8391
8392/// Build initialization of the counter to be used for codegen.
8393Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8394
8395/// Build step of the counter be used for codegen.
8396Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8397
8398Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8399 Scope *S, Expr *Counter,
8400 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8401 Expr *Inc, OverloadedOperatorKind OOK) {
8402 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8403 if (!Cnt)
8404 return nullptr;
8405 if (Inc) {
8406 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8407, __PRETTY_FUNCTION__))
8407 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8407, __PRETTY_FUNCTION__))
;
8408 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8409 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8410 if (!Cnt)
8411 return nullptr;
8412 }
8413 QualType VarType = LCDecl->getType().getNonReferenceType();
8414 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8415 !SemaRef.getLangOpts().CPlusPlus)
8416 return nullptr;
8417 // Upper - Lower
8418 Expr *Upper = TestIsLessOp.getValue()
8419 ? Cnt
8420 : tryBuildCapture(SemaRef, LB, Captures).get();
8421 Expr *Lower = TestIsLessOp.getValue()
8422 ? tryBuildCapture(SemaRef, LB, Captures).get()
8423 : Cnt;
8424 if (!Upper || !Lower)
8425 return nullptr;
8426
8427 ExprResult Diff = calculateNumIters(
8428 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8429 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8430 if (!Diff.isUsable())
8431 return nullptr;
8432
8433 return Diff.get();
8434}
8435} // namespace
8436
8437void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8438 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8438, __PRETTY_FUNCTION__))
;
8439 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8439, __PRETTY_FUNCTION__))
;
8440 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
8441 if (AssociatedLoops > 0 &&
8442 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
8443 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
8444 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8445 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
8446 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8447 if (ValueDecl *D = ISC.getLoopDecl()) {
8448 auto *VD = dyn_cast<VarDecl>(D);
8449 DeclRefExpr *PrivateRef = nullptr;
8450 if (!VD) {
8451 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8452 VD = Private;
8453 } else {
8454 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8455 /*WithInit=*/false);
8456 VD = cast<VarDecl>(PrivateRef->getDecl());
8457 }
8458 }
8459 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
8460 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
8461 if (LD != D->getCanonicalDecl()) {
8462 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
8463 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8464 MarkDeclarationsReferencedInExpr(
8465 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8466 Var->getType().getNonLValueExprType(Context),
8467 ForLoc, /*RefersToCapture=*/true));
8468 }
8469 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
8470 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8471 // Referenced in a Construct, C/C++]. The loop iteration variable in the
8472 // associated for-loop of a simd construct with just one associated
8473 // for-loop may be listed in a linear clause with a constant-linear-step
8474 // that is the increment of the associated for-loop. The loop iteration
8475 // variable(s) in the associated for-loop(s) of a for or parallel for
8476 // construct may be listed in a private or lastprivate clause.
8477 DSAStackTy::DSAVarData DVar =
8478 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
8479 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8480 // is declared in the loop and it is predetermined as a private.
8481 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8482 OpenMPClauseKind PredeterminedCKind =
8483 isOpenMPSimdDirective(DKind)
8484 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8485 : OMPC_private;
8486 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8487 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8488 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8489 DVar.CKind != OMPC_private))) ||
8490 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8491 DKind == OMPD_master_taskloop ||
8492 DKind == OMPD_parallel_master_taskloop ||
8493 isOpenMPDistributeDirective(DKind)) &&
8494 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8495 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8496 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8497 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8498 << getOpenMPClauseName(DVar.CKind)
8499 << getOpenMPDirectiveName(DKind)
8500 << getOpenMPClauseName(PredeterminedCKind);
8501 if (DVar.RefExpr == nullptr)
8502 DVar.CKind = PredeterminedCKind;
8503 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
8504 /*IsLoopIterVar=*/true);
8505 } else if (LoopDeclRefExpr) {
8506 // Make the loop iteration variable private (for worksharing
8507 // constructs), linear (for simd directives with the only one
8508 // associated loop) or lastprivate (for simd directives with several
8509 // collapsed or ordered loops).
8510 if (DVar.CKind == OMPC_unknown)
8511 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8512 PrivateRef);
8513 }
8514 }
8515 }
8516 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
8517 }
8518}
8519
8520/// Called on a for stmt to check and extract its iteration space
8521/// for further processing (such as collapsing).
8522static bool checkOpenMPIterationSpace(
8523 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8524 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8525 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8526 Expr *OrderedLoopCountExpr,
8527 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8528 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8529 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8530 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8531 // OpenMP [2.9.1, Canonical Loop Form]
8532 // for (init-expr; test-expr; incr-expr) structured-block
8533 // for (range-decl: range-expr) structured-block
8534 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8535 S = CanonLoop->getLoopStmt();
8536 auto *For = dyn_cast_or_null<ForStmt>(S);
8537 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8538 // Ranged for is supported only in OpenMP 5.0.
8539 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8540 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8541 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8542 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8543 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8544 if (TotalNestedLoopCount > 1) {
8545 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8546 SemaRef.Diag(DSA.getConstructLoc(),
8547 diag::note_omp_collapse_ordered_expr)
8548 << 2 << CollapseLoopCountExpr->getSourceRange()
8549 << OrderedLoopCountExpr->getSourceRange();
8550 else if (CollapseLoopCountExpr)
8551 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8552 diag::note_omp_collapse_ordered_expr)
8553 << 0 << CollapseLoopCountExpr->getSourceRange();
8554 else
8555 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8556 diag::note_omp_collapse_ordered_expr)
8557 << 1 << OrderedLoopCountExpr->getSourceRange();
8558 }
8559 return true;
8560 }
8561 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8562, __PRETTY_FUNCTION__))
8562 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8562, __PRETTY_FUNCTION__))
;
8563
8564 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8565 For ? For->getForLoc() : CXXFor->getForLoc());
8566
8567 // Check init.
8568 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8569 if (ISC.checkAndSetInit(Init))
8570 return true;
8571
8572 bool HasErrors = false;
8573
8574 // Check loop variable's type.
8575 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8576 // OpenMP [2.6, Canonical Loop Form]
8577 // Var is one of the following:
8578 // A variable of signed or unsigned integer type.
8579 // For C++, a variable of a random access iterator type.
8580 // For C, a variable of a pointer type.
8581 QualType VarType = LCDecl->getType().getNonReferenceType();
8582 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8583 !VarType->isPointerType() &&
8584 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8585 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8586 << SemaRef.getLangOpts().CPlusPlus;
8587 HasErrors = true;
8588 }
8589
8590 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8591 // a Construct
8592 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8593 // parallel for construct is (are) private.
8594 // The loop iteration variable in the associated for-loop of a simd
8595 // construct with just one associated for-loop is linear with a
8596 // constant-linear-step that is the increment of the associated for-loop.
8597 // Exclude loop var from the list of variables with implicitly defined data
8598 // sharing attributes.
8599 VarsWithImplicitDSA.erase(LCDecl);
8600
8601 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 8601, __PRETTY_FUNCTION__))
;
8602
8603 // Check test-expr.
8604 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8605
8606 // Check incr-expr.
8607 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8608 }
8609
8610 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8611 return HasErrors;
8612
8613 // Build the loop's iteration space representation.
8614 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8615 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8616 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8617 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8618 (isOpenMPWorksharingDirective(DKind) ||
8619 isOpenMPTaskLoopDirective(DKind) ||
8620 isOpenMPDistributeDirective(DKind) ||
8621 isOpenMPLoopTransformationDirective(DKind)),
8622 Captures);
8623 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8624 ISC.buildCounterVar(Captures, DSA);
8625 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8626 ISC.buildPrivateCounterVar();
8627 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8628 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8629 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8630 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8631 ISC.getConditionSrcRange();
8632 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8633 ISC.getIncrementSrcRange();
8634 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8635 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8636 ISC.isStrictTestOp();
8637 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8638 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8639 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8640 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8641 ISC.buildFinalCondition(DSA.getCurScope());
8642 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8643 ISC.doesInitDependOnLC();
8644 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8645 ISC.doesCondDependOnLC();
8646 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8647 ISC.getLoopDependentIdx();
8648
8649 HasErrors |=
8650 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8651 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8652 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8653 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8654 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8655 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8656 if (!HasErrors && DSA.isOrderedRegion()) {
8657 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8658 if (CurrentNestedLoopCount <
8659 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8660 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8661 CurrentNestedLoopCount,
8662 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8663 DSA.getOrderedRegionParam().second->setLoopCounter(
8664 CurrentNestedLoopCount,
8665 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8666 }
8667 }
8668 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8669 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8670 // Erroneous case - clause has some problems.
8671 continue;
8672 }
8673 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8674 Pair.second.size() <= CurrentNestedLoopCount) {
8675 // Erroneous case - clause has some problems.
8676 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8677 continue;
8678 }
8679 Expr *CntValue;
8680 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8681 CntValue = ISC.buildOrderedLoopData(
8682 DSA.getCurScope(),
8683 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8684 Pair.first->getDependencyLoc());
8685 else
8686 CntValue = ISC.buildOrderedLoopData(
8687 DSA.getCurScope(),
8688 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8689 Pair.first->getDependencyLoc(),
8690 Pair.second[CurrentNestedLoopCount].first,
8691 Pair.second[CurrentNestedLoopCount].second);
8692 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8693 }
8694 }
8695
8696 return HasErrors;
8697}
8698
8699/// Build 'VarRef = Start.
8700static ExprResult
8701buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8702 ExprResult Start, bool IsNonRectangularLB,
8703 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8704 // Build 'VarRef = Start.
8705 ExprResult NewStart = IsNonRectangularLB
8706 ? Start.get()
8707 : tryBuildCapture(SemaRef, Start.get(), Captures);
8708 if (!NewStart.isUsable())
8709 return ExprError();
8710 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8711 VarRef.get()->getType())) {
8712 NewStart = SemaRef.PerformImplicitConversion(
8713 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8714 /*AllowExplicit=*/true);
8715 if (!NewStart.isUsable())
8716 return ExprError();
8717 }
8718
8719 ExprResult Init =
8720 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8721 return Init;
8722}
8723
8724/// Build 'VarRef = Start + Iter * Step'.
8725static ExprResult buildCounterUpdate(
8726 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8727 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8728 bool IsNonRectangularLB,
8729 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8730 // Add parentheses (for debugging purposes only).
8731 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8732 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8733 !Step.isUsable())
8734 return ExprError();
8735
8736 ExprResult NewStep = Step;
8737 if (Captures)
8738 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8739 if (NewStep.isInvalid())
8740 return ExprError();
8741 ExprResult Update =
8742 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8743 if (!Update.isUsable())
8744 return ExprError();
8745
8746 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8747 // 'VarRef = Start (+|-) Iter * Step'.
8748 if (!Start.isUsable())
8749 return ExprError();
8750 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8751 if (!NewStart.isUsable())
8752 return ExprError();
8753 if (Captures && !IsNonRectangularLB)
8754 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8755 if (NewStart.isInvalid())
8756 return ExprError();
8757
8758 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8759 ExprResult SavedUpdate = Update;
8760 ExprResult UpdateVal;
8761 if (VarRef.get()->getType()->isOverloadableType() ||
8762 NewStart.get()->getType()->isOverloadableType() ||
8763 Update.get()->getType()->isOverloadableType()) {
8764 Sema::TentativeAnalysisScope Trap(SemaRef);
8765
8766 Update =
8767 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8768 if (Update.isUsable()) {
8769 UpdateVal =
8770 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8771 VarRef.get(), SavedUpdate.get());
8772 if (UpdateVal.isUsable()) {
8773 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8774 UpdateVal.get());
8775 }
8776 }
8777 }
8778
8779 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8780 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8781 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8782 NewStart.get(), SavedUpdate.get());
8783 if (!Update.isUsable())
8784 return ExprError();
8785
8786 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8787 VarRef.get()->getType())) {
8788 Update = SemaRef.PerformImplicitConversion(
8789 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8790 if (!Update.isUsable())
8791 return ExprError();
8792 }
8793
8794 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8795 }
8796 return Update;
8797}
8798
8799/// Convert integer expression \a E to make it have at least \a Bits
8800/// bits.
8801static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8802 if (E == nullptr)
8803 return ExprError();
8804 ASTContext &C = SemaRef.Context;
8805 QualType OldType = E->getType();
8806 unsigned HasBits = C.getTypeSize(OldType);
8807 if (HasBits >= Bits)
8808 return ExprResult(E);
8809 // OK to convert to signed, because new type has more bits than old.
8810 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8811 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8812 true);
8813}
8814
8815/// Check if the given expression \a E is a constant integer that fits
8816/// into \a Bits bits.
8817static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8818 if (E == nullptr)
8819 return false;
8820 if (Optional<llvm::APSInt> Result =
8821 E->getIntegerConstantExpr(SemaRef.Context))
8822 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8823 return false;
8824}
8825
8826/// Build preinits statement for the given declarations.
8827static Stmt *buildPreInits(ASTContext &Context,
8828 MutableArrayRef<Decl *> PreInits) {
8829 if (!PreInits.empty()) {
8830 return new (Context) DeclStmt(
8831 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8832 SourceLocation(), SourceLocation());
8833 }
8834 return nullptr;
8835}
8836
8837/// Build preinits statement for the given declarations.
8838static Stmt *
8839buildPreInits(ASTContext &Context,
8840 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8841 if (!Captures.empty()) {
8842 SmallVector<Decl *, 16> PreInits;
8843 for (const auto &Pair : Captures)
8844 PreInits.push_back(Pair.second->getDecl());
8845 return buildPreInits(Context, PreInits);
8846 }
8847 return nullptr;
8848}
8849
8850/// Build postupdate expression for the given list of postupdates expressions.
8851static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8852 Expr *PostUpdate = nullptr;
8853 if (!PostUpdates.empty()) {
8854 for (Expr *E : PostUpdates) {
8855 Expr *ConvE = S.BuildCStyleCastExpr(
8856 E->getExprLoc(),
8857 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8858 E->getExprLoc(), E)
8859 .get();
8860 PostUpdate = PostUpdate
8861 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8862 PostUpdate, ConvE)
8863 .get()
8864 : ConvE;
8865 }
8866 }
8867 return PostUpdate;
8868}
8869
8870/// Called on a for stmt to check itself and nested loops (if any).
8871/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8872/// number of collapsed loops otherwise.
8873static unsigned
8874checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8875 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8876 DSAStackTy &DSA,
8877 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8878 OMPLoopBasedDirective::HelperExprs &Built) {
8879 unsigned NestedLoopCount = 1;
8880 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8881 !isOpenMPLoopTransformationDirective(DKind);
8882
8883 if (CollapseLoopCountExpr) {
8884 // Found 'collapse' clause - calculate collapse number.
8885 Expr::EvalResult Result;
8886 if (!CollapseLoopCountExpr->isValueDependent() &&
8887 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8888 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8889 } else {
8890 Built.clear(/*Size=*/1);
8891 return 1;
8892 }
8893 }
8894 unsigned OrderedLoopCount = 1;
8895 if (OrderedLoopCountExpr) {
8896 // Found 'ordered' clause - calculate collapse number.
8897 Expr::EvalResult EVResult;
8898 if (!OrderedLoopCountExpr->isValueDependent() &&
8899 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8900 SemaRef.getASTContext())) {
8901 llvm::APSInt Result = EVResult.Val.getInt();
8902 if (Result.getLimitedValue() < NestedLoopCount) {
8903 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8904 diag::err_omp_wrong_ordered_loop_count)
8905 << OrderedLoopCountExpr->getSourceRange();
8906 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8907 diag::note_collapse_loop_count)
8908 << CollapseLoopCountExpr->getSourceRange();
8909 }
8910 OrderedLoopCount = Result.getLimitedValue();
8911 } else {
8912 Built.clear(/*Size=*/1);
8913 return 1;
8914 }
8915 }
8916 // This is helper routine for loop directives (e.g., 'for', 'simd',
8917 // 'for simd', etc.).
8918 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8919 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
8920 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
8921 if (!OMPLoopBasedDirective::doForAllLoops(
8922 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
8923 SupportsNonPerfectlyNested, NumLoops,
8924 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
8925 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
8926 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
8927 if (checkOpenMPIterationSpace(
8928 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8929 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
8930 VarsWithImplicitDSA, IterSpaces, Captures))
8931 return true;
8932 if (Cnt > 0 && Cnt >= NestedLoopCount &&
8933 IterSpaces[Cnt].CounterVar) {
8934 // Handle initialization of captured loop iterator variables.
8935 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8936 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8937 Captures[DRE] = DRE;
8938 }
8939 }
8940 return false;
8941 }))
8942 return 0;
8943
8944 Built.clear(/* size */ NestedLoopCount);
8945
8946 if (SemaRef.CurContext->isDependentContext())
8947 return NestedLoopCount;
8948
8949 // An example of what is generated for the following code:
8950 //
8951 // #pragma omp simd collapse(2) ordered(2)
8952 // for (i = 0; i < NI; ++i)
8953 // for (k = 0; k < NK; ++k)
8954 // for (j = J0; j < NJ; j+=2) {
8955 // <loop body>
8956 // }
8957 //
8958 // We generate the code below.
8959 // Note: the loop body may be outlined in CodeGen.
8960 // Note: some counters may be C++ classes, operator- is used to find number of
8961 // iterations and operator+= to calculate counter value.
8962 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8963 // or i64 is currently supported).
8964 //
8965 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8966 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8967 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8968 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8969 // // similar updates for vars in clauses (e.g. 'linear')
8970 // <loop body (using local i and j)>
8971 // }
8972 // i = NI; // assign final values of counters
8973 // j = NJ;
8974 //
8975
8976 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8977 // the iteration counts of the collapsed for loops.
8978 // Precondition tests if there is at least one iteration (all conditions are
8979 // true).
8980 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8981 Expr *N0 = IterSpaces[0].NumIterations;
8982 ExprResult LastIteration32 =
8983 widenIterationCount(/*Bits=*/32,
8984 SemaRef
8985 .PerformImplicitConversion(
8986 N0->IgnoreImpCasts(), N0->getType(),
8987 Sema::AA_Converting, /*AllowExplicit=*/true)
8988 .get(),
8989 SemaRef);
8990 ExprResult LastIteration64 = widenIterationCount(
8991 /*Bits=*/64,
8992 SemaRef
8993 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8994 Sema::AA_Converting,
8995 /*AllowExplicit=*/true)
8996 .get(),
8997 SemaRef);
8998
8999 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9000 return NestedLoopCount;
9001
9002 ASTContext &C = SemaRef.Context;
9003 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9004
9005 Scope *CurScope = DSA.getCurScope();
9006 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9007 if (PreCond.isUsable()) {
9008 PreCond =
9009 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9010 PreCond.get(), IterSpaces[Cnt].PreCond);
9011 }
9012 Expr *N = IterSpaces[Cnt].NumIterations;
9013 SourceLocation Loc = N->getExprLoc();
9014 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9015 if (LastIteration32.isUsable())
9016 LastIteration32 = SemaRef.BuildBinOp(
9017 CurScope, Loc, BO_Mul, LastIteration32.get(),
9018 SemaRef
9019 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9020 Sema::AA_Converting,
9021 /*AllowExplicit=*/true)
9022 .get());
9023 if (LastIteration64.isUsable())
9024 LastIteration64 = SemaRef.BuildBinOp(
9025 CurScope, Loc, BO_Mul, LastIteration64.get(),
9026 SemaRef
9027 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9028 Sema::AA_Converting,
9029 /*AllowExplicit=*/true)
9030 .get());
9031 }
9032
9033 // Choose either the 32-bit or 64-bit version.
9034 ExprResult LastIteration = LastIteration64;
9035 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9036 (LastIteration32.isUsable() &&
9037 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9038 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9039 fitsInto(
9040 /*Bits=*/32,
9041 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9042 LastIteration64.get(), SemaRef))))
9043 LastIteration = LastIteration32;
9044 QualType VType = LastIteration.get()->getType();
9045 QualType RealVType = VType;
9046 QualType StrideVType = VType;
9047 if (isOpenMPTaskLoopDirective(DKind)) {
9048 VType =
9049 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9050 StrideVType =
9051 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9052 }
9053
9054 if (!LastIteration.isUsable())
9055 return 0;
9056
9057 // Save the number of iterations.
9058 ExprResult NumIterations = LastIteration;
9059 {
9060 LastIteration = SemaRef.BuildBinOp(
9061 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9062 LastIteration.get(),
9063 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9064 if (!LastIteration.isUsable())
9065 return 0;
9066 }
9067
9068 // Calculate the last iteration number beforehand instead of doing this on
9069 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9070 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9071 ExprResult CalcLastIteration;
9072 if (!IsConstant) {
9073 ExprResult SaveRef =
9074 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9075 LastIteration = SaveRef;
9076
9077 // Prepare SaveRef + 1.
9078 NumIterations = SemaRef.BuildBinOp(
9079 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9080 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9081 if (!NumIterations.isUsable())
9082 return 0;
9083 }
9084
9085 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9086
9087 // Build variables passed into runtime, necessary for worksharing directives.
9088 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9089 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9090 isOpenMPDistributeDirective(DKind) ||
9091 isOpenMPLoopTransformationDirective(DKind)) {
9092 // Lower bound variable, initialized with zero.
9093 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9094 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9095 SemaRef.AddInitializerToDecl(LBDecl,
9096 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9097 /*DirectInit*/ false);
9098
9099 // Upper bound variable, initialized with last iteration number.
9100 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9101 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9102 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9103 /*DirectInit*/ false);
9104
9105 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9106 // This will be used to implement clause 'lastprivate'.
9107 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9108 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9109 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9110 SemaRef.AddInitializerToDecl(ILDecl,
9111 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9112 /*DirectInit*/ false);
9113
9114 // Stride variable returned by runtime (we initialize it to 1 by default).
9115 VarDecl *STDecl =
9116 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9117 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9118 SemaRef.AddInitializerToDecl(STDecl,
9119 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9120 /*DirectInit*/ false);
9121
9122 // Build expression: UB = min(UB, LastIteration)
9123 // It is necessary for CodeGen of directives with static scheduling.
9124 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9125 UB.get(), LastIteration.get());
9126 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9127 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9128 LastIteration.get(), UB.get());
9129 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9130 CondOp.get());
9131 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9132
9133 // If we have a combined directive that combines 'distribute', 'for' or
9134 // 'simd' we need to be able to access the bounds of the schedule of the
9135 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9136 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9137 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9138 // Lower bound variable, initialized with zero.
9139 VarDecl *CombLBDecl =
9140 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9141 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9142 SemaRef.AddInitializerToDecl(
9143 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9144 /*DirectInit*/ false);
9145
9146 // Upper bound variable, initialized with last iteration number.
9147 VarDecl *CombUBDecl =
9148 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9149 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9150 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9151 /*DirectInit*/ false);
9152
9153 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9154 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9155 ExprResult CombCondOp =
9156 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9157 LastIteration.get(), CombUB.get());
9158 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9159 CombCondOp.get());
9160 CombEUB =
9161 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9162
9163 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9164 // We expect to have at least 2 more parameters than the 'parallel'
9165 // directive does - the lower and upper bounds of the previous schedule.
9166 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9167, __PRETTY_FUNCTION__))
9167 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9167, __PRETTY_FUNCTION__))
;
9168
9169 // Set the proper type for the bounds given what we learned from the
9170 // enclosed loops.
9171 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9172 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9173
9174 // Previous lower and upper bounds are obtained from the region
9175 // parameters.
9176 PrevLB =
9177 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9178 PrevUB =
9179 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9180 }
9181 }
9182
9183 // Build the iteration variable and its initialization before loop.
9184 ExprResult IV;
9185 ExprResult Init, CombInit;
9186 {
9187 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9188 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9189 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9190 isOpenMPTaskLoopDirective(DKind) ||
9191 isOpenMPDistributeDirective(DKind) ||
9192 isOpenMPLoopTransformationDirective(DKind))
9193 ? LB.get()
9194 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9195 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9196 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9197
9198 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9199 Expr *CombRHS =
9200 (isOpenMPWorksharingDirective(DKind) ||
9201 isOpenMPTaskLoopDirective(DKind) ||
9202 isOpenMPDistributeDirective(DKind))
9203 ? CombLB.get()
9204 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9205 CombInit =
9206 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9207 CombInit =
9208 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9209 }
9210 }
9211
9212 bool UseStrictCompare =
9213 RealVType->hasUnsignedIntegerRepresentation() &&
9214 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9215 return LIS.IsStrictCompare;
9216 });
9217 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9218 // unsigned IV)) for worksharing loops.
9219 SourceLocation CondLoc = AStmt->getBeginLoc();
9220 Expr *BoundUB = UB.get();
9221 if (UseStrictCompare) {
9222 BoundUB =
9223 SemaRef
9224 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9225 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9226 .get();
9227 BoundUB =
9228 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9229 }
9230 ExprResult Cond =
9231 (isOpenMPWorksharingDirective(DKind) ||
9232 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9233 isOpenMPLoopTransformationDirective(DKind))
9234 ? SemaRef.BuildBinOp(CurScope, CondLoc,
9235 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9236 BoundUB)
9237 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9238 NumIterations.get());
9239 ExprResult CombDistCond;
9240 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9241 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9242 NumIterations.get());
9243 }
9244
9245 ExprResult CombCond;
9246 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9247 Expr *BoundCombUB = CombUB.get();
9248 if (UseStrictCompare) {
9249 BoundCombUB =
9250 SemaRef
9251 .BuildBinOp(
9252 CurScope, CondLoc, BO_Add, BoundCombUB,
9253 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9254 .get();
9255 BoundCombUB =
9256 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9257 .get();
9258 }
9259 CombCond =
9260 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9261 IV.get(), BoundCombUB);
9262 }
9263 // Loop increment (IV = IV + 1)
9264 SourceLocation IncLoc = AStmt->getBeginLoc();
9265 ExprResult Inc =
9266 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9267 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9268 if (!Inc.isUsable())
9269 return 0;
9270 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9271 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9272 if (!Inc.isUsable())
9273 return 0;
9274
9275 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9276 // Used for directives with static scheduling.
9277 // In combined construct, add combined version that use CombLB and CombUB
9278 // base variables for the update
9279 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9280 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9281 isOpenMPDistributeDirective(DKind) ||
9282 isOpenMPLoopTransformationDirective(DKind)) {
9283 // LB + ST
9284 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9285 if (!NextLB.isUsable())
9286 return 0;
9287 // LB = LB + ST
9288 NextLB =
9289 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9290 NextLB =
9291 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9292 if (!NextLB.isUsable())
9293 return 0;
9294 // UB + ST
9295 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9296 if (!NextUB.isUsable())
9297 return 0;
9298 // UB = UB + ST
9299 NextUB =
9300 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9301 NextUB =
9302 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9303 if (!NextUB.isUsable())
9304 return 0;
9305 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9306 CombNextLB =
9307 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9308 if (!NextLB.isUsable())
9309 return 0;
9310 // LB = LB + ST
9311 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9312 CombNextLB.get());
9313 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9314 /*DiscardedValue*/ false);
9315 if (!CombNextLB.isUsable())
9316 return 0;
9317 // UB + ST
9318 CombNextUB =
9319 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9320 if (!CombNextUB.isUsable())
9321 return 0;
9322 // UB = UB + ST
9323 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9324 CombNextUB.get());
9325 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9326 /*DiscardedValue*/ false);
9327 if (!CombNextUB.isUsable())
9328 return 0;
9329 }
9330 }
9331
9332 // Create increment expression for distribute loop when combined in a same
9333 // directive with for as IV = IV + ST; ensure upper bound expression based
9334 // on PrevUB instead of NumIterations - used to implement 'for' when found
9335 // in combination with 'distribute', like in 'distribute parallel for'
9336 SourceLocation DistIncLoc = AStmt->getBeginLoc();
9337 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9338 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9339 DistCond = SemaRef.BuildBinOp(
9340 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9341 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9341, __PRETTY_FUNCTION__))
;
9342
9343 DistInc =
9344 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9345 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9345, __PRETTY_FUNCTION__))
;
9346 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9347 DistInc.get());
9348 DistInc =
9349 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9350 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9350, __PRETTY_FUNCTION__))
;
9351
9352 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9353 // construct
9354 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9355 ExprResult IsUBGreater =
9356 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
9357 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9358 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
9359 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9360 CondOp.get());
9361 PrevEUB =
9362 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9363
9364 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9365 // parallel for is in combination with a distribute directive with
9366 // schedule(static, 1)
9367 Expr *BoundPrevUB = PrevUB.get();
9368 if (UseStrictCompare) {
9369 BoundPrevUB =
9370 SemaRef
9371 .BuildBinOp(
9372 CurScope, CondLoc, BO_Add, BoundPrevUB,
9373 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9374 .get();
9375 BoundPrevUB =
9376 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9377 .get();
9378 }
9379 ParForInDistCond =
9380 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9381 IV.get(), BoundPrevUB);
9382 }
9383
9384 // Build updates and final values of the loop counters.
9385 bool HasErrors = false;
9386 Built.Counters.resize(NestedLoopCount);
9387 Built.Inits.resize(NestedLoopCount);
9388 Built.Updates.resize(NestedLoopCount);
9389 Built.Finals.resize(NestedLoopCount);
9390 Built.DependentCounters.resize(NestedLoopCount);
9391 Built.DependentInits.resize(NestedLoopCount);
9392 Built.FinalsConditions.resize(NestedLoopCount);
9393 {
9394 // We implement the following algorithm for obtaining the
9395 // original loop iteration variable values based on the
9396 // value of the collapsed loop iteration variable IV.
9397 //
9398 // Let n+1 be the number of collapsed loops in the nest.
9399 // Iteration variables (I0, I1, .... In)
9400 // Iteration counts (N0, N1, ... Nn)
9401 //
9402 // Acc = IV;
9403 //
9404 // To compute Ik for loop k, 0 <= k <= n, generate:
9405 // Prod = N(k+1) * N(k+2) * ... * Nn;
9406 // Ik = Acc / Prod;
9407 // Acc -= Ik * Prod;
9408 //
9409 ExprResult Acc = IV;
9410 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9411 LoopIterationSpace &IS = IterSpaces[Cnt];
9412 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9413 ExprResult Iter;
9414
9415 // Compute prod
9416 ExprResult Prod =
9417 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9418 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9419 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9420 IterSpaces[K].NumIterations);
9421
9422 // Iter = Acc / Prod
9423 // If there is at least one more inner loop to avoid
9424 // multiplication by 1.
9425 if (Cnt + 1 < NestedLoopCount)
9426 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9427 Acc.get(), Prod.get());
9428 else
9429 Iter = Acc;
9430 if (!Iter.isUsable()) {
9431 HasErrors = true;
9432 break;
9433 }
9434
9435 // Update Acc:
9436 // Acc -= Iter * Prod
9437 // Check if there is at least one more inner loop to avoid
9438 // multiplication by 1.
9439 if (Cnt + 1 < NestedLoopCount)
9440 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9441 Iter.get(), Prod.get());
9442 else
9443 Prod = Iter;
9444 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9445 Acc.get(), Prod.get());
9446
9447 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9448 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9449 DeclRefExpr *CounterVar = buildDeclRefExpr(
9450 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9451 /*RefersToCapture=*/true);
9452 ExprResult Init =
9453 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9454 IS.CounterInit, IS.IsNonRectangularLB, Captures);
9455 if (!Init.isUsable()) {
9456 HasErrors = true;
9457 break;
9458 }
9459 ExprResult Update = buildCounterUpdate(
9460 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9461 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9462 if (!Update.isUsable()) {
9463 HasErrors = true;
9464 break;
9465 }
9466
9467 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9468 ExprResult Final =
9469 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9470 IS.CounterInit, IS.NumIterations, IS.CounterStep,
9471 IS.Subtract, IS.IsNonRectangularLB, &Captures);
9472 if (!Final.isUsable()) {
9473 HasErrors = true;
9474 break;
9475 }
9476
9477 if (!Update.isUsable() || !Final.isUsable()) {
9478 HasErrors = true;
9479 break;
9480 }
9481 // Save results
9482 Built.Counters[Cnt] = IS.CounterVar;
9483 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9484 Built.Inits[Cnt] = Init.get();
9485 Built.Updates[Cnt] = Update.get();
9486 Built.Finals[Cnt] = Final.get();
9487 Built.DependentCounters[Cnt] = nullptr;
9488 Built.DependentInits[Cnt] = nullptr;
9489 Built.FinalsConditions[Cnt] = nullptr;
9490 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9491 Built.DependentCounters[Cnt] =
9492 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9493 Built.DependentInits[Cnt] =
9494 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9495 Built.FinalsConditions[Cnt] = IS.FinalCondition;
9496 }
9497 }
9498 }
9499
9500 if (HasErrors)
9501 return 0;
9502
9503 // Save results
9504 Built.IterationVarRef = IV.get();
9505 Built.LastIteration = LastIteration.get();
9506 Built.NumIterations = NumIterations.get();
9507 Built.CalcLastIteration = SemaRef
9508 .ActOnFinishFullExpr(CalcLastIteration.get(),
9509 /*DiscardedValue=*/false)
9510 .get();
9511 Built.PreCond = PreCond.get();
9512 Built.PreInits = buildPreInits(C, Captures);
9513 Built.Cond = Cond.get();
9514 Built.Init = Init.get();
9515 Built.Inc = Inc.get();
9516 Built.LB = LB.get();
9517 Built.UB = UB.get();
9518 Built.IL = IL.get();
9519 Built.ST = ST.get();
9520 Built.EUB = EUB.get();
9521 Built.NLB = NextLB.get();
9522 Built.NUB = NextUB.get();
9523 Built.PrevLB = PrevLB.get();
9524 Built.PrevUB = PrevUB.get();
9525 Built.DistInc = DistInc.get();
9526 Built.PrevEUB = PrevEUB.get();
9527 Built.DistCombinedFields.LB = CombLB.get();
9528 Built.DistCombinedFields.UB = CombUB.get();
9529 Built.DistCombinedFields.EUB = CombEUB.get();
9530 Built.DistCombinedFields.Init = CombInit.get();
9531 Built.DistCombinedFields.Cond = CombCond.get();
9532 Built.DistCombinedFields.NLB = CombNextLB.get();
9533 Built.DistCombinedFields.NUB = CombNextUB.get();
9534 Built.DistCombinedFields.DistCond = CombDistCond.get();
9535 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9536
9537 return NestedLoopCount;
9538}
9539
9540static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9541 auto CollapseClauses =
9542 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9543 if (CollapseClauses.begin() != CollapseClauses.end())
9544 return (*CollapseClauses.begin())->getNumForLoops();
9545 return nullptr;
9546}
9547
9548static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9549 auto OrderedClauses =
9550 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9551 if (OrderedClauses.begin() != OrderedClauses.end())
9552 return (*OrderedClauses.begin())->getNumForLoops();
9553 return nullptr;
9554}
9555
9556static bool checkSimdlenSafelenSpecified(Sema &S,
9557 const ArrayRef<OMPClause *> Clauses) {
9558 const OMPSafelenClause *Safelen = nullptr;
9559 const OMPSimdlenClause *Simdlen = nullptr;
9560
9561 for (const OMPClause *Clause : Clauses) {
9562 if (Clause->getClauseKind() == OMPC_safelen)
9563 Safelen = cast<OMPSafelenClause>(Clause);
9564 else if (Clause->getClauseKind() == OMPC_simdlen)
9565 Simdlen = cast<OMPSimdlenClause>(Clause);
9566 if (Safelen && Simdlen)
9567 break;
9568 }
9569
9570 if (Simdlen && Safelen) {
9571 const Expr *SimdlenLength = Simdlen->getSimdlen();
9572 const Expr *SafelenLength = Safelen->getSafelen();
9573 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9574 SimdlenLength->isInstantiationDependent() ||
9575 SimdlenLength->containsUnexpandedParameterPack())
9576 return false;
9577 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9578 SafelenLength->isInstantiationDependent() ||
9579 SafelenLength->containsUnexpandedParameterPack())
9580 return false;
9581 Expr::EvalResult SimdlenResult, SafelenResult;
9582 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9583 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9584 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9585 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9586 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9587 // If both simdlen and safelen clauses are specified, the value of the
9588 // simdlen parameter must be less than or equal to the value of the safelen
9589 // parameter.
9590 if (SimdlenRes > SafelenRes) {
9591 S.Diag(SimdlenLength->getExprLoc(),
9592 diag::err_omp_wrong_simdlen_safelen_values)
9593 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9594 return true;
9595 }
9596 }
9597 return false;
9598}
9599
9600StmtResult
9601Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9602 SourceLocation StartLoc, SourceLocation EndLoc,
9603 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9604 if (!AStmt)
9605 return StmtError();
9606
9607 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9607, __PRETTY_FUNCTION__))
;
9608 OMPLoopBasedDirective::HelperExprs B;
9609 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9610 // define the nested loops number.
9611 unsigned NestedLoopCount = checkOpenMPLoop(
9612 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9613 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9614 if (NestedLoopCount == 0)
9615 return StmtError();
9616
9617 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9618, __PRETTY_FUNCTION__))
9618 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9618, __PRETTY_FUNCTION__))
;
9619
9620 if (!CurContext->isDependentContext()) {
9621 // Finalize the clauses that need pre-built expressions for CodeGen.
9622 for (OMPClause *C : Clauses) {
9623 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9624 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9625 B.NumIterations, *this, CurScope,
9626 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9627 return StmtError();
9628 }
9629 }
9630
9631 if (checkSimdlenSafelenSpecified(*this, Clauses))
9632 return StmtError();
9633
9634 setFunctionHasBranchProtectedScope();
9635 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9636 Clauses, AStmt, B);
9637}
9638
9639StmtResult
9640Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9641 SourceLocation StartLoc, SourceLocation EndLoc,
9642 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9643 if (!AStmt)
9644 return StmtError();
9645
9646 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9646, __PRETTY_FUNCTION__))
;
9647 OMPLoopBasedDirective::HelperExprs B;
9648 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9649 // define the nested loops number.
9650 unsigned NestedLoopCount = checkOpenMPLoop(
9651 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9652 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9653 if (NestedLoopCount == 0)
9654 return StmtError();
9655
9656 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9657, __PRETTY_FUNCTION__))
9657 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9657, __PRETTY_FUNCTION__))
;
9658
9659 if (!CurContext->isDependentContext()) {
9660 // Finalize the clauses that need pre-built expressions for CodeGen.
9661 for (OMPClause *C : Clauses) {
9662 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9663 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9664 B.NumIterations, *this, CurScope,
9665 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9666 return StmtError();
9667 }
9668 }
9669
9670 setFunctionHasBranchProtectedScope();
9671 return OMPForDirective::Create(
9672 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9673 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9674}
9675
9676StmtResult Sema::ActOnOpenMPForSimdDirective(
9677 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9678 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9679 if (!AStmt)
9680 return StmtError();
9681
9682 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9682, __PRETTY_FUNCTION__))
;
9683 OMPLoopBasedDirective::HelperExprs B;
9684 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9685 // define the nested loops number.
9686 unsigned NestedLoopCount =
9687 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9688 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9689 VarsWithImplicitDSA, B);
9690 if (NestedLoopCount == 0)
9691 return StmtError();
9692
9693 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9694, __PRETTY_FUNCTION__))
9694 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9694, __PRETTY_FUNCTION__))
;
9695
9696 if (!CurContext->isDependentContext()) {
9697 // Finalize the clauses that need pre-built expressions for CodeGen.
9698 for (OMPClause *C : Clauses) {
9699 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9700 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9701 B.NumIterations, *this, CurScope,
9702 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9703 return StmtError();
9704 }
9705 }
9706
9707 if (checkSimdlenSafelenSpecified(*this, Clauses))
9708 return StmtError();
9709
9710 setFunctionHasBranchProtectedScope();
9711 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9712 Clauses, AStmt, B);
9713}
9714
9715StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9716 Stmt *AStmt,
9717 SourceLocation StartLoc,
9718 SourceLocation EndLoc) {
9719 if (!AStmt)
9720 return StmtError();
9721
9722 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9722, __PRETTY_FUNCTION__))
;
9723 auto BaseStmt = AStmt;
9724 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9725 BaseStmt = CS->getCapturedStmt();
9726 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9727 auto S = C->children();
9728 if (S.begin() == S.end())
9729 return StmtError();
9730 // All associated statements must be '#pragma omp section' except for
9731 // the first one.
9732 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9733 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9734 if (SectionStmt)
9735 Diag(SectionStmt->getBeginLoc(),
9736 diag::err_omp_sections_substmt_not_section);
9737 return StmtError();
9738 }
9739 cast<OMPSectionDirective>(SectionStmt)
9740 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9741 }
9742 } else {
9743 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9744 return StmtError();
9745 }
9746
9747 setFunctionHasBranchProtectedScope();
9748
9749 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9750 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
9751 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9752}
9753
9754StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9755 SourceLocation StartLoc,
9756 SourceLocation EndLoc) {
9757 if (!AStmt)
9758 return StmtError();
9759
9760 setFunctionHasBranchProtectedScope();
9761 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9762
9763 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9764 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9765}
9766
9767static Expr *getDirectCallExpr(Expr *E) {
9768 E = E->IgnoreParenCasts()->IgnoreImplicit();
9769 if (auto *CE = dyn_cast<CallExpr>(E))
9770 if (CE->getDirectCallee())
9771 return E;
9772 return nullptr;
9773}
9774
9775StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
9776 Stmt *AStmt,
9777 SourceLocation StartLoc,
9778 SourceLocation EndLoc) {
9779 if (!AStmt)
9780 return StmtError();
9781
9782 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
9783
9784 // 5.1 OpenMP
9785 // expression-stmt : an expression statement with one of the following forms:
9786 // expression = target-call ( [expression-list] );
9787 // target-call ( [expression-list] );
9788
9789 SourceLocation TargetCallLoc;
9790
9791 if (!CurContext->isDependentContext()) {
9792 Expr *TargetCall = nullptr;
9793
9794 auto *E = dyn_cast<Expr>(S);
9795 if (!E) {
9796 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9797 return StmtError();
9798 }
9799
9800 E = E->IgnoreParenCasts()->IgnoreImplicit();
9801
9802 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
9803 if (BO->getOpcode() == BO_Assign)
9804 TargetCall = getDirectCallExpr(BO->getRHS());
9805 } else {
9806 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
9807 if (COCE->getOperator() == OO_Equal)
9808 TargetCall = getDirectCallExpr(COCE->getArg(1));
9809 if (!TargetCall)
9810 TargetCall = getDirectCallExpr(E);
9811 }
9812 if (!TargetCall) {
9813 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9814 return StmtError();
9815 }
9816 TargetCallLoc = TargetCall->getExprLoc();
9817 }
9818
9819 setFunctionHasBranchProtectedScope();
9820
9821 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9822 TargetCallLoc);
9823}
9824
9825StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9826 Stmt *AStmt,
9827 SourceLocation StartLoc,
9828 SourceLocation EndLoc) {
9829 if (!AStmt)
9830 return StmtError();
9831
9832 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9832, __PRETTY_FUNCTION__))
;
9833
9834 setFunctionHasBranchProtectedScope();
9835
9836 // OpenMP [2.7.3, single Construct, Restrictions]
9837 // The copyprivate clause must not be used with the nowait clause.
9838 const OMPClause *Nowait = nullptr;
9839 const OMPClause *Copyprivate = nullptr;
9840 for (const OMPClause *Clause : Clauses) {
9841 if (Clause->getClauseKind() == OMPC_nowait)
9842 Nowait = Clause;
9843 else if (Clause->getClauseKind() == OMPC_copyprivate)
9844 Copyprivate = Clause;
9845 if (Copyprivate && Nowait) {
9846 Diag(Copyprivate->getBeginLoc(),
9847 diag::err_omp_single_copyprivate_with_nowait);
9848 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9849 return StmtError();
9850 }
9851 }
9852
9853 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9854}
9855
9856StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9857 SourceLocation StartLoc,
9858 SourceLocation EndLoc) {
9859 if (!AStmt)
9860 return StmtError();
9861
9862 setFunctionHasBranchProtectedScope();
9863
9864 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9865}
9866
9867StmtResult Sema::ActOnOpenMPCriticalDirective(
9868 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9869 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9870 if (!AStmt)
9871 return StmtError();
9872
9873 bool ErrorFound = false;
9874 llvm::APSInt Hint;
9875 SourceLocation HintLoc;
9876 bool DependentHint = false;
9877 for (const OMPClause *C : Clauses) {
9878 if (C->getClauseKind() == OMPC_hint) {
9879 if (!DirName.getName()) {
9880 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9881 ErrorFound = true;
9882 }
9883 Expr *E = cast<OMPHintClause>(C)->getHint();
9884 if (E->isTypeDependent() || E->isValueDependent() ||
9885 E->isInstantiationDependent()) {
9886 DependentHint = true;
9887 } else {
9888 Hint = E->EvaluateKnownConstInt(Context);
9889 HintLoc = C->getBeginLoc();
9890 }
9891 }
9892 }
9893 if (ErrorFound)
9894 return StmtError();
9895 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
9896 if (Pair.first && DirName.getName() && !DependentHint) {
9897 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9898 Diag(StartLoc, diag::err_omp_critical_with_hint);
9899 if (HintLoc.isValid())
9900 Diag(HintLoc, diag::note_omp_critical_hint_here)
9901 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9902 else
9903 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9904 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9905 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9906 << 1
9907 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9908 /*Radix=*/10, /*Signed=*/false);
9909 } else {
9910 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9911 }
9912 }
9913 }
9914
9915 setFunctionHasBranchProtectedScope();
9916
9917 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9918 Clauses, AStmt);
9919 if (!Pair.first && DirName.getName() && !DependentHint)
9920 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
9921 return Dir;
9922}
9923
9924StmtResult Sema::ActOnOpenMPParallelForDirective(
9925 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9926 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9927 if (!AStmt)
9928 return StmtError();
9929
9930 auto *CS = cast<CapturedStmt>(AStmt);
9931 // 1.2.2 OpenMP Language Terminology
9932 // Structured block - An executable statement with a single entry at the
9933 // top and a single exit at the bottom.
9934 // The point of exit cannot be a branch out of the structured block.
9935 // longjmp() and throw() must not violate the entry/exit criteria.
9936 CS->getCapturedDecl()->setNothrow();
9937
9938 OMPLoopBasedDirective::HelperExprs B;
9939 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9940 // define the nested loops number.
9941 unsigned NestedLoopCount =
9942 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9943 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9944 VarsWithImplicitDSA, B);
9945 if (NestedLoopCount == 0)
9946 return StmtError();
9947
9948 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9949, __PRETTY_FUNCTION__))
9949 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 9949, __PRETTY_FUNCTION__))
;
9950
9951 if (!CurContext->isDependentContext()) {
9952 // Finalize the clauses that need pre-built expressions for CodeGen.
9953 for (OMPClause *C : Clauses) {
9954 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9955 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9956 B.NumIterations, *this, CurScope,
9957 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9958 return StmtError();
9959 }
9960 }
9961
9962 setFunctionHasBranchProtectedScope();
9963 return OMPParallelForDirective::Create(
9964 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9965 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9966}
9967
9968StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9969 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9970 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9971 if (!AStmt)
9972 return StmtError();
9973
9974 auto *CS = cast<CapturedStmt>(AStmt);
9975 // 1.2.2 OpenMP Language Terminology
9976 // Structured block - An executable statement with a single entry at the
9977 // top and a single exit at the bottom.
9978 // The point of exit cannot be a branch out of the structured block.
9979 // longjmp() and throw() must not violate the entry/exit criteria.
9980 CS->getCapturedDecl()->setNothrow();
9981
9982 OMPLoopBasedDirective::HelperExprs B;
9983 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9984 // define the nested loops number.
9985 unsigned NestedLoopCount =
9986 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9987 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9988 VarsWithImplicitDSA, B);
9989 if (NestedLoopCount == 0)
9990 return StmtError();
9991
9992 if (!CurContext->isDependentContext()) {
9993 // Finalize the clauses that need pre-built expressions for CodeGen.
9994 for (OMPClause *C : Clauses) {
9995 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9996 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9997 B.NumIterations, *this, CurScope,
9998 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9999 return StmtError();
10000 }
10001 }
10002
10003 if (checkSimdlenSafelenSpecified(*this, Clauses))
10004 return StmtError();
10005
10006 setFunctionHasBranchProtectedScope();
10007 return OMPParallelForSimdDirective::Create(
10008 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10009}
10010
10011StmtResult
10012Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10013 Stmt *AStmt, SourceLocation StartLoc,
10014 SourceLocation EndLoc) {
10015 if (!AStmt)
10016 return StmtError();
10017
10018 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 10018, __PRETTY_FUNCTION__))
;
10019 auto *CS = cast<CapturedStmt>(AStmt);
10020 // 1.2.2 OpenMP Language Terminology
10021 // Structured block - An executable statement with a single entry at the
10022 // top and a single exit at the bottom.
10023 // The point of exit cannot be a branch out of the structured block.
10024 // longjmp() and throw() must not violate the entry/exit criteria.
10025 CS->getCapturedDecl()->setNothrow();
10026
10027 setFunctionHasBranchProtectedScope();
10028
10029 return OMPParallelMasterDirective::Create(
10030 Context, StartLoc, EndLoc, Clauses, AStmt,
10031 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10032}
10033
10034StmtResult
10035Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10036 Stmt *AStmt, SourceLocation StartLoc,
10037 SourceLocation EndLoc) {
10038 if (!AStmt)
10039 return StmtError();
10040
10041 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 10041, __PRETTY_FUNCTION__))
;
10042 auto BaseStmt = AStmt;
10043 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10044 BaseStmt = CS->getCapturedStmt();
10045 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10046 auto S = C->children();
10047 if (S.begin() == S.end())
10048 return StmtError();
10049 // All associated statements must be '#pragma omp section' except for
10050 // the first one.
10051 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
10052 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10053 if (SectionStmt)
10054 Diag(SectionStmt->getBeginLoc(),
10055 diag::err_omp_parallel_sections_substmt_not_section);
10056 return StmtError();
10057 }
10058 cast<OMPSectionDirective>(SectionStmt)
10059 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10060 }
10061 } else {
10062 Diag(AStmt->getBeginLoc(),
10063 diag::err_omp_parallel_sections_not_compound_stmt);
10064 return StmtError();
10065 }
10066
10067 setFunctionHasBranchProtectedScope();
10068
10069 return OMPParallelSectionsDirective::Create(
10070 Context, StartLoc, EndLoc, Clauses, AStmt,
10071 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10072}
10073
10074/// detach and mergeable clauses are mutially exclusive, check for it.
10075static bool checkDetachMergeableClauses(Sema &S,
10076 ArrayRef<OMPClause *> Clauses) {
10077 const OMPClause *PrevClause = nullptr;
10078 bool ErrorFound = false;
10079 for (const OMPClause *C : Clauses) {
10080 if (C->getClauseKind() == OMPC_detach ||
10081 C->getClauseKind() == OMPC_mergeable) {
10082 if (!PrevClause) {
10083 PrevClause = C;
10084 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10085 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10086 << getOpenMPClauseName(C->getClauseKind())
10087 << getOpenMPClauseName(PrevClause->getClauseKind());
10088 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10089 << getOpenMPClauseName(PrevClause->getClauseKind());
10090 ErrorFound = true;
10091 }
10092 }
10093 }
10094 return ErrorFound;
10095}
10096
10097StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10098 Stmt *AStmt, SourceLocation StartLoc,
10099 SourceLocation EndLoc) {
10100 if (!AStmt)
10101 return StmtError();
10102
10103 // OpenMP 5.0, 2.10.1 task Construct
10104 // If a detach clause appears on the directive, then a mergeable clause cannot
10105 // appear on the same directive.
10106 if (checkDetachMergeableClauses(*this, Clauses))
10107 return StmtError();
10108
10109 auto *CS = cast<CapturedStmt>(AStmt);
10110 // 1.2.2 OpenMP Language Terminology
10111 // Structured block - An executable statement with a single entry at the
10112 // top and a single exit at the bottom.
10113 // The point of exit cannot be a branch out of the structured block.
10114 // longjmp() and throw() must not violate the entry/exit criteria.
10115 CS->getCapturedDecl()->setNothrow();
10116
10117 setFunctionHasBranchProtectedScope();
10118
10119 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10120 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10121}
10122
10123StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10124 SourceLocation EndLoc) {
10125 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10126}
10127
10128StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10129 SourceLocation EndLoc) {
10130 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10131}
10132
10133StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
10134 SourceLocation EndLoc) {
10135 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
10136}
10137
10138StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10139 Stmt *AStmt,
10140 SourceLocation StartLoc,
10141 SourceLocation EndLoc) {
10142 if (!AStmt)
10143 return StmtError();
10144
10145 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 10145, __PRETTY_FUNCTION__))
;
10146
10147 setFunctionHasBranchProtectedScope();
10148
10149 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10150 AStmt,
10151 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10152}
10153
10154StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10155 SourceLocation StartLoc,
10156 SourceLocation EndLoc) {
10157 OMPFlushClause *FC = nullptr;
10158 OMPClause *OrderClause = nullptr;
10159 for (OMPClause *C : Clauses) {
10160 if (C->getClauseKind() == OMPC_flush)
10161 FC = cast<OMPFlushClause>(C);
10162 else
10163 OrderClause = C;
10164 }
10165 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10166 SourceLocation MemOrderLoc;
10167 for (const OMPClause *C : Clauses) {
10168 if (C->getClauseKind() == OMPC_acq_rel ||
10169 C->getClauseKind() == OMPC_acquire ||
10170 C->getClauseKind() == OMPC_release) {
10171 if (MemOrderKind != OMPC_unknown) {
10172 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10173 << getOpenMPDirectiveName(OMPD_flush) << 1
10174 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10175 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10176 << getOpenMPClauseName(MemOrderKind);
10177 } else {
10178 MemOrderKind = C->getClauseKind();
10179 MemOrderLoc = C->getBeginLoc();
10180 }
10181 }
10182 }
10183 if (FC && OrderClause) {
10184 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10185 << getOpenMPClauseName(OrderClause->getClauseKind());
10186 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10187 << getOpenMPClauseName(OrderClause->getClauseKind());
10188 return StmtError();
10189 }
10190 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10191}
10192
10193StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10194 SourceLocation StartLoc,
10195 SourceLocation EndLoc) {
10196 if (Clauses.empty()) {
10197 Diag(StartLoc, diag::err_omp_depobj_expected);
10198 return StmtError();
10199 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10200 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10201 return StmtError();
10202 }
10203 // Only depobj expression and another single clause is allowed.
10204 if (Clauses.size() > 2) {
10205 Diag(Clauses[2]->getBeginLoc(),
10206 diag::err_omp_depobj_single_clause_expected);
10207 return StmtError();
10208 } else if (Clauses.size() < 1) {
10209 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10210 return StmtError();
10211 }
10212 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10213}
10214
10215StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10216 SourceLocation StartLoc,
10217 SourceLocation EndLoc) {
10218 // Check that exactly one clause is specified.
10219 if (Clauses.size() != 1) {
10220 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10221 diag::err_omp_scan_single_clause_expected);
10222 return StmtError();
10223 }
10224 // Check that scan directive is used in the scopeof the OpenMP loop body.
10225 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
10226 Scope *ParentS = S->getParent();
10227 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10228 !ParentS->getBreakParent()->isOpenMPLoopScope())
10229 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10230 << getOpenMPDirectiveName(OMPD_scan) << 5);
10231 }
10232 // Check that only one instance of scan directives is used in the same outer
10233 // region.
10234 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
10235 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10236 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
10237 diag::note_omp_previous_directive)
10238 << "scan";
10239 return StmtError();
10240 }
10241 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
10242 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10243}
10244
10245StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10246 Stmt *AStmt,
10247 SourceLocation StartLoc,
10248 SourceLocation EndLoc) {
10249 const OMPClause *DependFound = nullptr;
10250 const OMPClause *DependSourceClause = nullptr;
10251 const OMPClause *DependSinkClause = nullptr;
10252 bool ErrorFound = false;
10253 const OMPThreadsClause *TC = nullptr;
10254 const OMPSIMDClause *SC = nullptr;
10255 for (const OMPClause *C : Clauses) {
10256 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10257 DependFound = C;
10258 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10259 if (DependSourceClause) {
10260 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10261 << getOpenMPDirectiveName(OMPD_ordered)
10262 << getOpenMPClauseName(OMPC_depend) << 2;
10263 ErrorFound = true;
10264 } else {
10265 DependSourceClause = C;
10266 }
10267 if (DependSinkClause) {
10268 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10269 << 0;
10270 ErrorFound = true;
10271 }
10272 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10273 if (DependSourceClause) {
10274 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10275 << 1;
10276 ErrorFound = true;
10277 }
10278 DependSinkClause = C;
10279 }
10280 } else if (C->getClauseKind() == OMPC_threads) {
10281 TC = cast<OMPThreadsClause>(C);
10282 } else if (C->getClauseKind() == OMPC_simd) {
10283 SC = cast<OMPSIMDClause>(C);
10284 }
10285 }
10286 if (!ErrorFound && !SC &&
10287 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
10288 // OpenMP [2.8.1,simd Construct, Restrictions]
10289 // An ordered construct with the simd clause is the only OpenMP construct
10290 // that can appear in the simd region.
10291 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10292 << (LangOpts.OpenMP >= 50 ? 1 : 0);
10293 ErrorFound = true;
10294 } else if (DependFound && (TC || SC)) {
10295 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10296 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10297 ErrorFound = true;
10298 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10299 Diag(DependFound->getBeginLoc(),
10300 diag::err_omp_ordered_directive_without_param);
10301 ErrorFound = true;
10302 } else if (TC || Clauses.empty()) {
10303 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10304 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10305 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10306 << (TC != nullptr);
10307 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10308 ErrorFound = true;
10309 }
10310 }
10311 if ((!AStmt && !DependFound) || ErrorFound)
10312 return StmtError();
10313
10314 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10315 // During execution of an iteration of a worksharing-loop or a loop nest
10316 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10317 // must not execute more than one ordered region corresponding to an ordered
10318 // construct without a depend clause.
10319 if (!DependFound) {
10320 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
10321 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10322 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
10323 diag::note_omp_previous_directive)
10324 << "ordered";
10325 return StmtError();
10326 }
10327 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
10328 }
10329
10330 if (AStmt) {
10331 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 10331, __PRETTY_FUNCTION__))
;
10332
10333 setFunctionHasBranchProtectedScope();
10334 }
10335
10336 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10337}
10338
10339namespace {
10340/// Helper class for checking expression in 'omp atomic [update]'
10341/// construct.
10342class OpenMPAtomicUpdateChecker {
10343 /// Error results for atomic update expressions.
10344 enum ExprAnalysisErrorCode {
10345 /// A statement is not an expression statement.
10346 NotAnExpression,
10347 /// Expression is not builtin binary or unary operation.
10348 NotABinaryOrUnaryExpression,
10349 /// Unary operation is not post-/pre- increment/decrement operation.
10350 NotAnUnaryIncDecExpression,
10351 /// An expression is not of scalar type.
10352 NotAScalarType,
10353 /// A binary operation is not an assignment operation.
10354 NotAnAssignmentOp,
10355 /// RHS part of the binary operation is not a binary expression.
10356 NotABinaryExpression,
10357 /// RHS part is not additive/multiplicative/shift/biwise binary
10358 /// expression.
10359 NotABinaryOperator,
10360 /// RHS binary operation does not have reference to the updated LHS
10361 /// part.
10362 NotAnUpdateExpression,
10363 /// No errors is found.
10364 NoError
10365 };
10366 /// Reference to Sema.
10367 Sema &SemaRef;
10368 /// A location for note diagnostics (when error is found).
10369 SourceLocation NoteLoc;
10370 /// 'x' lvalue part of the source atomic expression.
10371 Expr *X;
10372 /// 'expr' rvalue part of the source atomic expression.
10373 Expr *E;
10374 /// Helper expression of the form
10375 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10376 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10377 Expr *UpdateExpr;
10378 /// Is 'x' a LHS in a RHS part of full update expression. It is
10379 /// important for non-associative operations.
10380 bool IsXLHSInRHSPart;
10381 BinaryOperatorKind Op;
10382 SourceLocation OpLoc;
10383 /// true if the source expression is a postfix unary operation, false
10384 /// if it is a prefix unary operation.
10385 bool IsPostfixUpdate;
10386
10387public:
10388 OpenMPAtomicUpdateChecker(Sema &SemaRef)
10389 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10390 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10391 /// Check specified statement that it is suitable for 'atomic update'
10392 /// constructs and extract 'x', 'expr' and Operation from the original
10393 /// expression. If DiagId and NoteId == 0, then only check is performed
10394 /// without error notification.
10395 /// \param DiagId Diagnostic which should be emitted if error is found.
10396 /// \param NoteId Diagnostic note for the main error message.
10397 /// \return true if statement is not an update expression, false otherwise.
10398 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10399 /// Return the 'x' lvalue part of the source atomic expression.
10400 Expr *getX() const { return X; }
10401 /// Return the 'expr' rvalue part of the source atomic expression.
10402 Expr *getExpr() const { return E; }
10403 /// Return the update expression used in calculation of the updated
10404 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10405 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10406 Expr *getUpdateExpr() const { return UpdateExpr; }
10407 /// Return true if 'x' is LHS in RHS part of full update expression,
10408 /// false otherwise.
10409 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10410
10411 /// true if the source expression is a postfix unary operation, false
10412 /// if it is a prefix unary operation.
10413 bool isPostfixUpdate() const { return IsPostfixUpdate; }
10414
10415private:
10416 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10417 unsigned NoteId = 0);
10418};
10419} // namespace
10420
10421bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10422 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10423 ExprAnalysisErrorCode ErrorFound = NoError;
10424 SourceLocation ErrorLoc, NoteLoc;
10425 SourceRange ErrorRange, NoteRange;
10426 // Allowed constructs are:
10427 // x = x binop expr;
10428 // x = expr binop x;
10429 if (AtomicBinOp->getOpcode() == BO_Assign) {
10430 X = AtomicBinOp->getLHS();
10431 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10432 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10433 if (AtomicInnerBinOp->isMultiplicativeOp() ||
10434 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10435 AtomicInnerBinOp->isBitwiseOp()) {
10436 Op = AtomicInnerBinOp->getOpcode();
10437 OpLoc = AtomicInnerBinOp->getOperatorLoc();
10438 Expr *LHS = AtomicInnerBinOp->getLHS();
10439 Expr *RHS = AtomicInnerBinOp->getRHS();
10440 llvm::FoldingSetNodeID XId, LHSId, RHSId;
10441 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10442 /*Canonical=*/true);
10443 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10444 /*Canonical=*/true);
10445 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10446 /*Canonical=*/true);
10447 if (XId == LHSId) {
10448 E = RHS;
10449 IsXLHSInRHSPart = true;
10450 } else if (XId == RHSId) {
10451 E = LHS;
10452 IsXLHSInRHSPart = false;
10453 } else {
10454 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10455 ErrorRange = AtomicInnerBinOp->getSourceRange();
10456 NoteLoc = X->getExprLoc();
10457 NoteRange = X->getSourceRange();
10458 ErrorFound = NotAnUpdateExpression;
10459 }
10460 } else {
10461 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10462 ErrorRange = AtomicInnerBinOp->getSourceRange();
10463 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10464 NoteRange = SourceRange(NoteLoc, NoteLoc);
10465 ErrorFound = NotABinaryOperator;
10466 }
10467 } else {
10468 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10469 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10470 ErrorFound = NotABinaryExpression;
10471 }
10472 } else {
10473 ErrorLoc = AtomicBinOp->getExprLoc();
10474 ErrorRange = AtomicBinOp->getSourceRange();
10475 NoteLoc = AtomicBinOp->getOperatorLoc();
10476 NoteRange = SourceRange(NoteLoc, NoteLoc);
10477 ErrorFound = NotAnAssignmentOp;
10478 }
10479 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10480 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10481 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10482 return true;
10483 }
10484 if (SemaRef.CurContext->isDependentContext())
10485 E = X = UpdateExpr = nullptr;
10486 return ErrorFound != NoError;
10487}
10488
10489bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10490 unsigned NoteId) {
10491 ExprAnalysisErrorCode ErrorFound = NoError;
10492 SourceLocation ErrorLoc, NoteLoc;
10493 SourceRange ErrorRange, NoteRange;
10494 // Allowed constructs are:
10495 // x++;
10496 // x--;
10497 // ++x;
10498 // --x;
10499 // x binop= expr;
10500 // x = x binop expr;
10501 // x = expr binop x;
10502 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10503 AtomicBody = AtomicBody->IgnoreParenImpCasts();
10504 if (AtomicBody->getType()->isScalarType() ||
10505 AtomicBody->isInstantiationDependent()) {
10506 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10507 AtomicBody->IgnoreParenImpCasts())) {
10508 // Check for Compound Assignment Operation
10509 Op = BinaryOperator::getOpForCompoundAssignment(
10510 AtomicCompAssignOp->getOpcode());
10511 OpLoc = AtomicCompAssignOp->getOperatorLoc();
10512 E = AtomicCompAssignOp->getRHS();
10513 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10514 IsXLHSInRHSPart = true;
10515 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10516 AtomicBody->IgnoreParenImpCasts())) {
10517 // Check for Binary Operation
10518 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10519 return true;
10520 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10521 AtomicBody->IgnoreParenImpCasts())) {
10522 // Check for Unary Operation
10523 if (AtomicUnaryOp->isIncrementDecrementOp()) {
10524 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10525 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10526 OpLoc = AtomicUnaryOp->getOperatorLoc();
10527 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10528 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10529 IsXLHSInRHSPart = true;
10530 } else {
10531 ErrorFound = NotAnUnaryIncDecExpression;
10532 ErrorLoc = AtomicUnaryOp->getExprLoc();
10533 ErrorRange = AtomicUnaryOp->getSourceRange();
10534 NoteLoc = AtomicUnaryOp->getOperatorLoc();
10535 NoteRange = SourceRange(NoteLoc, NoteLoc);
10536 }
10537 } else if (!AtomicBody->isInstantiationDependent()) {
10538 ErrorFound = NotABinaryOrUnaryExpression;
10539 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10540 NoteRange = ErrorRange = AtomicBody->getSourceRange();
10541 }
10542 } else {
10543 ErrorFound = NotAScalarType;
10544 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10545 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10546 }
10547 } else {
10548 ErrorFound = NotAnExpression;
10549 NoteLoc = ErrorLoc = S->getBeginLoc();
10550 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10551 }
10552 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10553 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10554 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10555 return true;
10556 }
10557 if (SemaRef.CurContext->isDependentContext())
10558 E = X = UpdateExpr = nullptr;
10559 if (ErrorFound == NoError && E && X) {
10560 // Build an update expression of form 'OpaqueValueExpr(x) binop
10561 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10562 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10563 auto *OVEX = new (SemaRef.getASTContext())
10564 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
10565 auto *OVEExpr = new (SemaRef.getASTContext())
10566 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
10567 ExprResult Update =
10568 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10569 IsXLHSInRHSPart ? OVEExpr : OVEX);
10570 if (Update.isInvalid())
10571 return true;
10572 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10573 Sema::AA_Casting);
10574 if (Update.isInvalid())
10575 return true;
10576 UpdateExpr = Update.get();
10577 }
10578 return ErrorFound != NoError;
10579}
10580
10581StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10582 Stmt *AStmt,
10583 SourceLocation StartLoc,
10584 SourceLocation EndLoc) {
10585 // Register location of the first atomic directive.
10586 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
10587 if (!AStmt)
10588 return StmtError();
10589
10590 // 1.2.2 OpenMP Language Terminology
10591 // Structured block - An executable statement with a single entry at the
10592 // top and a single exit at the bottom.
10593 // The point of exit cannot be a branch out of the structured block.
10594 // longjmp() and throw() must not violate the entry/exit criteria.
10595 OpenMPClauseKind AtomicKind = OMPC_unknown;
10596 SourceLocation AtomicKindLoc;
10597 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10598 SourceLocation MemOrderLoc;
10599 for (const OMPClause *C : Clauses) {
10600 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10601 C->getClauseKind() == OMPC_update ||
10602 C->getClauseKind() == OMPC_capture) {
10603 if (AtomicKind != OMPC_unknown) {
10604 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10605 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10606 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10607 << getOpenMPClauseName(AtomicKind);
10608 } else {
10609 AtomicKind = C->getClauseKind();
10610 AtomicKindLoc = C->getBeginLoc();
10611 }
10612 }
10613 if (C->getClauseKind() == OMPC_seq_cst ||
10614 C->getClauseKind() == OMPC_acq_rel ||
10615 C->getClauseKind() == OMPC_acquire ||
10616 C->getClauseKind() == OMPC_release ||
10617 C->getClauseKind() == OMPC_relaxed) {
10618 if (MemOrderKind != OMPC_unknown) {
10619 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10620 << getOpenMPDirectiveName(OMPD_atomic) << 0
10621 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10622 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10623 << getOpenMPClauseName(MemOrderKind);
10624 } else {
10625 MemOrderKind = C->getClauseKind();
10626 MemOrderLoc = C->getBeginLoc();
10627 }
10628 }
10629 }
10630 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10631 // If atomic-clause is read then memory-order-clause must not be acq_rel or
10632 // release.
10633 // If atomic-clause is write then memory-order-clause must not be acq_rel or
10634 // acquire.
10635 // If atomic-clause is update or not present then memory-order-clause must not
10636 // be acq_rel or acquire.
10637 if ((AtomicKind == OMPC_read &&
10638 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10639 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10640 AtomicKind == OMPC_unknown) &&
10641 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10642 SourceLocation Loc = AtomicKindLoc;
10643 if (AtomicKind == OMPC_unknown)
10644 Loc = StartLoc;
10645 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10646 << getOpenMPClauseName(AtomicKind)
10647 << (AtomicKind == OMPC_unknown ? 1 : 0)
10648 << getOpenMPClauseName(MemOrderKind);
10649 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10650 << getOpenMPClauseName(MemOrderKind);
10651 }
10652
10653 Stmt *Body = AStmt;
10654 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10655 Body = EWC->getSubExpr();
10656
10657 Expr *X = nullptr;
10658 Expr *V = nullptr;
10659 Expr *E = nullptr;
10660 Expr *UE = nullptr;
10661 bool IsXLHSInRHSPart = false;
10662 bool IsPostfixUpdate = false;
10663 // OpenMP [2.12.6, atomic Construct]
10664 // In the next expressions:
10665 // * x and v (as applicable) are both l-value expressions with scalar type.
10666 // * During the execution of an atomic region, multiple syntactic
10667 // occurrences of x must designate the same storage location.
10668 // * Neither of v and expr (as applicable) may access the storage location
10669 // designated by x.
10670 // * Neither of x and expr (as applicable) may access the storage location
10671 // designated by v.
10672 // * expr is an expression with scalar type.
10673 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10674 // * binop, binop=, ++, and -- are not overloaded operators.
10675 // * The expression x binop expr must be numerically equivalent to x binop
10676 // (expr). This requirement is satisfied if the operators in expr have
10677 // precedence greater than binop, or by using parentheses around expr or
10678 // subexpressions of expr.
10679 // * The expression expr binop x must be numerically equivalent to (expr)
10680 // binop x. This requirement is satisfied if the operators in expr have
10681 // precedence equal to or greater than binop, or by using parentheses around
10682 // expr or subexpressions of expr.
10683 // * For forms that allow multiple occurrences of x, the number of times
10684 // that x is evaluated is unspecified.
10685 if (AtomicKind == OMPC_read) {
10686 enum {
10687 NotAnExpression,
10688 NotAnAssignmentOp,
10689 NotAScalarType,
10690 NotAnLValue,
10691 NoError
10692 } ErrorFound = NoError;
10693 SourceLocation ErrorLoc, NoteLoc;
10694 SourceRange ErrorRange, NoteRange;
10695 // If clause is read:
10696 // v = x;
10697 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10698 const auto *AtomicBinOp =
10699 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10700 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10701 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10702 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10703 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10704 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10705 if (!X->isLValue() || !V->isLValue()) {
10706 const Expr *NotLValueExpr = X->isLValue() ? V : X;
10707 ErrorFound = NotAnLValue;
10708 ErrorLoc = AtomicBinOp->getExprLoc();
10709 ErrorRange = AtomicBinOp->getSourceRange();
10710 NoteLoc = NotLValueExpr->getExprLoc();
10711 NoteRange = NotLValueExpr->getSourceRange();
10712 }
10713 } else if (!X->isInstantiationDependent() ||
10714 !V->isInstantiationDependent()) {
10715 const Expr *NotScalarExpr =
10716 (X->isInstantiationDependent() || X->getType()->isScalarType())
10717 ? V
10718 : X;
10719 ErrorFound = NotAScalarType;
10720 ErrorLoc = AtomicBinOp->getExprLoc();
10721 ErrorRange = AtomicBinOp->getSourceRange();
10722 NoteLoc = NotScalarExpr->getExprLoc();
10723 NoteRange = NotScalarExpr->getSourceRange();
10724 }
10725 } else if (!AtomicBody->isInstantiationDependent()) {
10726 ErrorFound = NotAnAssignmentOp;
10727 ErrorLoc = AtomicBody->getExprLoc();
10728 ErrorRange = AtomicBody->getSourceRange();
10729 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10730 : AtomicBody->getExprLoc();
10731 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10732 : AtomicBody->getSourceRange();
10733 }
10734 } else {
10735 ErrorFound = NotAnExpression;
10736 NoteLoc = ErrorLoc = Body->getBeginLoc();
10737 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10738 }
10739 if (ErrorFound != NoError) {
10740 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10741 << ErrorRange;
10742 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10743 << NoteRange;
10744 return StmtError();
10745 }
10746 if (CurContext->isDependentContext())
10747 V = X = nullptr;
10748 } else if (AtomicKind == OMPC_write) {
10749 enum {
10750 NotAnExpression,
10751 NotAnAssignmentOp,
10752 NotAScalarType,
10753 NotAnLValue,
10754 NoError
10755 } ErrorFound = NoError;
10756 SourceLocation ErrorLoc, NoteLoc;
10757 SourceRange ErrorRange, NoteRange;
10758 // If clause is write:
10759 // x = expr;
10760 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10761 const auto *AtomicBinOp =
10762 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10763 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10764 X = AtomicBinOp->getLHS();
10765 E = AtomicBinOp->getRHS();
10766 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10767 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10768 if (!X->isLValue()) {
10769 ErrorFound = NotAnLValue;
10770 ErrorLoc = AtomicBinOp->getExprLoc();
10771 ErrorRange = AtomicBinOp->getSourceRange();
10772 NoteLoc = X->getExprLoc();
10773 NoteRange = X->getSourceRange();
10774 }
10775 } else if (!X->isInstantiationDependent() ||
10776 !E->isInstantiationDependent()) {
10777 const Expr *NotScalarExpr =
10778 (X->isInstantiationDependent() || X->getType()->isScalarType())
10779 ? E
10780 : X;
10781 ErrorFound = NotAScalarType;
10782 ErrorLoc = AtomicBinOp->getExprLoc();
10783 ErrorRange = AtomicBinOp->getSourceRange();
10784 NoteLoc = NotScalarExpr->getExprLoc();
10785 NoteRange = NotScalarExpr->getSourceRange();
10786 }
10787 } else if (!AtomicBody->isInstantiationDependent()) {
10788 ErrorFound = NotAnAssignmentOp;
10789 ErrorLoc = AtomicBody->getExprLoc();
10790 ErrorRange = AtomicBody->getSourceRange();
10791 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10792 : AtomicBody->getExprLoc();
10793 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10794 : AtomicBody->getSourceRange();
10795 }
10796 } else {
10797 ErrorFound = NotAnExpression;
10798 NoteLoc = ErrorLoc = Body->getBeginLoc();
10799 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10800 }
10801 if (ErrorFound != NoError) {
10802 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10803 << ErrorRange;
10804 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10805 << NoteRange;
10806 return StmtError();
10807 }
10808 if (CurContext->isDependentContext())
10809 E = X = nullptr;
10810 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10811 // If clause is update:
10812 // x++;
10813 // x--;
10814 // ++x;
10815 // --x;
10816 // x binop= expr;
10817 // x = x binop expr;
10818 // x = expr binop x;
10819 OpenMPAtomicUpdateChecker Checker(*this);
10820 if (Checker.checkStatement(
10821 Body, (AtomicKind == OMPC_update)
10822 ? diag::err_omp_atomic_update_not_expression_statement
10823 : diag::err_omp_atomic_not_expression_statement,
10824 diag::note_omp_atomic_update))
10825 return StmtError();
10826 if (!CurContext->isDependentContext()) {
10827 E = Checker.getExpr();
10828 X = Checker.getX();
10829 UE = Checker.getUpdateExpr();
10830 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10831 }
10832 } else if (AtomicKind == OMPC_capture) {
10833 enum {
10834 NotAnAssignmentOp,
10835 NotACompoundStatement,
10836 NotTwoSubstatements,
10837 NotASpecificExpression,
10838 NoError
10839 } ErrorFound = NoError;
10840 SourceLocation ErrorLoc, NoteLoc;
10841 SourceRange ErrorRange, NoteRange;
10842 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10843 // If clause is a capture:
10844 // v = x++;
10845 // v = x--;
10846 // v = ++x;
10847 // v = --x;
10848 // v = x binop= expr;
10849 // v = x = x binop expr;
10850 // v = x = expr binop x;
10851 const auto *AtomicBinOp =
10852 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10853 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10854 V = AtomicBinOp->getLHS();
10855 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10856 OpenMPAtomicUpdateChecker Checker(*this);
10857 if (Checker.checkStatement(
10858 Body, diag::err_omp_atomic_capture_not_expression_statement,
10859 diag::note_omp_atomic_update))
10860 return StmtError();
10861 E = Checker.getExpr();
10862 X = Checker.getX();
10863 UE = Checker.getUpdateExpr();
10864 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10865 IsPostfixUpdate = Checker.isPostfixUpdate();
10866 } else if (!AtomicBody->isInstantiationDependent()) {
10867 ErrorLoc = AtomicBody->getExprLoc();
10868 ErrorRange = AtomicBody->getSourceRange();
10869 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10870 : AtomicBody->getExprLoc();
10871 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10872 : AtomicBody->getSourceRange();
10873 ErrorFound = NotAnAssignmentOp;
10874 }
10875 if (ErrorFound != NoError) {
10876 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10877 << ErrorRange;
10878 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10879 return StmtError();
10880 }
10881 if (CurContext->isDependentContext())
10882 UE = V = E = X = nullptr;
10883 } else {
10884 // If clause is a capture:
10885 // { v = x; x = expr; }
10886 // { v = x; x++; }
10887 // { v = x; x--; }
10888 // { v = x; ++x; }
10889 // { v = x; --x; }
10890 // { v = x; x binop= expr; }
10891 // { v = x; x = x binop expr; }
10892 // { v = x; x = expr binop x; }
10893 // { x++; v = x; }
10894 // { x--; v = x; }
10895 // { ++x; v = x; }
10896 // { --x; v = x; }
10897 // { x binop= expr; v = x; }
10898 // { x = x binop expr; v = x; }
10899 // { x = expr binop x; v = x; }
10900 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10901 // Check that this is { expr1; expr2; }
10902 if (CS->size() == 2) {
10903 Stmt *First = CS->body_front();
10904 Stmt *Second = CS->body_back();
10905 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10906 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10907 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10908 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10909 // Need to find what subexpression is 'v' and what is 'x'.
10910 OpenMPAtomicUpdateChecker Checker(*this);
10911 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10912 BinaryOperator *BinOp = nullptr;
10913 if (IsUpdateExprFound) {
10914 BinOp = dyn_cast<BinaryOperator>(First);
10915 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10916 }
10917 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10918 // { v = x; x++; }
10919 // { v = x; x--; }
10920 // { v = x; ++x; }
10921 // { v = x; --x; }
10922 // { v = x; x binop= expr; }
10923 // { v = x; x = x binop expr; }
10924 // { v = x; x = expr binop x; }
10925 // Check that the first expression has form v = x.
10926 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10927 llvm::FoldingSetNodeID XId, PossibleXId;
10928 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10929 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10930 IsUpdateExprFound = XId == PossibleXId;
10931 if (IsUpdateExprFound) {
10932 V = BinOp->getLHS();
10933 X = Checker.getX();
10934 E = Checker.getExpr();
10935 UE = Checker.getUpdateExpr();
10936 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10937 IsPostfixUpdate = true;
10938 }
10939 }
10940 if (!IsUpdateExprFound) {
10941 IsUpdateExprFound = !Checker.checkStatement(First);
10942 BinOp = nullptr;
10943 if (IsUpdateExprFound) {
10944 BinOp = dyn_cast<BinaryOperator>(Second);
10945 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10946 }
10947 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10948 // { x++; v = x; }
10949 // { x--; v = x; }
10950 // { ++x; v = x; }
10951 // { --x; v = x; }
10952 // { x binop= expr; v = x; }
10953 // { x = x binop expr; v = x; }
10954 // { x = expr binop x; v = x; }
10955 // Check that the second expression has form v = x.
10956 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10957 llvm::FoldingSetNodeID XId, PossibleXId;
10958 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10959 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10960 IsUpdateExprFound = XId == PossibleXId;
10961 if (IsUpdateExprFound) {
10962 V = BinOp->getLHS();
10963 X = Checker.getX();
10964 E = Checker.getExpr();
10965 UE = Checker.getUpdateExpr();
10966 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10967 IsPostfixUpdate = false;
10968 }
10969 }
10970 }
10971 if (!IsUpdateExprFound) {
10972 // { v = x; x = expr; }
10973 auto *FirstExpr = dyn_cast<Expr>(First);
10974 auto *SecondExpr = dyn_cast<Expr>(Second);
10975 if (!FirstExpr || !SecondExpr ||
10976 !(FirstExpr->isInstantiationDependent() ||
10977 SecondExpr->isInstantiationDependent())) {
10978 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10979 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10980 ErrorFound = NotAnAssignmentOp;
10981 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10982 : First->getBeginLoc();
10983 NoteRange = ErrorRange = FirstBinOp
10984 ? FirstBinOp->getSourceRange()
10985 : SourceRange(ErrorLoc, ErrorLoc);
10986 } else {
10987 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10988 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10989 ErrorFound = NotAnAssignmentOp;
10990 NoteLoc = ErrorLoc = SecondBinOp
10991 ? SecondBinOp->getOperatorLoc()
10992 : Second->getBeginLoc();
10993 NoteRange = ErrorRange =
10994 SecondBinOp ? SecondBinOp->getSourceRange()
10995 : SourceRange(ErrorLoc, ErrorLoc);
10996 } else {
10997 Expr *PossibleXRHSInFirst =
10998 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10999 Expr *PossibleXLHSInSecond =
11000 SecondBinOp->getLHS()->IgnoreParenImpCasts();
11001 llvm::FoldingSetNodeID X1Id, X2Id;
11002 PossibleXRHSInFirst->Profile(X1Id, Context,
11003 /*Canonical=*/true);
11004 PossibleXLHSInSecond->Profile(X2Id, Context,
11005 /*Canonical=*/true);
11006 IsUpdateExprFound = X1Id == X2Id;
11007 if (IsUpdateExprFound) {
11008 V = FirstBinOp->getLHS();
11009 X = SecondBinOp->getLHS();
11010 E = SecondBinOp->getRHS();
11011 UE = nullptr;
11012 IsXLHSInRHSPart = false;
11013 IsPostfixUpdate = true;
11014 } else {
11015 ErrorFound = NotASpecificExpression;
11016 ErrorLoc = FirstBinOp->getExprLoc();
11017 ErrorRange = FirstBinOp->getSourceRange();
11018 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
11019 NoteRange = SecondBinOp->getRHS()->getSourceRange();
11020 }
11021 }
11022 }
11023 }
11024 }
11025 } else {
11026 NoteLoc = ErrorLoc = Body->getBeginLoc();
11027 NoteRange = ErrorRange =
11028 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11029 ErrorFound = NotTwoSubstatements;
11030 }
11031 } else {
11032 NoteLoc = ErrorLoc = Body->getBeginLoc();
11033 NoteRange = ErrorRange =
11034 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11035 ErrorFound = NotACompoundStatement;
11036 }
11037 if (ErrorFound != NoError) {
11038 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
11039 << ErrorRange;
11040 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11041 return StmtError();
11042 }
11043 if (CurContext->isDependentContext())
11044 UE = V = E = X = nullptr;
11045 }
11046 }
11047
11048 setFunctionHasBranchProtectedScope();
11049
11050 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11051 X, V, E, UE, IsXLHSInRHSPart,
11052 IsPostfixUpdate);
11053}
11054
11055StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
11056 Stmt *AStmt,
11057 SourceLocation StartLoc,
11058 SourceLocation EndLoc) {
11059 if (!AStmt)
11060 return StmtError();
11061
11062 auto *CS = cast<CapturedStmt>(AStmt);
11063 // 1.2.2 OpenMP Language Terminology
11064 // Structured block - An executable statement with a single entry at the
11065 // top and a single exit at the bottom.
11066 // The point of exit cannot be a branch out of the structured block.
11067 // longjmp() and throw() must not violate the entry/exit criteria.
11068 CS->getCapturedDecl()->setNothrow();
11069 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
11070 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11071 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11072 // 1.2.2 OpenMP Language Terminology
11073 // Structured block - An executable statement with a single entry at the
11074 // top and a single exit at the bottom.
11075 // The point of exit cannot be a branch out of the structured block.
11076 // longjmp() and throw() must not violate the entry/exit criteria.
11077 CS->getCapturedDecl()->setNothrow();
11078 }
11079
11080 // OpenMP [2.16, Nesting of Regions]
11081 // If specified, a teams construct must be contained within a target
11082 // construct. That target construct must contain no statements or directives
11083 // outside of the teams construct.
11084 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
11085 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
11086 bool OMPTeamsFound = true;
11087 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
11088 auto I = CS->body_begin();
11089 while (I != CS->body_end()) {
11090 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
11091 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
11092 OMPTeamsFound) {
11093
11094 OMPTeamsFound = false;
11095 break;
11096 }
11097 ++I;
11098 }
11099 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11099, __PRETTY_FUNCTION__))
;
11100 S = *I;
11101 } else {
11102 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
11103 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
11104 }
11105 if (!OMPTeamsFound) {
11106 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
11107 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
11108 diag::note_omp_nested_teams_construct_here);
11109 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
11110 << isa<OMPExecutableDirective>(S);
11111 return StmtError();
11112 }
11113 }
11114
11115 setFunctionHasBranchProtectedScope();
11116
11117 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11118}
11119
11120StmtResult
11121Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
11122 Stmt *AStmt, SourceLocation StartLoc,
11123 SourceLocation EndLoc) {
11124 if (!AStmt)
11125 return StmtError();
11126
11127 auto *CS = cast<CapturedStmt>(AStmt);
11128 // 1.2.2 OpenMP Language Terminology
11129 // Structured block - An executable statement with a single entry at the
11130 // top and a single exit at the bottom.
11131 // The point of exit cannot be a branch out of the structured block.
11132 // longjmp() and throw() must not violate the entry/exit criteria.
11133 CS->getCapturedDecl()->setNothrow();
11134 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
11135 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11136 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11137 // 1.2.2 OpenMP Language Terminology
11138 // Structured block - An executable statement with a single entry at the
11139 // top and a single exit at the bottom.
11140 // The point of exit cannot be a branch out of the structured block.
11141 // longjmp() and throw() must not violate the entry/exit criteria.
11142 CS->getCapturedDecl()->setNothrow();
11143 }
11144
11145 setFunctionHasBranchProtectedScope();
11146
11147 return OMPTargetParallelDirective::Create(
11148 Context, StartLoc, EndLoc, Clauses, AStmt,
11149 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11150}
11151
11152StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
11153 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11154 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11155 if (!AStmt)
11156 return StmtError();
11157
11158 auto *CS = cast<CapturedStmt>(AStmt);
11159 // 1.2.2 OpenMP Language Terminology
11160 // Structured block - An executable statement with a single entry at the
11161 // top and a single exit at the bottom.
11162 // The point of exit cannot be a branch out of the structured block.
11163 // longjmp() and throw() must not violate the entry/exit criteria.
11164 CS->getCapturedDecl()->setNothrow();
11165 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11166 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11167 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11168 // 1.2.2 OpenMP Language Terminology
11169 // Structured block - An executable statement with a single entry at the
11170 // top and a single exit at the bottom.
11171 // The point of exit cannot be a branch out of the structured block.
11172 // longjmp() and throw() must not violate the entry/exit criteria.
11173 CS->getCapturedDecl()->setNothrow();
11174 }
11175
11176 OMPLoopBasedDirective::HelperExprs B;
11177 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11178 // define the nested loops number.
11179 unsigned NestedLoopCount =
11180 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
11181 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11182 VarsWithImplicitDSA, B);
11183 if (NestedLoopCount == 0)
11184 return StmtError();
11185
11186 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11187, __PRETTY_FUNCTION__))
11187 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11187, __PRETTY_FUNCTION__))
;
11188
11189 if (!CurContext->isDependentContext()) {
11190 // Finalize the clauses that need pre-built expressions for CodeGen.
11191 for (OMPClause *C : Clauses) {
11192 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11193 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11194 B.NumIterations, *this, CurScope,
11195 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11196 return StmtError();
11197 }
11198 }
11199
11200 setFunctionHasBranchProtectedScope();
11201 return OMPTargetParallelForDirective::Create(
11202 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11203 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11204}
11205
11206/// Check for existence of a map clause in the list of clauses.
11207static bool hasClauses(ArrayRef<OMPClause *> Clauses,
11208 const OpenMPClauseKind K) {
11209 return llvm::any_of(
11210 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
11211}
11212
11213template <typename... Params>
11214static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
11215 const Params... ClauseTypes) {
11216 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
11217}
11218
11219StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
11220 Stmt *AStmt,
11221 SourceLocation StartLoc,
11222 SourceLocation EndLoc) {
11223 if (!AStmt)
11224 return StmtError();
11225
11226 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11226, __PRETTY_FUNCTION__))
;
11227
11228 // OpenMP [2.12.2, target data Construct, Restrictions]
11229 // At least one map, use_device_addr or use_device_ptr clause must appear on
11230 // the directive.
11231 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
11232 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
11233 StringRef Expected;
11234 if (LangOpts.OpenMP < 50)
11235 Expected = "'map' or 'use_device_ptr'";
11236 else
11237 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
11238 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11239 << Expected << getOpenMPDirectiveName(OMPD_target_data);
11240 return StmtError();
11241 }
11242
11243 setFunctionHasBranchProtectedScope();
11244
11245 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11246 AStmt);
11247}
11248
11249StmtResult
11250Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
11251 SourceLocation StartLoc,
11252 SourceLocation EndLoc, Stmt *AStmt) {
11253 if (!AStmt)
11254 return StmtError();
11255
11256 auto *CS = cast<CapturedStmt>(AStmt);
11257 // 1.2.2 OpenMP Language Terminology
11258 // Structured block - An executable statement with a single entry at the
11259 // top and a single exit at the bottom.
11260 // The point of exit cannot be a branch out of the structured block.
11261 // longjmp() and throw() must not violate the entry/exit criteria.
11262 CS->getCapturedDecl()->setNothrow();
11263 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
11264 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11265 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11266 // 1.2.2 OpenMP Language Terminology
11267 // Structured block - An executable statement with a single entry at the
11268 // top and a single exit at the bottom.
11269 // The point of exit cannot be a branch out of the structured block.
11270 // longjmp() and throw() must not violate the entry/exit criteria.
11271 CS->getCapturedDecl()->setNothrow();
11272 }
11273
11274 // OpenMP [2.10.2, Restrictions, p. 99]
11275 // At least one map clause must appear on the directive.
11276 if (!hasClauses(Clauses, OMPC_map)) {
11277 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11278 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
11279 return StmtError();
11280 }
11281
11282 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11283 AStmt);
11284}
11285
11286StmtResult
11287Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
11288 SourceLocation StartLoc,
11289 SourceLocation EndLoc, Stmt *AStmt) {
11290 if (!AStmt)
11291 return StmtError();
11292
11293 auto *CS = cast<CapturedStmt>(AStmt);
11294 // 1.2.2 OpenMP Language Terminology
11295 // Structured block - An executable statement with a single entry at the
11296 // top and a single exit at the bottom.
11297 // The point of exit cannot be a branch out of the structured block.
11298 // longjmp() and throw() must not violate the entry/exit criteria.
11299 CS->getCapturedDecl()->setNothrow();
11300 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
11301 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11302 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11303 // 1.2.2 OpenMP Language Terminology
11304 // Structured block - An executable statement with a single entry at the
11305 // top and a single exit at the bottom.
11306 // The point of exit cannot be a branch out of the structured block.
11307 // longjmp() and throw() must not violate the entry/exit criteria.
11308 CS->getCapturedDecl()->setNothrow();
11309 }
11310
11311 // OpenMP [2.10.3, Restrictions, p. 102]
11312 // At least one map clause must appear on the directive.
11313 if (!hasClauses(Clauses, OMPC_map)) {
11314 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11315 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
11316 return StmtError();
11317 }
11318
11319 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11320 AStmt);
11321}
11322
11323StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
11324 SourceLocation StartLoc,
11325 SourceLocation EndLoc,
11326 Stmt *AStmt) {
11327 if (!AStmt)
11328 return StmtError();
11329
11330 auto *CS = cast<CapturedStmt>(AStmt);
11331 // 1.2.2 OpenMP Language Terminology
11332 // Structured block - An executable statement with a single entry at the
11333 // top and a single exit at the bottom.
11334 // The point of exit cannot be a branch out of the structured block.
11335 // longjmp() and throw() must not violate the entry/exit criteria.
11336 CS->getCapturedDecl()->setNothrow();
11337 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
11338 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11339 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11340 // 1.2.2 OpenMP Language Terminology
11341 // Structured block - An executable statement with a single entry at the
11342 // top and a single exit at the bottom.
11343 // The point of exit cannot be a branch out of the structured block.
11344 // longjmp() and throw() must not violate the entry/exit criteria.
11345 CS->getCapturedDecl()->setNothrow();
11346 }
11347
11348 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
11349 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
11350 return StmtError();
11351 }
11352 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
11353 AStmt);
11354}
11355
11356StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
11357 Stmt *AStmt, SourceLocation StartLoc,
11358 SourceLocation EndLoc) {
11359 if (!AStmt)
11360 return StmtError();
11361
11362 auto *CS = cast<CapturedStmt>(AStmt);
11363 // 1.2.2 OpenMP Language Terminology
11364 // Structured block - An executable statement with a single entry at the
11365 // top and a single exit at the bottom.
11366 // The point of exit cannot be a branch out of the structured block.
11367 // longjmp() and throw() must not violate the entry/exit criteria.
11368 CS->getCapturedDecl()->setNothrow();
11369
11370 setFunctionHasBranchProtectedScope();
11371
11372 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11373
11374 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11375}
11376
11377StmtResult
11378Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
11379 SourceLocation EndLoc,
11380 OpenMPDirectiveKind CancelRegion) {
11381 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
11382 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
11383 return StmtError();
11384 }
11385 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
11386 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
11387 return StmtError();
11388 }
11389 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
11390 CancelRegion);
11391}
11392
11393StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
11394 SourceLocation StartLoc,
11395 SourceLocation EndLoc,
11396 OpenMPDirectiveKind CancelRegion) {
11397 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
11398 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
11399 return StmtError();
11400 }
11401 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
11402 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
11403 return StmtError();
11404 }
11405 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
11406 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
11407 CancelRegion);
11408}
11409
11410static bool checkGrainsizeNumTasksClauses(Sema &S,
11411 ArrayRef<OMPClause *> Clauses) {
11412 const OMPClause *PrevClause = nullptr;
11413 bool ErrorFound = false;
11414 for (const OMPClause *C : Clauses) {
11415 if (C->getClauseKind() == OMPC_grainsize ||
11416 C->getClauseKind() == OMPC_num_tasks) {
11417 if (!PrevClause)
11418 PrevClause = C;
11419 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11420 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11421 << getOpenMPClauseName(C->getClauseKind())
11422 << getOpenMPClauseName(PrevClause->getClauseKind());
11423 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11424 << getOpenMPClauseName(PrevClause->getClauseKind());
11425 ErrorFound = true;
11426 }
11427 }
11428 }
11429 return ErrorFound;
11430}
11431
11432static bool checkReductionClauseWithNogroup(Sema &S,
11433 ArrayRef<OMPClause *> Clauses) {
11434 const OMPClause *ReductionClause = nullptr;
11435 const OMPClause *NogroupClause = nullptr;
11436 for (const OMPClause *C : Clauses) {
11437 if (C->getClauseKind() == OMPC_reduction) {
11438 ReductionClause = C;
11439 if (NogroupClause)
11440 break;
11441 continue;
11442 }
11443 if (C->getClauseKind() == OMPC_nogroup) {
11444 NogroupClause = C;
11445 if (ReductionClause)
11446 break;
11447 continue;
11448 }
11449 }
11450 if (ReductionClause && NogroupClause) {
11451 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
11452 << SourceRange(NogroupClause->getBeginLoc(),
11453 NogroupClause->getEndLoc());
11454 return true;
11455 }
11456 return false;
11457}
11458
11459StmtResult Sema::ActOnOpenMPTaskLoopDirective(
11460 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11461 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11462 if (!AStmt)
11463 return StmtError();
11464
11465 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11465, __PRETTY_FUNCTION__))
;
11466 OMPLoopBasedDirective::HelperExprs B;
11467 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11468 // define the nested loops number.
11469 unsigned NestedLoopCount =
11470 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11471 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11472 VarsWithImplicitDSA, B);
11473 if (NestedLoopCount == 0)
11474 return StmtError();
11475
11476 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11477, __PRETTY_FUNCTION__))
11477 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11477, __PRETTY_FUNCTION__))
;
11478
11479 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11480 // The grainsize clause and num_tasks clause are mutually exclusive and may
11481 // not appear on the same taskloop directive.
11482 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11483 return StmtError();
11484 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11485 // If a reduction clause is present on the taskloop directive, the nogroup
11486 // clause must not be specified.
11487 if (checkReductionClauseWithNogroup(*this, Clauses))
11488 return StmtError();
11489
11490 setFunctionHasBranchProtectedScope();
11491 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11492 NestedLoopCount, Clauses, AStmt, B,
11493 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11494}
11495
11496StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11497 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11498 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11499 if (!AStmt)
11500 return StmtError();
11501
11502 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11502, __PRETTY_FUNCTION__))
;
11503 OMPLoopBasedDirective::HelperExprs B;
11504 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11505 // define the nested loops number.
11506 unsigned NestedLoopCount =
11507 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11508 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11509 VarsWithImplicitDSA, B);
11510 if (NestedLoopCount == 0)
11511 return StmtError();
11512
11513 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11514, __PRETTY_FUNCTION__))
11514 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11514, __PRETTY_FUNCTION__))
;
11515
11516 if (!CurContext->isDependentContext()) {
11517 // Finalize the clauses that need pre-built expressions for CodeGen.
11518 for (OMPClause *C : Clauses) {
11519 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11520 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11521 B.NumIterations, *this, CurScope,
11522 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11523 return StmtError();
11524 }
11525 }
11526
11527 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11528 // The grainsize clause and num_tasks clause are mutually exclusive and may
11529 // not appear on the same taskloop directive.
11530 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11531 return StmtError();
11532 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11533 // If a reduction clause is present on the taskloop directive, the nogroup
11534 // clause must not be specified.
11535 if (checkReductionClauseWithNogroup(*this, Clauses))
11536 return StmtError();
11537 if (checkSimdlenSafelenSpecified(*this, Clauses))
11538 return StmtError();
11539
11540 setFunctionHasBranchProtectedScope();
11541 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11542 NestedLoopCount, Clauses, AStmt, B);
11543}
11544
11545StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11546 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11547 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11548 if (!AStmt)
11549 return StmtError();
11550
11551 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11551, __PRETTY_FUNCTION__))
;
11552 OMPLoopBasedDirective::HelperExprs B;
11553 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11554 // define the nested loops number.
11555 unsigned NestedLoopCount =
11556 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11557 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11558 VarsWithImplicitDSA, B);
11559 if (NestedLoopCount == 0)
11560 return StmtError();
11561
11562 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11563, __PRETTY_FUNCTION__))
11563 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11563, __PRETTY_FUNCTION__))
;
11564
11565 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11566 // The grainsize clause and num_tasks clause are mutually exclusive and may
11567 // not appear on the same taskloop directive.
11568 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11569 return StmtError();
11570 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11571 // If a reduction clause is present on the taskloop directive, the nogroup
11572 // clause must not be specified.
11573 if (checkReductionClauseWithNogroup(*this, Clauses))
11574 return StmtError();
11575
11576 setFunctionHasBranchProtectedScope();
11577 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11578 NestedLoopCount, Clauses, AStmt, B,
11579 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11580}
11581
11582StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11583 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11584 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11585 if (!AStmt)
11586 return StmtError();
11587
11588 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11588, __PRETTY_FUNCTION__))
;
11589 OMPLoopBasedDirective::HelperExprs B;
11590 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11591 // define the nested loops number.
11592 unsigned NestedLoopCount =
11593 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11594 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11595 VarsWithImplicitDSA, B);
11596 if (NestedLoopCount == 0)
11597 return StmtError();
11598
11599 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11600, __PRETTY_FUNCTION__))
11600 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11600, __PRETTY_FUNCTION__))
;
11601
11602 if (!CurContext->isDependentContext()) {
11603 // Finalize the clauses that need pre-built expressions for CodeGen.
11604 for (OMPClause *C : Clauses) {
11605 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11606 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11607 B.NumIterations, *this, CurScope,
11608 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11609 return StmtError();
11610 }
11611 }
11612
11613 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11614 // The grainsize clause and num_tasks clause are mutually exclusive and may
11615 // not appear on the same taskloop directive.
11616 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11617 return StmtError();
11618 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11619 // If a reduction clause is present on the taskloop directive, the nogroup
11620 // clause must not be specified.
11621 if (checkReductionClauseWithNogroup(*this, Clauses))
11622 return StmtError();
11623 if (checkSimdlenSafelenSpecified(*this, Clauses))
11624 return StmtError();
11625
11626 setFunctionHasBranchProtectedScope();
11627 return OMPMasterTaskLoopSimdDirective::Create(
11628 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11629}
11630
11631StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11632 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11633 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11634 if (!AStmt)
11635 return StmtError();
11636
11637 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11637, __PRETTY_FUNCTION__))
;
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_parallel_master_taskloop);
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' or 'ordered' with number of loops, it will
11659 // define the nested loops number.
11660 unsigned NestedLoopCount = checkOpenMPLoop(
11661 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11662 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11663 VarsWithImplicitDSA, B);
11664 if (NestedLoopCount == 0)
11665 return StmtError();
11666
11667 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11668, __PRETTY_FUNCTION__))
11668 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11668, __PRETTY_FUNCTION__))
;
11669
11670 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11671 // The grainsize clause and num_tasks clause are mutually exclusive and may
11672 // not appear on the same taskloop directive.
11673 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11674 return StmtError();
11675 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11676 // If a reduction clause is present on the taskloop directive, the nogroup
11677 // clause must not be specified.
11678 if (checkReductionClauseWithNogroup(*this, Clauses))
11679 return StmtError();
11680
11681 setFunctionHasBranchProtectedScope();
11682 return OMPParallelMasterTaskLoopDirective::Create(
11683 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11684 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11685}
11686
11687StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11688 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11689 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11690 if (!AStmt)
11691 return StmtError();
11692
11693 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11693, __PRETTY_FUNCTION__))
;
11694 auto *CS = cast<CapturedStmt>(AStmt);
11695 // 1.2.2 OpenMP Language Terminology
11696 // Structured block - An executable statement with a single entry at the
11697 // top and a single exit at the bottom.
11698 // The point of exit cannot be a branch out of the structured block.
11699 // longjmp() and throw() must not violate the entry/exit criteria.
11700 CS->getCapturedDecl()->setNothrow();
11701 for (int ThisCaptureLevel =
11702 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11703 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11704 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11705 // 1.2.2 OpenMP Language Terminology
11706 // Structured block - An executable statement with a single entry at the
11707 // top and a single exit at the bottom.
11708 // The point of exit cannot be a branch out of the structured block.
11709 // longjmp() and throw() must not violate the entry/exit criteria.
11710 CS->getCapturedDecl()->setNothrow();
11711 }
11712
11713 OMPLoopBasedDirective::HelperExprs B;
11714 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11715 // define the nested loops number.
11716 unsigned NestedLoopCount = checkOpenMPLoop(
11717 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11718 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11719 VarsWithImplicitDSA, B);
11720 if (NestedLoopCount == 0)
11721 return StmtError();
11722
11723 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11724, __PRETTY_FUNCTION__))
11724 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11724, __PRETTY_FUNCTION__))
;
11725
11726 if (!CurContext->isDependentContext()) {
11727 // Finalize the clauses that need pre-built expressions for CodeGen.
11728 for (OMPClause *C : Clauses) {
11729 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11730 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11731 B.NumIterations, *this, CurScope,
11732 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11733 return StmtError();
11734 }
11735 }
11736
11737 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11738 // The grainsize clause and num_tasks clause are mutually exclusive and may
11739 // not appear on the same taskloop directive.
11740 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11741 return StmtError();
11742 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11743 // If a reduction clause is present on the taskloop directive, the nogroup
11744 // clause must not be specified.
11745 if (checkReductionClauseWithNogroup(*this, Clauses))
11746 return StmtError();
11747 if (checkSimdlenSafelenSpecified(*this, Clauses))
11748 return StmtError();
11749
11750 setFunctionHasBranchProtectedScope();
11751 return OMPParallelMasterTaskLoopSimdDirective::Create(
11752 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11753}
11754
11755StmtResult Sema::ActOnOpenMPDistributeDirective(
11756 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11757 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11758 if (!AStmt)
11759 return StmtError();
11760
11761 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11761, __PRETTY_FUNCTION__))
;
11762 OMPLoopBasedDirective::HelperExprs B;
11763 // In presence of clause 'collapse' with number of loops, it will
11764 // define the nested loops number.
11765 unsigned NestedLoopCount =
11766 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11767 nullptr /*ordered not a clause on distribute*/, AStmt,
11768 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11769 if (NestedLoopCount == 0)
11770 return StmtError();
11771
11772 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11773, __PRETTY_FUNCTION__))
11773 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11773, __PRETTY_FUNCTION__))
;
11774
11775 setFunctionHasBranchProtectedScope();
11776 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11777 NestedLoopCount, Clauses, AStmt, B);
11778}
11779
11780StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11781 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11782 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11783 if (!AStmt)
11784 return StmtError();
11785
11786 auto *CS = cast<CapturedStmt>(AStmt);
11787 // 1.2.2 OpenMP Language Terminology
11788 // Structured block - An executable statement with a single entry at the
11789 // top and a single exit at the bottom.
11790 // The point of exit cannot be a branch out of the structured block.
11791 // longjmp() and throw() must not violate the entry/exit criteria.
11792 CS->getCapturedDecl()->setNothrow();
11793 for (int ThisCaptureLevel =
11794 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11795 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11796 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11797 // 1.2.2 OpenMP Language Terminology
11798 // Structured block - An executable statement with a single entry at the
11799 // top and a single exit at the bottom.
11800 // The point of exit cannot be a branch out of the structured block.
11801 // longjmp() and throw() must not violate the entry/exit criteria.
11802 CS->getCapturedDecl()->setNothrow();
11803 }
11804
11805 OMPLoopBasedDirective::HelperExprs B;
11806 // In presence of clause 'collapse' with number of loops, it will
11807 // define the nested loops number.
11808 unsigned NestedLoopCount = checkOpenMPLoop(
11809 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11810 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11811 VarsWithImplicitDSA, B);
11812 if (NestedLoopCount == 0)
11813 return StmtError();
11814
11815 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11816, __PRETTY_FUNCTION__))
11816 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11816, __PRETTY_FUNCTION__))
;
11817
11818 setFunctionHasBranchProtectedScope();
11819 return OMPDistributeParallelForDirective::Create(
11820 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11821 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11822}
11823
11824StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11825 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11826 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11827 if (!AStmt)
11828 return StmtError();
11829
11830 auto *CS = cast<CapturedStmt>(AStmt);
11831 // 1.2.2 OpenMP Language Terminology
11832 // Structured block - An executable statement with a single entry at the
11833 // top and a single exit at the bottom.
11834 // The point of exit cannot be a branch out of the structured block.
11835 // longjmp() and throw() must not violate the entry/exit criteria.
11836 CS->getCapturedDecl()->setNothrow();
11837 for (int ThisCaptureLevel =
11838 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11839 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11840 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11841 // 1.2.2 OpenMP Language Terminology
11842 // Structured block - An executable statement with a single entry at the
11843 // top and a single exit at the bottom.
11844 // The point of exit cannot be a branch out of the structured block.
11845 // longjmp() and throw() must not violate the entry/exit criteria.
11846 CS->getCapturedDecl()->setNothrow();
11847 }
11848
11849 OMPLoopBasedDirective::HelperExprs B;
11850 // In presence of clause 'collapse' with number of loops, it will
11851 // define the nested loops number.
11852 unsigned NestedLoopCount = checkOpenMPLoop(
11853 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11854 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11855 VarsWithImplicitDSA, B);
11856 if (NestedLoopCount == 0)
11857 return StmtError();
11858
11859 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11860, __PRETTY_FUNCTION__))
11860 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11860, __PRETTY_FUNCTION__))
;
11861
11862 if (!CurContext->isDependentContext()) {
11863 // Finalize the clauses that need pre-built expressions for CodeGen.
11864 for (OMPClause *C : Clauses) {
11865 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11866 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11867 B.NumIterations, *this, CurScope,
11868 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11869 return StmtError();
11870 }
11871 }
11872
11873 if (checkSimdlenSafelenSpecified(*this, Clauses))
11874 return StmtError();
11875
11876 setFunctionHasBranchProtectedScope();
11877 return OMPDistributeParallelForSimdDirective::Create(
11878 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11879}
11880
11881StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11882 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11883 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11884 if (!AStmt)
11885 return StmtError();
11886
11887 auto *CS = cast<CapturedStmt>(AStmt);
11888 // 1.2.2 OpenMP Language Terminology
11889 // Structured block - An executable statement with a single entry at the
11890 // top and a single exit at the bottom.
11891 // The point of exit cannot be a branch out of the structured block.
11892 // longjmp() and throw() must not violate the entry/exit criteria.
11893 CS->getCapturedDecl()->setNothrow();
11894 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11895 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11896 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11897 // 1.2.2 OpenMP Language Terminology
11898 // Structured block - An executable statement with a single entry at the
11899 // top and a single exit at the bottom.
11900 // The point of exit cannot be a branch out of the structured block.
11901 // longjmp() and throw() must not violate the entry/exit criteria.
11902 CS->getCapturedDecl()->setNothrow();
11903 }
11904
11905 OMPLoopBasedDirective::HelperExprs B;
11906 // In presence of clause 'collapse' with number of loops, it will
11907 // define the nested loops number.
11908 unsigned NestedLoopCount =
11909 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11910 nullptr /*ordered not a clause on distribute*/, CS, *this,
11911 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11912 if (NestedLoopCount == 0)
11913 return StmtError();
11914
11915 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11916, __PRETTY_FUNCTION__))
11916 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11916, __PRETTY_FUNCTION__))
;
11917
11918 if (!CurContext->isDependentContext()) {
11919 // Finalize the clauses that need pre-built expressions for CodeGen.
11920 for (OMPClause *C : Clauses) {
11921 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11922 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11923 B.NumIterations, *this, CurScope,
11924 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11925 return StmtError();
11926 }
11927 }
11928
11929 if (checkSimdlenSafelenSpecified(*this, Clauses))
11930 return StmtError();
11931
11932 setFunctionHasBranchProtectedScope();
11933 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11934 NestedLoopCount, Clauses, AStmt, B);
11935}
11936
11937StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11938 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11939 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11940 if (!AStmt)
11941 return StmtError();
11942
11943 auto *CS = cast<CapturedStmt>(AStmt);
11944 // 1.2.2 OpenMP Language Terminology
11945 // Structured block - An executable statement with a single entry at the
11946 // top and a single exit at the bottom.
11947 // The point of exit cannot be a branch out of the structured block.
11948 // longjmp() and throw() must not violate the entry/exit criteria.
11949 CS->getCapturedDecl()->setNothrow();
11950 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11951 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11952 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11953 // 1.2.2 OpenMP Language Terminology
11954 // Structured block - An executable statement with a single entry at the
11955 // top and a single exit at the bottom.
11956 // The point of exit cannot be a branch out of the structured block.
11957 // longjmp() and throw() must not violate the entry/exit criteria.
11958 CS->getCapturedDecl()->setNothrow();
11959 }
11960
11961 OMPLoopBasedDirective::HelperExprs B;
11962 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11963 // define the nested loops number.
11964 unsigned NestedLoopCount = checkOpenMPLoop(
11965 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11966 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11967 VarsWithImplicitDSA, B);
11968 if (NestedLoopCount == 0)
11969 return StmtError();
11970
11971 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11972, __PRETTY_FUNCTION__))
11972 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 11972, __PRETTY_FUNCTION__))
;
11973
11974 if (!CurContext->isDependentContext()) {
11975 // Finalize the clauses that need pre-built expressions for CodeGen.
11976 for (OMPClause *C : Clauses) {
11977 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11978 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11979 B.NumIterations, *this, CurScope,
11980 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11981 return StmtError();
11982 }
11983 }
11984 if (checkSimdlenSafelenSpecified(*this, Clauses))
11985 return StmtError();
11986
11987 setFunctionHasBranchProtectedScope();
11988 return OMPTargetParallelForSimdDirective::Create(
11989 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11990}
11991
11992StmtResult Sema::ActOnOpenMPTargetSimdDirective(
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 = getOpenMPCaptureLevels(OMPD_target_simd);
12006 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12007 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12008 // 1.2.2 OpenMP Language Terminology
12009 // Structured block - An executable statement with a single entry at the
12010 // top and a single exit at the bottom.
12011 // The point of exit cannot be a branch out of the structured block.
12012 // longjmp() and throw() must not violate the entry/exit criteria.
12013 CS->getCapturedDecl()->setNothrow();
12014 }
12015
12016 OMPLoopBasedDirective::HelperExprs B;
12017 // In presence of clause 'collapse' with number of loops, it will define the
12018 // nested loops number.
12019 unsigned NestedLoopCount =
12020 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
12021 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12022 VarsWithImplicitDSA, B);
12023 if (NestedLoopCount == 0)
12024 return StmtError();
12025
12026 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12027, __PRETTY_FUNCTION__))
12027 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12027, __PRETTY_FUNCTION__))
;
12028
12029 if (!CurContext->isDependentContext()) {
12030 // Finalize the clauses that need pre-built expressions for CodeGen.
12031 for (OMPClause *C : Clauses) {
12032 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12033 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12034 B.NumIterations, *this, CurScope,
12035 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12036 return StmtError();
12037 }
12038 }
12039
12040 if (checkSimdlenSafelenSpecified(*this, Clauses))
12041 return StmtError();
12042
12043 setFunctionHasBranchProtectedScope();
12044 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
12045 NestedLoopCount, Clauses, AStmt, B);
12046}
12047
12048StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
12049 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12050 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12051 if (!AStmt)
12052 return StmtError();
12053
12054 auto *CS = cast<CapturedStmt>(AStmt);
12055 // 1.2.2 OpenMP Language Terminology
12056 // Structured block - An executable statement with a single entry at the
12057 // top and a single exit at the bottom.
12058 // The point of exit cannot be a branch out of the structured block.
12059 // longjmp() and throw() must not violate the entry/exit criteria.
12060 CS->getCapturedDecl()->setNothrow();
12061 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
12062 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12063 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12064 // 1.2.2 OpenMP Language Terminology
12065 // Structured block - An executable statement with a single entry at the
12066 // top and a single exit at the bottom.
12067 // The point of exit cannot be a branch out of the structured block.
12068 // longjmp() and throw() must not violate the entry/exit criteria.
12069 CS->getCapturedDecl()->setNothrow();
12070 }
12071
12072 OMPLoopBasedDirective::HelperExprs B;
12073 // In presence of clause 'collapse' with number of loops, it will
12074 // define the nested loops number.
12075 unsigned NestedLoopCount =
12076 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
12077 nullptr /*ordered not a clause on distribute*/, CS, *this,
12078 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
12079 if (NestedLoopCount == 0)
12080 return StmtError();
12081
12082 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12083, __PRETTY_FUNCTION__))
12083 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12083, __PRETTY_FUNCTION__))
;
12084
12085 setFunctionHasBranchProtectedScope();
12086
12087 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12088
12089 return OMPTeamsDistributeDirective::Create(
12090 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12091}
12092
12093StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
12094 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12095 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12096 if (!AStmt)
12097 return StmtError();
12098
12099 auto *CS = cast<CapturedStmt>(AStmt);
12100 // 1.2.2 OpenMP Language Terminology
12101 // Structured block - An executable statement with a single entry at the
12102 // top and a single exit at the bottom.
12103 // The point of exit cannot be a branch out of the structured block.
12104 // longjmp() and throw() must not violate the entry/exit criteria.
12105 CS->getCapturedDecl()->setNothrow();
12106 for (int ThisCaptureLevel =
12107 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
12108 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12109 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12110 // 1.2.2 OpenMP Language Terminology
12111 // Structured block - An executable statement with a single entry at the
12112 // top and a single exit at the bottom.
12113 // The point of exit cannot be a branch out of the structured block.
12114 // longjmp() and throw() must not violate the entry/exit criteria.
12115 CS->getCapturedDecl()->setNothrow();
12116 }
12117
12118 OMPLoopBasedDirective::HelperExprs B;
12119 // In presence of clause 'collapse' with number of loops, it will
12120 // define the nested loops number.
12121 unsigned NestedLoopCount = checkOpenMPLoop(
12122 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12123 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12124 VarsWithImplicitDSA, B);
12125
12126 if (NestedLoopCount == 0)
12127 return StmtError();
12128
12129 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12130, __PRETTY_FUNCTION__))
12130 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12130, __PRETTY_FUNCTION__))
;
12131
12132 if (!CurContext->isDependentContext()) {
12133 // Finalize the clauses that need pre-built expressions for CodeGen.
12134 for (OMPClause *C : Clauses) {
12135 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12136 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12137 B.NumIterations, *this, CurScope,
12138 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12139 return StmtError();
12140 }
12141 }
12142
12143 if (checkSimdlenSafelenSpecified(*this, Clauses))
12144 return StmtError();
12145
12146 setFunctionHasBranchProtectedScope();
12147
12148 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12149
12150 return OMPTeamsDistributeSimdDirective::Create(
12151 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12152}
12153
12154StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
12155 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12156 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12157 if (!AStmt)
12158 return StmtError();
12159
12160 auto *CS = cast<CapturedStmt>(AStmt);
12161 // 1.2.2 OpenMP Language Terminology
12162 // Structured block - An executable statement with a single entry at the
12163 // top and a single exit at the bottom.
12164 // The point of exit cannot be a branch out of the structured block.
12165 // longjmp() and throw() must not violate the entry/exit criteria.
12166 CS->getCapturedDecl()->setNothrow();
12167
12168 for (int ThisCaptureLevel =
12169 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
12170 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12171 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12172 // 1.2.2 OpenMP Language Terminology
12173 // Structured block - An executable statement with a single entry at the
12174 // top and a single exit at the bottom.
12175 // The point of exit cannot be a branch out of the structured block.
12176 // longjmp() and throw() must not violate the entry/exit criteria.
12177 CS->getCapturedDecl()->setNothrow();
12178 }
12179
12180 OMPLoopBasedDirective::HelperExprs B;
12181 // In presence of clause 'collapse' with number of loops, it will
12182 // define the nested loops number.
12183 unsigned NestedLoopCount = checkOpenMPLoop(
12184 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
12185 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12186 VarsWithImplicitDSA, B);
12187
12188 if (NestedLoopCount == 0)
12189 return StmtError();
12190
12191 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12192, __PRETTY_FUNCTION__))
12192 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12192, __PRETTY_FUNCTION__))
;
12193
12194 if (!CurContext->isDependentContext()) {
12195 // Finalize the clauses that need pre-built expressions for CodeGen.
12196 for (OMPClause *C : Clauses) {
12197 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12198 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12199 B.NumIterations, *this, CurScope,
12200 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12201 return StmtError();
12202 }
12203 }
12204
12205 if (checkSimdlenSafelenSpecified(*this, Clauses))
12206 return StmtError();
12207
12208 setFunctionHasBranchProtectedScope();
12209
12210 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12211
12212 return OMPTeamsDistributeParallelForSimdDirective::Create(
12213 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12214}
12215
12216StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
12217 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12218 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12219 if (!AStmt)
12220 return StmtError();
12221
12222 auto *CS = cast<CapturedStmt>(AStmt);
12223 // 1.2.2 OpenMP Language Terminology
12224 // Structured block - An executable statement with a single entry at the
12225 // top and a single exit at the bottom.
12226 // The point of exit cannot be a branch out of the structured block.
12227 // longjmp() and throw() must not violate the entry/exit criteria.
12228 CS->getCapturedDecl()->setNothrow();
12229
12230 for (int ThisCaptureLevel =
12231 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
12232 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12233 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12234 // 1.2.2 OpenMP Language Terminology
12235 // Structured block - An executable statement with a single entry at the
12236 // top and a single exit at the bottom.
12237 // The point of exit cannot be a branch out of the structured block.
12238 // longjmp() and throw() must not violate the entry/exit criteria.
12239 CS->getCapturedDecl()->setNothrow();
12240 }
12241
12242 OMPLoopBasedDirective::HelperExprs B;
12243 // In presence of clause 'collapse' with number of loops, it will
12244 // define the nested loops number.
12245 unsigned NestedLoopCount = checkOpenMPLoop(
12246 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12247 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12248 VarsWithImplicitDSA, B);
12249
12250 if (NestedLoopCount == 0)
12251 return StmtError();
12252
12253 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12254, __PRETTY_FUNCTION__))
12254 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12254, __PRETTY_FUNCTION__))
;
12255
12256 setFunctionHasBranchProtectedScope();
12257
12258 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12259
12260 return OMPTeamsDistributeParallelForDirective::Create(
12261 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12262 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12263}
12264
12265StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
12266 Stmt *AStmt,
12267 SourceLocation StartLoc,
12268 SourceLocation EndLoc) {
12269 if (!AStmt)
12270 return StmtError();
12271
12272 auto *CS = cast<CapturedStmt>(AStmt);
12273 // 1.2.2 OpenMP Language Terminology
12274 // Structured block - An executable statement with a single entry at the
12275 // top and a single exit at the bottom.
12276 // The point of exit cannot be a branch out of the structured block.
12277 // longjmp() and throw() must not violate the entry/exit criteria.
12278 CS->getCapturedDecl()->setNothrow();
12279
12280 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
12281 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12282 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12283 // 1.2.2 OpenMP Language Terminology
12284 // Structured block - An executable statement with a single entry at the
12285 // top and a single exit at the bottom.
12286 // The point of exit cannot be a branch out of the structured block.
12287 // longjmp() and throw() must not violate the entry/exit criteria.
12288 CS->getCapturedDecl()->setNothrow();
12289 }
12290 setFunctionHasBranchProtectedScope();
12291
12292 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
12293 AStmt);
12294}
12295
12296StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
12297 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12298 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12299 if (!AStmt)
12300 return StmtError();
12301
12302 auto *CS = cast<CapturedStmt>(AStmt);
12303 // 1.2.2 OpenMP Language Terminology
12304 // Structured block - An executable statement with a single entry at the
12305 // top and a single exit at the bottom.
12306 // The point of exit cannot be a branch out of the structured block.
12307 // longjmp() and throw() must not violate the entry/exit criteria.
12308 CS->getCapturedDecl()->setNothrow();
12309 for (int ThisCaptureLevel =
12310 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
12311 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12312 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12313 // 1.2.2 OpenMP Language Terminology
12314 // Structured block - An executable statement with a single entry at the
12315 // top and a single exit at the bottom.
12316 // The point of exit cannot be a branch out of the structured block.
12317 // longjmp() and throw() must not violate the entry/exit criteria.
12318 CS->getCapturedDecl()->setNothrow();
12319 }
12320
12321 OMPLoopBasedDirective::HelperExprs B;
12322 // In presence of clause 'collapse' with number of loops, it will
12323 // define the nested loops number.
12324 unsigned NestedLoopCount = checkOpenMPLoop(
12325 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
12326 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12327 VarsWithImplicitDSA, B);
12328 if (NestedLoopCount == 0)
12329 return StmtError();
12330
12331 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12332, __PRETTY_FUNCTION__))
12332 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12332, __PRETTY_FUNCTION__))
;
12333
12334 setFunctionHasBranchProtectedScope();
12335 return OMPTargetTeamsDistributeDirective::Create(
12336 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12337}
12338
12339StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
12340 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12341 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12342 if (!AStmt)
12343 return StmtError();
12344
12345 auto *CS = cast<CapturedStmt>(AStmt);
12346 // 1.2.2 OpenMP Language Terminology
12347 // Structured block - An executable statement with a single entry at the
12348 // top and a single exit at the bottom.
12349 // The point of exit cannot be a branch out of the structured block.
12350 // longjmp() and throw() must not violate the entry/exit criteria.
12351 CS->getCapturedDecl()->setNothrow();
12352 for (int ThisCaptureLevel =
12353 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
12354 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12355 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12356 // 1.2.2 OpenMP Language Terminology
12357 // Structured block - An executable statement with a single entry at the
12358 // top and a single exit at the bottom.
12359 // The point of exit cannot be a branch out of the structured block.
12360 // longjmp() and throw() must not violate the entry/exit criteria.
12361 CS->getCapturedDecl()->setNothrow();
12362 }
12363
12364 OMPLoopBasedDirective::HelperExprs B;
12365 // In presence of clause 'collapse' with number of loops, it will
12366 // define the nested loops number.
12367 unsigned NestedLoopCount = checkOpenMPLoop(
12368 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12369 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12370 VarsWithImplicitDSA, B);
12371 if (NestedLoopCount == 0)
12372 return StmtError();
12373
12374 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12375, __PRETTY_FUNCTION__))
12375 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12375, __PRETTY_FUNCTION__))
;
12376
12377 if (!CurContext->isDependentContext()) {
12378 // Finalize the clauses that need pre-built expressions for CodeGen.
12379 for (OMPClause *C : Clauses) {
12380 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12381 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12382 B.NumIterations, *this, CurScope,
12383 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12384 return StmtError();
12385 }
12386 }
12387
12388 setFunctionHasBranchProtectedScope();
12389 return OMPTargetTeamsDistributeParallelForDirective::Create(
12390 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12391 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12392}
12393
12394StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
12395 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12396 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12397 if (!AStmt)
12398 return StmtError();
12399
12400 auto *CS = cast<CapturedStmt>(AStmt);
12401 // 1.2.2 OpenMP Language Terminology
12402 // Structured block - An executable statement with a single entry at the
12403 // top and a single exit at the bottom.
12404 // The point of exit cannot be a branch out of the structured block.
12405 // longjmp() and throw() must not violate the entry/exit criteria.
12406 CS->getCapturedDecl()->setNothrow();
12407 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
12408 OMPD_target_teams_distribute_parallel_for_simd);
12409 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12410 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12411 // 1.2.2 OpenMP Language Terminology
12412 // Structured block - An executable statement with a single entry at the
12413 // top and a single exit at the bottom.
12414 // The point of exit cannot be a branch out of the structured block.
12415 // longjmp() and throw() must not violate the entry/exit criteria.
12416 CS->getCapturedDecl()->setNothrow();
12417 }
12418
12419 OMPLoopBasedDirective::HelperExprs B;
12420 // In presence of clause 'collapse' with number of loops, it will
12421 // define the nested loops number.
12422 unsigned NestedLoopCount =
12423 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
12424 getCollapseNumberExpr(Clauses),
12425 nullptr /*ordered not a clause on distribute*/, CS, *this,
12426 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
12427 if (NestedLoopCount == 0)
12428 return StmtError();
12429
12430 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12432, __PRETTY_FUNCTION__))
12431 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12432, __PRETTY_FUNCTION__))
12432 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12432, __PRETTY_FUNCTION__))
;
12433
12434 if (!CurContext->isDependentContext()) {
12435 // Finalize the clauses that need pre-built expressions for CodeGen.
12436 for (OMPClause *C : Clauses) {
12437 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12438 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12439 B.NumIterations, *this, CurScope,
12440 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12441 return StmtError();
12442 }
12443 }
12444
12445 if (checkSimdlenSafelenSpecified(*this, Clauses))
12446 return StmtError();
12447
12448 setFunctionHasBranchProtectedScope();
12449 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
12450 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12451}
12452
12453StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
12454 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12455 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12456 if (!AStmt)
12457 return StmtError();
12458
12459 auto *CS = cast<CapturedStmt>(AStmt);
12460 // 1.2.2 OpenMP Language Terminology
12461 // Structured block - An executable statement with a single entry at the
12462 // top and a single exit at the bottom.
12463 // The point of exit cannot be a branch out of the structured block.
12464 // longjmp() and throw() must not violate the entry/exit criteria.
12465 CS->getCapturedDecl()->setNothrow();
12466 for (int ThisCaptureLevel =
12467 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12468 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12469 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12470 // 1.2.2 OpenMP Language Terminology
12471 // Structured block - An executable statement with a single entry at the
12472 // top and a single exit at the bottom.
12473 // The point of exit cannot be a branch out of the structured block.
12474 // longjmp() and throw() must not violate the entry/exit criteria.
12475 CS->getCapturedDecl()->setNothrow();
12476 }
12477
12478 OMPLoopBasedDirective::HelperExprs B;
12479 // In presence of clause 'collapse' with number of loops, it will
12480 // define the nested loops number.
12481 unsigned NestedLoopCount = checkOpenMPLoop(
12482 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12483 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12484 VarsWithImplicitDSA, B);
12485 if (NestedLoopCount == 0)
12486 return StmtError();
12487
12488 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12489, __PRETTY_FUNCTION__))
12489 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12489, __PRETTY_FUNCTION__))
;
12490
12491 if (!CurContext->isDependentContext()) {
12492 // Finalize the clauses that need pre-built expressions for CodeGen.
12493 for (OMPClause *C : Clauses) {
12494 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12495 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12496 B.NumIterations, *this, CurScope,
12497 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12498 return StmtError();
12499 }
12500 }
12501
12502 if (checkSimdlenSafelenSpecified(*this, Clauses))
12503 return StmtError();
12504
12505 setFunctionHasBranchProtectedScope();
12506 return OMPTargetTeamsDistributeSimdDirective::Create(
12507 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12508}
12509
12510StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12511 Stmt *AStmt, SourceLocation StartLoc,
12512 SourceLocation EndLoc) {
12513 auto SizesClauses =
12514 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12515 if (SizesClauses.empty()) {
12516 // A missing 'sizes' clause is already reported by the parser.
12517 return StmtError();
12518 }
12519 const OMPSizesClause *SizesClause = *SizesClauses.begin();
12520 unsigned NumLoops = SizesClause->getNumSizes();
12521
12522 // Empty statement should only be possible if there already was an error.
12523 if (!AStmt)
12524 return StmtError();
12525
12526 // Verify and diagnose loop nest.
12527 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12528 Stmt *Body = nullptr;
12529 SmallVector<Stmt *, 4> OriginalInits;
12530 if (!OMPLoopBasedDirective::doForAllLoops(
12531 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false,
12532 NumLoops,
12533 [this, &LoopHelpers, &Body, &OriginalInits](unsigned Cnt,
12534 Stmt *CurStmt) {
12535 VarsWithInheritedDSAType TmpDSA;
12536 unsigned SingleNumLoops =
12537 checkOpenMPLoop(OMPD_tile, nullptr, nullptr, CurStmt, *this,
12538 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, TmpDSA, LoopHelpers[Cnt]);
12539 if (SingleNumLoops == 0)
12540 return true;
12541 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12541, __PRETTY_FUNCTION__))
;
12542 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12543 OriginalInits.push_back(For->getInit());
12544 Body = For->getBody();
12545 } else {
12546 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12547, __PRETTY_FUNCTION__))
12547 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12547, __PRETTY_FUNCTION__))
;
12548 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12549 OriginalInits.push_back(CXXFor->getBeginStmt());
12550 Body = CXXFor->getBody();
12551 }
12552 return false;
12553 }))
12554 return StmtError();
12555
12556 // Delay tiling to when template is completely instantiated.
12557 if (CurContext->isDependentContext())
12558 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12559 NumLoops, AStmt, nullptr, nullptr);
12560
12561 // Collection of generated variable declaration.
12562 SmallVector<Decl *, 4> PreInits;
12563
12564 // Create iteration variables for the generated loops.
12565 SmallVector<VarDecl *, 4> FloorIndVars;
12566 SmallVector<VarDecl *, 4> TileIndVars;
12567 FloorIndVars.resize(NumLoops);
12568 TileIndVars.resize(NumLoops);
12569 for (unsigned I = 0; I < NumLoops; ++I) {
12570 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12571 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12572 PreInits.append(PI->decl_begin(), PI->decl_end());
12573 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12574, __PRETTY_FUNCTION__))
12574 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12574, __PRETTY_FUNCTION__))
;
12575 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12576 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12577 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12578 QualType CntTy = IterVarRef->getType();
12579
12580 // Iteration variable for the floor (i.e. outer) loop.
12581 {
12582 std::string FloorCntName =
12583 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12584 VarDecl *FloorCntDecl =
12585 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12586 FloorIndVars[I] = FloorCntDecl;
12587 }
12588
12589 // Iteration variable for the tile (i.e. inner) loop.
12590 {
12591 std::string TileCntName =
12592 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12593
12594 // Reuse the iteration variable created by checkOpenMPLoop. It is also
12595 // used by the expressions to derive the original iteration variable's
12596 // value from the logical iteration number.
12597 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12598 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12599 TileIndVars[I] = TileCntDecl;
12600 }
12601 if (auto *PI = dyn_cast_or_null<DeclStmt>(OriginalInits[I]))
12602 PreInits.append(PI->decl_begin(), PI->decl_end());
12603 // Gather declarations for the data members used as counters.
12604 for (Expr *CounterRef : LoopHelper.Counters) {
12605 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12606 if (isa<OMPCapturedExprDecl>(CounterDecl))
12607 PreInits.push_back(CounterDecl);
12608 }
12609 }
12610
12611 // Once the original iteration values are set, append the innermost body.
12612 Stmt *Inner = Body;
12613
12614 // Create tile loops from the inside to the outside.
12615 for (int I = NumLoops - 1; I >= 0; --I) {
12616 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12617 Expr *NumIterations = LoopHelper.NumIterations;
12618 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12619 QualType CntTy = OrigCntVar->getType();
12620 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12621 Scope *CurScope = getCurScope();
12622
12623 // Commonly used variables.
12624 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12625 OrigCntVar->getExprLoc());
12626 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12627 OrigCntVar->getExprLoc());
12628
12629 // For init-statement: auto .tile.iv = .floor.iv
12630 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12631 /*DirectInit=*/false);
12632 Decl *CounterDecl = TileIndVars[I];
12633 StmtResult InitStmt = new (Context)
12634 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12635 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12636 if (!InitStmt.isUsable())
12637 return StmtError();
12638
12639 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12640 // NumIterations)
12641 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12642 BO_Add, FloorIV, DimTileSize);
12643 if (!EndOfTile.isUsable())
12644 return StmtError();
12645 ExprResult IsPartialTile =
12646 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12647 NumIterations, EndOfTile.get());
12648 if (!IsPartialTile.isUsable())
12649 return StmtError();
12650 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12651 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12652 IsPartialTile.get(), NumIterations, EndOfTile.get());
12653 if (!MinTileAndIterSpace.isUsable())
12654 return StmtError();
12655 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12656 BO_LT, TileIV, MinTileAndIterSpace.get());
12657 if (!CondExpr.isUsable())
12658 return StmtError();
12659
12660 // For incr-statement: ++.tile.iv
12661 ExprResult IncrStmt =
12662 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12663 if (!IncrStmt.isUsable())
12664 return StmtError();
12665
12666 // Statements to set the original iteration variable's value from the
12667 // logical iteration number.
12668 // Generated for loop is:
12669 // Original_for_init;
12670 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12671 // NumIterations); ++.tile.iv) {
12672 // Original_Body;
12673 // Original_counter_update;
12674 // }
12675 // FIXME: If the innermost body is an loop itself, inserting these
12676 // statements stops it being recognized as a perfectly nested loop (e.g.
12677 // for applying tiling again). If this is the case, sink the expressions
12678 // further into the inner loop.
12679 SmallVector<Stmt *, 4> BodyParts;
12680 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12681 BodyParts.push_back(Inner);
12682 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12683 Inner->getEndLoc());
12684 Inner = new (Context)
12685 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12686 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12687 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12688 }
12689
12690 // Create floor loops from the inside to the outside.
12691 for (int I = NumLoops - 1; I >= 0; --I) {
12692 auto &LoopHelper = LoopHelpers[I];
12693 Expr *NumIterations = LoopHelper.NumIterations;
12694 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12695 QualType CntTy = OrigCntVar->getType();
12696 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12697 Scope *CurScope = getCurScope();
12698
12699 // Commonly used variables.
12700 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12701 OrigCntVar->getExprLoc());
12702
12703 // For init-statement: auto .floor.iv = 0
12704 AddInitializerToDecl(
12705 FloorIndVars[I],
12706 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12707 /*DirectInit=*/false);
12708 Decl *CounterDecl = FloorIndVars[I];
12709 StmtResult InitStmt = new (Context)
12710 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12711 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12712 if (!InitStmt.isUsable())
12713 return StmtError();
12714
12715 // For cond-expression: .floor.iv < NumIterations
12716 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12717 BO_LT, FloorIV, NumIterations);
12718 if (!CondExpr.isUsable())
12719 return StmtError();
12720
12721 // For incr-statement: .floor.iv += DimTileSize
12722 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12723 BO_AddAssign, FloorIV, DimTileSize);
12724 if (!IncrStmt.isUsable())
12725 return StmtError();
12726
12727 Inner = new (Context)
12728 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12729 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12730 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12731 }
12732
12733 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12734 AStmt, Inner,
12735 buildPreInits(Context, PreInits));
12736}
12737
12738OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
12739 SourceLocation StartLoc,
12740 SourceLocation LParenLoc,
12741 SourceLocation EndLoc) {
12742 OMPClause *Res = nullptr;
12743 switch (Kind) {
12744 case OMPC_final:
12745 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
12746 break;
12747 case OMPC_num_threads:
12748 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
12749 break;
12750 case OMPC_safelen:
12751 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
12752 break;
12753 case OMPC_simdlen:
12754 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
12755 break;
12756 case OMPC_allocator:
12757 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
12758 break;
12759 case OMPC_collapse:
12760 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
12761 break;
12762 case OMPC_ordered:
12763 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
12764 break;
12765 case OMPC_num_teams:
12766 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
12767 break;
12768 case OMPC_thread_limit:
12769 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
12770 break;
12771 case OMPC_priority:
12772 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
12773 break;
12774 case OMPC_grainsize:
12775 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
12776 break;
12777 case OMPC_num_tasks:
12778 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
12779 break;
12780 case OMPC_hint:
12781 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
12782 break;
12783 case OMPC_depobj:
12784 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
12785 break;
12786 case OMPC_detach:
12787 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
12788 break;
12789 case OMPC_novariants:
12790 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
12791 break;
12792 case OMPC_device:
12793 case OMPC_if:
12794 case OMPC_default:
12795 case OMPC_proc_bind:
12796 case OMPC_schedule:
12797 case OMPC_private:
12798 case OMPC_firstprivate:
12799 case OMPC_lastprivate:
12800 case OMPC_shared:
12801 case OMPC_reduction:
12802 case OMPC_task_reduction:
12803 case OMPC_in_reduction:
12804 case OMPC_linear:
12805 case OMPC_aligned:
12806 case OMPC_copyin:
12807 case OMPC_copyprivate:
12808 case OMPC_nowait:
12809 case OMPC_untied:
12810 case OMPC_mergeable:
12811 case OMPC_threadprivate:
12812 case OMPC_sizes:
12813 case OMPC_allocate:
12814 case OMPC_flush:
12815 case OMPC_read:
12816 case OMPC_write:
12817 case OMPC_update:
12818 case OMPC_capture:
12819 case OMPC_seq_cst:
12820 case OMPC_acq_rel:
12821 case OMPC_acquire:
12822 case OMPC_release:
12823 case OMPC_relaxed:
12824 case OMPC_depend:
12825 case OMPC_threads:
12826 case OMPC_simd:
12827 case OMPC_map:
12828 case OMPC_nogroup:
12829 case OMPC_dist_schedule:
12830 case OMPC_defaultmap:
12831 case OMPC_unknown:
12832 case OMPC_uniform:
12833 case OMPC_to:
12834 case OMPC_from:
12835 case OMPC_use_device_ptr:
12836 case OMPC_use_device_addr:
12837 case OMPC_is_device_ptr:
12838 case OMPC_unified_address:
12839 case OMPC_unified_shared_memory:
12840 case OMPC_reverse_offload:
12841 case OMPC_dynamic_allocators:
12842 case OMPC_atomic_default_mem_order:
12843 case OMPC_device_type:
12844 case OMPC_match:
12845 case OMPC_nontemporal:
12846 case OMPC_order:
12847 case OMPC_destroy:
12848 case OMPC_inclusive:
12849 case OMPC_exclusive:
12850 case OMPC_uses_allocators:
12851 case OMPC_affinity:
12852 default:
12853 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 12853)
;
12854 }
12855 return Res;
12856}
12857
12858// An OpenMP directive such as 'target parallel' has two captured regions:
12859// for the 'target' and 'parallel' respectively. This function returns
12860// the region in which to capture expressions associated with a clause.
12861// A return value of OMPD_unknown signifies that the expression should not
12862// be captured.
12863static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
12864 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
12865 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
12866 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12867 switch (CKind) {
12868 case OMPC_if:
12869 switch (DKind) {
12870 case OMPD_target_parallel_for_simd:
12871 if (OpenMPVersion >= 50 &&
12872 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12873 CaptureRegion = OMPD_parallel;
12874 break;
12875 }
12876 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12877 case OMPD_target_parallel:
12878 case OMPD_target_parallel_for:
12879 // If this clause applies to the nested 'parallel' region, capture within
12880 // the 'target' region, otherwise do not capture.
12881 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12882 CaptureRegion = OMPD_target;
12883 break;
12884 case OMPD_target_teams_distribute_parallel_for_simd:
12885 if (OpenMPVersion >= 50 &&
12886 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12887 CaptureRegion = OMPD_parallel;
12888 break;
12889 }
12890 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12891 case OMPD_target_teams_distribute_parallel_for:
12892 // If this clause applies to the nested 'parallel' region, capture within
12893 // the 'teams' region, otherwise do not capture.
12894 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12895 CaptureRegion = OMPD_teams;
12896 break;
12897 case OMPD_teams_distribute_parallel_for_simd:
12898 if (OpenMPVersion >= 50 &&
12899 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12900 CaptureRegion = OMPD_parallel;
12901 break;
12902 }
12903 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12904 case OMPD_teams_distribute_parallel_for:
12905 CaptureRegion = OMPD_teams;
12906 break;
12907 case OMPD_target_update:
12908 case OMPD_target_enter_data:
12909 case OMPD_target_exit_data:
12910 CaptureRegion = OMPD_task;
12911 break;
12912 case OMPD_parallel_master_taskloop:
12913 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
12914 CaptureRegion = OMPD_parallel;
12915 break;
12916 case OMPD_parallel_master_taskloop_simd:
12917 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
12918 NameModifier == OMPD_taskloop) {
12919 CaptureRegion = OMPD_parallel;
12920 break;
12921 }
12922 if (OpenMPVersion <= 45)
12923 break;
12924 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12925 CaptureRegion = OMPD_taskloop;
12926 break;
12927 case OMPD_parallel_for_simd:
12928 if (OpenMPVersion <= 45)
12929 break;
12930 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12931 CaptureRegion = OMPD_parallel;
12932 break;
12933 case OMPD_taskloop_simd:
12934 case OMPD_master_taskloop_simd:
12935 if (OpenMPVersion <= 45)
12936 break;
12937 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12938 CaptureRegion = OMPD_taskloop;
12939 break;
12940 case OMPD_distribute_parallel_for_simd:
12941 if (OpenMPVersion <= 45)
12942 break;
12943 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12944 CaptureRegion = OMPD_parallel;
12945 break;
12946 case OMPD_target_simd:
12947 if (OpenMPVersion >= 50 &&
12948 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12949 CaptureRegion = OMPD_target;
12950 break;
12951 case OMPD_teams_distribute_simd:
12952 case OMPD_target_teams_distribute_simd:
12953 if (OpenMPVersion >= 50 &&
12954 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12955 CaptureRegion = OMPD_teams;
12956 break;
12957 case OMPD_cancel:
12958 case OMPD_parallel:
12959 case OMPD_parallel_master:
12960 case OMPD_parallel_sections:
12961 case OMPD_parallel_for:
12962 case OMPD_target:
12963 case OMPD_target_teams:
12964 case OMPD_target_teams_distribute:
12965 case OMPD_distribute_parallel_for:
12966 case OMPD_task:
12967 case OMPD_taskloop:
12968 case OMPD_master_taskloop:
12969 case OMPD_target_data:
12970 case OMPD_simd:
12971 case OMPD_for_simd:
12972 case OMPD_distribute_simd:
12973 // Do not capture if-clause expressions.
12974 break;
12975 case OMPD_threadprivate:
12976 case OMPD_allocate:
12977 case OMPD_taskyield:
12978 case OMPD_barrier:
12979 case OMPD_taskwait:
12980 case OMPD_cancellation_point:
12981 case OMPD_flush:
12982 case OMPD_depobj:
12983 case OMPD_scan:
12984 case OMPD_declare_reduction:
12985 case OMPD_declare_mapper:
12986 case OMPD_declare_simd:
12987 case OMPD_declare_variant:
12988 case OMPD_begin_declare_variant:
12989 case OMPD_end_declare_variant:
12990 case OMPD_declare_target:
12991 case OMPD_end_declare_target:
12992 case OMPD_teams:
12993 case OMPD_tile:
12994 case OMPD_for:
12995 case OMPD_sections:
12996 case OMPD_section:
12997 case OMPD_single:
12998 case OMPD_master:
12999 case OMPD_critical:
13000 case OMPD_taskgroup:
13001 case OMPD_distribute:
13002 case OMPD_ordered:
13003 case OMPD_atomic:
13004 case OMPD_teams_distribute:
13005 case OMPD_requires:
13006 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13006)
;
13007 case OMPD_unknown:
13008 default:
13009 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13009)
;
13010 }
13011 break;
13012 case OMPC_num_threads:
13013 switch (DKind) {
13014 case OMPD_target_parallel:
13015 case OMPD_target_parallel_for:
13016 case OMPD_target_parallel_for_simd:
13017 CaptureRegion = OMPD_target;
13018 break;
13019 case OMPD_teams_distribute_parallel_for:
13020 case OMPD_teams_distribute_parallel_for_simd:
13021 case OMPD_target_teams_distribute_parallel_for:
13022 case OMPD_target_teams_distribute_parallel_for_simd:
13023 CaptureRegion = OMPD_teams;
13024 break;
13025 case OMPD_parallel:
13026 case OMPD_parallel_master:
13027 case OMPD_parallel_sections:
13028 case OMPD_parallel_for:
13029 case OMPD_parallel_for_simd:
13030 case OMPD_distribute_parallel_for:
13031 case OMPD_distribute_parallel_for_simd:
13032 case OMPD_parallel_master_taskloop:
13033 case OMPD_parallel_master_taskloop_simd:
13034 // Do not capture num_threads-clause expressions.
13035 break;
13036 case OMPD_target_data:
13037 case OMPD_target_enter_data:
13038 case OMPD_target_exit_data:
13039 case OMPD_target_update:
13040 case OMPD_target:
13041 case OMPD_target_simd:
13042 case OMPD_target_teams:
13043 case OMPD_target_teams_distribute:
13044 case OMPD_target_teams_distribute_simd:
13045 case OMPD_cancel:
13046 case OMPD_task:
13047 case OMPD_taskloop:
13048 case OMPD_taskloop_simd:
13049 case OMPD_master_taskloop:
13050 case OMPD_master_taskloop_simd:
13051 case OMPD_threadprivate:
13052 case OMPD_allocate:
13053 case OMPD_taskyield:
13054 case OMPD_barrier:
13055 case OMPD_taskwait:
13056 case OMPD_cancellation_point:
13057 case OMPD_flush:
13058 case OMPD_depobj:
13059 case OMPD_scan:
13060 case OMPD_declare_reduction:
13061 case OMPD_declare_mapper:
13062 case OMPD_declare_simd:
13063 case OMPD_declare_variant:
13064 case OMPD_begin_declare_variant:
13065 case OMPD_end_declare_variant:
13066 case OMPD_declare_target:
13067 case OMPD_end_declare_target:
13068 case OMPD_teams:
13069 case OMPD_simd:
13070 case OMPD_tile:
13071 case OMPD_for:
13072 case OMPD_for_simd:
13073 case OMPD_sections:
13074 case OMPD_section:
13075 case OMPD_single:
13076 case OMPD_master:
13077 case OMPD_critical:
13078 case OMPD_taskgroup:
13079 case OMPD_distribute:
13080 case OMPD_ordered:
13081 case OMPD_atomic:
13082 case OMPD_distribute_simd:
13083 case OMPD_teams_distribute:
13084 case OMPD_teams_distribute_simd:
13085 case OMPD_requires:
13086 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13086)
;
13087 case OMPD_unknown:
13088 default:
13089 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13089)
;
13090 }
13091 break;
13092 case OMPC_num_teams:
13093 switch (DKind) {
13094 case OMPD_target_teams:
13095 case OMPD_target_teams_distribute:
13096 case OMPD_target_teams_distribute_simd:
13097 case OMPD_target_teams_distribute_parallel_for:
13098 case OMPD_target_teams_distribute_parallel_for_simd:
13099 CaptureRegion = OMPD_target;
13100 break;
13101 case OMPD_teams_distribute_parallel_for:
13102 case OMPD_teams_distribute_parallel_for_simd:
13103 case OMPD_teams:
13104 case OMPD_teams_distribute:
13105 case OMPD_teams_distribute_simd:
13106 // Do not capture num_teams-clause expressions.
13107 break;
13108 case OMPD_distribute_parallel_for:
13109 case OMPD_distribute_parallel_for_simd:
13110 case OMPD_task:
13111 case OMPD_taskloop:
13112 case OMPD_taskloop_simd:
13113 case OMPD_master_taskloop:
13114 case OMPD_master_taskloop_simd:
13115 case OMPD_parallel_master_taskloop:
13116 case OMPD_parallel_master_taskloop_simd:
13117 case OMPD_target_data:
13118 case OMPD_target_enter_data:
13119 case OMPD_target_exit_data:
13120 case OMPD_target_update:
13121 case OMPD_cancel:
13122 case OMPD_parallel:
13123 case OMPD_parallel_master:
13124 case OMPD_parallel_sections:
13125 case OMPD_parallel_for:
13126 case OMPD_parallel_for_simd:
13127 case OMPD_target:
13128 case OMPD_target_simd:
13129 case OMPD_target_parallel:
13130 case OMPD_target_parallel_for:
13131 case OMPD_target_parallel_for_simd:
13132 case OMPD_threadprivate:
13133 case OMPD_allocate:
13134 case OMPD_taskyield:
13135 case OMPD_barrier:
13136 case OMPD_taskwait:
13137 case OMPD_cancellation_point:
13138 case OMPD_flush:
13139 case OMPD_depobj:
13140 case OMPD_scan:
13141 case OMPD_declare_reduction:
13142 case OMPD_declare_mapper:
13143 case OMPD_declare_simd:
13144 case OMPD_declare_variant:
13145 case OMPD_begin_declare_variant:
13146 case OMPD_end_declare_variant:
13147 case OMPD_declare_target:
13148 case OMPD_end_declare_target:
13149 case OMPD_simd:
13150 case OMPD_tile:
13151 case OMPD_for:
13152 case OMPD_for_simd:
13153 case OMPD_sections:
13154 case OMPD_section:
13155 case OMPD_single:
13156 case OMPD_master:
13157 case OMPD_critical:
13158 case OMPD_taskgroup:
13159 case OMPD_distribute:
13160 case OMPD_ordered:
13161 case OMPD_atomic:
13162 case OMPD_distribute_simd:
13163 case OMPD_requires:
13164 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13164)
;
13165 case OMPD_unknown:
13166 default:
13167 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13167)
;
13168 }
13169 break;
13170 case OMPC_thread_limit:
13171 switch (DKind) {
13172 case OMPD_target_teams:
13173 case OMPD_target_teams_distribute:
13174 case OMPD_target_teams_distribute_simd:
13175 case OMPD_target_teams_distribute_parallel_for:
13176 case OMPD_target_teams_distribute_parallel_for_simd:
13177 CaptureRegion = OMPD_target;
13178 break;
13179 case OMPD_teams_distribute_parallel_for:
13180 case OMPD_teams_distribute_parallel_for_simd:
13181 case OMPD_teams:
13182 case OMPD_teams_distribute:
13183 case OMPD_teams_distribute_simd:
13184 // Do not capture thread_limit-clause expressions.
13185 break;
13186 case OMPD_distribute_parallel_for:
13187 case OMPD_distribute_parallel_for_simd:
13188 case OMPD_task:
13189 case OMPD_taskloop:
13190 case OMPD_taskloop_simd:
13191 case OMPD_master_taskloop:
13192 case OMPD_master_taskloop_simd:
13193 case OMPD_parallel_master_taskloop:
13194 case OMPD_parallel_master_taskloop_simd:
13195 case OMPD_target_data:
13196 case OMPD_target_enter_data:
13197 case OMPD_target_exit_data:
13198 case OMPD_target_update:
13199 case OMPD_cancel:
13200 case OMPD_parallel:
13201 case OMPD_parallel_master:
13202 case OMPD_parallel_sections:
13203 case OMPD_parallel_for:
13204 case OMPD_parallel_for_simd:
13205 case OMPD_target:
13206 case OMPD_target_simd:
13207 case OMPD_target_parallel:
13208 case OMPD_target_parallel_for:
13209 case OMPD_target_parallel_for_simd:
13210 case OMPD_threadprivate:
13211 case OMPD_allocate:
13212 case OMPD_taskyield:
13213 case OMPD_barrier:
13214 case OMPD_taskwait:
13215 case OMPD_cancellation_point:
13216 case OMPD_flush:
13217 case OMPD_depobj:
13218 case OMPD_scan:
13219 case OMPD_declare_reduction:
13220 case OMPD_declare_mapper:
13221 case OMPD_declare_simd:
13222 case OMPD_declare_variant:
13223 case OMPD_begin_declare_variant:
13224 case OMPD_end_declare_variant:
13225 case OMPD_declare_target:
13226 case OMPD_end_declare_target:
13227 case OMPD_simd:
13228 case OMPD_tile:
13229 case OMPD_for:
13230 case OMPD_for_simd:
13231 case OMPD_sections:
13232 case OMPD_section:
13233 case OMPD_single:
13234 case OMPD_master:
13235 case OMPD_critical:
13236 case OMPD_taskgroup:
13237 case OMPD_distribute:
13238 case OMPD_ordered:
13239 case OMPD_atomic:
13240 case OMPD_distribute_simd:
13241 case OMPD_requires:
13242 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13242)
;
13243 case OMPD_unknown:
13244 default:
13245 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13245)
;
13246 }
13247 break;
13248 case OMPC_schedule:
13249 switch (DKind) {
13250 case OMPD_parallel_for:
13251 case OMPD_parallel_for_simd:
13252 case OMPD_distribute_parallel_for:
13253 case OMPD_distribute_parallel_for_simd:
13254 case OMPD_teams_distribute_parallel_for:
13255 case OMPD_teams_distribute_parallel_for_simd:
13256 case OMPD_target_parallel_for:
13257 case OMPD_target_parallel_for_simd:
13258 case OMPD_target_teams_distribute_parallel_for:
13259 case OMPD_target_teams_distribute_parallel_for_simd:
13260 CaptureRegion = OMPD_parallel;
13261 break;
13262 case OMPD_for:
13263 case OMPD_for_simd:
13264 // Do not capture schedule-clause expressions.
13265 break;
13266 case OMPD_task:
13267 case OMPD_taskloop:
13268 case OMPD_taskloop_simd:
13269 case OMPD_master_taskloop:
13270 case OMPD_master_taskloop_simd:
13271 case OMPD_parallel_master_taskloop:
13272 case OMPD_parallel_master_taskloop_simd:
13273 case OMPD_target_data:
13274 case OMPD_target_enter_data:
13275 case OMPD_target_exit_data:
13276 case OMPD_target_update:
13277 case OMPD_teams:
13278 case OMPD_teams_distribute:
13279 case OMPD_teams_distribute_simd:
13280 case OMPD_target_teams_distribute:
13281 case OMPD_target_teams_distribute_simd:
13282 case OMPD_target:
13283 case OMPD_target_simd:
13284 case OMPD_target_parallel:
13285 case OMPD_cancel:
13286 case OMPD_parallel:
13287 case OMPD_parallel_master:
13288 case OMPD_parallel_sections:
13289 case OMPD_threadprivate:
13290 case OMPD_allocate:
13291 case OMPD_taskyield:
13292 case OMPD_barrier:
13293 case OMPD_taskwait:
13294 case OMPD_cancellation_point:
13295 case OMPD_flush:
13296 case OMPD_depobj:
13297 case OMPD_scan:
13298 case OMPD_declare_reduction:
13299 case OMPD_declare_mapper:
13300 case OMPD_declare_simd:
13301 case OMPD_declare_variant:
13302 case OMPD_begin_declare_variant:
13303 case OMPD_end_declare_variant:
13304 case OMPD_declare_target:
13305 case OMPD_end_declare_target:
13306 case OMPD_simd:
13307 case OMPD_tile:
13308 case OMPD_sections:
13309 case OMPD_section:
13310 case OMPD_single:
13311 case OMPD_master:
13312 case OMPD_critical:
13313 case OMPD_taskgroup:
13314 case OMPD_distribute:
13315 case OMPD_ordered:
13316 case OMPD_atomic:
13317 case OMPD_distribute_simd:
13318 case OMPD_target_teams:
13319 case OMPD_requires:
13320 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13320)
;
13321 case OMPD_unknown:
13322 default:
13323 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13323)
;
13324 }
13325 break;
13326 case OMPC_dist_schedule:
13327 switch (DKind) {
13328 case OMPD_teams_distribute_parallel_for:
13329 case OMPD_teams_distribute_parallel_for_simd:
13330 case OMPD_teams_distribute:
13331 case OMPD_teams_distribute_simd:
13332 case OMPD_target_teams_distribute_parallel_for:
13333 case OMPD_target_teams_distribute_parallel_for_simd:
13334 case OMPD_target_teams_distribute:
13335 case OMPD_target_teams_distribute_simd:
13336 CaptureRegion = OMPD_teams;
13337 break;
13338 case OMPD_distribute_parallel_for:
13339 case OMPD_distribute_parallel_for_simd:
13340 case OMPD_distribute:
13341 case OMPD_distribute_simd:
13342 // Do not capture dist_schedule-clause expressions.
13343 break;
13344 case OMPD_parallel_for:
13345 case OMPD_parallel_for_simd:
13346 case OMPD_target_parallel_for_simd:
13347 case OMPD_target_parallel_for:
13348 case OMPD_task:
13349 case OMPD_taskloop:
13350 case OMPD_taskloop_simd:
13351 case OMPD_master_taskloop:
13352 case OMPD_master_taskloop_simd:
13353 case OMPD_parallel_master_taskloop:
13354 case OMPD_parallel_master_taskloop_simd:
13355 case OMPD_target_data:
13356 case OMPD_target_enter_data:
13357 case OMPD_target_exit_data:
13358 case OMPD_target_update:
13359 case OMPD_teams:
13360 case OMPD_target:
13361 case OMPD_target_simd:
13362 case OMPD_target_parallel:
13363 case OMPD_cancel:
13364 case OMPD_parallel:
13365 case OMPD_parallel_master:
13366 case OMPD_parallel_sections:
13367 case OMPD_threadprivate:
13368 case OMPD_allocate:
13369 case OMPD_taskyield:
13370 case OMPD_barrier:
13371 case OMPD_taskwait:
13372 case OMPD_cancellation_point:
13373 case OMPD_flush:
13374 case OMPD_depobj:
13375 case OMPD_scan:
13376 case OMPD_declare_reduction:
13377 case OMPD_declare_mapper:
13378 case OMPD_declare_simd:
13379 case OMPD_declare_variant:
13380 case OMPD_begin_declare_variant:
13381 case OMPD_end_declare_variant:
13382 case OMPD_declare_target:
13383 case OMPD_end_declare_target:
13384 case OMPD_simd:
13385 case OMPD_tile:
13386 case OMPD_for:
13387 case OMPD_for_simd:
13388 case OMPD_sections:
13389 case OMPD_section:
13390 case OMPD_single:
13391 case OMPD_master:
13392 case OMPD_critical:
13393 case OMPD_taskgroup:
13394 case OMPD_ordered:
13395 case OMPD_atomic:
13396 case OMPD_target_teams:
13397 case OMPD_requires:
13398 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13398)
;
13399 case OMPD_unknown:
13400 default:
13401 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13401)
;
13402 }
13403 break;
13404 case OMPC_device:
13405 switch (DKind) {
13406 case OMPD_target_update:
13407 case OMPD_target_enter_data:
13408 case OMPD_target_exit_data:
13409 case OMPD_target:
13410 case OMPD_target_simd:
13411 case OMPD_target_teams:
13412 case OMPD_target_parallel:
13413 case OMPD_target_teams_distribute:
13414 case OMPD_target_teams_distribute_simd:
13415 case OMPD_target_parallel_for:
13416 case OMPD_target_parallel_for_simd:
13417 case OMPD_target_teams_distribute_parallel_for:
13418 case OMPD_target_teams_distribute_parallel_for_simd:
13419 case OMPD_dispatch:
13420 CaptureRegion = OMPD_task;
13421 break;
13422 case OMPD_target_data:
13423 case OMPD_interop:
13424 // Do not capture device-clause expressions.
13425 break;
13426 case OMPD_teams_distribute_parallel_for:
13427 case OMPD_teams_distribute_parallel_for_simd:
13428 case OMPD_teams:
13429 case OMPD_teams_distribute:
13430 case OMPD_teams_distribute_simd:
13431 case OMPD_distribute_parallel_for:
13432 case OMPD_distribute_parallel_for_simd:
13433 case OMPD_task:
13434 case OMPD_taskloop:
13435 case OMPD_taskloop_simd:
13436 case OMPD_master_taskloop:
13437 case OMPD_master_taskloop_simd:
13438 case OMPD_parallel_master_taskloop:
13439 case OMPD_parallel_master_taskloop_simd:
13440 case OMPD_cancel:
13441 case OMPD_parallel:
13442 case OMPD_parallel_master:
13443 case OMPD_parallel_sections:
13444 case OMPD_parallel_for:
13445 case OMPD_parallel_for_simd:
13446 case OMPD_threadprivate:
13447 case OMPD_allocate:
13448 case OMPD_taskyield:
13449 case OMPD_barrier:
13450 case OMPD_taskwait:
13451 case OMPD_cancellation_point:
13452 case OMPD_flush:
13453 case OMPD_depobj:
13454 case OMPD_scan:
13455 case OMPD_declare_reduction:
13456 case OMPD_declare_mapper:
13457 case OMPD_declare_simd:
13458 case OMPD_declare_variant:
13459 case OMPD_begin_declare_variant:
13460 case OMPD_end_declare_variant:
13461 case OMPD_declare_target:
13462 case OMPD_end_declare_target:
13463 case OMPD_simd:
13464 case OMPD_tile:
13465 case OMPD_for:
13466 case OMPD_for_simd:
13467 case OMPD_sections:
13468 case OMPD_section:
13469 case OMPD_single:
13470 case OMPD_master:
13471 case OMPD_critical:
13472 case OMPD_taskgroup:
13473 case OMPD_distribute:
13474 case OMPD_ordered:
13475 case OMPD_atomic:
13476 case OMPD_distribute_simd:
13477 case OMPD_requires:
13478 llvm_unreachable("Unexpected OpenMP directive with device-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with device-clause"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13478)
;
13479 case OMPD_unknown:
13480 default:
13481 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13481)
;
13482 }
13483 break;
13484 case OMPC_grainsize:
13485 case OMPC_num_tasks:
13486 case OMPC_final:
13487 case OMPC_priority:
13488 switch (DKind) {
13489 case OMPD_task:
13490 case OMPD_taskloop:
13491 case OMPD_taskloop_simd:
13492 case OMPD_master_taskloop:
13493 case OMPD_master_taskloop_simd:
13494 break;
13495 case OMPD_parallel_master_taskloop:
13496 case OMPD_parallel_master_taskloop_simd:
13497 CaptureRegion = OMPD_parallel;
13498 break;
13499 case OMPD_target_update:
13500 case OMPD_target_enter_data:
13501 case OMPD_target_exit_data:
13502 case OMPD_target:
13503 case OMPD_target_simd:
13504 case OMPD_target_teams:
13505 case OMPD_target_parallel:
13506 case OMPD_target_teams_distribute:
13507 case OMPD_target_teams_distribute_simd:
13508 case OMPD_target_parallel_for:
13509 case OMPD_target_parallel_for_simd:
13510 case OMPD_target_teams_distribute_parallel_for:
13511 case OMPD_target_teams_distribute_parallel_for_simd:
13512 case OMPD_target_data:
13513 case OMPD_teams_distribute_parallel_for:
13514 case OMPD_teams_distribute_parallel_for_simd:
13515 case OMPD_teams:
13516 case OMPD_teams_distribute:
13517 case OMPD_teams_distribute_simd:
13518 case OMPD_distribute_parallel_for:
13519 case OMPD_distribute_parallel_for_simd:
13520 case OMPD_cancel:
13521 case OMPD_parallel:
13522 case OMPD_parallel_master:
13523 case OMPD_parallel_sections:
13524 case OMPD_parallel_for:
13525 case OMPD_parallel_for_simd:
13526 case OMPD_threadprivate:
13527 case OMPD_allocate:
13528 case OMPD_taskyield:
13529 case OMPD_barrier:
13530 case OMPD_taskwait:
13531 case OMPD_cancellation_point:
13532 case OMPD_flush:
13533 case OMPD_depobj:
13534 case OMPD_scan:
13535 case OMPD_declare_reduction:
13536 case OMPD_declare_mapper:
13537 case OMPD_declare_simd:
13538 case OMPD_declare_variant:
13539 case OMPD_begin_declare_variant:
13540 case OMPD_end_declare_variant:
13541 case OMPD_declare_target:
13542 case OMPD_end_declare_target:
13543 case OMPD_simd:
13544 case OMPD_tile:
13545 case OMPD_for:
13546 case OMPD_for_simd:
13547 case OMPD_sections:
13548 case OMPD_section:
13549 case OMPD_single:
13550 case OMPD_master:
13551 case OMPD_critical:
13552 case OMPD_taskgroup:
13553 case OMPD_distribute:
13554 case OMPD_ordered:
13555 case OMPD_atomic:
13556 case OMPD_distribute_simd:
13557 case OMPD_requires:
13558 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13558)
;
13559 case OMPD_unknown:
13560 default:
13561 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13561)
;
13562 }
13563 break;
13564 case OMPC_novariants:
13565 switch (DKind) {
13566 case OMPD_dispatch:
13567 CaptureRegion = OMPD_task;
13568 break;
13569 default:
13570 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13570)
;
13571 }
13572 break;
13573 case OMPC_firstprivate:
13574 case OMPC_lastprivate:
13575 case OMPC_reduction:
13576 case OMPC_task_reduction:
13577 case OMPC_in_reduction:
13578 case OMPC_linear:
13579 case OMPC_default:
13580 case OMPC_proc_bind:
13581 case OMPC_safelen:
13582 case OMPC_simdlen:
13583 case OMPC_sizes:
13584 case OMPC_allocator:
13585 case OMPC_collapse:
13586 case OMPC_private:
13587 case OMPC_shared:
13588 case OMPC_aligned:
13589 case OMPC_copyin:
13590 case OMPC_copyprivate:
13591 case OMPC_ordered:
13592 case OMPC_nowait:
13593 case OMPC_untied:
13594 case OMPC_mergeable:
13595 case OMPC_threadprivate:
13596 case OMPC_allocate:
13597 case OMPC_flush:
13598 case OMPC_depobj:
13599 case OMPC_read:
13600 case OMPC_write:
13601 case OMPC_update:
13602 case OMPC_capture:
13603 case OMPC_seq_cst:
13604 case OMPC_acq_rel:
13605 case OMPC_acquire:
13606 case OMPC_release:
13607 case OMPC_relaxed:
13608 case OMPC_depend:
13609 case OMPC_threads:
13610 case OMPC_simd:
13611 case OMPC_map:
13612 case OMPC_nogroup:
13613 case OMPC_hint:
13614 case OMPC_defaultmap:
13615 case OMPC_unknown:
13616 case OMPC_uniform:
13617 case OMPC_to:
13618 case OMPC_from:
13619 case OMPC_use_device_ptr:
13620 case OMPC_use_device_addr:
13621 case OMPC_is_device_ptr:
13622 case OMPC_unified_address:
13623 case OMPC_unified_shared_memory:
13624 case OMPC_reverse_offload:
13625 case OMPC_dynamic_allocators:
13626 case OMPC_atomic_default_mem_order:
13627 case OMPC_device_type:
13628 case OMPC_match:
13629 case OMPC_nontemporal:
13630 case OMPC_order:
13631 case OMPC_destroy:
13632 case OMPC_detach:
13633 case OMPC_inclusive:
13634 case OMPC_exclusive:
13635 case OMPC_uses_allocators:
13636 case OMPC_affinity:
13637 default:
13638 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13638)
;
13639 }
13640 return CaptureRegion;
13641}
13642
13643OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
13644 Expr *Condition, SourceLocation StartLoc,
13645 SourceLocation LParenLoc,
13646 SourceLocation NameModifierLoc,
13647 SourceLocation ColonLoc,
13648 SourceLocation EndLoc) {
13649 Expr *ValExpr = Condition;
13650 Stmt *HelperValStmt = nullptr;
13651 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13652 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13653 !Condition->isInstantiationDependent() &&
13654 !Condition->containsUnexpandedParameterPack()) {
13655 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13656 if (Val.isInvalid())
13657 return nullptr;
13658
13659 ValExpr = Val.get();
13660
13661 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13662 CaptureRegion = getOpenMPCaptureRegionForClause(
13663 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
13664 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13665 ValExpr = MakeFullExpr(ValExpr).get();
13666 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13667 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13668 HelperValStmt = buildPreInits(Context, Captures);
13669 }
13670 }
13671
13672 return new (Context)
13673 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
13674 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
13675}
13676
13677OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
13678 SourceLocation StartLoc,
13679 SourceLocation LParenLoc,
13680 SourceLocation EndLoc) {
13681 Expr *ValExpr = Condition;
13682 Stmt *HelperValStmt = nullptr;
13683 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13684 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13685 !Condition->isInstantiationDependent() &&
13686 !Condition->containsUnexpandedParameterPack()) {
13687 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13688 if (Val.isInvalid())
13689 return nullptr;
13690
13691 ValExpr = MakeFullExpr(Val.get()).get();
13692
13693 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13694 CaptureRegion =
13695 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
13696 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13697 ValExpr = MakeFullExpr(ValExpr).get();
13698 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13699 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13700 HelperValStmt = buildPreInits(Context, Captures);
13701 }
13702 }
13703
13704 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
13705 StartLoc, LParenLoc, EndLoc);
13706}
13707
13708ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
13709 Expr *Op) {
13710 if (!Op)
13711 return ExprError();
13712
13713 class IntConvertDiagnoser : public ICEConvertDiagnoser {
13714 public:
13715 IntConvertDiagnoser()
13716 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
13717 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
13718 QualType T) override {
13719 return S.Diag(Loc, diag::err_omp_not_integral) << T;
13720 }
13721 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
13722 QualType T) override {
13723 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
13724 }
13725 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
13726 QualType T,
13727 QualType ConvTy) override {
13728 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
13729 }
13730 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
13731 QualType ConvTy) override {
13732 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13733 << ConvTy->isEnumeralType() << ConvTy;
13734 }
13735 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
13736 QualType T) override {
13737 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
13738 }
13739 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
13740 QualType ConvTy) override {
13741 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13742 << ConvTy->isEnumeralType() << ConvTy;
13743 }
13744 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
13745 QualType) override {
13746 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 13746)
;
13747 }
13748 } ConvertDiagnoser;
13749 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
13750}
13751
13752static bool
13753isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
13754 bool StrictlyPositive, bool BuildCapture = false,
13755 OpenMPDirectiveKind DKind = OMPD_unknown,
13756 OpenMPDirectiveKind *CaptureRegion = nullptr,
13757 Stmt **HelperValStmt = nullptr) {
13758 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
13759 !ValExpr->isInstantiationDependent()) {
13760 SourceLocation Loc = ValExpr->getExprLoc();
13761 ExprResult Value =
13762 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
13763 if (Value.isInvalid())
13764 return false;
13765
13766 ValExpr = Value.get();
13767 // The expression must evaluate to a non-negative integer value.
13768 if (Optional<llvm::APSInt> Result =
13769 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
13770 if (Result->isSigned() &&
13771 !((!StrictlyPositive && Result->isNonNegative()) ||
13772 (StrictlyPositive && Result->isStrictlyPositive()))) {
13773 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
13774 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13775 << ValExpr->getSourceRange();
13776 return false;
13777 }
13778 }
13779 if (!BuildCapture)
13780 return true;
13781 *CaptureRegion =
13782 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
13783 if (*CaptureRegion != OMPD_unknown &&
13784 !SemaRef.CurContext->isDependentContext()) {
13785 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
13786 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13787 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
13788 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
13789 }
13790 }
13791 return true;
13792}
13793
13794OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
13795 SourceLocation StartLoc,
13796 SourceLocation LParenLoc,
13797 SourceLocation EndLoc) {
13798 Expr *ValExpr = NumThreads;
13799 Stmt *HelperValStmt = nullptr;
13800
13801 // OpenMP [2.5, Restrictions]
13802 // The num_threads expression must evaluate to a positive integer value.
13803 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
13804 /*StrictlyPositive=*/true))
13805 return nullptr;
13806
13807 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13808 OpenMPDirectiveKind CaptureRegion =
13809 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
13810 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13811 ValExpr = MakeFullExpr(ValExpr).get();
13812 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13813 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13814 HelperValStmt = buildPreInits(Context, Captures);
13815 }
13816
13817 return new (Context) OMPNumThreadsClause(
13818 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13819}
13820
13821ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
13822 OpenMPClauseKind CKind,
13823 bool StrictlyPositive) {
13824 if (!E)
13825 return ExprError();
13826 if (E->isValueDependent() || E->isTypeDependent() ||
13827 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
13828 return E;
13829 llvm::APSInt Result;
13830 ExprResult ICE =
13831 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
13832 if (ICE.isInvalid())
13833 return ExprError();
13834 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
13835 (!StrictlyPositive && !Result.isNonNegative())) {
13836 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
13837 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13838 << E->getSourceRange();
13839 return ExprError();
13840 }
13841 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
13842 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
13843 << E->getSourceRange();
13844 return ExprError();
13845 }
13846 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
13847 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
13848 else if (CKind == OMPC_ordered)
13849 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
13850 return ICE;
13851}
13852
13853OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
13854 SourceLocation LParenLoc,
13855 SourceLocation EndLoc) {
13856 // OpenMP [2.8.1, simd construct, Description]
13857 // The parameter of the safelen clause must be a constant
13858 // positive integer expression.
13859 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
13860 if (Safelen.isInvalid())
13861 return nullptr;
13862 return new (Context)
13863 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
13864}
13865
13866OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
13867 SourceLocation LParenLoc,
13868 SourceLocation EndLoc) {
13869 // OpenMP [2.8.1, simd construct, Description]
13870 // The parameter of the simdlen clause must be a constant
13871 // positive integer expression.
13872 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
13873 if (Simdlen.isInvalid())
13874 return nullptr;
13875 return new (Context)
13876 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
13877}
13878
13879/// Tries to find omp_allocator_handle_t type.
13880static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
13881 DSAStackTy *Stack) {
13882 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
13883 if (!OMPAllocatorHandleT.isNull())
13884 return true;
13885 // Build the predefined allocator expressions.
13886 bool ErrorFound = false;
13887 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
13888 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
13889 StringRef Allocator =
13890 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
13891 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
13892 auto *VD = dyn_cast_or_null<ValueDecl>(
13893 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
13894 if (!VD) {
13895 ErrorFound = true;
13896 break;
13897 }
13898 QualType AllocatorType =
13899 VD->getType().getNonLValueExprType(S.getASTContext());
13900 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
13901 if (!Res.isUsable()) {
13902 ErrorFound = true;
13903 break;
13904 }
13905 if (OMPAllocatorHandleT.isNull())
13906 OMPAllocatorHandleT = AllocatorType;
13907 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
13908 ErrorFound = true;
13909 break;
13910 }
13911 Stack->setAllocator(AllocatorKind, Res.get());
13912 }
13913 if (ErrorFound) {
13914 S.Diag(Loc, diag::err_omp_implied_type_not_found)
13915 << "omp_allocator_handle_t";
13916 return false;
13917 }
13918 OMPAllocatorHandleT.addConst();
13919 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
13920 return true;
13921}
13922
13923OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
13924 SourceLocation LParenLoc,
13925 SourceLocation EndLoc) {
13926 // OpenMP [2.11.3, allocate Directive, Description]
13927 // allocator is an expression of omp_allocator_handle_t type.
13928 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13929 return nullptr;
13930
13931 ExprResult Allocator = DefaultLvalueConversion(A);
13932 if (Allocator.isInvalid())
13933 return nullptr;
13934 Allocator = PerformImplicitConversion(Allocator.get(),
13935 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
13936 Sema::AA_Initializing,
13937 /*AllowExplicit=*/true);
13938 if (Allocator.isInvalid())
13939 return nullptr;
13940 return new (Context)
13941 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
13942}
13943
13944OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
13945 SourceLocation StartLoc,
13946 SourceLocation LParenLoc,
13947 SourceLocation EndLoc) {
13948 // OpenMP [2.7.1, loop construct, Description]
13949 // OpenMP [2.8.1, simd construct, Description]
13950 // OpenMP [2.9.6, distribute construct, Description]
13951 // The parameter of the collapse clause must be a constant
13952 // positive integer expression.
13953 ExprResult NumForLoopsResult =
13954 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
13955 if (NumForLoopsResult.isInvalid())
13956 return nullptr;
13957 return new (Context)
13958 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
13959}
13960
13961OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
13962 SourceLocation EndLoc,
13963 SourceLocation LParenLoc,
13964 Expr *NumForLoops) {
13965 // OpenMP [2.7.1, loop construct, Description]
13966 // OpenMP [2.8.1, simd construct, Description]
13967 // OpenMP [2.9.6, distribute construct, Description]
13968 // The parameter of the ordered clause must be a constant
13969 // positive integer expression if any.
13970 if (NumForLoops && LParenLoc.isValid()) {
13971 ExprResult NumForLoopsResult =
13972 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
13973 if (NumForLoopsResult.isInvalid())
13974 return nullptr;
13975 NumForLoops = NumForLoopsResult.get();
13976 } else {
13977 NumForLoops = nullptr;
13978 }
13979 auto *Clause = OMPOrderedClause::Create(
13980 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
13981 StartLoc, LParenLoc, EndLoc);
13982 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
13983 return Clause;
13984}
13985
13986OMPClause *Sema::ActOnOpenMPSimpleClause(
13987 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
13988 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13989 OMPClause *Res = nullptr;
13990 switch (Kind) {
13991 case OMPC_default:
13992 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
13993 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13994 break;
13995 case OMPC_proc_bind:
13996 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
13997 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13998 break;
13999 case OMPC_atomic_default_mem_order:
14000 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
14001 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
14002 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14003 break;
14004 case OMPC_order:
14005 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
14006 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14007 break;
14008 case OMPC_update:
14009 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
14010 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14011 break;
14012 case OMPC_if:
14013 case OMPC_final:
14014 case OMPC_num_threads:
14015 case OMPC_safelen:
14016 case OMPC_simdlen:
14017 case OMPC_sizes:
14018 case OMPC_allocator:
14019 case OMPC_collapse:
14020 case OMPC_schedule:
14021 case OMPC_private:
14022 case OMPC_firstprivate:
14023 case OMPC_lastprivate:
14024 case OMPC_shared:
14025 case OMPC_reduction:
14026 case OMPC_task_reduction:
14027 case OMPC_in_reduction:
14028 case OMPC_linear:
14029 case OMPC_aligned:
14030 case OMPC_copyin:
14031 case OMPC_copyprivate:
14032 case OMPC_ordered:
14033 case OMPC_nowait:
14034 case OMPC_untied:
14035 case OMPC_mergeable:
14036 case OMPC_threadprivate:
14037 case OMPC_allocate:
14038 case OMPC_flush:
14039 case OMPC_depobj:
14040 case OMPC_read:
14041 case OMPC_write:
14042 case OMPC_capture:
14043 case OMPC_seq_cst:
14044 case OMPC_acq_rel:
14045 case OMPC_acquire:
14046 case OMPC_release:
14047 case OMPC_relaxed:
14048 case OMPC_depend:
14049 case OMPC_device:
14050 case OMPC_threads:
14051 case OMPC_simd:
14052 case OMPC_map:
14053 case OMPC_num_teams:
14054 case OMPC_thread_limit:
14055 case OMPC_priority:
14056 case OMPC_grainsize:
14057 case OMPC_nogroup:
14058 case OMPC_num_tasks:
14059 case OMPC_hint:
14060 case OMPC_dist_schedule:
14061 case OMPC_defaultmap:
14062 case OMPC_unknown:
14063 case OMPC_uniform:
14064 case OMPC_to:
14065 case OMPC_from:
14066 case OMPC_use_device_ptr:
14067 case OMPC_use_device_addr:
14068 case OMPC_is_device_ptr:
14069 case OMPC_unified_address:
14070 case OMPC_unified_shared_memory:
14071 case OMPC_reverse_offload:
14072 case OMPC_dynamic_allocators:
14073 case OMPC_device_type:
14074 case OMPC_match:
14075 case OMPC_nontemporal:
14076 case OMPC_destroy:
14077 case OMPC_novariants:
14078 case OMPC_detach:
14079 case OMPC_inclusive:
14080 case OMPC_exclusive:
14081 case OMPC_uses_allocators:
14082 case OMPC_affinity:
14083 default:
14084 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14084)
;
14085 }
14086 return Res;
14087}
14088
14089static std::string
14090getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
14091 ArrayRef<unsigned> Exclude = llvm::None) {
14092 SmallString<256> Buffer;
14093 llvm::raw_svector_ostream Out(Buffer);
14094 unsigned Skipped = Exclude.size();
14095 auto S = Exclude.begin(), E = Exclude.end();
14096 for (unsigned I = First; I < Last; ++I) {
14097 if (std::find(S, E, I) != E) {
14098 --Skipped;
14099 continue;
14100 }
14101 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
14102 if (I + Skipped + 2 == Last)
14103 Out << " or ";
14104 else if (I + Skipped + 1 != Last)
14105 Out << ", ";
14106 }
14107 return std::string(Out.str());
14108}
14109
14110OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
14111 SourceLocation KindKwLoc,
14112 SourceLocation StartLoc,
14113 SourceLocation LParenLoc,
14114 SourceLocation EndLoc) {
14115 if (Kind == OMP_DEFAULT_unknown) {
14116 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14117 << getListOfPossibleValues(OMPC_default, /*First=*/0,
14118 /*Last=*/unsigned(OMP_DEFAULT_unknown))
14119 << getOpenMPClauseName(OMPC_default);
14120 return nullptr;
14121 }
14122
14123 switch (Kind) {
14124 case OMP_DEFAULT_none:
14125 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
14126 break;
14127 case OMP_DEFAULT_shared:
14128 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
14129 break;
14130 case OMP_DEFAULT_firstprivate:
14131 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
14132 break;
14133 default:
14134 llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14134)
;
14135 }
14136
14137 return new (Context)
14138 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14139}
14140
14141OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
14142 SourceLocation KindKwLoc,
14143 SourceLocation StartLoc,
14144 SourceLocation LParenLoc,
14145 SourceLocation EndLoc) {
14146 if (Kind == OMP_PROC_BIND_unknown) {
14147 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14148 << getListOfPossibleValues(OMPC_proc_bind,
14149 /*First=*/unsigned(OMP_PROC_BIND_master),
14150 /*Last=*/
14151 unsigned(LangOpts.OpenMP > 50
14152 ? OMP_PROC_BIND_primary
14153 : OMP_PROC_BIND_spread) +
14154 1)
14155 << getOpenMPClauseName(OMPC_proc_bind);
14156 return nullptr;
14157 }
14158 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
14159 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14160 << getListOfPossibleValues(OMPC_proc_bind,
14161 /*First=*/unsigned(OMP_PROC_BIND_master),
14162 /*Last=*/
14163 unsigned(OMP_PROC_BIND_spread) + 1)
14164 << getOpenMPClauseName(OMPC_proc_bind);
14165 return new (Context)
14166 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14167}
14168
14169OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
14170 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
14171 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14172 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
14173 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14174 << getListOfPossibleValues(
14175 OMPC_atomic_default_mem_order, /*First=*/0,
14176 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
14177 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
14178 return nullptr;
14179 }
14180 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
14181 LParenLoc, EndLoc);
14182}
14183
14184OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
14185 SourceLocation KindKwLoc,
14186 SourceLocation StartLoc,
14187 SourceLocation LParenLoc,
14188 SourceLocation EndLoc) {
14189 if (Kind == OMPC_ORDER_unknown) {
14190 static_assert(OMPC_ORDER_unknown > 0,
14191 "OMPC_ORDER_unknown not greater than 0");
14192 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14193 << getListOfPossibleValues(OMPC_order, /*First=*/0,
14194 /*Last=*/OMPC_ORDER_unknown)
14195 << getOpenMPClauseName(OMPC_order);
14196 return nullptr;
14197 }
14198 return new (Context)
14199 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14200}
14201
14202OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
14203 SourceLocation KindKwLoc,
14204 SourceLocation StartLoc,
14205 SourceLocation LParenLoc,
14206 SourceLocation EndLoc) {
14207 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
14208 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
14209 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
14210 OMPC_DEPEND_depobj};
14211 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14212 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14213 /*Last=*/OMPC_DEPEND_unknown, Except)
14214 << getOpenMPClauseName(OMPC_update);
14215 return nullptr;
14216 }
14217 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
14218 EndLoc);
14219}
14220
14221OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
14222 SourceLocation StartLoc,
14223 SourceLocation LParenLoc,
14224 SourceLocation EndLoc) {
14225 for (Expr *SizeExpr : SizeExprs) {
14226 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
14227 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
14228 if (!NumForLoopsResult.isUsable())
14229 return nullptr;
14230 }
14231
14232 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(SizeExprs.size());
14233 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14234 SizeExprs);
14235}
14236
14237OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
14238 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
14239 SourceLocation StartLoc, SourceLocation LParenLoc,
14240 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
14241 SourceLocation EndLoc) {
14242 OMPClause *Res = nullptr;
14243 switch (Kind) {
14244 case OMPC_schedule:
14245 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
14246 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14247, __PRETTY_FUNCTION__))
14247 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14247, __PRETTY_FUNCTION__))
;
14248 Res = ActOnOpenMPScheduleClause(
14249 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
14250 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
14251 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
14252 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
14253 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
14254 break;
14255 case OMPC_if:
14256 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14256, __PRETTY_FUNCTION__))
;
14257 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
14258 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
14259 DelimLoc, EndLoc);
14260 break;
14261 case OMPC_dist_schedule:
14262 Res = ActOnOpenMPDistScheduleClause(
14263 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
14264 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
14265 break;
14266 case OMPC_defaultmap:
14267 enum { Modifier, DefaultmapKind };
14268 Res = ActOnOpenMPDefaultmapClause(
14269 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
14270 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
14271 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
14272 EndLoc);
14273 break;
14274 case OMPC_device:
14275 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14275, __PRETTY_FUNCTION__))
;
14276 Res = ActOnOpenMPDeviceClause(
14277 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
14278 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
14279 break;
14280 case OMPC_final:
14281 case OMPC_num_threads:
14282 case OMPC_safelen:
14283 case OMPC_simdlen:
14284 case OMPC_sizes:
14285 case OMPC_allocator:
14286 case OMPC_collapse:
14287 case OMPC_default:
14288 case OMPC_proc_bind:
14289 case OMPC_private:
14290 case OMPC_firstprivate:
14291 case OMPC_lastprivate:
14292 case OMPC_shared:
14293 case OMPC_reduction:
14294 case OMPC_task_reduction:
14295 case OMPC_in_reduction:
14296 case OMPC_linear:
14297 case OMPC_aligned:
14298 case OMPC_copyin:
14299 case OMPC_copyprivate:
14300 case OMPC_ordered:
14301 case OMPC_nowait:
14302 case OMPC_untied:
14303 case OMPC_mergeable:
14304 case OMPC_threadprivate:
14305 case OMPC_allocate:
14306 case OMPC_flush:
14307 case OMPC_depobj:
14308 case OMPC_read:
14309 case OMPC_write:
14310 case OMPC_update:
14311 case OMPC_capture:
14312 case OMPC_seq_cst:
14313 case OMPC_acq_rel:
14314 case OMPC_acquire:
14315 case OMPC_release:
14316 case OMPC_relaxed:
14317 case OMPC_depend:
14318 case OMPC_threads:
14319 case OMPC_simd:
14320 case OMPC_map:
14321 case OMPC_num_teams:
14322 case OMPC_thread_limit:
14323 case OMPC_priority:
14324 case OMPC_grainsize:
14325 case OMPC_nogroup:
14326 case OMPC_num_tasks:
14327 case OMPC_hint:
14328 case OMPC_unknown:
14329 case OMPC_uniform:
14330 case OMPC_to:
14331 case OMPC_from:
14332 case OMPC_use_device_ptr:
14333 case OMPC_use_device_addr:
14334 case OMPC_is_device_ptr:
14335 case OMPC_unified_address:
14336 case OMPC_unified_shared_memory:
14337 case OMPC_reverse_offload:
14338 case OMPC_dynamic_allocators:
14339 case OMPC_atomic_default_mem_order:
14340 case OMPC_device_type:
14341 case OMPC_match:
14342 case OMPC_nontemporal:
14343 case OMPC_order:
14344 case OMPC_destroy:
14345 case OMPC_novariants:
14346 case OMPC_detach:
14347 case OMPC_inclusive:
14348 case OMPC_exclusive:
14349 case OMPC_uses_allocators:
14350 case OMPC_affinity:
14351 default:
14352 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14352)
;
14353 }
14354 return Res;
14355}
14356
14357static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
14358 OpenMPScheduleClauseModifier M2,
14359 SourceLocation M1Loc, SourceLocation M2Loc) {
14360 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
14361 SmallVector<unsigned, 2> Excluded;
14362 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
14363 Excluded.push_back(M2);
14364 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
14365 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
14366 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
14367 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
14368 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
14369 << getListOfPossibleValues(OMPC_schedule,
14370 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
14371 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14372 Excluded)
14373 << getOpenMPClauseName(OMPC_schedule);
14374 return true;
14375 }
14376 return false;
14377}
14378
14379OMPClause *Sema::ActOnOpenMPScheduleClause(
14380 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
14381 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14382 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
14383 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
14384 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
14385 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
14386 return nullptr;
14387 // OpenMP, 2.7.1, Loop Construct, Restrictions
14388 // Either the monotonic modifier or the nonmonotonic modifier can be specified
14389 // but not both.
14390 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
14391 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
14392 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
14393 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
14394 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
14395 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
14396 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
14397 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
14398 return nullptr;
14399 }
14400 if (Kind == OMPC_SCHEDULE_unknown) {
14401 std::string Values;
14402 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
14403 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
14404 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14405 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14406 Exclude);
14407 } else {
14408 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14409 /*Last=*/OMPC_SCHEDULE_unknown);
14410 }
14411 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14412 << Values << getOpenMPClauseName(OMPC_schedule);
14413 return nullptr;
14414 }
14415 // OpenMP, 2.7.1, Loop Construct, Restrictions
14416 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
14417 // schedule(guided).
14418 // OpenMP 5.0 does not have this restriction.
14419 if (LangOpts.OpenMP < 50 &&
14420 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
14421 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
14422 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
14423 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
14424 diag::err_omp_schedule_nonmonotonic_static);
14425 return nullptr;
14426 }
14427 Expr *ValExpr = ChunkSize;
14428 Stmt *HelperValStmt = nullptr;
14429 if (ChunkSize) {
14430 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14431 !ChunkSize->isInstantiationDependent() &&
14432 !ChunkSize->containsUnexpandedParameterPack()) {
14433 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14434 ExprResult Val =
14435 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14436 if (Val.isInvalid())
14437 return nullptr;
14438
14439 ValExpr = Val.get();
14440
14441 // OpenMP [2.7.1, Restrictions]
14442 // chunk_size must be a loop invariant integer expression with a positive
14443 // value.
14444 if (Optional<llvm::APSInt> Result =
14445 ValExpr->getIntegerConstantExpr(Context)) {
14446 if (Result->isSigned() && !Result->isStrictlyPositive()) {
14447 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14448 << "schedule" << 1 << ChunkSize->getSourceRange();
14449 return nullptr;
14450 }
14451 } else if (getOpenMPCaptureRegionForClause(
14452 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
14453 LangOpts.OpenMP) != OMPD_unknown &&
14454 !CurContext->isDependentContext()) {
14455 ValExpr = MakeFullExpr(ValExpr).get();
14456 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14457 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14458 HelperValStmt = buildPreInits(Context, Captures);
14459 }
14460 }
14461 }
14462
14463 return new (Context)
14464 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
14465 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
14466}
14467
14468OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
14469 SourceLocation StartLoc,
14470 SourceLocation EndLoc) {
14471 OMPClause *Res = nullptr;
14472 switch (Kind) {
14473 case OMPC_ordered:
14474 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
14475 break;
14476 case OMPC_nowait:
14477 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
14478 break;
14479 case OMPC_untied:
14480 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
14481 break;
14482 case OMPC_mergeable:
14483 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
14484 break;
14485 case OMPC_read:
14486 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
14487 break;
14488 case OMPC_write:
14489 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
14490 break;
14491 case OMPC_update:
14492 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
14493 break;
14494 case OMPC_capture:
14495 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
14496 break;
14497 case OMPC_seq_cst:
14498 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
14499 break;
14500 case OMPC_acq_rel:
14501 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
14502 break;
14503 case OMPC_acquire:
14504 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
14505 break;
14506 case OMPC_release:
14507 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
14508 break;
14509 case OMPC_relaxed:
14510 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
14511 break;
14512 case OMPC_threads:
14513 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
14514 break;
14515 case OMPC_simd:
14516 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
14517 break;
14518 case OMPC_nogroup:
14519 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
14520 break;
14521 case OMPC_unified_address:
14522 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
14523 break;
14524 case OMPC_unified_shared_memory:
14525 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14526 break;
14527 case OMPC_reverse_offload:
14528 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
14529 break;
14530 case OMPC_dynamic_allocators:
14531 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
14532 break;
14533 case OMPC_destroy:
14534 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
14535 /*LParenLoc=*/SourceLocation(),
14536 /*VarLoc=*/SourceLocation(), EndLoc);
14537 break;
14538 case OMPC_if:
14539 case OMPC_final:
14540 case OMPC_num_threads:
14541 case OMPC_safelen:
14542 case OMPC_simdlen:
14543 case OMPC_sizes:
14544 case OMPC_allocator:
14545 case OMPC_collapse:
14546 case OMPC_schedule:
14547 case OMPC_private:
14548 case OMPC_firstprivate:
14549 case OMPC_lastprivate:
14550 case OMPC_shared:
14551 case OMPC_reduction:
14552 case OMPC_task_reduction:
14553 case OMPC_in_reduction:
14554 case OMPC_linear:
14555 case OMPC_aligned:
14556 case OMPC_copyin:
14557 case OMPC_copyprivate:
14558 case OMPC_default:
14559 case OMPC_proc_bind:
14560 case OMPC_threadprivate:
14561 case OMPC_allocate:
14562 case OMPC_flush:
14563 case OMPC_depobj:
14564 case OMPC_depend:
14565 case OMPC_device:
14566 case OMPC_map:
14567 case OMPC_num_teams:
14568 case OMPC_thread_limit:
14569 case OMPC_priority:
14570 case OMPC_grainsize:
14571 case OMPC_num_tasks:
14572 case OMPC_hint:
14573 case OMPC_dist_schedule:
14574 case OMPC_defaultmap:
14575 case OMPC_unknown:
14576 case OMPC_uniform:
14577 case OMPC_to:
14578 case OMPC_from:
14579 case OMPC_use_device_ptr:
14580 case OMPC_use_device_addr:
14581 case OMPC_is_device_ptr:
14582 case OMPC_atomic_default_mem_order:
14583 case OMPC_device_type:
14584 case OMPC_match:
14585 case OMPC_nontemporal:
14586 case OMPC_order:
14587 case OMPC_novariants:
14588 case OMPC_detach:
14589 case OMPC_inclusive:
14590 case OMPC_exclusive:
14591 case OMPC_uses_allocators:
14592 case OMPC_affinity:
14593 default:
14594 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14594)
;
14595 }
14596 return Res;
14597}
14598
14599OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
14600 SourceLocation EndLoc) {
14601 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
14602 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
14603}
14604
14605OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
14606 SourceLocation EndLoc) {
14607 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
14608}
14609
14610OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
14611 SourceLocation EndLoc) {
14612 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
14613}
14614
14615OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
14616 SourceLocation EndLoc) {
14617 return new (Context) OMPReadClause(StartLoc, EndLoc);
14618}
14619
14620OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
14621 SourceLocation EndLoc) {
14622 return new (Context) OMPWriteClause(StartLoc, EndLoc);
14623}
14624
14625OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
14626 SourceLocation EndLoc) {
14627 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
14628}
14629
14630OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
14631 SourceLocation EndLoc) {
14632 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
14633}
14634
14635OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
14636 SourceLocation EndLoc) {
14637 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
14638}
14639
14640OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
14641 SourceLocation EndLoc) {
14642 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
14643}
14644
14645OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
14646 SourceLocation EndLoc) {
14647 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
14648}
14649
14650OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
14651 SourceLocation EndLoc) {
14652 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
14653}
14654
14655OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
14656 SourceLocation EndLoc) {
14657 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
14658}
14659
14660OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
14661 SourceLocation EndLoc) {
14662 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
14663}
14664
14665OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
14666 SourceLocation EndLoc) {
14667 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
14668}
14669
14670OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
14671 SourceLocation EndLoc) {
14672 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
14673}
14674
14675OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
14676 SourceLocation EndLoc) {
14677 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
14678}
14679
14680OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
14681 SourceLocation EndLoc) {
14682 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14683}
14684
14685OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
14686 SourceLocation EndLoc) {
14687 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
14688}
14689
14690OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
14691 SourceLocation EndLoc) {
14692 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
14693}
14694
14695StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
14696 SourceLocation StartLoc,
14697 SourceLocation EndLoc) {
14698
14699 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14700 // At least one action-clause must appear on a directive.
14701 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
14702 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
14703 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
14704 << Expected << getOpenMPDirectiveName(OMPD_interop);
14705 return StmtError();
14706 }
14707
14708 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14709 // A depend clause can only appear on the directive if a targetsync
14710 // interop-type is present or the interop-var was initialized with
14711 // the targetsync interop-type.
14712
14713 // If there is any 'init' clause diagnose if there is no 'init' clause with
14714 // interop-type of 'targetsync'. Cases involving other directives cannot be
14715 // diagnosed.
14716 const OMPDependClause *DependClause = nullptr;
14717 bool HasInitClause = false;
14718 bool IsTargetSync = false;
14719 for (const OMPClause *C : Clauses) {
14720 if (IsTargetSync)
14721 break;
14722 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
14723 HasInitClause = true;
14724 if (InitClause->getIsTargetSync())
14725 IsTargetSync = true;
14726 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
14727 DependClause = DC;
14728 }
14729 }
14730 if (DependClause && HasInitClause && !IsTargetSync) {
14731 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
14732 return StmtError();
14733 }
14734
14735 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14736 // Each interop-var may be specified for at most one action-clause of each
14737 // interop construct.
14738 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
14739 for (const OMPClause *C : Clauses) {
14740 OpenMPClauseKind ClauseKind = C->getClauseKind();
14741 const DeclRefExpr *DRE = nullptr;
14742 SourceLocation VarLoc;
14743
14744 if (ClauseKind == OMPC_init) {
14745 const auto *IC = cast<OMPInitClause>(C);
14746 VarLoc = IC->getVarLoc();
14747 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
14748 } else if (ClauseKind == OMPC_use) {
14749 const auto *UC = cast<OMPUseClause>(C);
14750 VarLoc = UC->getVarLoc();
14751 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
14752 } else if (ClauseKind == OMPC_destroy) {
14753 const auto *DC = cast<OMPDestroyClause>(C);
14754 VarLoc = DC->getVarLoc();
14755 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
14756 }
14757
14758 if (!DRE)
14759 continue;
14760
14761 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
14762 if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
14763 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
14764 return StmtError();
14765 }
14766 }
14767 }
14768
14769 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
14770}
14771
14772static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
14773 SourceLocation VarLoc,
14774 OpenMPClauseKind Kind) {
14775 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
14776 InteropVarExpr->isInstantiationDependent() ||
14777 InteropVarExpr->containsUnexpandedParameterPack())
14778 return true;
14779
14780 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
14781 if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
14782 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
14783 return false;
14784 }
14785
14786 // Interop variable should be of type omp_interop_t.
14787 bool HasError = false;
14788 QualType InteropType;
14789 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
14790 VarLoc, Sema::LookupOrdinaryName);
14791 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
14792 NamedDecl *ND = Result.getFoundDecl();
14793 if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
14794 InteropType = QualType(TD->getTypeForDecl(), 0);
14795 } else {
14796 HasError = true;
14797 }
14798 } else {
14799 HasError = true;
14800 }
14801
14802 if (HasError) {
14803 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
14804 << "omp_interop_t";
14805 return false;
14806 }
14807
14808 QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
14809 if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
14810 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
14811 return false;
14812 }
14813
14814 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14815 // The interop-var passed to init or destroy must be non-const.
14816 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
14817 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
14818 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
14819 << /*non-const*/ 1;
14820 return false;
14821 }
14822 return true;
14823}
14824
14825OMPClause *
14826Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
14827 bool IsTarget, bool IsTargetSync,
14828 SourceLocation StartLoc, SourceLocation LParenLoc,
14829 SourceLocation VarLoc, SourceLocation EndLoc) {
14830
14831 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
14832 return nullptr;
14833
14834 // Check prefer_type values. These foreign-runtime-id values are either
14835 // string literals or constant integral expressions.
14836 for (const Expr *E : PrefExprs) {
14837 if (E->isValueDependent() || E->isTypeDependent() ||
14838 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
14839 continue;
14840 if (E->isIntegerConstantExpr(Context))
14841 continue;
14842 if (isa<StringLiteral>(E))
14843 continue;
14844 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
14845 return nullptr;
14846 }
14847
14848 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
14849 IsTargetSync, StartLoc, LParenLoc, VarLoc,
14850 EndLoc);
14851}
14852
14853OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
14854 SourceLocation LParenLoc,
14855 SourceLocation VarLoc,
14856 SourceLocation EndLoc) {
14857
14858 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
14859 return nullptr;
14860
14861 return new (Context)
14862 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
14863}
14864
14865OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
14866 SourceLocation StartLoc,
14867 SourceLocation LParenLoc,
14868 SourceLocation VarLoc,
14869 SourceLocation EndLoc) {
14870 if (InteropVar &&
14871 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
14872 return nullptr;
14873
14874 return new (Context)
14875 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
14876}
14877
14878OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
14879 SourceLocation StartLoc,
14880 SourceLocation LParenLoc,
14881 SourceLocation EndLoc) {
14882 Expr *ValExpr = Condition;
14883 Stmt *HelperValStmt = nullptr;
14884 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14885 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14886 !Condition->isInstantiationDependent() &&
14887 !Condition->containsUnexpandedParameterPack()) {
14888 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14889 if (Val.isInvalid())
14890 return nullptr;
14891
14892 ValExpr = MakeFullExpr(Val.get()).get();
14893
14894 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14895 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
14896 LangOpts.OpenMP);
14897 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14898 ValExpr = MakeFullExpr(ValExpr).get();
14899 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14900 HelperValStmt = buildPreInits(Context, Captures);
14901 }
14902 }
14903
14904 return new (Context) OMPNovariantsClause(
14905 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14906}
14907
14908OMPClause *Sema::ActOnOpenMPVarListClause(
14909 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
14910 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
14911 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
14912 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
14913 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
14914 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
14915 SourceLocation ExtraModifierLoc,
14916 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
14917 ArrayRef<SourceLocation> MotionModifiersLoc) {
14918 SourceLocation StartLoc = Locs.StartLoc;
14919 SourceLocation LParenLoc = Locs.LParenLoc;
14920 SourceLocation EndLoc = Locs.EndLoc;
14921 OMPClause *Res = nullptr;
14922 switch (Kind) {
14923 case OMPC_private:
14924 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
14925 break;
14926 case OMPC_firstprivate:
14927 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
14928 break;
14929 case OMPC_lastprivate:
14930 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14931, __PRETTY_FUNCTION__))
14931 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14931, __PRETTY_FUNCTION__))
;
14932 Res = ActOnOpenMPLastprivateClause(
14933 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
14934 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
14935 break;
14936 case OMPC_shared:
14937 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
14938 break;
14939 case OMPC_reduction:
14940 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14941, __PRETTY_FUNCTION__))
14941 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14941, __PRETTY_FUNCTION__))
;
14942 Res = ActOnOpenMPReductionClause(
14943 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
14944 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
14945 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
14946 break;
14947 case OMPC_task_reduction:
14948 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
14949 EndLoc, ReductionOrMapperIdScopeSpec,
14950 ReductionOrMapperId);
14951 break;
14952 case OMPC_in_reduction:
14953 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
14954 EndLoc, ReductionOrMapperIdScopeSpec,
14955 ReductionOrMapperId);
14956 break;
14957 case OMPC_linear:
14958 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14959, __PRETTY_FUNCTION__))
14959 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14959, __PRETTY_FUNCTION__))
;
14960 Res = ActOnOpenMPLinearClause(
14961 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
14962 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
14963 ColonLoc, EndLoc);
14964 break;
14965 case OMPC_aligned:
14966 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
14967 LParenLoc, ColonLoc, EndLoc);
14968 break;
14969 case OMPC_copyin:
14970 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
14971 break;
14972 case OMPC_copyprivate:
14973 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
14974 break;
14975 case OMPC_flush:
14976 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
14977 break;
14978 case OMPC_depend:
14979 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14980, __PRETTY_FUNCTION__))
14980 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14980, __PRETTY_FUNCTION__))
;
14981 Res = ActOnOpenMPDependClause(
14982 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
14983 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
14984 break;
14985 case OMPC_map:
14986 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14987, __PRETTY_FUNCTION__))
14987 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 14987, __PRETTY_FUNCTION__))
;
14988 Res = ActOnOpenMPMapClause(
14989 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
14990 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
14991 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
14992 break;
14993 case OMPC_to:
14994 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
14995 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
14996 ColonLoc, VarList, Locs);
14997 break;
14998 case OMPC_from:
14999 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
15000 ReductionOrMapperIdScopeSpec,
15001 ReductionOrMapperId, ColonLoc, VarList, Locs);
15002 break;
15003 case OMPC_use_device_ptr:
15004 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
15005 break;
15006 case OMPC_use_device_addr:
15007 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
15008 break;
15009 case OMPC_is_device_ptr:
15010 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
15011 break;
15012 case OMPC_allocate:
15013 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
15014 LParenLoc, ColonLoc, EndLoc);
15015 break;
15016 case OMPC_nontemporal:
15017 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
15018 break;
15019 case OMPC_inclusive:
15020 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15021 break;
15022 case OMPC_exclusive:
15023 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15024 break;
15025 case OMPC_affinity:
15026 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
15027 DepModOrTailExpr, VarList);
15028 break;
15029 case OMPC_if:
15030 case OMPC_depobj:
15031 case OMPC_final:
15032 case OMPC_num_threads:
15033 case OMPC_safelen:
15034 case OMPC_simdlen:
15035 case OMPC_sizes:
15036 case OMPC_allocator:
15037 case OMPC_collapse:
15038 case OMPC_default:
15039 case OMPC_proc_bind:
15040 case OMPC_schedule:
15041 case OMPC_ordered:
15042 case OMPC_nowait:
15043 case OMPC_untied:
15044 case OMPC_mergeable:
15045 case OMPC_threadprivate:
15046 case OMPC_read:
15047 case OMPC_write:
15048 case OMPC_update:
15049 case OMPC_capture:
15050 case OMPC_seq_cst:
15051 case OMPC_acq_rel:
15052 case OMPC_acquire:
15053 case OMPC_release:
15054 case OMPC_relaxed:
15055 case OMPC_device:
15056 case OMPC_threads:
15057 case OMPC_simd:
15058 case OMPC_num_teams:
15059 case OMPC_thread_limit:
15060 case OMPC_priority:
15061 case OMPC_grainsize:
15062 case OMPC_nogroup:
15063 case OMPC_num_tasks:
15064 case OMPC_hint:
15065 case OMPC_dist_schedule:
15066 case OMPC_defaultmap:
15067 case OMPC_unknown:
15068 case OMPC_uniform:
15069 case OMPC_unified_address:
15070 case OMPC_unified_shared_memory:
15071 case OMPC_reverse_offload:
15072 case OMPC_dynamic_allocators:
15073 case OMPC_atomic_default_mem_order:
15074 case OMPC_device_type:
15075 case OMPC_match:
15076 case OMPC_order:
15077 case OMPC_destroy:
15078 case OMPC_novariants:
15079 case OMPC_detach:
15080 case OMPC_uses_allocators:
15081 default:
15082 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 15082)
;
15083 }
15084 return Res;
15085}
15086
15087ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
15088 ExprObjectKind OK, SourceLocation Loc) {
15089 ExprResult Res = BuildDeclRefExpr(
15090 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
15091 if (!Res.isUsable())
15092 return ExprError();
15093 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
15094 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
15095 if (!Res.isUsable())
15096 return ExprError();
15097 }
15098 if (VK != VK_LValue && Res.get()->isGLValue()) {
15099 Res = DefaultLvalueConversion(Res.get());
15100 if (!Res.isUsable())
15101 return ExprError();
15102 }
15103 return Res;
15104}
15105
15106OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
15107 SourceLocation StartLoc,
15108 SourceLocation LParenLoc,
15109 SourceLocation EndLoc) {
15110 SmallVector<Expr *, 8> Vars;
15111 SmallVector<Expr *, 8> PrivateCopies;
15112 for (Expr *RefExpr : VarList) {
15113 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 15113, __PRETTY_FUNCTION__))
;
15114 SourceLocation ELoc;
15115 SourceRange ERange;
15116 Expr *SimpleRefExpr = RefExpr;
15117 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15118 if (Res.second) {
15119 // It will be analyzed later.
15120 Vars.push_back(RefExpr);
15121 PrivateCopies.push_back(nullptr);
15122 }
15123 ValueDecl *D = Res.first;
15124 if (!D)
15125 continue;
15126
15127 QualType Type = D->getType();
15128 auto *VD = dyn_cast<VarDecl>(D);
15129
15130 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15131 // A variable that appears in a private clause must not have an incomplete
15132 // type or a reference type.
15133 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
15134 continue;
15135 Type = Type.getNonReferenceType();
15136
15137 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15138 // A variable that is privatized must not have a const-qualified type
15139 // unless it is of class type with a mutable member. This restriction does
15140 // not apply to the firstprivate clause.
15141 //
15142 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
15143 // A variable that appears in a private clause must not have a
15144 // const-qualified type unless it is of class type with a mutable member.
15145 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
15146 continue;
15147
15148 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15149 // in a Construct]
15150 // Variables with the predetermined data-sharing attributes may not be
15151 // listed in data-sharing attributes clauses, except for the cases
15152 // listed below. For these exceptions only, listing a predetermined
15153 // variable in a data-sharing attribute clause is allowed and overrides
15154 // the variable's predetermined data-sharing attributes.
15155 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15156 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
15157 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15158 << getOpenMPClauseName(OMPC_private);
15159 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15160 continue;
15161 }
15162
15163 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15164 // Variably modified types are not supported for tasks.
15165 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15166 isOpenMPTaskingDirective(CurrDir)) {
15167 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15168 << getOpenMPClauseName(OMPC_private) << Type
15169 << getOpenMPDirectiveName(CurrDir);
15170 bool IsDecl =
15171 !VD ||
15172 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15173 Diag(D->getLocation(),
15174 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15175 << D;
15176 continue;
15177 }
15178
15179 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15180 // A list item cannot appear in both a map clause and a data-sharing
15181 // attribute clause on the same construct
15182 //
15183 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15184 // A list item cannot appear in both a map clause and a data-sharing
15185 // attribute clause on the same construct unless the construct is a
15186 // combined construct.
15187 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
15188 CurrDir == OMPD_target) {
15189 OpenMPClauseKind ConflictKind;
15190 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
15191 VD, /*CurrentRegionOnly=*/true,
15192 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
15193 OpenMPClauseKind WhereFoundClauseKind) -> bool {
15194 ConflictKind = WhereFoundClauseKind;
15195 return true;
15196 })) {
15197 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15198 << getOpenMPClauseName(OMPC_private)
15199 << getOpenMPClauseName(ConflictKind)
15200 << getOpenMPDirectiveName(CurrDir);
15201 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15202 continue;
15203 }
15204 }
15205
15206 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
15207 // A variable of class type (or array thereof) that appears in a private
15208 // clause requires an accessible, unambiguous default constructor for the
15209 // class type.
15210 // Generate helper private variable and initialize it with the default
15211 // value. The address of the original variable is replaced by the address of
15212 // the new private variable in CodeGen. This new variable is not added to
15213 // IdResolver, so the code in the OpenMP region uses original variable for
15214 // proper diagnostics.
15215 Type = Type.getUnqualifiedType();
15216 VarDecl *VDPrivate =
15217 buildVarDecl(*this, ELoc, Type, D->getName(),
15218 D->hasAttrs() ? &D->getAttrs() : nullptr,
15219 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15220 ActOnUninitializedDecl(VDPrivate);
15221 if (VDPrivate->isInvalidDecl())
15222 continue;
15223 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15224 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15225
15226 DeclRefExpr *Ref = nullptr;
15227 if (!VD && !CurContext->isDependentContext())
15228 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15229 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
15230 Vars.push_back((VD || CurContext->isDependentContext())
15231 ? RefExpr->IgnoreParens()
15232 : Ref);
15233 PrivateCopies.push_back(VDPrivateRefExpr);
15234 }
15235
15236 if (Vars.empty())
15237 return nullptr;
15238
15239 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15240 PrivateCopies);
15241}
15242
15243namespace {
15244class DiagsUninitializedSeveretyRAII {
15245private:
15246 DiagnosticsEngine &Diags;
15247 SourceLocation SavedLoc;
15248 bool IsIgnored = false;
15249
15250public:
15251 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
15252 bool IsIgnored)
15253 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
15254 if (!IsIgnored) {
15255 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
15256 /*Map*/ diag::Severity::Ignored, Loc);
15257 }
15258 }
15259 ~DiagsUninitializedSeveretyRAII() {
15260 if (!IsIgnored)
15261 Diags.popMappings(SavedLoc);
15262 }
15263};
15264}
15265
15266OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
15267 SourceLocation StartLoc,
15268 SourceLocation LParenLoc,
15269 SourceLocation EndLoc) {
15270 SmallVector<Expr *, 8> Vars;
15271 SmallVector<Expr *, 8> PrivateCopies;
15272 SmallVector<Expr *, 8> Inits;
15273 SmallVector<Decl *, 4> ExprCaptures;
15274 bool IsImplicitClause =
15275 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
15276 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
15277
15278 for (Expr *RefExpr : VarList) {
15279 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 15279, __PRETTY_FUNCTION__))
;
15280 SourceLocation ELoc;
15281 SourceRange ERange;
15282 Expr *SimpleRefExpr = RefExpr;
15283 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15284 if (Res.second) {
15285 // It will be analyzed later.
15286 Vars.push_back(RefExpr);
15287 PrivateCopies.push_back(nullptr);
15288 Inits.push_back(nullptr);
15289 }
15290 ValueDecl *D = Res.first;
15291 if (!D)
15292 continue;
15293
15294 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
15295 QualType Type = D->getType();
15296 auto *VD = dyn_cast<VarDecl>(D);
15297
15298 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15299 // A variable that appears in a private clause must not have an incomplete
15300 // type or a reference type.
15301 if (RequireCompleteType(ELoc, Type,
15302 diag::err_omp_firstprivate_incomplete_type))
15303 continue;
15304 Type = Type.getNonReferenceType();
15305
15306 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
15307 // A variable of class type (or array thereof) that appears in a private
15308 // clause requires an accessible, unambiguous copy constructor for the
15309 // class type.
15310 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15311
15312 // If an implicit firstprivate variable found it was checked already.
15313 DSAStackTy::DSAVarData TopDVar;
15314 if (!IsImplicitClause) {
15315 DSAStackTy::DSAVarData DVar =
15316 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15317 TopDVar = DVar;
15318 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15319 bool IsConstant = ElemType.isConstant(Context);
15320 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
15321 // A list item that specifies a given variable may not appear in more
15322 // than one clause on the same directive, except that a variable may be
15323 // specified in both firstprivate and lastprivate clauses.
15324 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15325 // A list item may appear in a firstprivate or lastprivate clause but not
15326 // both.
15327 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
15328 (isOpenMPDistributeDirective(CurrDir) ||
15329 DVar.CKind != OMPC_lastprivate) &&
15330 DVar.RefExpr) {
15331 Diag(ELoc, diag::err_omp_wrong_dsa)
15332 << getOpenMPClauseName(DVar.CKind)
15333 << getOpenMPClauseName(OMPC_firstprivate);
15334 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15335 continue;
15336 }
15337
15338 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15339 // in a Construct]
15340 // Variables with the predetermined data-sharing attributes may not be
15341 // listed in data-sharing attributes clauses, except for the cases
15342 // listed below. For these exceptions only, listing a predetermined
15343 // variable in a data-sharing attribute clause is allowed and overrides
15344 // the variable's predetermined data-sharing attributes.
15345 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15346 // in a Construct, C/C++, p.2]
15347 // Variables with const-qualified type having no mutable member may be
15348 // listed in a firstprivate clause, even if they are static data members.
15349 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
15350 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
15351 Diag(ELoc, diag::err_omp_wrong_dsa)
15352 << getOpenMPClauseName(DVar.CKind)
15353 << getOpenMPClauseName(OMPC_firstprivate);
15354 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15355 continue;
15356 }
15357
15358 // OpenMP [2.9.3.4, Restrictions, p.2]
15359 // A list item that is private within a parallel region must not appear
15360 // in a firstprivate clause on a worksharing construct if any of the
15361 // worksharing regions arising from the worksharing construct ever bind
15362 // to any of the parallel regions arising from the parallel construct.
15363 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15364 // A list item that is private within a teams region must not appear in a
15365 // firstprivate clause on a distribute construct if any of the distribute
15366 // regions arising from the distribute construct ever bind to any of the
15367 // teams regions arising from the teams construct.
15368 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15369 // A list item that appears in a reduction clause of a teams construct
15370 // must not appear in a firstprivate clause on a distribute construct if
15371 // any of the distribute regions arising from the distribute construct
15372 // ever bind to any of the teams regions arising from the teams construct.
15373 if ((isOpenMPWorksharingDirective(CurrDir) ||
15374 isOpenMPDistributeDirective(CurrDir)) &&
15375 !isOpenMPParallelDirective(CurrDir) &&
15376 !isOpenMPTeamsDirective(CurrDir)) {
15377 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
15378 if (DVar.CKind != OMPC_shared &&
15379 (isOpenMPParallelDirective(DVar.DKind) ||
15380 isOpenMPTeamsDirective(DVar.DKind) ||
15381 DVar.DKind == OMPD_unknown)) {
15382 Diag(ELoc, diag::err_omp_required_access)
15383 << getOpenMPClauseName(OMPC_firstprivate)
15384 << getOpenMPClauseName(OMPC_shared);
15385 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15386 continue;
15387 }
15388 }
15389 // OpenMP [2.9.3.4, Restrictions, p.3]
15390 // A list item that appears in a reduction clause of a parallel construct
15391 // must not appear in a firstprivate clause on a worksharing or task
15392 // construct if any of the worksharing or task regions arising from the
15393 // worksharing or task construct ever bind to any of the parallel regions
15394 // arising from the parallel construct.
15395 // OpenMP [2.9.3.4, Restrictions, p.4]
15396 // A list item that appears in a reduction clause in worksharing
15397 // construct must not appear in a firstprivate clause in a task construct
15398 // encountered during execution of any of the worksharing regions arising
15399 // from the worksharing construct.
15400 if (isOpenMPTaskingDirective(CurrDir)) {
15401 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
15402 D,
15403 [](OpenMPClauseKind C, bool AppliedToPointee) {
15404 return C == OMPC_reduction && !AppliedToPointee;
15405 },
15406 [](OpenMPDirectiveKind K) {
15407 return isOpenMPParallelDirective(K) ||
15408 isOpenMPWorksharingDirective(K) ||
15409 isOpenMPTeamsDirective(K);
15410 },
15411 /*FromParent=*/true);
15412 if (DVar.CKind == OMPC_reduction &&
15413 (isOpenMPParallelDirective(DVar.DKind) ||
15414 isOpenMPWorksharingDirective(DVar.DKind) ||
15415 isOpenMPTeamsDirective(DVar.DKind))) {
15416 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
15417 << getOpenMPDirectiveName(DVar.DKind);
15418 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15419 continue;
15420 }
15421 }
15422
15423 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15424 // A list item cannot appear in both a map clause and a data-sharing
15425 // attribute clause on the same construct
15426 //
15427 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15428 // A list item cannot appear in both a map clause and a data-sharing
15429 // attribute clause on the same construct unless the construct is a
15430 // combined construct.
15431 if ((LangOpts.OpenMP <= 45 &&
15432 isOpenMPTargetExecutionDirective(CurrDir)) ||
15433 CurrDir == OMPD_target) {
15434 OpenMPClauseKind ConflictKind;
15435 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
15436 VD, /*CurrentRegionOnly=*/true,
15437 [&ConflictKind](
15438 OMPClauseMappableExprCommon::MappableExprComponentListRef,
15439 OpenMPClauseKind WhereFoundClauseKind) {
15440 ConflictKind = WhereFoundClauseKind;
15441 return true;
15442 })) {
15443 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15444 << getOpenMPClauseName(OMPC_firstprivate)
15445 << getOpenMPClauseName(ConflictKind)
15446 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
15447 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15448 continue;
15449 }
15450 }
15451 }
15452
15453 // Variably modified types are not supported for tasks.
15454 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15455 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
15456 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15457 << getOpenMPClauseName(OMPC_firstprivate) << Type
15458 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
15459 bool IsDecl =
15460 !VD ||
15461 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15462 Diag(D->getLocation(),
15463 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15464 << D;
15465 continue;
15466 }
15467
15468 Type = Type.getUnqualifiedType();
15469 VarDecl *VDPrivate =
15470 buildVarDecl(*this, ELoc, Type, D->getName(),
15471 D->hasAttrs() ? &D->getAttrs() : nullptr,
15472 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15473 // Generate helper private variable and initialize it with the value of the
15474 // original variable. The address of the original variable is replaced by
15475 // the address of the new private variable in the CodeGen. This new variable
15476 // is not added to IdResolver, so the code in the OpenMP region uses
15477 // original variable for proper diagnostics and variable capturing.
15478 Expr *VDInitRefExpr = nullptr;
15479 // For arrays generate initializer for single element and replace it by the
15480 // original array element in CodeGen.
15481 if (Type->isArrayType()) {
15482 VarDecl *VDInit =
15483 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
15484 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
15485 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
15486 ElemType = ElemType.getUnqualifiedType();
15487 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
15488 ".firstprivate.temp");
15489 InitializedEntity Entity =
15490 InitializedEntity::InitializeVariable(VDInitTemp);
15491 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
15492
15493 InitializationSequence InitSeq(*this, Entity, Kind, Init);
15494 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
15495 if (Result.isInvalid())
15496 VDPrivate->setInvalidDecl();
15497 else
15498 VDPrivate->setInit(Result.getAs<Expr>());
15499 // Remove temp variable declaration.
15500 Context.Deallocate(VDInitTemp);
15501 } else {
15502 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
15503 ".firstprivate.temp");
15504 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
15505 RefExpr->getExprLoc());
15506 AddInitializerToDecl(VDPrivate,
15507 DefaultLvalueConversion(VDInitRefExpr).get(),
15508 /*DirectInit=*/false);
15509 }
15510 if (VDPrivate->isInvalidDecl()) {
15511 if (IsImplicitClause) {
15512 Diag(RefExpr->getExprLoc(),
15513 diag::note_omp_task_predetermined_firstprivate_here);
15514 }
15515 continue;
15516 }
15517 CurContext->addDecl(VDPrivate);
15518 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15519 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
15520 RefExpr->getExprLoc());
15521 DeclRefExpr *Ref = nullptr;
15522 if (!VD && !CurContext->isDependentContext()) {
15523 if (TopDVar.CKind == OMPC_lastprivate) {
15524 Ref = TopDVar.PrivateCopy;
15525 } else {
15526 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15527 if (!isOpenMPCapturedDecl(D))
15528 ExprCaptures.push_back(Ref->getDecl());
15529 }
15530 }
15531 if (!IsImplicitClause)
15532 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
15533 Vars.push_back((VD || CurContext->isDependentContext())
15534 ? RefExpr->IgnoreParens()
15535 : Ref);
15536 PrivateCopies.push_back(VDPrivateRefExpr);
15537 Inits.push_back(VDInitRefExpr);
15538 }
15539
15540 if (Vars.empty())
15541 return nullptr;
15542
15543 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15544 Vars, PrivateCopies, Inits,
15545 buildPreInits(Context, ExprCaptures));
15546}
15547
15548OMPClause *Sema::ActOnOpenMPLastprivateClause(
15549 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
15550 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
15551 SourceLocation LParenLoc, SourceLocation EndLoc) {
15552 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
15553 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 15553, __PRETTY_FUNCTION__))
;
15554 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
15555 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
15556 /*Last=*/OMPC_LASTPRIVATE_unknown)
15557 << getOpenMPClauseName(OMPC_lastprivate);
15558 return nullptr;
15559 }
15560
15561 SmallVector<Expr *, 8> Vars;
15562 SmallVector<Expr *, 8> SrcExprs;
15563 SmallVector<Expr *, 8> DstExprs;
15564 SmallVector<Expr *, 8> AssignmentOps;
15565 SmallVector<Decl *, 4> ExprCaptures;
15566 SmallVector<Expr *, 4> ExprPostUpdates;
15567 for (Expr *RefExpr : VarList) {
15568 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 15568, __PRETTY_FUNCTION__))
;
15569 SourceLocation ELoc;
15570 SourceRange ERange;
15571 Expr *SimpleRefExpr = RefExpr;
15572 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15573 if (Res.second) {
15574 // It will be analyzed later.
15575 Vars.push_back(RefExpr);
15576 SrcExprs.push_back(nullptr);
15577 DstExprs.push_back(nullptr);
15578 AssignmentOps.push_back(nullptr);
15579 }
15580 ValueDecl *D = Res.first;
15581 if (!D)
15582 continue;
15583
15584 QualType Type = D->getType();
15585 auto *VD = dyn_cast<VarDecl>(D);
15586
15587 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
15588 // A variable that appears in a lastprivate clause must not have an
15589 // incomplete type or a reference type.
15590 if (RequireCompleteType(ELoc, Type,
15591 diag::err_omp_lastprivate_incomplete_type))
15592 continue;
15593 Type = Type.getNonReferenceType();
15594
15595 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15596 // A variable that is privatized must not have a const-qualified type
15597 // unless it is of class type with a mutable member. This restriction does
15598 // not apply to the firstprivate clause.
15599 //
15600 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
15601 // A variable that appears in a lastprivate clause must not have a
15602 // const-qualified type unless it is of class type with a mutable member.
15603 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
15604 continue;
15605
15606 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
15607 // A list item that appears in a lastprivate clause with the conditional
15608 // modifier must be a scalar variable.
15609 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
15610 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
15611 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15612 VarDecl::DeclarationOnly;
15613 Diag(D->getLocation(),
15614 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15615 << D;
15616 continue;
15617 }
15618
15619 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15620 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15621 // in a Construct]
15622 // Variables with the predetermined data-sharing attributes may not be
15623 // listed in data-sharing attributes clauses, except for the cases
15624 // listed below.
15625 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15626 // A list item may appear in a firstprivate or lastprivate clause but not
15627 // both.
15628 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15629 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
15630 (isOpenMPDistributeDirective(CurrDir) ||
15631 DVar.CKind != OMPC_firstprivate) &&
15632 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
15633 Diag(ELoc, diag::err_omp_wrong_dsa)
15634 << getOpenMPClauseName(DVar.CKind)
15635 << getOpenMPClauseName(OMPC_lastprivate);
15636 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15637 continue;
15638 }
15639
15640 // OpenMP [2.14.3.5, Restrictions, p.2]
15641 // A list item that is private within a parallel region, or that appears in
15642 // the reduction clause of a parallel construct, must not appear in a
15643 // lastprivate clause on a worksharing construct if any of the corresponding
15644 // worksharing regions ever binds to any of the corresponding parallel
15645 // regions.
15646 DSAStackTy::DSAVarData TopDVar = DVar;
15647 if (isOpenMPWorksharingDirective(CurrDir) &&
15648 !isOpenMPParallelDirective(CurrDir) &&
15649 !isOpenMPTeamsDirective(CurrDir)) {
15650 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
15651 if (DVar.CKind != OMPC_shared) {
15652 Diag(ELoc, diag::err_omp_required_access)
15653 << getOpenMPClauseName(OMPC_lastprivate)
15654 << getOpenMPClauseName(OMPC_shared);
15655 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15656 continue;
15657 }
15658 }
15659
15660 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
15661 // A variable of class type (or array thereof) that appears in a
15662 // lastprivate clause requires an accessible, unambiguous default
15663 // constructor for the class type, unless the list item is also specified
15664 // in a firstprivate clause.
15665 // A variable of class type (or array thereof) that appears in a
15666 // lastprivate clause requires an accessible, unambiguous copy assignment
15667 // operator for the class type.
15668 Type = Context.getBaseElementType(Type).getNonReferenceType();
15669 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
15670 Type.getUnqualifiedType(), ".lastprivate.src",
15671 D->hasAttrs() ? &D->getAttrs() : nullptr);
15672 DeclRefExpr *PseudoSrcExpr =
15673 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
15674 VarDecl *DstVD =
15675 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
15676 D->hasAttrs() ? &D->getAttrs() : nullptr);
15677 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
15678 // For arrays generate assignment operation for single element and replace
15679 // it by the original array element in CodeGen.
15680 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
15681 PseudoDstExpr, PseudoSrcExpr);
15682 if (AssignmentOp.isInvalid())
15683 continue;
15684 AssignmentOp =
15685 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
15686 if (AssignmentOp.isInvalid())
15687 continue;
15688
15689 DeclRefExpr *Ref = nullptr;
15690 if (!VD && !CurContext->isDependentContext()) {
15691 if (TopDVar.CKind == OMPC_firstprivate) {
15692 Ref = TopDVar.PrivateCopy;
15693 } else {
15694 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15695 if (!isOpenMPCapturedDecl(D))
15696 ExprCaptures.push_back(Ref->getDecl());
15697 }
15698 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
15699 (!isOpenMPCapturedDecl(D) &&
15700 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
15701 ExprResult RefRes = DefaultLvalueConversion(Ref);
15702 if (!RefRes.isUsable())
15703 continue;
15704 ExprResult PostUpdateRes =
15705 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15706 RefRes.get());
15707 if (!PostUpdateRes.isUsable())
15708 continue;
15709 ExprPostUpdates.push_back(
15710 IgnoredValueConversions(PostUpdateRes.get()).get());
15711 }
15712 }
15713 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
15714 Vars.push_back((VD || CurContext->isDependentContext())
15715 ? RefExpr->IgnoreParens()
15716 : Ref);
15717 SrcExprs.push_back(PseudoSrcExpr);
15718 DstExprs.push_back(PseudoDstExpr);
15719 AssignmentOps.push_back(AssignmentOp.get());
15720 }
15721
15722 if (Vars.empty())
15723 return nullptr;
15724
15725 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15726 Vars, SrcExprs, DstExprs, AssignmentOps,
15727 LPKind, LPKindLoc, ColonLoc,
15728 buildPreInits(Context, ExprCaptures),
15729 buildPostUpdate(*this, ExprPostUpdates));
15730}
15731
15732OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
15733 SourceLocation StartLoc,
15734 SourceLocation LParenLoc,
15735 SourceLocation EndLoc) {
15736 SmallVector<Expr *, 8> Vars;
15737 for (Expr *RefExpr : VarList) {
15738 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 15738, __PRETTY_FUNCTION__))
;
15739 SourceLocation ELoc;
15740 SourceRange ERange;
15741 Expr *SimpleRefExpr = RefExpr;
15742 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15743 if (Res.second) {
15744 // It will be analyzed later.
15745 Vars.push_back(RefExpr);
15746 }
15747 ValueDecl *D = Res.first;
15748 if (!D)
15749 continue;
15750
15751 auto *VD = dyn_cast<VarDecl>(D);
15752 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15753 // in a Construct]
15754 // Variables with the predetermined data-sharing attributes may not be
15755 // listed in data-sharing attributes clauses, except for the cases
15756 // listed below. For these exceptions only, listing a predetermined
15757 // variable in a data-sharing attribute clause is allowed and overrides
15758 // the variable's predetermined data-sharing attributes.
15759 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15760 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
15761 DVar.RefExpr) {
15762 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15763 << getOpenMPClauseName(OMPC_shared);
15764 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15765 continue;
15766 }
15767
15768 DeclRefExpr *Ref = nullptr;
15769 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
15770 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15771 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
15772 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
15773 ? RefExpr->IgnoreParens()
15774 : Ref);
15775 }
15776
15777 if (Vars.empty())
15778 return nullptr;
15779
15780 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
15781}
15782
15783namespace {
15784class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
15785 DSAStackTy *Stack;
15786
15787public:
15788 bool VisitDeclRefExpr(DeclRefExpr *E) {
15789 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
15790 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
15791 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
15792 return false;
15793 if (DVar.CKind != OMPC_unknown)
15794 return true;
15795 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
15796 VD,
15797 [](OpenMPClauseKind C, bool AppliedToPointee) {
15798 return isOpenMPPrivate(C) && !AppliedToPointee;
15799 },
15800 [](OpenMPDirectiveKind) { return true; },
15801 /*FromParent=*/true);
15802 return DVarPrivate.CKind != OMPC_unknown;
15803 }
15804 return false;
15805 }
15806 bool VisitStmt(Stmt *S) {
15807 for (Stmt *Child : S->children()) {
15808 if (Child && Visit(Child))
15809 return true;
15810 }
15811 return false;
15812 }
15813 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
15814};
15815} // namespace
15816
15817namespace {
15818// Transform MemberExpression for specified FieldDecl of current class to
15819// DeclRefExpr to specified OMPCapturedExprDecl.
15820class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
15821 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
15822 ValueDecl *Field = nullptr;
15823 DeclRefExpr *CapturedExpr = nullptr;
15824
15825public:
15826 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
15827 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
15828
15829 ExprResult TransformMemberExpr(MemberExpr *E) {
15830 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
15831 E->getMemberDecl() == Field) {
15832 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
15833 return CapturedExpr;
15834 }
15835 return BaseTransform::TransformMemberExpr(E);
15836 }
15837 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
15838};
15839} // namespace
15840
15841template <typename T, typename U>
15842static T filterLookupForUDReductionAndMapper(
15843 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
15844 for (U &Set : Lookups) {
15845 for (auto *D : Set) {
15846 if (T Res = Gen(cast<ValueDecl>(D)))
15847 return Res;
15848 }
15849 }
15850 return T();
15851}
15852
15853static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
15854 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 15854, __PRETTY_FUNCTION__))
;
15855
15856 for (auto RD : D->redecls()) {
15857 // Don't bother with extra checks if we already know this one isn't visible.
15858 if (RD == D)
15859 continue;
15860
15861 auto ND = cast<NamedDecl>(RD);
15862 if (LookupResult::isVisible(SemaRef, ND))
15863 return ND;
15864 }
15865
15866 return nullptr;
15867}
15868
15869static void
15870argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
15871 SourceLocation Loc, QualType Ty,
15872 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
15873 // Find all of the associated namespaces and classes based on the
15874 // arguments we have.
15875 Sema::AssociatedNamespaceSet AssociatedNamespaces;
15876 Sema::AssociatedClassSet AssociatedClasses;
15877 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
15878 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
15879 AssociatedClasses);
15880
15881 // C++ [basic.lookup.argdep]p3:
15882 // Let X be the lookup set produced by unqualified lookup (3.4.1)
15883 // and let Y be the lookup set produced by argument dependent
15884 // lookup (defined as follows). If X contains [...] then Y is
15885 // empty. Otherwise Y is the set of declarations found in the
15886 // namespaces associated with the argument types as described
15887 // below. The set of declarations found by the lookup of the name
15888 // is the union of X and Y.
15889 //
15890 // Here, we compute Y and add its members to the overloaded
15891 // candidate set.
15892 for (auto *NS : AssociatedNamespaces) {
15893 // When considering an associated namespace, the lookup is the
15894 // same as the lookup performed when the associated namespace is
15895 // used as a qualifier (3.4.3.2) except that:
15896 //
15897 // -- Any using-directives in the associated namespace are
15898 // ignored.
15899 //
15900 // -- Any namespace-scope friend functions declared in
15901 // associated classes are visible within their respective
15902 // namespaces even if they are not visible during an ordinary
15903 // lookup (11.4).
15904 DeclContext::lookup_result R = NS->lookup(Id.getName());
15905 for (auto *D : R) {
15906 auto *Underlying = D;
15907 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
15908 Underlying = USD->getTargetDecl();
15909
15910 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
15911 !isa<OMPDeclareMapperDecl>(Underlying))
15912 continue;
15913
15914 if (!SemaRef.isVisible(D)) {
15915 D = findAcceptableDecl(SemaRef, D);
15916 if (!D)
15917 continue;
15918 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
15919 Underlying = USD->getTargetDecl();
15920 }
15921 Lookups.emplace_back();
15922 Lookups.back().addDecl(Underlying);
15923 }
15924 }
15925}
15926
15927static ExprResult
15928buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
15929 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
15930 const DeclarationNameInfo &ReductionId, QualType Ty,
15931 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
15932 if (ReductionIdScopeSpec.isInvalid())
15933 return ExprError();
15934 SmallVector<UnresolvedSet<8>, 4> Lookups;
15935 if (S) {
15936 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
15937 Lookup.suppressDiagnostics();
15938 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
15939 NamedDecl *D = Lookup.getRepresentativeDecl();
15940 do {
15941 S = S->getParent();
15942 } while (S && !S->isDeclScope(D));
15943 if (S)
15944 S = S->getParent();
15945 Lookups.emplace_back();
15946 Lookups.back().append(Lookup.begin(), Lookup.end());
15947 Lookup.clear();
15948 }
15949 } else if (auto *ULE =
15950 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
15951 Lookups.push_back(UnresolvedSet<8>());
15952 Decl *PrevD = nullptr;
15953 for (NamedDecl *D : ULE->decls()) {
15954 if (D == PrevD)
15955 Lookups.push_back(UnresolvedSet<8>());
15956 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
15957 Lookups.back().addDecl(DRD);
15958 PrevD = D;
15959 }
15960 }
15961 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
15962 Ty->isInstantiationDependentType() ||
15963 Ty->containsUnexpandedParameterPack() ||
15964 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
15965 return !D->isInvalidDecl() &&
15966 (D->getType()->isDependentType() ||
15967 D->getType()->isInstantiationDependentType() ||
15968 D->getType()->containsUnexpandedParameterPack());
15969 })) {
15970 UnresolvedSet<8> ResSet;
15971 for (const UnresolvedSet<8> &Set : Lookups) {
15972 if (Set.empty())
15973 continue;
15974 ResSet.append(Set.begin(), Set.end());
15975 // The last item marks the end of all declarations at the specified scope.
15976 ResSet.addDecl(Set[Set.size() - 1]);
15977 }
15978 return UnresolvedLookupExpr::Create(
15979 SemaRef.Context, /*NamingClass=*/nullptr,
15980 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
15981 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
15982 }
15983 // Lookup inside the classes.
15984 // C++ [over.match.oper]p3:
15985 // For a unary operator @ with an operand of a type whose
15986 // cv-unqualified version is T1, and for a binary operator @ with
15987 // a left operand of a type whose cv-unqualified version is T1 and
15988 // a right operand of a type whose cv-unqualified version is T2,
15989 // three sets of candidate functions, designated member
15990 // candidates, non-member candidates and built-in candidates, are
15991 // constructed as follows:
15992 // -- If T1 is a complete class type or a class currently being
15993 // defined, the set of member candidates is the result of the
15994 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
15995 // the set of member candidates is empty.
15996 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
15997 Lookup.suppressDiagnostics();
15998 if (const auto *TyRec = Ty->getAs<RecordType>()) {
15999 // Complete the type if it can be completed.
16000 // If the type is neither complete nor being defined, bail out now.
16001 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
16002 TyRec->getDecl()->getDefinition()) {
16003 Lookup.clear();
16004 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
16005 if (Lookup.empty()) {
16006 Lookups.emplace_back();
16007 Lookups.back().append(Lookup.begin(), Lookup.end());
16008 }
16009 }
16010 }
16011 // Perform ADL.
16012 if (SemaRef.getLangOpts().CPlusPlus)
16013 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
16014 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16015 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
16016 if (!D->isInvalidDecl() &&
16017 SemaRef.Context.hasSameType(D->getType(), Ty))
16018 return D;
16019 return nullptr;
16020 }))
16021 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
16022 VK_LValue, Loc);
16023 if (SemaRef.getLangOpts().CPlusPlus) {
16024 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16025 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
16026 if (!D->isInvalidDecl() &&
16027 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
16028 !Ty.isMoreQualifiedThan(D->getType()))
16029 return D;
16030 return nullptr;
16031 })) {
16032 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16033 /*DetectVirtual=*/false);
16034 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
16035 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16036 VD->getType().getUnqualifiedType()))) {
16037 if (SemaRef.CheckBaseClassAccess(
16038 Loc, VD->getType(), Ty, Paths.front(),
16039 /*DiagID=*/0) != Sema::AR_inaccessible) {
16040 SemaRef.BuildBasePathArray(Paths, BasePath);
16041 return SemaRef.BuildDeclRefExpr(
16042 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
16043 }
16044 }
16045 }
16046 }
16047 }
16048 if (ReductionIdScopeSpec.isSet()) {
16049 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
16050 << Ty << Range;
16051 return ExprError();
16052 }
16053 return ExprEmpty();
16054}
16055
16056namespace {
16057/// Data for the reduction-based clauses.
16058struct ReductionData {
16059 /// List of original reduction items.
16060 SmallVector<Expr *, 8> Vars;
16061 /// List of private copies of the reduction items.
16062 SmallVector<Expr *, 8> Privates;
16063 /// LHS expressions for the reduction_op expressions.
16064 SmallVector<Expr *, 8> LHSs;
16065 /// RHS expressions for the reduction_op expressions.
16066 SmallVector<Expr *, 8> RHSs;
16067 /// Reduction operation expression.
16068 SmallVector<Expr *, 8> ReductionOps;
16069 /// inscan copy operation expressions.
16070 SmallVector<Expr *, 8> InscanCopyOps;
16071 /// inscan copy temp array expressions for prefix sums.
16072 SmallVector<Expr *, 8> InscanCopyArrayTemps;
16073 /// inscan copy temp array element expressions for prefix sums.
16074 SmallVector<Expr *, 8> InscanCopyArrayElems;
16075 /// Taskgroup descriptors for the corresponding reduction items in
16076 /// in_reduction clauses.
16077 SmallVector<Expr *, 8> TaskgroupDescriptors;
16078 /// List of captures for clause.
16079 SmallVector<Decl *, 4> ExprCaptures;
16080 /// List of postupdate expressions.
16081 SmallVector<Expr *, 4> ExprPostUpdates;
16082 /// Reduction modifier.
16083 unsigned RedModifier = 0;
16084 ReductionData() = delete;
16085 /// Reserves required memory for the reduction data.
16086 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
16087 Vars.reserve(Size);
16088 Privates.reserve(Size);
16089 LHSs.reserve(Size);
16090 RHSs.reserve(Size);
16091 ReductionOps.reserve(Size);
16092 if (RedModifier == OMPC_REDUCTION_inscan) {
16093 InscanCopyOps.reserve(Size);
16094 InscanCopyArrayTemps.reserve(Size);
16095 InscanCopyArrayElems.reserve(Size);
16096 }
16097 TaskgroupDescriptors.reserve(Size);
16098 ExprCaptures.reserve(Size);
16099 ExprPostUpdates.reserve(Size);
16100 }
16101 /// Stores reduction item and reduction operation only (required for dependent
16102 /// reduction item).
16103 void push(Expr *Item, Expr *ReductionOp) {
16104 Vars.emplace_back(Item);
16105 Privates.emplace_back(nullptr);
16106 LHSs.emplace_back(nullptr);
16107 RHSs.emplace_back(nullptr);
16108 ReductionOps.emplace_back(ReductionOp);
16109 TaskgroupDescriptors.emplace_back(nullptr);
16110 if (RedModifier == OMPC_REDUCTION_inscan) {
16111 InscanCopyOps.push_back(nullptr);
16112 InscanCopyArrayTemps.push_back(nullptr);
16113 InscanCopyArrayElems.push_back(nullptr);
16114 }
16115 }
16116 /// Stores reduction data.
16117 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
16118 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
16119 Expr *CopyArrayElem) {
16120 Vars.emplace_back(Item);
16121 Privates.emplace_back(Private);
16122 LHSs.emplace_back(LHS);
16123 RHSs.emplace_back(RHS);
16124 ReductionOps.emplace_back(ReductionOp);
16125 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
16126 if (RedModifier == OMPC_REDUCTION_inscan) {
16127 InscanCopyOps.push_back(CopyOp);
16128 InscanCopyArrayTemps.push_back(CopyArrayTemp);
16129 InscanCopyArrayElems.push_back(CopyArrayElem);
16130 } else {
16131 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 16133, __PRETTY_FUNCTION__))
16132 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 16133, __PRETTY_FUNCTION__))
16133 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 16133, __PRETTY_FUNCTION__))
;
16134 }
16135 }
16136};
16137} // namespace
16138
16139static bool checkOMPArraySectionConstantForReduction(
16140 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
16141 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
16142 const Expr *Length = OASE->getLength();
16143 if (Length == nullptr) {
16144 // For array sections of the form [1:] or [:], we would need to analyze
16145 // the lower bound...
16146 if (OASE->getColonLocFirst().isValid())
16147 return false;
16148
16149 // This is an array subscript which has implicit length 1!
16150 SingleElement = true;
16151 ArraySizes.push_back(llvm::APSInt::get(1));
16152 } else {
16153 Expr::EvalResult Result;
16154 if (!Length->EvaluateAsInt(Result, Context))
16155 return false;
16156
16157 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16158 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
16159 ArraySizes.push_back(ConstantLengthValue);
16160 }
16161
16162 // Get the base of this array section and walk up from there.
16163 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
16164
16165 // We require length = 1 for all array sections except the right-most to
16166 // guarantee that the memory region is contiguous and has no holes in it.
16167 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
16168 Length = TempOASE->getLength();
16169 if (Length == nullptr) {
16170 // For array sections of the form [1:] or [:], we would need to analyze
16171 // the lower bound...
16172 if (OASE->getColonLocFirst().isValid())
16173 return false;
16174
16175 // This is an array subscript which has implicit length 1!
16176 ArraySizes.push_back(llvm::APSInt::get(1));
16177 } else {
16178 Expr::EvalResult Result;
16179 if (!Length->EvaluateAsInt(Result, Context))
16180 return false;
16181
16182 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16183 if (ConstantLengthValue.getSExtValue() != 1)
16184 return false;
16185
16186 ArraySizes.push_back(ConstantLengthValue);
16187 }
16188 Base = TempOASE->getBase()->IgnoreParenImpCasts();
16189 }
16190
16191 // If we have a single element, we don't need to add the implicit lengths.
16192 if (!SingleElement) {
16193 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
16194 // Has implicit length 1!
16195 ArraySizes.push_back(llvm::APSInt::get(1));
16196 Base = TempASE->getBase()->IgnoreParenImpCasts();
16197 }
16198 }
16199
16200 // This array section can be privatized as a single value or as a constant
16201 // sized array.
16202 return true;
16203}
16204
16205static bool actOnOMPReductionKindClause(
16206 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
16207 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16208 SourceLocation ColonLoc, SourceLocation EndLoc,
16209 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16210 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
16211 DeclarationName DN = ReductionId.getName();
16212 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
16213 BinaryOperatorKind BOK = BO_Comma;
16214
16215 ASTContext &Context = S.Context;
16216 // OpenMP [2.14.3.6, reduction clause]
16217 // C
16218 // reduction-identifier is either an identifier or one of the following
16219 // operators: +, -, *, &, |, ^, && and ||
16220 // C++
16221 // reduction-identifier is either an id-expression or one of the following
16222 // operators: +, -, *, &, |, ^, && and ||
16223 switch (OOK) {
16224 case OO_Plus:
16225 case OO_Minus:
16226 BOK = BO_Add;
16227 break;
16228 case OO_Star:
16229 BOK = BO_Mul;
16230 break;
16231 case OO_Amp:
16232 BOK = BO_And;
16233 break;
16234 case OO_Pipe:
16235 BOK = BO_Or;
16236 break;
16237 case OO_Caret:
16238 BOK = BO_Xor;
16239 break;
16240 case OO_AmpAmp:
16241 BOK = BO_LAnd;
16242 break;
16243 case OO_PipePipe:
16244 BOK = BO_LOr;
16245 break;
16246 case OO_New:
16247 case OO_Delete:
16248 case OO_Array_New:
16249 case OO_Array_Delete:
16250 case OO_Slash:
16251 case OO_Percent:
16252 case OO_Tilde:
16253 case OO_Exclaim:
16254 case OO_Equal:
16255 case OO_Less:
16256 case OO_Greater:
16257 case OO_LessEqual:
16258 case OO_GreaterEqual:
16259 case OO_PlusEqual:
16260 case OO_MinusEqual:
16261 case OO_StarEqual:
16262 case OO_SlashEqual:
16263 case OO_PercentEqual:
16264 case OO_CaretEqual:
16265 case OO_AmpEqual:
16266 case OO_PipeEqual:
16267 case OO_LessLess:
16268 case OO_GreaterGreater:
16269 case OO_LessLessEqual:
16270 case OO_GreaterGreaterEqual:
16271 case OO_EqualEqual:
16272 case OO_ExclaimEqual:
16273 case OO_Spaceship:
16274 case OO_PlusPlus:
16275 case OO_MinusMinus:
16276 case OO_Comma:
16277 case OO_ArrowStar:
16278 case OO_Arrow:
16279 case OO_Call:
16280 case OO_Subscript:
16281 case OO_Conditional:
16282 case OO_Coawait:
16283 case NUM_OVERLOADED_OPERATORS:
16284 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 16284)
;
16285 case OO_None:
16286 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
16287 if (II->isStr("max"))
16288 BOK = BO_GT;
16289 else if (II->isStr("min"))
16290 BOK = BO_LT;
16291 }
16292 break;
16293 }
16294 SourceRange ReductionIdRange;
16295 if (ReductionIdScopeSpec.isValid())
16296 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
16297 else
16298 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
16299 ReductionIdRange.setEnd(ReductionId.getEndLoc());
16300
16301 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
16302 bool FirstIter = true;
16303 for (Expr *RefExpr : VarList) {
16304 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 16304, __PRETTY_FUNCTION__))
;
16305 // OpenMP [2.1, C/C++]
16306 // A list item is a variable or array section, subject to the restrictions
16307 // specified in Section 2.4 on page 42 and in each of the sections
16308 // describing clauses and directives for which a list appears.
16309 // OpenMP [2.14.3.3, Restrictions, p.1]
16310 // A variable that is part of another variable (as an array or
16311 // structure element) cannot appear in a private clause.
16312 if (!FirstIter && IR != ER)
16313 ++IR;
16314 FirstIter = false;
16315 SourceLocation ELoc;
16316 SourceRange ERange;
16317 Expr *SimpleRefExpr = RefExpr;
16318 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
16319 /*AllowArraySection=*/true);
16320 if (Res.second) {
16321 // Try to find 'declare reduction' corresponding construct before using
16322 // builtin/overloaded operators.
16323 QualType Type = Context.DependentTy;
16324 CXXCastPath BasePath;
16325 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16326 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16327 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16328 Expr *ReductionOp = nullptr;
16329 if (S.CurContext->isDependentContext() &&
16330 (DeclareReductionRef.isUnset() ||
16331 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
16332 ReductionOp = DeclareReductionRef.get();
16333 // It will be analyzed later.
16334 RD.push(RefExpr, ReductionOp);
16335 }
16336 ValueDecl *D = Res.first;
16337 if (!D)
16338 continue;
16339
16340 Expr *TaskgroupDescriptor = nullptr;
16341 QualType Type;
16342 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
16343 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
16344 if (ASE) {
16345 Type = ASE->getType().getNonReferenceType();
16346 } else if (OASE) {
16347 QualType BaseType =
16348 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16349 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16350 Type = ATy->getElementType();
16351 else
16352 Type = BaseType->getPointeeType();
16353 Type = Type.getNonReferenceType();
16354 } else {
16355 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
16356 }
16357 auto *VD = dyn_cast<VarDecl>(D);
16358
16359 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16360 // A variable that appears in a private clause must not have an incomplete
16361 // type or a reference type.
16362 if (S.RequireCompleteType(ELoc, D->getType(),
16363 diag::err_omp_reduction_incomplete_type))
16364 continue;
16365 // OpenMP [2.14.3.6, reduction clause, Restrictions]
16366 // A list item that appears in a reduction clause must not be
16367 // const-qualified.
16368 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
16369 /*AcceptIfMutable*/ false, ASE || OASE))
16370 continue;
16371
16372 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
16373 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
16374 // If a list-item is a reference type then it must bind to the same object
16375 // for all threads of the team.
16376 if (!ASE && !OASE) {
16377 if (VD) {
16378 VarDecl *VDDef = VD->getDefinition();
16379 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
16380 DSARefChecker Check(Stack);
16381 if (Check.Visit(VDDef->getInit())) {
16382 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
16383 << getOpenMPClauseName(ClauseKind) << ERange;
16384 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
16385 continue;
16386 }
16387 }
16388 }
16389
16390 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16391 // in a Construct]
16392 // Variables with the predetermined data-sharing attributes may not be
16393 // listed in data-sharing attributes clauses, except for the cases
16394 // listed below. For these exceptions only, listing a predetermined
16395 // variable in a data-sharing attribute clause is allowed and overrides
16396 // the variable's predetermined data-sharing attributes.
16397 // OpenMP [2.14.3.6, Restrictions, p.3]
16398 // Any number of reduction clauses can be specified on the directive,
16399 // but a list item can appear only once in the reduction clauses for that
16400 // directive.
16401 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16402 if (DVar.CKind == OMPC_reduction) {
16403 S.Diag(ELoc, diag::err_omp_once_referenced)
16404 << getOpenMPClauseName(ClauseKind);
16405 if (DVar.RefExpr)
16406 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
16407 continue;
16408 }
16409 if (DVar.CKind != OMPC_unknown) {
16410 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16411 << getOpenMPClauseName(DVar.CKind)
16412 << getOpenMPClauseName(OMPC_reduction);
16413 reportOriginalDsa(S, Stack, D, DVar);
16414 continue;
16415 }
16416
16417 // OpenMP [2.14.3.6, Restrictions, p.1]
16418 // A list item that appears in a reduction clause of a worksharing
16419 // construct must be shared in the parallel regions to which any of the
16420 // worksharing regions arising from the worksharing construct bind.
16421 if (isOpenMPWorksharingDirective(CurrDir) &&
16422 !isOpenMPParallelDirective(CurrDir) &&
16423 !isOpenMPTeamsDirective(CurrDir)) {
16424 DVar = Stack->getImplicitDSA(D, true);
16425 if (DVar.CKind != OMPC_shared) {
16426 S.Diag(ELoc, diag::err_omp_required_access)
16427 << getOpenMPClauseName(OMPC_reduction)
16428 << getOpenMPClauseName(OMPC_shared);
16429 reportOriginalDsa(S, Stack, D, DVar);
16430 continue;
16431 }
16432 }
16433 } else {
16434 // Threadprivates cannot be shared between threads, so dignose if the base
16435 // is a threadprivate variable.
16436 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16437 if (DVar.CKind == OMPC_threadprivate) {
16438 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16439 << getOpenMPClauseName(DVar.CKind)
16440 << getOpenMPClauseName(OMPC_reduction);
16441 reportOriginalDsa(S, Stack, D, DVar);
16442 continue;
16443 }
16444 }
16445
16446 // Try to find 'declare reduction' corresponding construct before using
16447 // builtin/overloaded operators.
16448 CXXCastPath BasePath;
16449 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16450 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16451 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16452 if (DeclareReductionRef.isInvalid())
16453 continue;
16454 if (S.CurContext->isDependentContext() &&
16455 (DeclareReductionRef.isUnset() ||
16456 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
16457 RD.push(RefExpr, DeclareReductionRef.get());
16458 continue;
16459 }
16460 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
16461 // Not allowed reduction identifier is found.
16462 S.Diag(ReductionId.getBeginLoc(),
16463 diag::err_omp_unknown_reduction_identifier)
16464 << Type << ReductionIdRange;
16465 continue;
16466 }
16467
16468 // OpenMP [2.14.3.6, reduction clause, Restrictions]
16469 // The type of a list item that appears in a reduction clause must be valid
16470 // for the reduction-identifier. For a max or min reduction in C, the type
16471 // of the list item must be an allowed arithmetic data type: char, int,
16472 // float, double, or _Bool, possibly modified with long, short, signed, or
16473 // unsigned. For a max or min reduction in C++, the type of the list item
16474 // must be an allowed arithmetic data type: char, wchar_t, int, float,
16475 // double, or bool, possibly modified with long, short, signed, or unsigned.
16476 if (DeclareReductionRef.isUnset()) {
16477 if ((BOK == BO_GT || BOK == BO_LT) &&
16478 !(Type->isScalarType() ||
16479 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
16480 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
16481 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
16482 if (!ASE && !OASE) {
16483 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16484 VarDecl::DeclarationOnly;
16485 S.Diag(D->getLocation(),
16486 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16487 << D;
16488 }
16489 continue;
16490 }
16491 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
16492 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
16493 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
16494 << getOpenMPClauseName(ClauseKind);
16495 if (!ASE && !OASE) {
16496 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16497 VarDecl::DeclarationOnly;
16498 S.Diag(D->getLocation(),
16499 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16500 << D;
16501 }
16502 continue;
16503 }
16504 }
16505
16506 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
16507 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
16508 D->hasAttrs() ? &D->getAttrs() : nullptr);
16509 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
16510 D->hasAttrs() ? &D->getAttrs() : nullptr);
16511 QualType PrivateTy = Type;
16512
16513 // Try if we can determine constant lengths for all array sections and avoid
16514 // the VLA.
16515 bool ConstantLengthOASE = false;
16516 if (OASE) {
16517 bool SingleElement;
16518 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
16519 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
16520 Context, OASE, SingleElement, ArraySizes);
16521
16522 // If we don't have a single element, we must emit a constant array type.
16523 if (ConstantLengthOASE && !SingleElement) {
16524 for (llvm::APSInt &Size : ArraySizes)
16525 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
16526 ArrayType::Normal,
16527 /*IndexTypeQuals=*/0);
16528 }
16529 }
16530
16531 if ((OASE && !ConstantLengthOASE) ||
16532 (!OASE && !ASE &&
16533 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
16534 if (!Context.getTargetInfo().isVLASupported()) {
16535 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
16536 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
16537 S.Diag(ELoc, diag::note_vla_unsupported);
16538 continue;
16539 } else {
16540 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
16541 S.targetDiag(ELoc, diag::note_vla_unsupported);
16542 }
16543 }
16544 // For arrays/array sections only:
16545 // Create pseudo array type for private copy. The size for this array will
16546 // be generated during codegen.
16547 // For array subscripts or single variables Private Ty is the same as Type
16548 // (type of the variable or single array element).
16549 PrivateTy = Context.getVariableArrayType(
16550 Type,
16551 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
16552 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
16553 } else if (!ASE && !OASE &&
16554 Context.getAsArrayType(D->getType().getNonReferenceType())) {
16555 PrivateTy = D->getType().getNonReferenceType();
16556 }
16557 // Private copy.
16558 VarDecl *PrivateVD =
16559 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
16560 D->hasAttrs() ? &D->getAttrs() : nullptr,
16561 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
16562 // Add initializer for private variable.
16563 Expr *Init = nullptr;
16564 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
16565 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
16566 if (DeclareReductionRef.isUsable()) {
16567 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
16568 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
16569 if (DRD->getInitializer()) {
16570 S.ActOnUninitializedDecl(PrivateVD);
16571 Init = DRDRef;
16572 RHSVD->setInit(DRDRef);
16573 RHSVD->setInitStyle(VarDecl::CallInit);
16574 }
16575 } else {
16576 switch (BOK) {
16577 case BO_Add:
16578 case BO_Xor:
16579 case BO_Or:
16580 case BO_LOr:
16581 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
16582 if (Type->isScalarType() || Type->isAnyComplexType())
16583 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
16584 break;
16585 case BO_Mul:
16586 case BO_LAnd:
16587 if (Type->isScalarType() || Type->isAnyComplexType()) {
16588 // '*' and '&&' reduction ops - initializer is '1'.
16589 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
16590 }
16591 break;
16592 case BO_And: {
16593 // '&' reduction op - initializer is '~0'.
16594 QualType OrigType = Type;
16595 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
16596 Type = ComplexTy->getElementType();
16597 if (Type->isRealFloatingType()) {
16598 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
16599 Context.getFloatTypeSemantics(Type),
16600 Context.getTypeSize(Type));
16601 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
16602 Type, ELoc);
16603 } else if (Type->isScalarType()) {
16604 uint64_t Size = Context.getTypeSize(Type);
16605 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
16606 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
16607 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
16608 }
16609 if (Init && OrigType->isAnyComplexType()) {
16610 // Init = 0xFFFF + 0xFFFFi;
16611 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
16612 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
16613 }
16614 Type = OrigType;
16615 break;
16616 }
16617 case BO_LT:
16618 case BO_GT: {
16619 // 'min' reduction op - initializer is 'Largest representable number in
16620 // the reduction list item type'.
16621 // 'max' reduction op - initializer is 'Least representable number in
16622 // the reduction list item type'.
16623 if (Type->isIntegerType() || Type->isPointerType()) {
16624 bool IsSigned = Type->hasSignedIntegerRepresentation();
16625 uint64_t Size = Context.getTypeSize(Type);
16626 QualType IntTy =
16627 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
16628 llvm::APInt InitValue =
16629 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
16630 : llvm::APInt::getMinValue(Size)
16631 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
16632 : llvm::APInt::getMaxValue(Size);
16633 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
16634 if (Type->isPointerType()) {
16635 // Cast to pointer type.
16636 ExprResult CastExpr = S.BuildCStyleCastExpr(
16637 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
16638 if (CastExpr.isInvalid())
16639 continue;
16640 Init = CastExpr.get();
16641 }
16642 } else if (Type->isRealFloatingType()) {
16643 llvm::APFloat InitValue = llvm::APFloat::getLargest(
16644 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
16645 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
16646 Type, ELoc);
16647 }
16648 break;
16649 }
16650 case BO_PtrMemD:
16651 case BO_PtrMemI:
16652 case BO_MulAssign:
16653 case BO_Div:
16654 case BO_Rem:
16655 case BO_Sub:
16656 case BO_Shl:
16657 case BO_Shr:
16658 case BO_LE:
16659 case BO_GE:
16660 case BO_EQ:
16661 case BO_NE:
16662 case BO_Cmp:
16663 case BO_AndAssign:
16664 case BO_XorAssign:
16665 case BO_OrAssign:
16666 case BO_Assign:
16667 case BO_AddAssign:
16668 case BO_SubAssign:
16669 case BO_DivAssign:
16670 case BO_RemAssign:
16671 case BO_ShlAssign:
16672 case BO_ShrAssign:
16673 case BO_Comma:
16674 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 16674)
;
16675 }
16676 }
16677 if (Init && DeclareReductionRef.isUnset()) {
16678 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
16679 // Store initializer for single element in private copy. Will be used
16680 // during codegen.
16681 PrivateVD->setInit(RHSVD->getInit());
16682 PrivateVD->setInitStyle(RHSVD->getInitStyle());
16683 } else if (!Init) {
16684 S.ActOnUninitializedDecl(RHSVD);
16685 // Store initializer for single element in private copy. Will be used
16686 // during codegen.
16687 PrivateVD->setInit(RHSVD->getInit());
16688 PrivateVD->setInitStyle(RHSVD->getInitStyle());
16689 }
16690 if (RHSVD->isInvalidDecl())
16691 continue;
16692 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
16693 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
16694 << Type << ReductionIdRange;
16695 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16696 VarDecl::DeclarationOnly;
16697 S.Diag(D->getLocation(),
16698 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16699 << D;
16700 continue;
16701 }
16702 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
16703 ExprResult ReductionOp;
16704 if (DeclareReductionRef.isUsable()) {
16705 QualType RedTy = DeclareReductionRef.get()->getType();
16706 QualType PtrRedTy = Context.getPointerType(RedTy);
16707 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
16708 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
16709 if (!BasePath.empty()) {
16710 LHS = S.DefaultLvalueConversion(LHS.get());
16711 RHS = S.DefaultLvalueConversion(RHS.get());
16712 LHS = ImplicitCastExpr::Create(
16713 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
16714 LHS.get()->getValueKind(), FPOptionsOverride());
16715 RHS = ImplicitCastExpr::Create(
16716 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
16717 RHS.get()->getValueKind(), FPOptionsOverride());
16718 }
16719 FunctionProtoType::ExtProtoInfo EPI;
16720 QualType Params[] = {PtrRedTy, PtrRedTy};
16721 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
16722 auto *OVE = new (Context) OpaqueValueExpr(
16723 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
16724 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
16725 Expr *Args[] = {LHS.get(), RHS.get()};
16726 ReductionOp =
16727 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
16728 S.CurFPFeatureOverrides());
16729 } else {
16730 ReductionOp = S.BuildBinOp(
16731 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
16732 if (ReductionOp.isUsable()) {
16733 if (BOK != BO_LT && BOK != BO_GT) {
16734 ReductionOp =
16735 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16736 BO_Assign, LHSDRE, ReductionOp.get());
16737 } else {
16738 auto *ConditionalOp = new (Context)
16739 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
16740 Type, VK_LValue, OK_Ordinary);
16741 ReductionOp =
16742 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16743 BO_Assign, LHSDRE, ConditionalOp);
16744 }
16745 if (ReductionOp.isUsable())
16746 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
16747 /*DiscardedValue*/ false);
16748 }
16749 if (!ReductionOp.isUsable())
16750 continue;
16751 }
16752
16753 // Add copy operations for inscan reductions.
16754 // LHS = RHS;
16755 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
16756 if (ClauseKind == OMPC_reduction &&
16757 RD.RedModifier == OMPC_REDUCTION_inscan) {
16758 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
16759 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
16760 RHS.get());
16761 if (!CopyOpRes.isUsable())
16762 continue;
16763 CopyOpRes =
16764 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
16765 if (!CopyOpRes.isUsable())
16766 continue;
16767 // For simd directive and simd-based directives in simd mode no need to
16768 // construct temp array, need just a single temp element.
16769 if (Stack->getCurrentDirective() == OMPD_simd ||
16770 (S.getLangOpts().OpenMPSimd &&
16771 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
16772 VarDecl *TempArrayVD =
16773 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
16774 D->hasAttrs() ? &D->getAttrs() : nullptr);
16775 // Add a constructor to the temp decl.
16776 S.ActOnUninitializedDecl(TempArrayVD);
16777 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
16778 } else {
16779 // Build temp array for prefix sum.
16780 auto *Dim = new (S.Context)
16781 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16782 QualType ArrayTy =
16783 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
16784 /*IndexTypeQuals=*/0, {ELoc, ELoc});
16785 VarDecl *TempArrayVD =
16786 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
16787 D->hasAttrs() ? &D->getAttrs() : nullptr);
16788 // Add a constructor to the temp decl.
16789 S.ActOnUninitializedDecl(TempArrayVD);
16790 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
16791 TempArrayElem =
16792 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
16793 auto *Idx = new (S.Context)
16794 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16795 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
16796 ELoc, Idx, ELoc);
16797 }
16798 }
16799
16800 // OpenMP [2.15.4.6, Restrictions, p.2]
16801 // A list item that appears in an in_reduction clause of a task construct
16802 // must appear in a task_reduction clause of a construct associated with a
16803 // taskgroup region that includes the participating task in its taskgroup
16804 // set. The construct associated with the innermost region that meets this
16805 // condition must specify the same reduction-identifier as the in_reduction
16806 // clause.
16807 if (ClauseKind == OMPC_in_reduction) {
16808 SourceRange ParentSR;
16809 BinaryOperatorKind ParentBOK;
16810 const Expr *ParentReductionOp = nullptr;
16811 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
16812 DSAStackTy::DSAVarData ParentBOKDSA =
16813 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
16814 ParentBOKTD);
16815 DSAStackTy::DSAVarData ParentReductionOpDSA =
16816 Stack->getTopMostTaskgroupReductionData(
16817 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
16818 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
16819 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
16820 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
16821 (DeclareReductionRef.isUsable() && IsParentBOK) ||
16822 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
16823 bool EmitError = true;
16824 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
16825 llvm::FoldingSetNodeID RedId, ParentRedId;
16826 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
16827 DeclareReductionRef.get()->Profile(RedId, Context,
16828 /*Canonical=*/true);
16829 EmitError = RedId != ParentRedId;
16830 }
16831 if (EmitError) {
16832 S.Diag(ReductionId.getBeginLoc(),
16833 diag::err_omp_reduction_identifier_mismatch)
16834 << ReductionIdRange << RefExpr->getSourceRange();
16835 S.Diag(ParentSR.getBegin(),
16836 diag::note_omp_previous_reduction_identifier)
16837 << ParentSR
16838 << (IsParentBOK ? ParentBOKDSA.RefExpr
16839 : ParentReductionOpDSA.RefExpr)
16840 ->getSourceRange();
16841 continue;
16842 }
16843 }
16844 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
16845 }
16846
16847 DeclRefExpr *Ref = nullptr;
16848 Expr *VarsExpr = RefExpr->IgnoreParens();
16849 if (!VD && !S.CurContext->isDependentContext()) {
16850 if (ASE || OASE) {
16851 TransformExprToCaptures RebuildToCapture(S, D);
16852 VarsExpr =
16853 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
16854 Ref = RebuildToCapture.getCapturedExpr();
16855 } else {
16856 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
16857 }
16858 if (!S.isOpenMPCapturedDecl(D)) {
16859 RD.ExprCaptures.emplace_back(Ref->getDecl());
16860 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
16861 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
16862 if (!RefRes.isUsable())
16863 continue;
16864 ExprResult PostUpdateRes =
16865 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
16866 RefRes.get());
16867 if (!PostUpdateRes.isUsable())
16868 continue;
16869 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
16870 Stack->getCurrentDirective() == OMPD_taskgroup) {
16871 S.Diag(RefExpr->getExprLoc(),
16872 diag::err_omp_reduction_non_addressable_expression)
16873 << RefExpr->getSourceRange();
16874 continue;
16875 }
16876 RD.ExprPostUpdates.emplace_back(
16877 S.IgnoredValueConversions(PostUpdateRes.get()).get());
16878 }
16879 }
16880 }
16881 // All reduction items are still marked as reduction (to do not increase
16882 // code base size).
16883 unsigned Modifier = RD.RedModifier;
16884 // Consider task_reductions as reductions with task modifier. Required for
16885 // correct analysis of in_reduction clauses.
16886 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
16887 Modifier = OMPC_REDUCTION_task;
16888 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
16889 ASE || OASE);
16890 if (Modifier == OMPC_REDUCTION_task &&
16891 (CurrDir == OMPD_taskgroup ||
16892 ((isOpenMPParallelDirective(CurrDir) ||
16893 isOpenMPWorksharingDirective(CurrDir)) &&
16894 !isOpenMPSimdDirective(CurrDir)))) {
16895 if (DeclareReductionRef.isUsable())
16896 Stack->addTaskgroupReductionData(D, ReductionIdRange,
16897 DeclareReductionRef.get());
16898 else
16899 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
16900 }
16901 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
16902 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
16903 TempArrayElem.get());
16904 }
16905 return RD.Vars.empty();
16906}
16907
16908OMPClause *Sema::ActOnOpenMPReductionClause(
16909 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
16910 SourceLocation StartLoc, SourceLocation LParenLoc,
16911 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
16912 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16913 ArrayRef<Expr *> UnresolvedReductions) {
16914 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
16915 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
16916 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
16917 /*Last=*/OMPC_REDUCTION_unknown)
16918 << getOpenMPClauseName(OMPC_reduction);
16919 return nullptr;
16920 }
16921 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
16922 // A reduction clause with the inscan reduction-modifier may only appear on a
16923 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
16924 // construct, a parallel worksharing-loop construct or a parallel
16925 // worksharing-loop SIMD construct.
16926 if (Modifier == OMPC_REDUCTION_inscan &&
16927 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
16928 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
16929 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
16930 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
16931 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
16932 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
16933 return nullptr;
16934 }
16935
16936 ReductionData RD(VarList.size(), Modifier);
16937 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
16938 StartLoc, LParenLoc, ColonLoc, EndLoc,
16939 ReductionIdScopeSpec, ReductionId,
16940 UnresolvedReductions, RD))
16941 return nullptr;
16942
16943 return OMPReductionClause::Create(
16944 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
16945 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
16946 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
16947 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
16948 buildPreInits(Context, RD.ExprCaptures),
16949 buildPostUpdate(*this, RD.ExprPostUpdates));
16950}
16951
16952OMPClause *Sema::ActOnOpenMPTaskReductionClause(
16953 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16954 SourceLocation ColonLoc, SourceLocation EndLoc,
16955 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16956 ArrayRef<Expr *> UnresolvedReductions) {
16957 ReductionData RD(VarList.size());
16958 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
16959 StartLoc, LParenLoc, ColonLoc, EndLoc,
16960 ReductionIdScopeSpec, ReductionId,
16961 UnresolvedReductions, RD))
16962 return nullptr;
16963
16964 return OMPTaskReductionClause::Create(
16965 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
16966 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
16967 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
16968 buildPreInits(Context, RD.ExprCaptures),
16969 buildPostUpdate(*this, RD.ExprPostUpdates));
16970}
16971
16972OMPClause *Sema::ActOnOpenMPInReductionClause(
16973 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16974 SourceLocation ColonLoc, SourceLocation EndLoc,
16975 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16976 ArrayRef<Expr *> UnresolvedReductions) {
16977 ReductionData RD(VarList.size());
16978 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
16979 StartLoc, LParenLoc, ColonLoc, EndLoc,
16980 ReductionIdScopeSpec, ReductionId,
16981 UnresolvedReductions, RD))
16982 return nullptr;
16983
16984 return OMPInReductionClause::Create(
16985 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
16986 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
16987 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
16988 buildPreInits(Context, RD.ExprCaptures),
16989 buildPostUpdate(*this, RD.ExprPostUpdates));
16990}
16991
16992bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
16993 SourceLocation LinLoc) {
16994 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
16995 LinKind == OMPC_LINEAR_unknown) {
16996 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
16997 return true;
16998 }
16999 return false;
17000}
17001
17002bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
17003 OpenMPLinearClauseKind LinKind, QualType Type,
17004 bool IsDeclareSimd) {
17005 const auto *VD = dyn_cast_or_null<VarDecl>(D);
17006 // A variable must not have an incomplete type or a reference type.
17007 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
17008 return true;
17009 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
17010 !Type->isReferenceType()) {
17011 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
17012 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
17013 return true;
17014 }
17015 Type = Type.getNonReferenceType();
17016
17017 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17018 // A variable that is privatized must not have a const-qualified type
17019 // unless it is of class type with a mutable member. This restriction does
17020 // not apply to the firstprivate clause, nor to the linear clause on
17021 // declarative directives (like declare simd).
17022 if (!IsDeclareSimd &&
17023 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
17024 return true;
17025
17026 // A list item must be of integral or pointer type.
17027 Type = Type.getUnqualifiedType().getCanonicalType();
17028 const auto *Ty = Type.getTypePtrOrNull();
17029 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
17030 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
17031 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
17032 if (D) {
17033 bool IsDecl =
17034 !VD ||
17035 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17036 Diag(D->getLocation(),
17037 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17038 << D;
17039 }
17040 return true;
17041 }
17042 return false;
17043}
17044
17045OMPClause *Sema::ActOnOpenMPLinearClause(
17046 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
17047 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
17048 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17049 SmallVector<Expr *, 8> Vars;
17050 SmallVector<Expr *, 8> Privates;
17051 SmallVector<Expr *, 8> Inits;
17052 SmallVector<Decl *, 4> ExprCaptures;
17053 SmallVector<Expr *, 4> ExprPostUpdates;
17054 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
17055 LinKind = OMPC_LINEAR_val;
17056 for (Expr *RefExpr : VarList) {
17057 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17057, __PRETTY_FUNCTION__))
;
17058 SourceLocation ELoc;
17059 SourceRange ERange;
17060 Expr *SimpleRefExpr = RefExpr;
17061 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17062 if (Res.second) {
17063 // It will be analyzed later.
17064 Vars.push_back(RefExpr);
17065 Privates.push_back(nullptr);
17066 Inits.push_back(nullptr);
17067 }
17068 ValueDecl *D = Res.first;
17069 if (!D)
17070 continue;
17071
17072 QualType Type = D->getType();
17073 auto *VD = dyn_cast<VarDecl>(D);
17074
17075 // OpenMP [2.14.3.7, linear clause]
17076 // A list-item cannot appear in more than one linear clause.
17077 // A list-item that appears in a linear clause cannot appear in any
17078 // other data-sharing attribute clause.
17079 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17080 if (DVar.RefExpr) {
17081 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17082 << getOpenMPClauseName(OMPC_linear);
17083 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17084 continue;
17085 }
17086
17087 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
17088 continue;
17089 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17090
17091 // Build private copy of original var.
17092 VarDecl *Private =
17093 buildVarDecl(*this, ELoc, Type, D->getName(),
17094 D->hasAttrs() ? &D->getAttrs() : nullptr,
17095 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17096 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
17097 // Build var to save initial value.
17098 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
17099 Expr *InitExpr;
17100 DeclRefExpr *Ref = nullptr;
17101 if (!VD && !CurContext->isDependentContext()) {
17102 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17103 if (!isOpenMPCapturedDecl(D)) {
17104 ExprCaptures.push_back(Ref->getDecl());
17105 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17106 ExprResult RefRes = DefaultLvalueConversion(Ref);
17107 if (!RefRes.isUsable())
17108 continue;
17109 ExprResult PostUpdateRes =
17110 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
17111 SimpleRefExpr, RefRes.get());
17112 if (!PostUpdateRes.isUsable())
17113 continue;
17114 ExprPostUpdates.push_back(
17115 IgnoredValueConversions(PostUpdateRes.get()).get());
17116 }
17117 }
17118 }
17119 if (LinKind == OMPC_LINEAR_uval)
17120 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
17121 else
17122 InitExpr = VD ? SimpleRefExpr : Ref;
17123 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
17124 /*DirectInit=*/false);
17125 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
17126
17127 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
17128 Vars.push_back((VD || CurContext->isDependentContext())
17129 ? RefExpr->IgnoreParens()
17130 : Ref);
17131 Privates.push_back(PrivateRef);
17132 Inits.push_back(InitRef);
17133 }
17134
17135 if (Vars.empty())
17136 return nullptr;
17137
17138 Expr *StepExpr = Step;
17139 Expr *CalcStepExpr = nullptr;
17140 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
17141 !Step->isInstantiationDependent() &&
17142 !Step->containsUnexpandedParameterPack()) {
17143 SourceLocation StepLoc = Step->getBeginLoc();
17144 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
17145 if (Val.isInvalid())
17146 return nullptr;
17147 StepExpr = Val.get();
17148
17149 // Build var to save the step value.
17150 VarDecl *SaveVar =
17151 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
17152 ExprResult SaveRef =
17153 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
17154 ExprResult CalcStep =
17155 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
17156 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
17157
17158 // Warn about zero linear step (it would be probably better specified as
17159 // making corresponding variables 'const').
17160 if (Optional<llvm::APSInt> Result =
17161 StepExpr->getIntegerConstantExpr(Context)) {
17162 if (!Result->isNegative() && !Result->isStrictlyPositive())
17163 Diag(StepLoc, diag::warn_omp_linear_step_zero)
17164 << Vars[0] << (Vars.size() > 1);
17165 } else if (CalcStep.isUsable()) {
17166 // Calculate the step beforehand instead of doing this on each iteration.
17167 // (This is not used if the number of iterations may be kfold-ed).
17168 CalcStepExpr = CalcStep.get();
17169 }
17170 }
17171
17172 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
17173 ColonLoc, EndLoc, Vars, Privates, Inits,
17174 StepExpr, CalcStepExpr,
17175 buildPreInits(Context, ExprCaptures),
17176 buildPostUpdate(*this, ExprPostUpdates));
17177}
17178
17179static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
17180 Expr *NumIterations, Sema &SemaRef,
17181 Scope *S, DSAStackTy *Stack) {
17182 // Walk the vars and build update/final expressions for the CodeGen.
17183 SmallVector<Expr *, 8> Updates;
17184 SmallVector<Expr *, 8> Finals;
17185 SmallVector<Expr *, 8> UsedExprs;
17186 Expr *Step = Clause.getStep();
17187 Expr *CalcStep = Clause.getCalcStep();
17188 // OpenMP [2.14.3.7, linear clause]
17189 // If linear-step is not specified it is assumed to be 1.
17190 if (!Step)
17191 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
17192 else if (CalcStep)
17193 Step = cast<BinaryOperator>(CalcStep)->getLHS();
17194 bool HasErrors = false;
17195 auto CurInit = Clause.inits().begin();
17196 auto CurPrivate = Clause.privates().begin();
17197 OpenMPLinearClauseKind LinKind = Clause.getModifier();
17198 for (Expr *RefExpr : Clause.varlists()) {
17199 SourceLocation ELoc;
17200 SourceRange ERange;
17201 Expr *SimpleRefExpr = RefExpr;
17202 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17203 ValueDecl *D = Res.first;
17204 if (Res.second || !D) {
17205 Updates.push_back(nullptr);
17206 Finals.push_back(nullptr);
17207 HasErrors = true;
17208 continue;
17209 }
17210 auto &&Info = Stack->isLoopControlVariable(D);
17211 // OpenMP [2.15.11, distribute simd Construct]
17212 // A list item may not appear in a linear clause, unless it is the loop
17213 // iteration variable.
17214 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
17215 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
17216 SemaRef.Diag(ELoc,
17217 diag::err_omp_linear_distribute_var_non_loop_iteration);
17218 Updates.push_back(nullptr);
17219 Finals.push_back(nullptr);
17220 HasErrors = true;
17221 continue;
17222 }
17223 Expr *InitExpr = *CurInit;
17224
17225 // Build privatized reference to the current linear var.
17226 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
17227 Expr *CapturedRef;
17228 if (LinKind == OMPC_LINEAR_uval)
17229 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
17230 else
17231 CapturedRef =
17232 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
17233 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
17234 /*RefersToCapture=*/true);
17235
17236 // Build update: Var = InitExpr + IV * Step
17237 ExprResult Update;
17238 if (!Info.first)
17239 Update = buildCounterUpdate(
17240 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
17241 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
17242 else
17243 Update = *CurPrivate;
17244 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
17245 /*DiscardedValue*/ false);
17246
17247 // Build final: Var = InitExpr + NumIterations * Step
17248 ExprResult Final;
17249 if (!Info.first)
17250 Final =
17251 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
17252 InitExpr, NumIterations, Step, /*Subtract=*/false,
17253 /*IsNonRectangularLB=*/false);
17254 else
17255 Final = *CurPrivate;
17256 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
17257 /*DiscardedValue*/ false);
17258
17259 if (!Update.isUsable() || !Final.isUsable()) {
17260 Updates.push_back(nullptr);
17261 Finals.push_back(nullptr);
17262 UsedExprs.push_back(nullptr);
17263 HasErrors = true;
17264 } else {
17265 Updates.push_back(Update.get());
17266 Finals.push_back(Final.get());
17267 if (!Info.first)
17268 UsedExprs.push_back(SimpleRefExpr);
17269 }
17270 ++CurInit;
17271 ++CurPrivate;
17272 }
17273 if (Expr *S = Clause.getStep())
17274 UsedExprs.push_back(S);
17275 // Fill the remaining part with the nullptr.
17276 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
17277 Clause.setUpdates(Updates);
17278 Clause.setFinals(Finals);
17279 Clause.setUsedExprs(UsedExprs);
17280 return HasErrors;
17281}
17282
17283OMPClause *Sema::ActOnOpenMPAlignedClause(
17284 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
17285 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17286 SmallVector<Expr *, 8> Vars;
17287 for (Expr *RefExpr : VarList) {
17288 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17288, __PRETTY_FUNCTION__))
;
17289 SourceLocation ELoc;
17290 SourceRange ERange;
17291 Expr *SimpleRefExpr = RefExpr;
17292 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17293 if (Res.second) {
17294 // It will be analyzed later.
17295 Vars.push_back(RefExpr);
17296 }
17297 ValueDecl *D = Res.first;
17298 if (!D)
17299 continue;
17300
17301 QualType QType = D->getType();
17302 auto *VD = dyn_cast<VarDecl>(D);
17303
17304 // OpenMP [2.8.1, simd construct, Restrictions]
17305 // The type of list items appearing in the aligned clause must be
17306 // array, pointer, reference to array, or reference to pointer.
17307 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17308 const Type *Ty = QType.getTypePtrOrNull();
17309 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
17310 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
17311 << QType << getLangOpts().CPlusPlus << ERange;
17312 bool IsDecl =
17313 !VD ||
17314 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17315 Diag(D->getLocation(),
17316 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17317 << D;
17318 continue;
17319 }
17320
17321 // OpenMP [2.8.1, simd construct, Restrictions]
17322 // A list-item cannot appear in more than one aligned clause.
17323 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
17324 Diag(ELoc, diag::err_omp_used_in_clause_twice)
17325 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
17326 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17327 << getOpenMPClauseName(OMPC_aligned);
17328 continue;
17329 }
17330
17331 DeclRefExpr *Ref = nullptr;
17332 if (!VD && isOpenMPCapturedDecl(D))
17333 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17334 Vars.push_back(DefaultFunctionArrayConversion(
17335 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
17336 .get());
17337 }
17338
17339 // OpenMP [2.8.1, simd construct, Description]
17340 // The parameter of the aligned clause, alignment, must be a constant
17341 // positive integer expression.
17342 // If no optional parameter is specified, implementation-defined default
17343 // alignments for SIMD instructions on the target platforms are assumed.
17344 if (Alignment != nullptr) {
17345 ExprResult AlignResult =
17346 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
17347 if (AlignResult.isInvalid())
17348 return nullptr;
17349 Alignment = AlignResult.get();
17350 }
17351 if (Vars.empty())
17352 return nullptr;
17353
17354 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
17355 EndLoc, Vars, Alignment);
17356}
17357
17358OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
17359 SourceLocation StartLoc,
17360 SourceLocation LParenLoc,
17361 SourceLocation EndLoc) {
17362 SmallVector<Expr *, 8> Vars;
17363 SmallVector<Expr *, 8> SrcExprs;
17364 SmallVector<Expr *, 8> DstExprs;
17365 SmallVector<Expr *, 8> AssignmentOps;
17366 for (Expr *RefExpr : VarList) {
17367 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17367, __PRETTY_FUNCTION__))
;
17368 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17369 // It will be analyzed later.
17370 Vars.push_back(RefExpr);
17371 SrcExprs.push_back(nullptr);
17372 DstExprs.push_back(nullptr);
17373 AssignmentOps.push_back(nullptr);
17374 continue;
17375 }
17376
17377 SourceLocation ELoc = RefExpr->getExprLoc();
17378 // OpenMP [2.1, C/C++]
17379 // A list item is a variable name.
17380 // OpenMP [2.14.4.1, Restrictions, p.1]
17381 // A list item that appears in a copyin clause must be threadprivate.
17382 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
17383 if (!DE || !isa<VarDecl>(DE->getDecl())) {
17384 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
17385 << 0 << RefExpr->getSourceRange();
17386 continue;
17387 }
17388
17389 Decl *D = DE->getDecl();
17390 auto *VD = cast<VarDecl>(D);
17391
17392 QualType Type = VD->getType();
17393 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
17394 // It will be analyzed later.
17395 Vars.push_back(DE);
17396 SrcExprs.push_back(nullptr);
17397 DstExprs.push_back(nullptr);
17398 AssignmentOps.push_back(nullptr);
17399 continue;
17400 }
17401
17402 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
17403 // A list item that appears in a copyin clause must be threadprivate.
17404 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
17405 Diag(ELoc, diag::err_omp_required_access)
17406 << getOpenMPClauseName(OMPC_copyin)
17407 << getOpenMPDirectiveName(OMPD_threadprivate);
17408 continue;
17409 }
17410
17411 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17412 // A variable of class type (or array thereof) that appears in a
17413 // copyin clause requires an accessible, unambiguous copy assignment
17414 // operator for the class type.
17415 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17416 VarDecl *SrcVD =
17417 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
17418 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17419 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
17420 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
17421 VarDecl *DstVD =
17422 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
17423 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17424 DeclRefExpr *PseudoDstExpr =
17425 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
17426 // For arrays generate assignment operation for single element and replace
17427 // it by the original array element in CodeGen.
17428 ExprResult AssignmentOp =
17429 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
17430 PseudoSrcExpr);
17431 if (AssignmentOp.isInvalid())
17432 continue;
17433 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
17434 /*DiscardedValue*/ false);
17435 if (AssignmentOp.isInvalid())
17436 continue;
17437
17438 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
17439 Vars.push_back(DE);
17440 SrcExprs.push_back(PseudoSrcExpr);
17441 DstExprs.push_back(PseudoDstExpr);
17442 AssignmentOps.push_back(AssignmentOp.get());
17443 }
17444
17445 if (Vars.empty())
17446 return nullptr;
17447
17448 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17449 SrcExprs, DstExprs, AssignmentOps);
17450}
17451
17452OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
17453 SourceLocation StartLoc,
17454 SourceLocation LParenLoc,
17455 SourceLocation EndLoc) {
17456 SmallVector<Expr *, 8> Vars;
17457 SmallVector<Expr *, 8> SrcExprs;
17458 SmallVector<Expr *, 8> DstExprs;
17459 SmallVector<Expr *, 8> AssignmentOps;
17460 for (Expr *RefExpr : VarList) {
17461 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17461, __PRETTY_FUNCTION__))
;
17462 SourceLocation ELoc;
17463 SourceRange ERange;
17464 Expr *SimpleRefExpr = RefExpr;
17465 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17466 if (Res.second) {
17467 // It will be analyzed later.
17468 Vars.push_back(RefExpr);
17469 SrcExprs.push_back(nullptr);
17470 DstExprs.push_back(nullptr);
17471 AssignmentOps.push_back(nullptr);
17472 }
17473 ValueDecl *D = Res.first;
17474 if (!D)
17475 continue;
17476
17477 QualType Type = D->getType();
17478 auto *VD = dyn_cast<VarDecl>(D);
17479
17480 // OpenMP [2.14.4.2, Restrictions, p.2]
17481 // A list item that appears in a copyprivate clause may not appear in a
17482 // private or firstprivate clause on the single construct.
17483 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
17484 DSAStackTy::DSAVarData DVar =
17485 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17486 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
17487 DVar.RefExpr) {
17488 Diag(ELoc, diag::err_omp_wrong_dsa)
17489 << getOpenMPClauseName(DVar.CKind)
17490 << getOpenMPClauseName(OMPC_copyprivate);
17491 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17492 continue;
17493 }
17494
17495 // OpenMP [2.11.4.2, Restrictions, p.1]
17496 // All list items that appear in a copyprivate clause must be either
17497 // threadprivate or private in the enclosing context.
17498 if (DVar.CKind == OMPC_unknown) {
17499 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
17500 if (DVar.CKind == OMPC_shared) {
17501 Diag(ELoc, diag::err_omp_required_access)
17502 << getOpenMPClauseName(OMPC_copyprivate)
17503 << "threadprivate or private in the enclosing context";
17504 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17505 continue;
17506 }
17507 }
17508 }
17509
17510 // Variably modified types are not supported.
17511 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
17512 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17513 << getOpenMPClauseName(OMPC_copyprivate) << Type
17514 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
17515 bool IsDecl =
17516 !VD ||
17517 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17518 Diag(D->getLocation(),
17519 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17520 << D;
17521 continue;
17522 }
17523
17524 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17525 // A variable of class type (or array thereof) that appears in a
17526 // copyin clause requires an accessible, unambiguous copy assignment
17527 // operator for the class type.
17528 Type = Context.getBaseElementType(Type.getNonReferenceType())
17529 .getUnqualifiedType();
17530 VarDecl *SrcVD =
17531 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
17532 D->hasAttrs() ? &D->getAttrs() : nullptr);
17533 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
17534 VarDecl *DstVD =
17535 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
17536 D->hasAttrs() ? &D->getAttrs() : nullptr);
17537 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
17538 ExprResult AssignmentOp = BuildBinOp(
17539 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
17540 if (AssignmentOp.isInvalid())
17541 continue;
17542 AssignmentOp =
17543 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
17544 if (AssignmentOp.isInvalid())
17545 continue;
17546
17547 // No need to mark vars as copyprivate, they are already threadprivate or
17548 // implicitly private.
17549 assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0
) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17549, __PRETTY_FUNCTION__))
;
17550 Vars.push_back(
17551 VD ? RefExpr->IgnoreParens()
17552 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
17553 SrcExprs.push_back(PseudoSrcExpr);
17554 DstExprs.push_back(PseudoDstExpr);
17555 AssignmentOps.push_back(AssignmentOp.get());
17556 }
17557
17558 if (Vars.empty())
17559 return nullptr;
17560
17561 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17562 Vars, SrcExprs, DstExprs, AssignmentOps);
17563}
17564
17565OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
17566 SourceLocation StartLoc,
17567 SourceLocation LParenLoc,
17568 SourceLocation EndLoc) {
17569 if (VarList.empty())
17570 return nullptr;
17571
17572 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
17573}
17574
17575/// Tries to find omp_depend_t. type.
17576static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
17577 bool Diagnose = true) {
17578 QualType OMPDependT = Stack->getOMPDependT();
17579 if (!OMPDependT.isNull())
17580 return true;
17581 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
17582 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
17583 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
17584 if (Diagnose)
17585 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
17586 return false;
17587 }
17588 Stack->setOMPDependT(PT.get());
17589 return true;
17590}
17591
17592OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
17593 SourceLocation LParenLoc,
17594 SourceLocation EndLoc) {
17595 if (!Depobj)
17596 return nullptr;
17597
17598 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
17599
17600 // OpenMP 5.0, 2.17.10.1 depobj Construct
17601 // depobj is an lvalue expression of type omp_depend_t.
17602 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
17603 !Depobj->isInstantiationDependent() &&
17604 !Depobj->containsUnexpandedParameterPack() &&
17605 (OMPDependTFound &&
17606 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
17607 /*CompareUnqualified=*/true))) {
17608 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
17609 << 0 << Depobj->getType() << Depobj->getSourceRange();
17610 }
17611
17612 if (!Depobj->isLValue()) {
17613 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
17614 << 1 << Depobj->getSourceRange();
17615 }
17616
17617 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
17618}
17619
17620OMPClause *
17621Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
17622 SourceLocation DepLoc, SourceLocation ColonLoc,
17623 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
17624 SourceLocation LParenLoc, SourceLocation EndLoc) {
17625 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
17626 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
17627 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
17628 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
17629 return nullptr;
17630 }
17631 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
17632 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
17633 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
17634 DepKind == OMPC_DEPEND_sink ||
17635 ((LangOpts.OpenMP < 50 ||
17636 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
17637 DepKind == OMPC_DEPEND_depobj))) {
17638 SmallVector<unsigned, 3> Except;
17639 Except.push_back(OMPC_DEPEND_source);
17640 Except.push_back(OMPC_DEPEND_sink);
17641 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
17642 Except.push_back(OMPC_DEPEND_depobj);
17643 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
17644 ? "depend modifier(iterator) or "
17645 : "";
17646 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
17647 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
17648 /*Last=*/OMPC_DEPEND_unknown,
17649 Except)
17650 << getOpenMPClauseName(OMPC_depend);
17651 return nullptr;
17652 }
17653 if (DepModifier &&
17654 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
17655 Diag(DepModifier->getExprLoc(),
17656 diag::err_omp_depend_sink_source_with_modifier);
17657 return nullptr;
17658 }
17659 if (DepModifier &&
17660 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
17661 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
17662
17663 SmallVector<Expr *, 8> Vars;
17664 DSAStackTy::OperatorOffsetTy OpsOffs;
17665 llvm::APSInt DepCounter(/*BitWidth=*/32);
17666 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
17667 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
17668 if (const Expr *OrderedCountExpr =
17669 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
17670 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
17671 TotalDepCount.setIsUnsigned(/*Val=*/true);
17672 }
17673 }
17674 for (Expr *RefExpr : VarList) {
17675 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17675, __PRETTY_FUNCTION__))
;
17676 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17677 // It will be analyzed later.
17678 Vars.push_back(RefExpr);
17679 continue;
17680 }
17681
17682 SourceLocation ELoc = RefExpr->getExprLoc();
17683 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
17684 if (DepKind == OMPC_DEPEND_sink) {
17685 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
17686 DepCounter >= TotalDepCount) {
17687 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
17688 continue;
17689 }
17690 ++DepCounter;
17691 // OpenMP [2.13.9, Summary]
17692 // depend(dependence-type : vec), where dependence-type is:
17693 // 'sink' and where vec is the iteration vector, which has the form:
17694 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
17695 // where n is the value specified by the ordered clause in the loop
17696 // directive, xi denotes the loop iteration variable of the i-th nested
17697 // loop associated with the loop directive, and di is a constant
17698 // non-negative integer.
17699 if (CurContext->isDependentContext()) {
17700 // It will be analyzed later.
17701 Vars.push_back(RefExpr);
17702 continue;
17703 }
17704 SimpleExpr = SimpleExpr->IgnoreImplicit();
17705 OverloadedOperatorKind OOK = OO_None;
17706 SourceLocation OOLoc;
17707 Expr *LHS = SimpleExpr;
17708 Expr *RHS = nullptr;
17709 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
17710 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
17711 OOLoc = BO->getOperatorLoc();
17712 LHS = BO->getLHS()->IgnoreParenImpCasts();
17713 RHS = BO->getRHS()->IgnoreParenImpCasts();
17714 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
17715 OOK = OCE->getOperator();
17716 OOLoc = OCE->getOperatorLoc();
17717 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17718 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
17719 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
17720 OOK = MCE->getMethodDecl()
17721 ->getNameInfo()
17722 .getName()
17723 .getCXXOverloadedOperator();
17724 OOLoc = MCE->getCallee()->getExprLoc();
17725 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
17726 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17727 }
17728 SourceLocation ELoc;
17729 SourceRange ERange;
17730 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
17731 if (Res.second) {
17732 // It will be analyzed later.
17733 Vars.push_back(RefExpr);
17734 }
17735 ValueDecl *D = Res.first;
17736 if (!D)
17737 continue;
17738
17739 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
17740 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
17741 continue;
17742 }
17743 if (RHS) {
17744 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
17745 RHS, OMPC_depend, /*StrictlyPositive=*/false);
17746 if (RHSRes.isInvalid())
17747 continue;
17748 }
17749 if (!CurContext->isDependentContext() &&
17750 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
17751 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
17752 const ValueDecl *VD =
17753 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
17754 if (VD)
17755 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
17756 << 1 << VD;
17757 else
17758 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
17759 continue;
17760 }
17761 OpsOffs.emplace_back(RHS, OOK);
17762 } else {
17763 bool OMPDependTFound = LangOpts.OpenMP >= 50;
17764 if (OMPDependTFound)
17765 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
17766 DepKind == OMPC_DEPEND_depobj);
17767 if (DepKind == OMPC_DEPEND_depobj) {
17768 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17769 // List items used in depend clauses with the depobj dependence type
17770 // must be expressions of the omp_depend_t type.
17771 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17772 !RefExpr->isInstantiationDependent() &&
17773 !RefExpr->containsUnexpandedParameterPack() &&
17774 (OMPDependTFound &&
17775 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
17776 RefExpr->getType()))) {
17777 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17778 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
17779 continue;
17780 }
17781 if (!RefExpr->isLValue()) {
17782 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17783 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
17784 continue;
17785 }
17786 } else {
17787 // OpenMP 5.0 [2.17.11, Restrictions]
17788 // List items used in depend clauses cannot be zero-length array
17789 // sections.
17790 QualType ExprTy = RefExpr->getType().getNonReferenceType();
17791 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
17792 if (OASE) {
17793 QualType BaseType =
17794 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17795 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17796 ExprTy = ATy->getElementType();
17797 else
17798 ExprTy = BaseType->getPointeeType();
17799 ExprTy = ExprTy.getNonReferenceType();
17800 const Expr *Length = OASE->getLength();
17801 Expr::EvalResult Result;
17802 if (Length && !Length->isValueDependent() &&
17803 Length->EvaluateAsInt(Result, Context) &&
17804 Result.Val.getInt().isNullValue()) {
17805 Diag(ELoc,
17806 diag::err_omp_depend_zero_length_array_section_not_allowed)
17807 << SimpleExpr->getSourceRange();
17808 continue;
17809 }
17810 }
17811
17812 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17813 // List items used in depend clauses with the in, out, inout or
17814 // mutexinoutset dependence types cannot be expressions of the
17815 // omp_depend_t type.
17816 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17817 !RefExpr->isInstantiationDependent() &&
17818 !RefExpr->containsUnexpandedParameterPack() &&
17819 (OMPDependTFound &&
17820 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
17821 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17822 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
17823 << RefExpr->getSourceRange();
17824 continue;
17825 }
17826
17827 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
17828 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
17829 (ASE && !ASE->getBase()->isTypeDependent() &&
17830 !ASE->getBase()
17831 ->getType()
17832 .getNonReferenceType()
17833 ->isPointerType() &&
17834 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
17835 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17836 << (LangOpts.OpenMP >= 50 ? 1 : 0)
17837 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17838 continue;
17839 }
17840
17841 ExprResult Res;
17842 {
17843 Sema::TentativeAnalysisScope Trap(*this);
17844 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
17845 RefExpr->IgnoreParenImpCasts());
17846 }
17847 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
17848 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
17849 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17850 << (LangOpts.OpenMP >= 50 ? 1 : 0)
17851 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17852 continue;
17853 }
17854 }
17855 }
17856 Vars.push_back(RefExpr->IgnoreParenImpCasts());
17857 }
17858
17859 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
17860 TotalDepCount > VarList.size() &&
17861 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
17862 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
17863 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
17864 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
17865 }
17866 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
17867 Vars.empty())
17868 return nullptr;
17869
17870 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17871 DepModifier, DepKind, DepLoc, ColonLoc,
17872 Vars, TotalDepCount.getZExtValue());
17873 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
17874 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
17875 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
17876 return C;
17877}
17878
17879OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
17880 Expr *Device, SourceLocation StartLoc,
17881 SourceLocation LParenLoc,
17882 SourceLocation ModifierLoc,
17883 SourceLocation EndLoc) {
17884 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17885, __PRETTY_FUNCTION__))
17885 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17885, __PRETTY_FUNCTION__))
;
17886
17887 bool ErrorFound = false;
17888 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
17889 std::string Values =
17890 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
17891 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
17892 << Values << getOpenMPClauseName(OMPC_device);
17893 ErrorFound = true;
17894 }
17895
17896 Expr *ValExpr = Device;
17897 Stmt *HelperValStmt = nullptr;
17898
17899 // OpenMP [2.9.1, Restrictions]
17900 // The device expression must evaluate to a non-negative integer value.
17901 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
17902 /*StrictlyPositive=*/false) ||
17903 ErrorFound;
17904 if (ErrorFound)
17905 return nullptr;
17906
17907 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17908 OpenMPDirectiveKind CaptureRegion =
17909 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
17910 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17911 ValExpr = MakeFullExpr(ValExpr).get();
17912 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17913 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17914 HelperValStmt = buildPreInits(Context, Captures);
17915 }
17916
17917 return new (Context)
17918 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
17919 LParenLoc, ModifierLoc, EndLoc);
17920}
17921
17922static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
17923 DSAStackTy *Stack, QualType QTy,
17924 bool FullCheck = true) {
17925 NamedDecl *ND;
17926 if (QTy->isIncompleteType(&ND)) {
17927 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
17928 return false;
17929 }
17930 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
17931 !QTy.isTriviallyCopyableType(SemaRef.Context))
17932 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
17933 return true;
17934}
17935
17936/// Return true if it can be proven that the provided array expression
17937/// (array section or array subscript) does NOT specify the whole size of the
17938/// array whose base type is \a BaseQTy.
17939static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
17940 const Expr *E,
17941 QualType BaseQTy) {
17942 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
17943
17944 // If this is an array subscript, it refers to the whole size if the size of
17945 // the dimension is constant and equals 1. Also, an array section assumes the
17946 // format of an array subscript if no colon is used.
17947 if (isa<ArraySubscriptExpr>(E) ||
17948 (OASE && OASE->getColonLocFirst().isInvalid())) {
17949 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
17950 return ATy->getSize().getSExtValue() != 1;
17951 // Size can't be evaluated statically.
17952 return false;
17953 }
17954
17955 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 17955, __PRETTY_FUNCTION__))
;
17956 const Expr *LowerBound = OASE->getLowerBound();
17957 const Expr *Length = OASE->getLength();
17958
17959 // If there is a lower bound that does not evaluates to zero, we are not
17960 // covering the whole dimension.
17961 if (LowerBound) {
17962 Expr::EvalResult Result;
17963 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
17964 return false; // Can't get the integer value as a constant.
17965
17966 llvm::APSInt ConstLowerBound = Result.Val.getInt();
17967 if (ConstLowerBound.getSExtValue())
17968 return true;
17969 }
17970
17971 // If we don't have a length we covering the whole dimension.
17972 if (!Length)
17973 return false;
17974
17975 // If the base is a pointer, we don't have a way to get the size of the
17976 // pointee.
17977 if (BaseQTy->isPointerType())
17978 return false;
17979
17980 // We can only check if the length is the same as the size of the dimension
17981 // if we have a constant array.
17982 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
17983 if (!CATy)
17984 return false;
17985
17986 Expr::EvalResult Result;
17987 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
17988 return false; // Can't get the integer value as a constant.
17989
17990 llvm::APSInt ConstLength = Result.Val.getInt();
17991 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
17992}
17993
17994// Return true if it can be proven that the provided array expression (array
17995// section or array subscript) does NOT specify a single element of the array
17996// whose base type is \a BaseQTy.
17997static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
17998 const Expr *E,
17999 QualType BaseQTy) {
18000 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18001
18002 // An array subscript always refer to a single element. Also, an array section
18003 // assumes the format of an array subscript if no colon is used.
18004 if (isa<ArraySubscriptExpr>(E) ||
18005 (OASE && OASE->getColonLocFirst().isInvalid()))
18006 return false;
18007
18008 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18008, __PRETTY_FUNCTION__))
;
18009 const Expr *Length = OASE->getLength();
18010
18011 // If we don't have a length we have to check if the array has unitary size
18012 // for this dimension. Also, we should always expect a length if the base type
18013 // is pointer.
18014 if (!Length) {
18015 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18016 return ATy->getSize().getSExtValue() != 1;
18017 // We cannot assume anything.
18018 return false;
18019 }
18020
18021 // Check if the length evaluates to 1.
18022 Expr::EvalResult Result;
18023 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18024 return false; // Can't get the integer value as a constant.
18025
18026 llvm::APSInt ConstLength = Result.Val.getInt();
18027 return ConstLength.getSExtValue() != 1;
18028}
18029
18030// The base of elements of list in a map clause have to be either:
18031// - a reference to variable or field.
18032// - a member expression.
18033// - an array expression.
18034//
18035// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
18036// reference to 'r'.
18037//
18038// If we have:
18039//
18040// struct SS {
18041// Bla S;
18042// foo() {
18043// #pragma omp target map (S.Arr[:12]);
18044// }
18045// }
18046//
18047// We want to retrieve the member expression 'this->S';
18048
18049// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
18050// If a list item is an array section, it must specify contiguous storage.
18051//
18052// For this restriction it is sufficient that we make sure only references
18053// to variables or fields and array expressions, and that no array sections
18054// exist except in the rightmost expression (unless they cover the whole
18055// dimension of the array). E.g. these would be invalid:
18056//
18057// r.ArrS[3:5].Arr[6:7]
18058//
18059// r.ArrS[3:5].x
18060//
18061// but these would be valid:
18062// r.ArrS[3].Arr[6:7]
18063//
18064// r.ArrS[3].x
18065namespace {
18066class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
18067 Sema &SemaRef;
18068 OpenMPClauseKind CKind = OMPC_unknown;
18069 OpenMPDirectiveKind DKind = OMPD_unknown;
18070 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
18071 bool IsNonContiguous = false;
18072 bool NoDiagnose = false;
18073 const Expr *RelevantExpr = nullptr;
18074 bool AllowUnitySizeArraySection = true;
18075 bool AllowWholeSizeArraySection = true;
18076 bool AllowAnotherPtr = true;
18077 SourceLocation ELoc;
18078 SourceRange ERange;
18079
18080 void emitErrorMsg() {
18081 // If nothing else worked, this is not a valid map clause expression.
18082 if (SemaRef.getLangOpts().OpenMP < 50) {
18083 SemaRef.Diag(ELoc,
18084 diag::err_omp_expected_named_var_member_or_array_expression)
18085 << ERange;
18086 } else {
18087 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18088 << getOpenMPClauseName(CKind) << ERange;
18089 }
18090 }
18091
18092public:
18093 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
18094 if (!isa<VarDecl>(DRE->getDecl())) {
18095 emitErrorMsg();
18096 return false;
18097 }
18098 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18098, __PRETTY_FUNCTION__))
;
18099 RelevantExpr = DRE;
18100 // Record the component.
18101 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
18102 return true;
18103 }
18104
18105 bool VisitMemberExpr(MemberExpr *ME) {
18106 Expr *E = ME;
18107 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
18108
18109 if (isa<CXXThisExpr>(BaseE)) {
18110 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18110, __PRETTY_FUNCTION__))
;
18111 // We found a base expression: this->Val.
18112 RelevantExpr = ME;
18113 } else {
18114 E = BaseE;
18115 }
18116
18117 if (!isa<FieldDecl>(ME->getMemberDecl())) {
18118 if (!NoDiagnose) {
18119 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
18120 << ME->getSourceRange();
18121 return false;
18122 }
18123 if (RelevantExpr)
18124 return false;
18125 return Visit(E);
18126 }
18127
18128 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
18129
18130 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
18131 // A bit-field cannot appear in a map clause.
18132 //
18133 if (FD->isBitField()) {
18134 if (!NoDiagnose) {
18135 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
18136 << ME->getSourceRange() << getOpenMPClauseName(CKind);
18137 return false;
18138 }
18139 if (RelevantExpr)
18140 return false;
18141 return Visit(E);
18142 }
18143
18144 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18145 // If the type of a list item is a reference to a type T then the type
18146 // will be considered to be T for all purposes of this clause.
18147 QualType CurType = BaseE->getType().getNonReferenceType();
18148
18149 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
18150 // A list item cannot be a variable that is a member of a structure with
18151 // a union type.
18152 //
18153 if (CurType->isUnionType()) {
18154 if (!NoDiagnose) {
18155 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
18156 << ME->getSourceRange();
18157 return false;
18158 }
18159 return RelevantExpr || Visit(E);
18160 }
18161
18162 // If we got a member expression, we should not expect any array section
18163 // before that:
18164 //
18165 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
18166 // If a list item is an element of a structure, only the rightmost symbol
18167 // of the variable reference can be an array section.
18168 //
18169 AllowUnitySizeArraySection = false;
18170 AllowWholeSizeArraySection = false;
18171
18172 // Record the component.
18173 Components.emplace_back(ME, FD, IsNonContiguous);
18174 return RelevantExpr || Visit(E);
18175 }
18176
18177 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
18178 Expr *E = AE->getBase()->IgnoreParenImpCasts();
18179
18180 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
18181 if (!NoDiagnose) {
18182 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18183 << 0 << AE->getSourceRange();
18184 return false;
18185 }
18186 return RelevantExpr || Visit(E);
18187 }
18188
18189 // If we got an array subscript that express the whole dimension we
18190 // can have any array expressions before. If it only expressing part of
18191 // the dimension, we can only have unitary-size array expressions.
18192 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
18193 E->getType()))
18194 AllowWholeSizeArraySection = false;
18195
18196 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
18197 Expr::EvalResult Result;
18198 if (!AE->getIdx()->isValueDependent() &&
18199 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
18200 !Result.Val.getInt().isNullValue()) {
18201 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18202 diag::err_omp_invalid_map_this_expr);
18203 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18204 diag::note_omp_invalid_subscript_on_this_ptr_map);
18205 }
18206 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18206, __PRETTY_FUNCTION__))
;
18207 RelevantExpr = TE;
18208 }
18209
18210 // Record the component - we don't have any declaration associated.
18211 Components.emplace_back(AE, nullptr, IsNonContiguous);
18212
18213 return RelevantExpr || Visit(E);
18214 }
18215
18216 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
18217 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18217, __PRETTY_FUNCTION__))
;
18218 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18219 QualType CurType =
18220 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18221
18222 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18223 // If the type of a list item is a reference to a type T then the type
18224 // will be considered to be T for all purposes of this clause.
18225 if (CurType->isReferenceType())
18226 CurType = CurType->getPointeeType();
18227
18228 bool IsPointer = CurType->isAnyPointerType();
18229
18230 if (!IsPointer && !CurType->isArrayType()) {
18231 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18232 << 0 << OASE->getSourceRange();
18233 return false;
18234 }
18235
18236 bool NotWhole =
18237 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
18238 bool NotUnity =
18239 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
18240
18241 if (AllowWholeSizeArraySection) {
18242 // Any array section is currently allowed. Allowing a whole size array
18243 // section implies allowing a unity array section as well.
18244 //
18245 // If this array section refers to the whole dimension we can still
18246 // accept other array sections before this one, except if the base is a
18247 // pointer. Otherwise, only unitary sections are accepted.
18248 if (NotWhole || IsPointer)
18249 AllowWholeSizeArraySection = false;
18250 } else if (DKind == OMPD_target_update &&
18251 SemaRef.getLangOpts().OpenMP >= 50) {
18252 if (IsPointer && !AllowAnotherPtr)
18253 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
18254 << /*array of unknown bound */ 1;
18255 else
18256 IsNonContiguous = true;
18257 } else if (AllowUnitySizeArraySection && NotUnity) {
18258 // A unity or whole array section is not allowed and that is not
18259 // compatible with the properties of the current array section.
18260 SemaRef.Diag(
18261 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
18262 << OASE->getSourceRange();
18263 return false;
18264 }
18265
18266 if (IsPointer)
18267 AllowAnotherPtr = false;
18268
18269 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
18270 Expr::EvalResult ResultR;
18271 Expr::EvalResult ResultL;
18272 if (!OASE->getLength()->isValueDependent() &&
18273 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
18274 !ResultR.Val.getInt().isOneValue()) {
18275 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18276 diag::err_omp_invalid_map_this_expr);
18277 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18278 diag::note_omp_invalid_length_on_this_ptr_mapping);
18279 }
18280 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
18281 OASE->getLowerBound()->EvaluateAsInt(ResultL,
18282 SemaRef.getASTContext()) &&
18283 !ResultL.Val.getInt().isNullValue()) {
18284 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18285 diag::err_omp_invalid_map_this_expr);
18286 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18287 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
18288 }
18289 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18289, __PRETTY_FUNCTION__))
;
18290 RelevantExpr = TE;
18291 }
18292
18293 // Record the component - we don't have any declaration associated.
18294 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
18295 return RelevantExpr || Visit(E);
18296 }
18297 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
18298 Expr *Base = E->getBase();
18299
18300 // Record the component - we don't have any declaration associated.
18301 Components.emplace_back(E, nullptr, IsNonContiguous);
18302
18303 return Visit(Base->IgnoreParenImpCasts());
18304 }
18305
18306 bool VisitUnaryOperator(UnaryOperator *UO) {
18307 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
18308 UO->getOpcode() != UO_Deref) {
18309 emitErrorMsg();
18310 return false;
18311 }
18312 if (!RelevantExpr) {
18313 // Record the component if haven't found base decl.
18314 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
18315 }
18316 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
18317 }
18318 bool VisitBinaryOperator(BinaryOperator *BO) {
18319 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
18320 emitErrorMsg();
18321 return false;
18322 }
18323
18324 // Pointer arithmetic is the only thing we expect to happen here so after we
18325 // make sure the binary operator is a pointer type, the we only thing need
18326 // to to is to visit the subtree that has the same type as root (so that we
18327 // know the other subtree is just an offset)
18328 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
18329 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
18330 Components.emplace_back(BO, nullptr, false);
18331 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18333, __PRETTY_FUNCTION__))
18332 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18333, __PRETTY_FUNCTION__))
18333 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18333, __PRETTY_FUNCTION__))
;
18334 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
18335 return RelevantExpr || Visit(LE);
18336 return RelevantExpr || Visit(RE);
18337 }
18338 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
18339 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18339, __PRETTY_FUNCTION__))
;
18340 RelevantExpr = CTE;
18341 Components.emplace_back(CTE, nullptr, IsNonContiguous);
18342 return true;
18343 }
18344 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
18345 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18345, __PRETTY_FUNCTION__))
;
18346 Components.emplace_back(COCE, nullptr, IsNonContiguous);
18347 return true;
18348 }
18349 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
18350 Expr *Source = E->getSourceExpr();
18351 if (!Source) {
18352 emitErrorMsg();
18353 return false;
18354 }
18355 return Visit(Source);
18356 }
18357 bool VisitStmt(Stmt *) {
18358 emitErrorMsg();
18359 return false;
18360 }
18361 const Expr *getFoundBase() const {
18362 return RelevantExpr;
18363 }
18364 explicit MapBaseChecker(
18365 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
18366 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
18367 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
18368 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
18369 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
18370};
18371} // namespace
18372
18373/// Return the expression of the base of the mappable expression or null if it
18374/// cannot be determined and do all the necessary checks to see if the expression
18375/// is valid as a standalone mappable expression. In the process, record all the
18376/// components of the expression.
18377static const Expr *checkMapClauseExpressionBase(
18378 Sema &SemaRef, Expr *E,
18379 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
18380 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
18381 SourceLocation ELoc = E->getExprLoc();
18382 SourceRange ERange = E->getSourceRange();
18383 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
18384 ERange);
18385 if (Checker.Visit(E->IgnoreParens())) {
18386 // Check if the highest dimension array section has length specified
18387 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
18388 (CKind == OMPC_to || CKind == OMPC_from)) {
18389 auto CI = CurComponents.rbegin();
18390 auto CE = CurComponents.rend();
18391 for (; CI != CE; ++CI) {
18392 const auto *OASE =
18393 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
18394 if (!OASE)
18395 continue;
18396 if (OASE && OASE->getLength())
18397 break;
18398 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
18399 << ERange;
18400 }
18401 }
18402 return Checker.getFoundBase();
18403 }
18404 return nullptr;
18405}
18406
18407// Return true if expression E associated with value VD has conflicts with other
18408// map information.
18409static bool checkMapConflicts(
18410 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
18411 bool CurrentRegionOnly,
18412 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
18413 OpenMPClauseKind CKind) {
18414 assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail
("VD && E", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18414, __PRETTY_FUNCTION__))
;
18415 SourceLocation ELoc = E->getExprLoc();
18416 SourceRange ERange = E->getSourceRange();
18417
18418 // In order to easily check the conflicts we need to match each component of
18419 // the expression under test with the components of the expressions that are
18420 // already in the stack.
18421
18422 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18422, __PRETTY_FUNCTION__))
;
18423 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18424, __PRETTY_FUNCTION__))
18424 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18424, __PRETTY_FUNCTION__))
;
18425
18426 // Variables to help detecting enclosing problems in data environment nests.
18427 bool IsEnclosedByDataEnvironmentExpr = false;
18428 const Expr *EnclosingExpr = nullptr;
18429
18430 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
18431 VD, CurrentRegionOnly,
18432 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
18433 ERange, CKind, &EnclosingExpr,
18434 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
18435 StackComponents,
18436 OpenMPClauseKind Kind) {
18437 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
18438 return false;
18439 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18440, __PRETTY_FUNCTION__))
18440 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18440, __PRETTY_FUNCTION__))
;
18441 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18442, __PRETTY_FUNCTION__))
18442 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18442, __PRETTY_FUNCTION__))
;
18443 (void)VD;
18444
18445 // The whole expression in the stack.
18446 const Expr *RE = StackComponents.front().getAssociatedExpression();
18447
18448 // Expressions must start from the same base. Here we detect at which
18449 // point both expressions diverge from each other and see if we can
18450 // detect if the memory referred to both expressions is contiguous and
18451 // do not overlap.
18452 auto CI = CurComponents.rbegin();
18453 auto CE = CurComponents.rend();
18454 auto SI = StackComponents.rbegin();
18455 auto SE = StackComponents.rend();
18456 for (; CI != CE && SI != SE; ++CI, ++SI) {
18457
18458 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
18459 // At most one list item can be an array item derived from a given
18460 // variable in map clauses of the same construct.
18461 if (CurrentRegionOnly &&
18462 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
18463 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
18464 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
18465 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
18466 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
18467 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
18468 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
18469 diag::err_omp_multiple_array_items_in_map_clause)
18470 << CI->getAssociatedExpression()->getSourceRange();
18471 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
18472 diag::note_used_here)
18473 << SI->getAssociatedExpression()->getSourceRange();
18474 return true;
18475 }
18476
18477 // Do both expressions have the same kind?
18478 if (CI->getAssociatedExpression()->getStmtClass() !=
18479 SI->getAssociatedExpression()->getStmtClass())
18480 break;
18481
18482 // Are we dealing with different variables/fields?
18483 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
18484 break;
18485 }
18486 // Check if the extra components of the expressions in the enclosing
18487 // data environment are redundant for the current base declaration.
18488 // If they are, the maps completely overlap, which is legal.
18489 for (; SI != SE; ++SI) {
18490 QualType Type;
18491 if (const auto *ASE =
18492 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
18493 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
18494 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
18495 SI->getAssociatedExpression())) {
18496 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18497 Type =
18498 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18499 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
18500 SI->getAssociatedExpression())) {
18501 Type = OASE->getBase()->getType()->getPointeeType();
18502 }
18503 if (Type.isNull() || Type->isAnyPointerType() ||
18504 checkArrayExpressionDoesNotReferToWholeSize(
18505 SemaRef, SI->getAssociatedExpression(), Type))
18506 break;
18507 }
18508
18509 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
18510 // List items of map clauses in the same construct must not share
18511 // original storage.
18512 //
18513 // If the expressions are exactly the same or one is a subset of the
18514 // other, it means they are sharing storage.
18515 if (CI == CE && SI == SE) {
18516 if (CurrentRegionOnly) {
18517 if (CKind == OMPC_map) {
18518 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
18519 } else {
18520 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18520, __PRETTY_FUNCTION__))
;
18521 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
18522 << ERange;
18523 }
18524 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18525 << RE->getSourceRange();
18526 return true;
18527 }
18528 // If we find the same expression in the enclosing data environment,
18529 // that is legal.
18530 IsEnclosedByDataEnvironmentExpr = true;
18531 return false;
18532 }
18533
18534 QualType DerivedType =
18535 std::prev(CI)->getAssociatedDeclaration()->getType();
18536 SourceLocation DerivedLoc =
18537 std::prev(CI)->getAssociatedExpression()->getExprLoc();
18538
18539 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18540 // If the type of a list item is a reference to a type T then the type
18541 // will be considered to be T for all purposes of this clause.
18542 DerivedType = DerivedType.getNonReferenceType();
18543
18544 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
18545 // A variable for which the type is pointer and an array section
18546 // derived from that variable must not appear as list items of map
18547 // clauses of the same construct.
18548 //
18549 // Also, cover one of the cases in:
18550 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
18551 // If any part of the original storage of a list item has corresponding
18552 // storage in the device data environment, all of the original storage
18553 // must have corresponding storage in the device data environment.
18554 //
18555 if (DerivedType->isAnyPointerType()) {
18556 if (CI == CE || SI == SE) {
18557 SemaRef.Diag(
18558 DerivedLoc,
18559 diag::err_omp_pointer_mapped_along_with_derived_section)
18560 << DerivedLoc;
18561 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18562 << RE->getSourceRange();
18563 return true;
18564 }
18565 if (CI->getAssociatedExpression()->getStmtClass() !=
18566 SI->getAssociatedExpression()->getStmtClass() ||
18567 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
18568 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
18569 assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0)
: __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18569, __PRETTY_FUNCTION__))
;
18570 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
18571 << DerivedLoc;
18572 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18573 << RE->getSourceRange();
18574 return true;
18575 }
18576 }
18577
18578 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
18579 // List items of map clauses in the same construct must not share
18580 // original storage.
18581 //
18582 // An expression is a subset of the other.
18583 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
18584 if (CKind == OMPC_map) {
18585 if (CI != CE || SI != SE) {
18586 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
18587 // a pointer.
18588 auto Begin =
18589 CI != CE ? CurComponents.begin() : StackComponents.begin();
18590 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
18591 auto It = Begin;
18592 while (It != End && !It->getAssociatedDeclaration())
18593 std::advance(It, 1);
18594 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18595, __PRETTY_FUNCTION__))
18595 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18595, __PRETTY_FUNCTION__))
;
18596 if (It != Begin && It->getAssociatedDeclaration()
18597 ->getType()
18598 .getCanonicalType()
18599 ->isAnyPointerType()) {
18600 IsEnclosedByDataEnvironmentExpr = false;
18601 EnclosingExpr = nullptr;
18602 return false;
18603 }
18604 }
18605 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
18606 } else {
18607 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18607, __PRETTY_FUNCTION__))
;
18608 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
18609 << ERange;
18610 }
18611 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18612 << RE->getSourceRange();
18613 return true;
18614 }
18615
18616 // The current expression uses the same base as other expression in the
18617 // data environment but does not contain it completely.
18618 if (!CurrentRegionOnly && SI != SE)
18619 EnclosingExpr = RE;
18620
18621 // The current expression is a subset of the expression in the data
18622 // environment.
18623 IsEnclosedByDataEnvironmentExpr |=
18624 (!CurrentRegionOnly && CI != CE && SI == SE);
18625
18626 return false;
18627 });
18628
18629 if (CurrentRegionOnly)
18630 return FoundError;
18631
18632 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
18633 // If any part of the original storage of a list item has corresponding
18634 // storage in the device data environment, all of the original storage must
18635 // have corresponding storage in the device data environment.
18636 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
18637 // If a list item is an element of a structure, and a different element of
18638 // the structure has a corresponding list item in the device data environment
18639 // prior to a task encountering the construct associated with the map clause,
18640 // then the list item must also have a corresponding list item in the device
18641 // data environment prior to the task encountering the construct.
18642 //
18643 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
18644 SemaRef.Diag(ELoc,
18645 diag::err_omp_original_storage_is_shared_and_does_not_contain)
18646 << ERange;
18647 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
18648 << EnclosingExpr->getSourceRange();
18649 return true;
18650 }
18651
18652 return FoundError;
18653}
18654
18655// Look up the user-defined mapper given the mapper name and mapped type, and
18656// build a reference to it.
18657static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
18658 CXXScopeSpec &MapperIdScopeSpec,
18659 const DeclarationNameInfo &MapperId,
18660 QualType Type,
18661 Expr *UnresolvedMapper) {
18662 if (MapperIdScopeSpec.isInvalid())
18663 return ExprError();
18664 // Get the actual type for the array type.
18665 if (Type->isArrayType()) {
18666 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18666, __PRETTY_FUNCTION__))
;
18667 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
18668 }
18669 // Find all user-defined mappers with the given MapperId.
18670 SmallVector<UnresolvedSet<8>, 4> Lookups;
18671 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
18672 Lookup.suppressDiagnostics();
18673 if (S) {
18674 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
18675 NamedDecl *D = Lookup.getRepresentativeDecl();
18676 while (S && !S->isDeclScope(D))
18677 S = S->getParent();
18678 if (S)
18679 S = S->getParent();
18680 Lookups.emplace_back();
18681 Lookups.back().append(Lookup.begin(), Lookup.end());
18682 Lookup.clear();
18683 }
18684 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
18685 // Extract the user-defined mappers with the given MapperId.
18686 Lookups.push_back(UnresolvedSet<8>());
18687 for (NamedDecl *D : ULE->decls()) {
18688 auto *DMD = cast<OMPDeclareMapperDecl>(D);
18689 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18689, __PRETTY_FUNCTION__))
;
18690 Lookups.back().addDecl(DMD);
18691 }
18692 }
18693 // Defer the lookup for dependent types. The results will be passed through
18694 // UnresolvedMapper on instantiation.
18695 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
18696 Type->isInstantiationDependentType() ||
18697 Type->containsUnexpandedParameterPack() ||
18698 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18699 return !D->isInvalidDecl() &&
18700 (D->getType()->isDependentType() ||
18701 D->getType()->isInstantiationDependentType() ||
18702 D->getType()->containsUnexpandedParameterPack());
18703 })) {
18704 UnresolvedSet<8> URS;
18705 for (const UnresolvedSet<8> &Set : Lookups) {
18706 if (Set.empty())
18707 continue;
18708 URS.append(Set.begin(), Set.end());
18709 }
18710 return UnresolvedLookupExpr::Create(
18711 SemaRef.Context, /*NamingClass=*/nullptr,
18712 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
18713 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
18714 }
18715 SourceLocation Loc = MapperId.getLoc();
18716 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18717 // The type must be of struct, union or class type in C and C++
18718 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
18719 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
18720 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
18721 return ExprError();
18722 }
18723 // Perform argument dependent lookup.
18724 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
18725 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
18726 // Return the first user-defined mapper with the desired type.
18727 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18728 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
18729 if (!D->isInvalidDecl() &&
18730 SemaRef.Context.hasSameType(D->getType(), Type))
18731 return D;
18732 return nullptr;
18733 }))
18734 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18735 // Find the first user-defined mapper with a type derived from the desired
18736 // type.
18737 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18738 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
18739 if (!D->isInvalidDecl() &&
18740 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
18741 !Type.isMoreQualifiedThan(D->getType()))
18742 return D;
18743 return nullptr;
18744 })) {
18745 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18746 /*DetectVirtual=*/false);
18747 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
18748 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18749 VD->getType().getUnqualifiedType()))) {
18750 if (SemaRef.CheckBaseClassAccess(
18751 Loc, VD->getType(), Type, Paths.front(),
18752 /*DiagID=*/0) != Sema::AR_inaccessible) {
18753 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18754 }
18755 }
18756 }
18757 }
18758 // Report error if a mapper is specified, but cannot be found.
18759 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
18760 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
18761 << Type << MapperId.getName();
18762 return ExprError();
18763 }
18764 return ExprEmpty();
18765}
18766
18767namespace {
18768// Utility struct that gathers all the related lists associated with a mappable
18769// expression.
18770struct MappableVarListInfo {
18771 // The list of expressions.
18772 ArrayRef<Expr *> VarList;
18773 // The list of processed expressions.
18774 SmallVector<Expr *, 16> ProcessedVarList;
18775 // The mappble components for each expression.
18776 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
18777 // The base declaration of the variable.
18778 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
18779 // The reference to the user-defined mapper associated with every expression.
18780 SmallVector<Expr *, 16> UDMapperList;
18781
18782 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
18783 // We have a list of components and base declarations for each entry in the
18784 // variable list.
18785 VarComponents.reserve(VarList.size());
18786 VarBaseDeclarations.reserve(VarList.size());
18787 }
18788};
18789}
18790
18791// Check the validity of the provided variable list for the provided clause kind
18792// \a CKind. In the check process the valid expressions, mappable expression
18793// components, variables, and user-defined mappers are extracted and used to
18794// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
18795// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
18796// and \a MapperId are expected to be valid if the clause kind is 'map'.
18797static void checkMappableExpressionList(
18798 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
18799 MappableVarListInfo &MVLI, SourceLocation StartLoc,
18800 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
18801 ArrayRef<Expr *> UnresolvedMappers,
18802 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
18803 bool IsMapTypeImplicit = false) {
18804 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
18805 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18806, __PRETTY_FUNCTION__))
18806 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18806, __PRETTY_FUNCTION__))
;
18807
18808 // If the identifier of user-defined mapper is not specified, it is "default".
18809 // We do not change the actual name in this clause to distinguish whether a
18810 // mapper is specified explicitly, i.e., it is not explicitly specified when
18811 // MapperId.getName() is empty.
18812 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
18813 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
18814 MapperId.setName(DeclNames.getIdentifier(
18815 &SemaRef.getASTContext().Idents.get("default")));
18816 MapperId.setLoc(StartLoc);
18817 }
18818
18819 // Iterators to find the current unresolved mapper expression.
18820 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
18821 bool UpdateUMIt = false;
18822 Expr *UnresolvedMapper = nullptr;
18823
18824 // Keep track of the mappable components and base declarations in this clause.
18825 // Each entry in the list is going to have a list of components associated. We
18826 // record each set of the components so that we can build the clause later on.
18827 // In the end we should have the same amount of declarations and component
18828 // lists.
18829
18830 for (Expr *RE : MVLI.VarList) {
18831 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18831, __PRETTY_FUNCTION__))
;
18832 SourceLocation ELoc = RE->getExprLoc();
18833
18834 // Find the current unresolved mapper expression.
18835 if (UpdateUMIt && UMIt != UMEnd) {
18836 UMIt++;
18837 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18839, __PRETTY_FUNCTION__))
18838 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18839, __PRETTY_FUNCTION__))
18839 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18839, __PRETTY_FUNCTION__))
;
18840 }
18841 UpdateUMIt = true;
18842 if (UMIt != UMEnd)
18843 UnresolvedMapper = *UMIt;
18844
18845 const Expr *VE = RE->IgnoreParenLValueCasts();
18846
18847 if (VE->isValueDependent() || VE->isTypeDependent() ||
18848 VE->isInstantiationDependent() ||
18849 VE->containsUnexpandedParameterPack()) {
18850 // Try to find the associated user-defined mapper.
18851 ExprResult ER = buildUserDefinedMapperRef(
18852 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
18853 VE->getType().getCanonicalType(), UnresolvedMapper);
18854 if (ER.isInvalid())
18855 continue;
18856 MVLI.UDMapperList.push_back(ER.get());
18857 // We can only analyze this information once the missing information is
18858 // resolved.
18859 MVLI.ProcessedVarList.push_back(RE);
18860 continue;
18861 }
18862
18863 Expr *SimpleExpr = RE->IgnoreParenCasts();
18864
18865 if (!RE->isLValue()) {
18866 if (SemaRef.getLangOpts().OpenMP < 50) {
18867 SemaRef.Diag(
18868 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
18869 << RE->getSourceRange();
18870 } else {
18871 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18872 << getOpenMPClauseName(CKind) << RE->getSourceRange();
18873 }
18874 continue;
18875 }
18876
18877 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
18878 ValueDecl *CurDeclaration = nullptr;
18879
18880 // Obtain the array or member expression bases if required. Also, fill the
18881 // components array with all the components identified in the process.
18882 const Expr *BE = checkMapClauseExpressionBase(
18883 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
18884 /*NoDiagnose=*/false);
18885 if (!BE)
18886 continue;
18887
18888 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18889, __PRETTY_FUNCTION__))
18889 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18889, __PRETTY_FUNCTION__))
;
18890
18891 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
18892 // Add store "this" pointer to class in DSAStackTy for future checking
18893 DSAS->addMappedClassesQualTypes(TE->getType());
18894 // Try to find the associated user-defined mapper.
18895 ExprResult ER = buildUserDefinedMapperRef(
18896 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
18897 VE->getType().getCanonicalType(), UnresolvedMapper);
18898 if (ER.isInvalid())
18899 continue;
18900 MVLI.UDMapperList.push_back(ER.get());
18901 // Skip restriction checking for variable or field declarations
18902 MVLI.ProcessedVarList.push_back(RE);
18903 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18904 MVLI.VarComponents.back().append(CurComponents.begin(),
18905 CurComponents.end());
18906 MVLI.VarBaseDeclarations.push_back(nullptr);
18907 continue;
18908 }
18909
18910 // For the following checks, we rely on the base declaration which is
18911 // expected to be associated with the last component. The declaration is
18912 // expected to be a variable or a field (if 'this' is being mapped).
18913 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
18914 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18914, __PRETTY_FUNCTION__))
;
18915 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18917, __PRETTY_FUNCTION__))
18916 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18917, __PRETTY_FUNCTION__))
18917 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18917, __PRETTY_FUNCTION__))
;
18918
18919 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
18920 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
18921
18922 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18922, __PRETTY_FUNCTION__))
;
18923 (void)FD;
18924
18925 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
18926 // threadprivate variables cannot appear in a map clause.
18927 // OpenMP 4.5 [2.10.5, target update Construct]
18928 // threadprivate variables cannot appear in a from clause.
18929 if (VD && DSAS->isThreadPrivate(VD)) {
18930 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
18931 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
18932 << getOpenMPClauseName(CKind);
18933 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
18934 continue;
18935 }
18936
18937 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
18938 // A list item cannot appear in both a map clause and a data-sharing
18939 // attribute clause on the same construct.
18940
18941 // Check conflicts with other map clause expressions. We check the conflicts
18942 // with the current construct separately from the enclosing data
18943 // environment, because the restrictions are different. We only have to
18944 // check conflicts across regions for the map clauses.
18945 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
18946 /*CurrentRegionOnly=*/true, CurComponents, CKind))
18947 break;
18948 if (CKind == OMPC_map &&
18949 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
18950 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
18951 /*CurrentRegionOnly=*/false, CurComponents, CKind))
18952 break;
18953
18954 // OpenMP 4.5 [2.10.5, target update Construct]
18955 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18956 // If the type of a list item is a reference to a type T then the type will
18957 // be considered to be T for all purposes of this clause.
18958 auto I = llvm::find_if(
18959 CurComponents,
18960 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
18961 return MC.getAssociatedDeclaration();
18962 });
18963 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 18963, __PRETTY_FUNCTION__))
;
18964 (void)I;
18965 QualType Type;
18966 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
18967 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
18968 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
18969 if (ASE) {
18970 Type = ASE->getType().getNonReferenceType();
18971 } else if (OASE) {
18972 QualType BaseType =
18973 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18974 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18975 Type = ATy->getElementType();
18976 else
18977 Type = BaseType->getPointeeType();
18978 Type = Type.getNonReferenceType();
18979 } else if (OAShE) {
18980 Type = OAShE->getBase()->getType()->getPointeeType();
18981 } else {
18982 Type = VE->getType();
18983 }
18984
18985 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
18986 // A list item in a to or from clause must have a mappable type.
18987 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
18988 // A list item must have a mappable type.
18989 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
18990 DSAS, Type))
18991 continue;
18992
18993 if (CKind == OMPC_map) {
18994 // target enter data
18995 // OpenMP [2.10.2, Restrictions, p. 99]
18996 // A map-type must be specified in all map clauses and must be either
18997 // to or alloc.
18998 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
18999 if (DKind == OMPD_target_enter_data &&
19000 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
19001 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19002 << (IsMapTypeImplicit ? 1 : 0)
19003 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19004 << getOpenMPDirectiveName(DKind);
19005 continue;
19006 }
19007
19008 // target exit_data
19009 // OpenMP [2.10.3, Restrictions, p. 102]
19010 // A map-type must be specified in all map clauses and must be either
19011 // from, release, or delete.
19012 if (DKind == OMPD_target_exit_data &&
19013 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
19014 MapType == OMPC_MAP_delete)) {
19015 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19016 << (IsMapTypeImplicit ? 1 : 0)
19017 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19018 << getOpenMPDirectiveName(DKind);
19019 continue;
19020 }
19021
19022 // target, target data
19023 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
19024 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
19025 // A map-type in a map clause must be to, from, tofrom or alloc
19026 if ((DKind == OMPD_target_data ||
19027 isOpenMPTargetExecutionDirective(DKind)) &&
19028 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
19029 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
19030 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19031 << (IsMapTypeImplicit ? 1 : 0)
19032 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19033 << getOpenMPDirectiveName(DKind);
19034 continue;
19035 }
19036
19037 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
19038 // A list item cannot appear in both a map clause and a data-sharing
19039 // attribute clause on the same construct
19040 //
19041 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
19042 // A list item cannot appear in both a map clause and a data-sharing
19043 // attribute clause on the same construct unless the construct is a
19044 // combined construct.
19045 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
19046 isOpenMPTargetExecutionDirective(DKind)) ||
19047 DKind == OMPD_target)) {
19048 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19049 if (isOpenMPPrivate(DVar.CKind)) {
19050 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19051 << getOpenMPClauseName(DVar.CKind)
19052 << getOpenMPClauseName(OMPC_map)
19053 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
19054 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
19055 continue;
19056 }
19057 }
19058 }
19059
19060 // Try to find the associated user-defined mapper.
19061 ExprResult ER = buildUserDefinedMapperRef(
19062 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19063 Type.getCanonicalType(), UnresolvedMapper);
19064 if (ER.isInvalid())
19065 continue;
19066 MVLI.UDMapperList.push_back(ER.get());
19067
19068 // Save the current expression.
19069 MVLI.ProcessedVarList.push_back(RE);
19070
19071 // Store the components in the stack so that they can be used to check
19072 // against other clauses later on.
19073 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
19074 /*WhereFoundClauseKind=*/OMPC_map);
19075
19076 // Save the components and declaration to create the clause. For purposes of
19077 // the clause creation, any component list that has has base 'this' uses
19078 // null as base declaration.
19079 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19080 MVLI.VarComponents.back().append(CurComponents.begin(),
19081 CurComponents.end());
19082 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
19083 : CurDeclaration);
19084 }
19085}
19086
19087OMPClause *Sema::ActOnOpenMPMapClause(
19088 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
19089 ArrayRef<SourceLocation> MapTypeModifiersLoc,
19090 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19091 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
19092 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19093 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
19094 OpenMPMapModifierKind Modifiers[] = {
19095 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19096 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
19097 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
19098
19099 // Process map-type-modifiers, flag errors for duplicate modifiers.
19100 unsigned Count = 0;
19101 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
19102 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
19103 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
19104 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
19105 continue;
19106 }
19107 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19108, __PRETTY_FUNCTION__))
19108 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19108, __PRETTY_FUNCTION__))
;
19109 Modifiers[Count] = MapTypeModifiers[I];
19110 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
19111 ++Count;
19112 }
19113
19114 MappableVarListInfo MVLI(VarList);
19115 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
19116 MapperIdScopeSpec, MapperId, UnresolvedMappers,
19117 MapType, IsMapTypeImplicit);
19118
19119 // We need to produce a map clause even if we don't have variables so that
19120 // other diagnostics related with non-existing map clauses are accurate.
19121 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
19122 MVLI.VarBaseDeclarations, MVLI.VarComponents,
19123 MVLI.UDMapperList, Modifiers, ModifiersLoc,
19124 MapperIdScopeSpec.getWithLocInContext(Context),
19125 MapperId, MapType, IsMapTypeImplicit, MapLoc);
19126}
19127
19128QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
19129 TypeResult ParsedType) {
19130 assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail
("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19130, __PRETTY_FUNCTION__))
;
19131
19132 QualType ReductionType = GetTypeFromParser(ParsedType.get());
19133 if (ReductionType.isNull())
19134 return QualType();
19135
19136 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
19137 // A type name in a declare reduction directive cannot be a function type, an
19138 // array type, a reference type, or a type qualified with const, volatile or
19139 // restrict.
19140 if (ReductionType.hasQualifiers()) {
19141 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
19142 return QualType();
19143 }
19144
19145 if (ReductionType->isFunctionType()) {
19146 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
19147 return QualType();
19148 }
19149 if (ReductionType->isReferenceType()) {
19150 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
19151 return QualType();
19152 }
19153 if (ReductionType->isArrayType()) {
19154 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
19155 return QualType();
19156 }
19157 return ReductionType;
19158}
19159
19160Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
19161 Scope *S, DeclContext *DC, DeclarationName Name,
19162 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
19163 AccessSpecifier AS, Decl *PrevDeclInScope) {
19164 SmallVector<Decl *, 8> Decls;
19165 Decls.reserve(ReductionTypes.size());
19166
19167 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
19168 forRedeclarationInCurContext());
19169 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
19170 // A reduction-identifier may not be re-declared in the current scope for the
19171 // same type or for a type that is compatible according to the base language
19172 // rules.
19173 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19174 OMPDeclareReductionDecl *PrevDRD = nullptr;
19175 bool InCompoundScope = true;
19176 if (S != nullptr) {
19177 // Find previous declaration with the same name not referenced in other
19178 // declarations.
19179 FunctionScopeInfo *ParentFn = getEnclosingFunction();
19180 InCompoundScope =
19181 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19182 LookupName(Lookup, S);
19183 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19184 /*AllowInlineNamespace=*/false);
19185 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
19186 LookupResult::Filter Filter = Lookup.makeFilter();
19187 while (Filter.hasNext()) {
19188 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
19189 if (InCompoundScope) {
19190 auto I = UsedAsPrevious.find(PrevDecl);
19191 if (I == UsedAsPrevious.end())
19192 UsedAsPrevious[PrevDecl] = false;
19193 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
19194 UsedAsPrevious[D] = true;
19195 }
19196 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19197 PrevDecl->getLocation();
19198 }
19199 Filter.done();
19200 if (InCompoundScope) {
19201 for (const auto &PrevData : UsedAsPrevious) {
19202 if (!PrevData.second) {
19203 PrevDRD = PrevData.first;
19204 break;
19205 }
19206 }
19207 }
19208 } else if (PrevDeclInScope != nullptr) {
19209 auto *PrevDRDInScope = PrevDRD =
19210 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
19211 do {
19212 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
19213 PrevDRDInScope->getLocation();
19214 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
19215 } while (PrevDRDInScope != nullptr);
19216 }
19217 for (const auto &TyData : ReductionTypes) {
19218 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
19219 bool Invalid = false;
19220 if (I != PreviousRedeclTypes.end()) {
19221 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
19222 << TyData.first;
19223 Diag(I->second, diag::note_previous_definition);
19224 Invalid = true;
19225 }
19226 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
19227 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
19228 Name, TyData.first, PrevDRD);
19229 DC->addDecl(DRD);
19230 DRD->setAccess(AS);
19231 Decls.push_back(DRD);
19232 if (Invalid)
19233 DRD->setInvalidDecl();
19234 else
19235 PrevDRD = DRD;
19236 }
19237
19238 return DeclGroupPtrTy::make(
19239 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
19240}
19241
19242void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
19243 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19244
19245 // Enter new function scope.
19246 PushFunctionScope();
19247 setFunctionHasBranchProtectedScope();
19248 getCurFunction()->setHasOMPDeclareReductionCombiner();
19249
19250 if (S != nullptr)
19251 PushDeclContext(S, DRD);
19252 else
19253 CurContext = DRD;
19254
19255 PushExpressionEvaluationContext(
19256 ExpressionEvaluationContext::PotentiallyEvaluated);
19257
19258 QualType ReductionType = DRD->getType();
19259 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
19260 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
19261 // uses semantics of argument handles by value, but it should be passed by
19262 // reference. C lang does not support references, so pass all parameters as
19263 // pointers.
19264 // Create 'T omp_in;' variable.
19265 VarDecl *OmpInParm =
19266 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
19267 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
19268 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
19269 // uses semantics of argument handles by value, but it should be passed by
19270 // reference. C lang does not support references, so pass all parameters as
19271 // pointers.
19272 // Create 'T omp_out;' variable.
19273 VarDecl *OmpOutParm =
19274 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
19275 if (S != nullptr) {
19276 PushOnScopeChains(OmpInParm, S);
19277 PushOnScopeChains(OmpOutParm, S);
19278 } else {
19279 DRD->addDecl(OmpInParm);
19280 DRD->addDecl(OmpOutParm);
19281 }
19282 Expr *InE =
19283 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
19284 Expr *OutE =
19285 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
19286 DRD->setCombinerData(InE, OutE);
19287}
19288
19289void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
19290 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19291 DiscardCleanupsInEvaluationContext();
19292 PopExpressionEvaluationContext();
19293
19294 PopDeclContext();
19295 PopFunctionScopeInfo();
19296
19297 if (Combiner != nullptr)
19298 DRD->setCombiner(Combiner);
19299 else
19300 DRD->setInvalidDecl();
19301}
19302
19303VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
19304 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19305
19306 // Enter new function scope.
19307 PushFunctionScope();
19308 setFunctionHasBranchProtectedScope();
19309
19310 if (S != nullptr)
19311 PushDeclContext(S, DRD);
19312 else
19313 CurContext = DRD;
19314
19315 PushExpressionEvaluationContext(
19316 ExpressionEvaluationContext::PotentiallyEvaluated);
19317
19318 QualType ReductionType = DRD->getType();
19319 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
19320 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
19321 // uses semantics of argument handles by value, but it should be passed by
19322 // reference. C lang does not support references, so pass all parameters as
19323 // pointers.
19324 // Create 'T omp_priv;' variable.
19325 VarDecl *OmpPrivParm =
19326 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
19327 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
19328 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
19329 // uses semantics of argument handles by value, but it should be passed by
19330 // reference. C lang does not support references, so pass all parameters as
19331 // pointers.
19332 // Create 'T omp_orig;' variable.
19333 VarDecl *OmpOrigParm =
19334 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
19335 if (S != nullptr) {
19336 PushOnScopeChains(OmpPrivParm, S);
19337 PushOnScopeChains(OmpOrigParm, S);
19338 } else {
19339 DRD->addDecl(OmpPrivParm);
19340 DRD->addDecl(OmpOrigParm);
19341 }
19342 Expr *OrigE =
19343 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
19344 Expr *PrivE =
19345 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
19346 DRD->setInitializerData(OrigE, PrivE);
19347 return OmpPrivParm;
19348}
19349
19350void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
19351 VarDecl *OmpPrivParm) {
19352 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19353 DiscardCleanupsInEvaluationContext();
19354 PopExpressionEvaluationContext();
19355
19356 PopDeclContext();
19357 PopFunctionScopeInfo();
19358
19359 if (Initializer != nullptr) {
19360 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
19361 } else if (OmpPrivParm->hasInit()) {
19362 DRD->setInitializer(OmpPrivParm->getInit(),
19363 OmpPrivParm->isDirectInit()
19364 ? OMPDeclareReductionDecl::DirectInit
19365 : OMPDeclareReductionDecl::CopyInit);
19366 } else {
19367 DRD->setInvalidDecl();
19368 }
19369}
19370
19371Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
19372 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
19373 for (Decl *D : DeclReductions.get()) {
19374 if (IsValid) {
19375 if (S)
19376 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
19377 /*AddToContext=*/false);
19378 } else {
19379 D->setInvalidDecl();
19380 }
19381 }
19382 return DeclReductions;
19383}
19384
19385TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
19386 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
19387 QualType T = TInfo->getType();
19388 if (D.isInvalidType())
19389 return true;
19390
19391 if (getLangOpts().CPlusPlus) {
19392 // Check that there are no default arguments (C++ only).
19393 CheckExtraCXXDefaultArguments(D);
19394 }
19395
19396 return CreateParsedType(T, TInfo);
19397}
19398
19399QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
19400 TypeResult ParsedType) {
19401 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19401, __PRETTY_FUNCTION__))
;
19402
19403 QualType MapperType = GetTypeFromParser(ParsedType.get());
19404 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19404, __PRETTY_FUNCTION__))
;
19405
19406 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19407 // The type must be of struct, union or class type in C and C++
19408 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
19409 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
19410 return QualType();
19411 }
19412 return MapperType;
19413}
19414
19415Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
19416 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
19417 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
19418 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
19419 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
19420 forRedeclarationInCurContext());
19421 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19422 // A mapper-identifier may not be redeclared in the current scope for the
19423 // same type or for a type that is compatible according to the base language
19424 // rules.
19425 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19426 OMPDeclareMapperDecl *PrevDMD = nullptr;
19427 bool InCompoundScope = true;
19428 if (S != nullptr) {
19429 // Find previous declaration with the same name not referenced in other
19430 // declarations.
19431 FunctionScopeInfo *ParentFn = getEnclosingFunction();
19432 InCompoundScope =
19433 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19434 LookupName(Lookup, S);
19435 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19436 /*AllowInlineNamespace=*/false);
19437 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
19438 LookupResult::Filter Filter = Lookup.makeFilter();
19439 while (Filter.hasNext()) {
19440 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
19441 if (InCompoundScope) {
19442 auto I = UsedAsPrevious.find(PrevDecl);
19443 if (I == UsedAsPrevious.end())
19444 UsedAsPrevious[PrevDecl] = false;
19445 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
19446 UsedAsPrevious[D] = true;
19447 }
19448 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19449 PrevDecl->getLocation();
19450 }
19451 Filter.done();
19452 if (InCompoundScope) {
19453 for (const auto &PrevData : UsedAsPrevious) {
19454 if (!PrevData.second) {
19455 PrevDMD = PrevData.first;
19456 break;
19457 }
19458 }
19459 }
19460 } else if (PrevDeclInScope) {
19461 auto *PrevDMDInScope = PrevDMD =
19462 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
19463 do {
19464 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
19465 PrevDMDInScope->getLocation();
19466 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
19467 } while (PrevDMDInScope != nullptr);
19468 }
19469 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
19470 bool Invalid = false;
19471 if (I != PreviousRedeclTypes.end()) {
19472 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
19473 << MapperType << Name;
19474 Diag(I->second, diag::note_previous_definition);
19475 Invalid = true;
19476 }
19477 // Build expressions for implicit maps of data members with 'default'
19478 // mappers.
19479 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
19480 Clauses.end());
19481 if (LangOpts.OpenMP >= 50)
19482 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ClausesWithImplicit);
19483 auto *DMD =
19484 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
19485 ClausesWithImplicit, PrevDMD);
19486 if (S)
19487 PushOnScopeChains(DMD, S);
19488 else
19489 DC->addDecl(DMD);
19490 DMD->setAccess(AS);
19491 if (Invalid)
19492 DMD->setInvalidDecl();
19493
19494 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
19495 VD->setDeclContext(DMD);
19496 VD->setLexicalDeclContext(DMD);
19497 DMD->addDecl(VD);
19498 DMD->setMapperVarRef(MapperVarRef);
19499
19500 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
19501}
19502
19503ExprResult
19504Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
19505 SourceLocation StartLoc,
19506 DeclarationName VN) {
19507 TypeSourceInfo *TInfo =
19508 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
19509 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
19510 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
19511 MapperType, TInfo, SC_None);
19512 if (S)
19513 PushOnScopeChains(VD, S, /*AddToContext=*/false);
19514 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
19515 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
19516 return E;
19517}
19518
19519bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
19520 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19520, __PRETTY_FUNCTION__))
;
19521 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
19522 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
19523 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
19524 return true;
19525}
19526
19527const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
19528 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19528, __PRETTY_FUNCTION__))
;
19529 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
19530}
19531
19532OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
19533 SourceLocation StartLoc,
19534 SourceLocation LParenLoc,
19535 SourceLocation EndLoc) {
19536 Expr *ValExpr = NumTeams;
19537 Stmt *HelperValStmt = nullptr;
19538
19539 // OpenMP [teams Constrcut, Restrictions]
19540 // The num_teams expression must evaluate to a positive integer value.
19541 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
19542 /*StrictlyPositive=*/true))
19543 return nullptr;
19544
19545 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
19546 OpenMPDirectiveKind CaptureRegion =
19547 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
19548 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19549 ValExpr = MakeFullExpr(ValExpr).get();
19550 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19551 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19552 HelperValStmt = buildPreInits(Context, Captures);
19553 }
19554
19555 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
19556 StartLoc, LParenLoc, EndLoc);
19557}
19558
19559OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
19560 SourceLocation StartLoc,
19561 SourceLocation LParenLoc,
19562 SourceLocation EndLoc) {
19563 Expr *ValExpr = ThreadLimit;
19564 Stmt *HelperValStmt = nullptr;
19565
19566 // OpenMP [teams Constrcut, Restrictions]
19567 // The thread_limit expression must evaluate to a positive integer value.
19568 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
19569 /*StrictlyPositive=*/true))
19570 return nullptr;
19571
19572 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
19573 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
19574 DKind, OMPC_thread_limit, LangOpts.OpenMP);
19575 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19576 ValExpr = MakeFullExpr(ValExpr).get();
19577 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19578 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19579 HelperValStmt = buildPreInits(Context, Captures);
19580 }
19581
19582 return new (Context) OMPThreadLimitClause(
19583 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
19584}
19585
19586OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
19587 SourceLocation StartLoc,
19588 SourceLocation LParenLoc,
19589 SourceLocation EndLoc) {
19590 Expr *ValExpr = Priority;
19591 Stmt *HelperValStmt = nullptr;
19592 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19593
19594 // OpenMP [2.9.1, task Constrcut]
19595 // The priority-value is a non-negative numerical scalar expression.
19596 if (!isNonNegativeIntegerValue(
19597 ValExpr, *this, OMPC_priority,
19598 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
19599 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19600 return nullptr;
19601
19602 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
19603 StartLoc, LParenLoc, EndLoc);
19604}
19605
19606OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
19607 SourceLocation StartLoc,
19608 SourceLocation LParenLoc,
19609 SourceLocation EndLoc) {
19610 Expr *ValExpr = Grainsize;
19611 Stmt *HelperValStmt = nullptr;
19612 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19613
19614 // OpenMP [2.9.2, taskloop Constrcut]
19615 // The parameter of the grainsize clause must be a positive integer
19616 // expression.
19617 if (!isNonNegativeIntegerValue(
19618 ValExpr, *this, OMPC_grainsize,
19619 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
19620 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19621 return nullptr;
19622
19623 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
19624 StartLoc, LParenLoc, EndLoc);
19625}
19626
19627OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
19628 SourceLocation StartLoc,
19629 SourceLocation LParenLoc,
19630 SourceLocation EndLoc) {
19631 Expr *ValExpr = NumTasks;
19632 Stmt *HelperValStmt = nullptr;
19633 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19634
19635 // OpenMP [2.9.2, taskloop Constrcut]
19636 // The parameter of the num_tasks clause must be a positive integer
19637 // expression.
19638 if (!isNonNegativeIntegerValue(
19639 ValExpr, *this, OMPC_num_tasks,
19640 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
19641 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19642 return nullptr;
19643
19644 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
19645 StartLoc, LParenLoc, EndLoc);
19646}
19647
19648OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
19649 SourceLocation LParenLoc,
19650 SourceLocation EndLoc) {
19651 // OpenMP [2.13.2, critical construct, Description]
19652 // ... where hint-expression is an integer constant expression that evaluates
19653 // to a valid lock hint.
19654 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
19655 if (HintExpr.isInvalid())
19656 return nullptr;
19657 return new (Context)
19658 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
19659}
19660
19661/// Tries to find omp_event_handle_t type.
19662static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
19663 DSAStackTy *Stack) {
19664 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
19665 if (!OMPEventHandleT.isNull())
19666 return true;
19667 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
19668 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
19669 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19670 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
19671 return false;
19672 }
19673 Stack->setOMPEventHandleT(PT.get());
19674 return true;
19675}
19676
19677OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
19678 SourceLocation LParenLoc,
19679 SourceLocation EndLoc) {
19680 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
19681 !Evt->isInstantiationDependent() &&
19682 !Evt->containsUnexpandedParameterPack()) {
19683 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19684 return nullptr;
19685 // OpenMP 5.0, 2.10.1 task Construct.
19686 // event-handle is a variable of the omp_event_handle_t type.
19687 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
19688 if (!Ref) {
19689 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19690 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
19691 return nullptr;
19692 }
19693 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
19694 if (!VD) {
19695 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19696 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
19697 return nullptr;
19698 }
19699 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
19700 VD->getType()) ||
19701 VD->getType().isConstant(Context)) {
19702 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19703 << "omp_event_handle_t" << 1 << VD->getType()
19704 << Evt->getSourceRange();
19705 return nullptr;
19706 }
19707 // OpenMP 5.0, 2.10.1 task Construct
19708 // [detach clause]... The event-handle will be considered as if it was
19709 // specified on a firstprivate clause.
19710 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
19711 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
19712 DVar.RefExpr) {
19713 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
19714 << getOpenMPClauseName(DVar.CKind)
19715 << getOpenMPClauseName(OMPC_firstprivate);
19716 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
19717 return nullptr;
19718 }
19719 }
19720
19721 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
19722}
19723
19724OMPClause *Sema::ActOnOpenMPDistScheduleClause(
19725 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
19726 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
19727 SourceLocation EndLoc) {
19728 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
19729 std::string Values;
19730 Values += "'";
19731 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
19732 Values += "'";
19733 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19734 << Values << getOpenMPClauseName(OMPC_dist_schedule);
19735 return nullptr;
19736 }
19737 Expr *ValExpr = ChunkSize;
19738 Stmt *HelperValStmt = nullptr;
19739 if (ChunkSize) {
19740 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
19741 !ChunkSize->isInstantiationDependent() &&
19742 !ChunkSize->containsUnexpandedParameterPack()) {
19743 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
19744 ExprResult Val =
19745 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
19746 if (Val.isInvalid())
19747 return nullptr;
19748
19749 ValExpr = Val.get();
19750
19751 // OpenMP [2.7.1, Restrictions]
19752 // chunk_size must be a loop invariant integer expression with a positive
19753 // value.
19754 if (Optional<llvm::APSInt> Result =
19755 ValExpr->getIntegerConstantExpr(Context)) {
19756 if (Result->isSigned() && !Result->isStrictlyPositive()) {
19757 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
19758 << "dist_schedule" << ChunkSize->getSourceRange();
19759 return nullptr;
19760 }
19761 } else if (getOpenMPCaptureRegionForClause(
19762 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
19763 LangOpts.OpenMP) != OMPD_unknown &&
19764 !CurContext->isDependentContext()) {
19765 ValExpr = MakeFullExpr(ValExpr).get();
19766 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19767 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19768 HelperValStmt = buildPreInits(Context, Captures);
19769 }
19770 }
19771 }
19772
19773 return new (Context)
19774 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
19775 Kind, ValExpr, HelperValStmt);
19776}
19777
19778OMPClause *Sema::ActOnOpenMPDefaultmapClause(
19779 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
19780 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
19781 SourceLocation KindLoc, SourceLocation EndLoc) {
19782 if (getLangOpts().OpenMP < 50) {
19783 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
19784 Kind != OMPC_DEFAULTMAP_scalar) {
19785 std::string Value;
19786 SourceLocation Loc;
19787 Value += "'";
19788 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
19789 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19790 OMPC_DEFAULTMAP_MODIFIER_tofrom);
19791 Loc = MLoc;
19792 } else {
19793 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19794 OMPC_DEFAULTMAP_scalar);
19795 Loc = KindLoc;
19796 }
19797 Value += "'";
19798 Diag(Loc, diag::err_omp_unexpected_clause_value)
19799 << Value << getOpenMPClauseName(OMPC_defaultmap);
19800 return nullptr;
19801 }
19802 } else {
19803 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
19804 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
19805 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
19806 if (!isDefaultmapKind || !isDefaultmapModifier) {
19807 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
19808 if (LangOpts.OpenMP == 50) {
19809 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
19810 "'firstprivate', 'none', 'default'";
19811 if (!isDefaultmapKind && isDefaultmapModifier) {
19812 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19813 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19814 } else if (isDefaultmapKind && !isDefaultmapModifier) {
19815 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19816 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19817 } else {
19818 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19819 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19820 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19821 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19822 }
19823 } else {
19824 StringRef ModifierValue =
19825 "'alloc', 'from', 'to', 'tofrom', "
19826 "'firstprivate', 'none', 'default', 'present'";
19827 if (!isDefaultmapKind && isDefaultmapModifier) {
19828 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19829 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19830 } else if (isDefaultmapKind && !isDefaultmapModifier) {
19831 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19832 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19833 } else {
19834 Diag(MLoc, diag::err_omp_unexpected_clause_value)
19835 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19836 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19837 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19838 }
19839 }
19840 return nullptr;
19841 }
19842
19843 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
19844 // At most one defaultmap clause for each category can appear on the
19845 // directive.
19846 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
19847 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
19848 return nullptr;
19849 }
19850 }
19851 if (Kind == OMPC_DEFAULTMAP_unknown) {
19852 // Variable category is not specified - mark all categories.
19853 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
19854 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
19855 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
19856 } else {
19857 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
19858 }
19859
19860 return new (Context)
19861 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
19862}
19863
19864bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
19865 DeclContext *CurLexicalContext = getCurLexicalContext();
19866 if (!CurLexicalContext->isFileContext() &&
19867 !CurLexicalContext->isExternCContext() &&
19868 !CurLexicalContext->isExternCXXContext() &&
19869 !isa<CXXRecordDecl>(CurLexicalContext) &&
19870 !isa<ClassTemplateDecl>(CurLexicalContext) &&
19871 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
19872 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
19873 Diag(Loc, diag::err_omp_region_not_file_context);
19874 return false;
19875 }
19876 DeclareTargetNesting.push_back(Loc);
19877 return true;
19878}
19879
19880void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
19881 assert(!DeclareTargetNesting.empty() &&((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19882, __PRETTY_FUNCTION__))
19882 "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19882, __PRETTY_FUNCTION__))
;
19883 DeclareTargetNesting.pop_back();
19884}
19885
19886NamedDecl *
19887Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
19888 const DeclarationNameInfo &Id,
19889 NamedDeclSetType &SameDirectiveDecls) {
19890 LookupResult Lookup(*this, Id, LookupOrdinaryName);
19891 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
19892
19893 if (Lookup.isAmbiguous())
19894 return nullptr;
19895 Lookup.suppressDiagnostics();
19896
19897 if (!Lookup.isSingleResult()) {
19898 VarOrFuncDeclFilterCCC CCC(*this);
19899 if (TypoCorrection Corrected =
19900 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
19901 CTK_ErrorRecovery)) {
19902 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
19903 << Id.getName());
19904 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
19905 return nullptr;
19906 }
19907
19908 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
19909 return nullptr;
19910 }
19911
19912 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
19913 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
19914 !isa<FunctionTemplateDecl>(ND)) {
19915 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
19916 return nullptr;
19917 }
19918 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
19919 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
19920 return ND;
19921}
19922
19923void Sema::ActOnOpenMPDeclareTargetName(
19924 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
19925 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
19926 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19928, __PRETTY_FUNCTION__))
19927 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19928, __PRETTY_FUNCTION__))
19928 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 19928, __PRETTY_FUNCTION__))
;
19929
19930 // Diagnose marking after use as it may lead to incorrect diagnosis and
19931 // codegen.
19932 if (LangOpts.OpenMP >= 50 &&
19933 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
19934 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
19935
19936 auto *VD = cast<ValueDecl>(ND);
19937 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
19938 OMPDeclareTargetDeclAttr::getDeviceType(VD);
19939 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
19940 if (DevTy.hasValue() && *DevTy != DT &&
19941 (DeclareTargetNesting.empty() ||
19942 *AttrLoc != DeclareTargetNesting.back())) {
19943 Diag(Loc, diag::err_omp_device_type_mismatch)
19944 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
19945 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
19946 return;
19947 }
19948 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
19949 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
19950 if (!Res || (!DeclareTargetNesting.empty() &&
19951 *AttrLoc == DeclareTargetNesting.back())) {
19952 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
19953 Context, MT, DT, DeclareTargetNesting.size() + 1,
19954 SourceRange(Loc, Loc));
19955 ND->addAttr(A);
19956 if (ASTMutationListener *ML = Context.getASTMutationListener())
19957 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
19958 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
19959 } else if (*Res != MT) {
19960 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
19961 }
19962}
19963
19964static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
19965 Sema &SemaRef, Decl *D) {
19966 if (!D || !isa<VarDecl>(D))
19967 return;
19968 auto *VD = cast<VarDecl>(D);
19969 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
19970 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
19971 if (SemaRef.LangOpts.OpenMP >= 50 &&
19972 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
19973 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
19974 VD->hasGlobalStorage()) {
19975 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
19976 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
19977 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
19978 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
19979 // If a lambda declaration and definition appears between a
19980 // declare target directive and the matching end declare target
19981 // directive, all variables that are captured by the lambda
19982 // expression must also appear in a to clause.
19983 SemaRef.Diag(VD->getLocation(),
19984 diag::err_omp_lambda_capture_in_declare_target_not_to);
19985 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
19986 << VD << 0 << SR;
19987 return;
19988 }
19989 }
19990 if (MapTy.hasValue())
19991 return;
19992 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
19993 SemaRef.Diag(SL, diag::note_used_here) << SR;
19994}
19995
19996static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
19997 Sema &SemaRef, DSAStackTy *Stack,
19998 ValueDecl *VD) {
19999 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
20000 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
20001 /*FullCheck=*/false);
20002}
20003
20004void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
20005 SourceLocation IdLoc) {
20006 if (!D || D->isInvalidDecl())
20007 return;
20008 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
20009 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
20010 if (auto *VD = dyn_cast<VarDecl>(D)) {
20011 // Only global variables can be marked as declare target.
20012 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
20013 !VD->isStaticDataMember())
20014 return;
20015 // 2.10.6: threadprivate variable cannot appear in a declare target
20016 // directive.
20017 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
20018 Diag(SL, diag::err_omp_threadprivate_in_target);
20019 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
20020 return;
20021 }
20022 }
20023 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
20024 D = FTD->getTemplatedDecl();
20025 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
20026 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
20027 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
20028 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
20029 Diag(IdLoc, diag::err_omp_function_in_link_clause);
20030 Diag(FD->getLocation(), diag::note_defined_here) << FD;
20031 return;
20032 }
20033 }
20034 if (auto *VD = dyn_cast<ValueDecl>(D)) {
20035 // Problem if any with var declared with incomplete type will be reported
20036 // as normal, so no need to check it here.
20037 if ((E || !VD->getType()->isIncompleteType()) &&
20038 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
20039 return;
20040 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
20041 // Checking declaration inside declare target region.
20042 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
20043 isa<FunctionTemplateDecl>(D)) {
20044 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
20045 Context, OMPDeclareTargetDeclAttr::MT_To,
20046 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
20047 SourceRange(DeclareTargetNesting.back(),
20048 DeclareTargetNesting.back()));
20049 D->addAttr(A);
20050 if (ASTMutationListener *ML = Context.getASTMutationListener())
20051 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
20052 }
20053 return;
20054 }
20055 }
20056 if (!E)
20057 return;
20058 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
20059}
20060
20061OMPClause *Sema::ActOnOpenMPToClause(
20062 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20063 ArrayRef<SourceLocation> MotionModifiersLoc,
20064 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20065 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20066 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20067 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20068 OMPC_MOTION_MODIFIER_unknown};
20069 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20070
20071 // Process motion-modifiers, flag errors for duplicate modifiers.
20072 unsigned Count = 0;
20073 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20074 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20075 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20076 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20077 continue;
20078 }
20079 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20080, __PRETTY_FUNCTION__))
20080 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20080, __PRETTY_FUNCTION__))
;
20081 Modifiers[Count] = MotionModifiers[I];
20082 ModifiersLoc[Count] = MotionModifiersLoc[I];
20083 ++Count;
20084 }
20085
20086 MappableVarListInfo MVLI(VarList);
20087 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
20088 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20089 if (MVLI.ProcessedVarList.empty())
20090 return nullptr;
20091
20092 return OMPToClause::Create(
20093 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20094 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20095 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20096}
20097
20098OMPClause *Sema::ActOnOpenMPFromClause(
20099 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20100 ArrayRef<SourceLocation> MotionModifiersLoc,
20101 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20102 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20103 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20104 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20105 OMPC_MOTION_MODIFIER_unknown};
20106 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20107
20108 // Process motion-modifiers, flag errors for duplicate modifiers.
20109 unsigned Count = 0;
20110 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20111 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20112 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20113 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20114 continue;
20115 }
20116 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20117, __PRETTY_FUNCTION__))
20117 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20117, __PRETTY_FUNCTION__))
;
20118 Modifiers[Count] = MotionModifiers[I];
20119 ModifiersLoc[Count] = MotionModifiersLoc[I];
20120 ++Count;
20121 }
20122
20123 MappableVarListInfo MVLI(VarList);
20124 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
20125 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20126 if (MVLI.ProcessedVarList.empty())
20127 return nullptr;
20128
20129 return OMPFromClause::Create(
20130 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20131 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20132 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20133}
20134
20135OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
20136 const OMPVarListLocTy &Locs) {
20137 MappableVarListInfo MVLI(VarList);
20138 SmallVector<Expr *, 8> PrivateCopies;
20139 SmallVector<Expr *, 8> Inits;
20140
20141 for (Expr *RefExpr : VarList) {
20142 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20142, __PRETTY_FUNCTION__))
;
20143 SourceLocation ELoc;
20144 SourceRange ERange;
20145 Expr *SimpleRefExpr = RefExpr;
20146 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20147 if (Res.second) {
20148 // It will be analyzed later.
20149 MVLI.ProcessedVarList.push_back(RefExpr);
20150 PrivateCopies.push_back(nullptr);
20151 Inits.push_back(nullptr);
20152 }
20153 ValueDecl *D = Res.first;
20154 if (!D)
20155 continue;
20156
20157 QualType Type = D->getType();
20158 Type = Type.getNonReferenceType().getUnqualifiedType();
20159
20160 auto *VD = dyn_cast<VarDecl>(D);
20161
20162 // Item should be a pointer or reference to pointer.
20163 if (!Type->isPointerType()) {
20164 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
20165 << 0 << RefExpr->getSourceRange();
20166 continue;
20167 }
20168
20169 // Build the private variable and the expression that refers to it.
20170 auto VDPrivate =
20171 buildVarDecl(*this, ELoc, Type, D->getName(),
20172 D->hasAttrs() ? &D->getAttrs() : nullptr,
20173 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20174 if (VDPrivate->isInvalidDecl())
20175 continue;
20176
20177 CurContext->addDecl(VDPrivate);
20178 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
20179 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
20180
20181 // Add temporary variable to initialize the private copy of the pointer.
20182 VarDecl *VDInit =
20183 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
20184 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
20185 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
20186 AddInitializerToDecl(VDPrivate,
20187 DefaultLvalueConversion(VDInitRefExpr).get(),
20188 /*DirectInit=*/false);
20189
20190 // If required, build a capture to implement the privatization initialized
20191 // with the current list item value.
20192 DeclRefExpr *Ref = nullptr;
20193 if (!VD)
20194 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20195 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20196 PrivateCopies.push_back(VDPrivateRefExpr);
20197 Inits.push_back(VDInitRefExpr);
20198
20199 // We need to add a data sharing attribute for this variable to make sure it
20200 // is correctly captured. A variable that shows up in a use_device_ptr has
20201 // similar properties of a first private variable.
20202 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20203
20204 // Create a mappable component for the list item. List items in this clause
20205 // only need a component.
20206 MVLI.VarBaseDeclarations.push_back(D);
20207 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20208 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
20209 /*IsNonContiguous=*/false);
20210 }
20211
20212 if (MVLI.ProcessedVarList.empty())
20213 return nullptr;
20214
20215 return OMPUseDevicePtrClause::Create(
20216 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
20217 MVLI.VarBaseDeclarations, MVLI.VarComponents);
20218}
20219
20220OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
20221 const OMPVarListLocTy &Locs) {
20222 MappableVarListInfo MVLI(VarList);
20223
20224 for (Expr *RefExpr : VarList) {
20225 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20225, __PRETTY_FUNCTION__))
;
20226 SourceLocation ELoc;
20227 SourceRange ERange;
20228 Expr *SimpleRefExpr = RefExpr;
20229 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20230 /*AllowArraySection=*/true);
20231 if (Res.second) {
20232 // It will be analyzed later.
20233 MVLI.ProcessedVarList.push_back(RefExpr);
20234 }
20235 ValueDecl *D = Res.first;
20236 if (!D)
20237 continue;
20238 auto *VD = dyn_cast<VarDecl>(D);
20239
20240 // If required, build a capture to implement the privatization initialized
20241 // with the current list item value.
20242 DeclRefExpr *Ref = nullptr;
20243 if (!VD)
20244 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20245 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20246
20247 // We need to add a data sharing attribute for this variable to make sure it
20248 // is correctly captured. A variable that shows up in a use_device_addr has
20249 // similar properties of a first private variable.
20250 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20251
20252 // Create a mappable component for the list item. List items in this clause
20253 // only need a component.
20254 MVLI.VarBaseDeclarations.push_back(D);
20255 MVLI.VarComponents.emplace_back();
20256 Expr *Component = SimpleRefExpr;
20257 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
20258 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
20259 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
20260 MVLI.VarComponents.back().emplace_back(Component, D,
20261 /*IsNonContiguous=*/false);
20262 }
20263
20264 if (MVLI.ProcessedVarList.empty())
20265 return nullptr;
20266
20267 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20268 MVLI.VarBaseDeclarations,
20269 MVLI.VarComponents);
20270}
20271
20272OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
20273 const OMPVarListLocTy &Locs) {
20274 MappableVarListInfo MVLI(VarList);
20275 for (Expr *RefExpr : VarList) {
20276 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20276, __PRETTY_FUNCTION__))
;
20277 SourceLocation ELoc;
20278 SourceRange ERange;
20279 Expr *SimpleRefExpr = RefExpr;
20280 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20281 if (Res.second) {
20282 // It will be analyzed later.
20283 MVLI.ProcessedVarList.push_back(RefExpr);
20284 }
20285 ValueDecl *D = Res.first;
20286 if (!D)
20287 continue;
20288
20289 QualType Type = D->getType();
20290 // item should be a pointer or array or reference to pointer or array
20291 if (!Type.getNonReferenceType()->isPointerType() &&
20292 !Type.getNonReferenceType()->isArrayType()) {
20293 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
20294 << 0 << RefExpr->getSourceRange();
20295 continue;
20296 }
20297
20298 // Check if the declaration in the clause does not show up in any data
20299 // sharing attribute.
20300 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
20301 if (isOpenMPPrivate(DVar.CKind)) {
20302 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20303 << getOpenMPClauseName(DVar.CKind)
20304 << getOpenMPClauseName(OMPC_is_device_ptr)
20305 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
20306 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
20307 continue;
20308 }
20309
20310 const Expr *ConflictExpr;
20311 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
20312 D, /*CurrentRegionOnly=*/true,
20313 [&ConflictExpr](
20314 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
20315 OpenMPClauseKind) -> bool {
20316 ConflictExpr = R.front().getAssociatedExpression();
20317 return true;
20318 })) {
20319 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
20320 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
20321 << ConflictExpr->getSourceRange();
20322 continue;
20323 }
20324
20325 // Store the components in the stack so that they can be used to check
20326 // against other clauses later on.
20327 OMPClauseMappableExprCommon::MappableComponent MC(
20328 SimpleRefExpr, D, /*IsNonContiguous=*/false);
20329 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
20330 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
20331
20332 // Record the expression we've just processed.
20333 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
20334
20335 // Create a mappable component for the list item. List items in this clause
20336 // only need a component. We use a null declaration to signal fields in
20337 // 'this'.
20338 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20340, __PRETTY_FUNCTION__))
20339 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20340, __PRETTY_FUNCTION__))
20340 "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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20340, __PRETTY_FUNCTION__))
;
20341 MVLI.VarBaseDeclarations.push_back(
20342 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
20343 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20344 MVLI.VarComponents.back().push_back(MC);
20345 }
20346
20347 if (MVLI.ProcessedVarList.empty())
20348 return nullptr;
20349
20350 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20351 MVLI.VarBaseDeclarations,
20352 MVLI.VarComponents);
20353}
20354
20355OMPClause *Sema::ActOnOpenMPAllocateClause(
20356 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
20357 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
20358 if (Allocator) {
20359 // OpenMP [2.11.4 allocate Clause, Description]
20360 // allocator is an expression of omp_allocator_handle_t type.
20361 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
20362 return nullptr;
20363
20364 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
20365 if (AllocatorRes.isInvalid())
20366 return nullptr;
20367 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
20368 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
20369 Sema::AA_Initializing,
20370 /*AllowExplicit=*/true);
20371 if (AllocatorRes.isInvalid())
20372 return nullptr;
20373 Allocator = AllocatorRes.get();
20374 } else {
20375 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
20376 // allocate clauses that appear on a target construct or on constructs in a
20377 // target region must specify an allocator expression unless a requires
20378 // directive with the dynamic_allocators clause is present in the same
20379 // compilation unit.
20380 if (LangOpts.OpenMPIsDevice &&
20381 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
20382 targetDiag(StartLoc, diag::err_expected_allocator_expression);
20383 }
20384 // Analyze and build list of variables.
20385 SmallVector<Expr *, 8> Vars;
20386 for (Expr *RefExpr : VarList) {
20387 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20387, __PRETTY_FUNCTION__))
;
20388 SourceLocation ELoc;
20389 SourceRange ERange;
20390 Expr *SimpleRefExpr = RefExpr;
20391 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20392 if (Res.second) {
20393 // It will be analyzed later.
20394 Vars.push_back(RefExpr);
20395 }
20396 ValueDecl *D = Res.first;
20397 if (!D)
20398 continue;
20399
20400 auto *VD = dyn_cast<VarDecl>(D);
20401 DeclRefExpr *Ref = nullptr;
20402 if (!VD && !CurContext->isDependentContext())
20403 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20404 Vars.push_back((VD || CurContext->isDependentContext())
20405 ? RefExpr->IgnoreParens()
20406 : Ref);
20407 }
20408
20409 if (Vars.empty())
20410 return nullptr;
20411
20412 if (Allocator)
20413 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
20414 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
20415 ColonLoc, EndLoc, Vars);
20416}
20417
20418OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
20419 SourceLocation StartLoc,
20420 SourceLocation LParenLoc,
20421 SourceLocation EndLoc) {
20422 SmallVector<Expr *, 8> Vars;
20423 for (Expr *RefExpr : VarList) {
20424 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20424, __PRETTY_FUNCTION__))
;
20425 SourceLocation ELoc;
20426 SourceRange ERange;
20427 Expr *SimpleRefExpr = RefExpr;
20428 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20429 if (Res.second)
20430 // It will be analyzed later.
20431 Vars.push_back(RefExpr);
20432 ValueDecl *D = Res.first;
20433 if (!D)
20434 continue;
20435
20436 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
20437 // A list-item cannot appear in more than one nontemporal clause.
20438 if (const Expr *PrevRef =
20439 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
20440 Diag(ELoc, diag::err_omp_used_in_clause_twice)
20441 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
20442 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20443 << getOpenMPClauseName(OMPC_nontemporal);
20444 continue;
20445 }
20446
20447 Vars.push_back(RefExpr);
20448 }
20449
20450 if (Vars.empty())
20451 return nullptr;
20452
20453 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20454 Vars);
20455}
20456
20457OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
20458 SourceLocation StartLoc,
20459 SourceLocation LParenLoc,
20460 SourceLocation EndLoc) {
20461 SmallVector<Expr *, 8> Vars;
20462 for (Expr *RefExpr : VarList) {
20463 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20463, __PRETTY_FUNCTION__))
;
20464 SourceLocation ELoc;
20465 SourceRange ERange;
20466 Expr *SimpleRefExpr = RefExpr;
20467 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20468 /*AllowArraySection=*/true);
20469 if (Res.second)
20470 // It will be analyzed later.
20471 Vars.push_back(RefExpr);
20472 ValueDecl *D = Res.first;
20473 if (!D)
20474 continue;
20475
20476 const DSAStackTy::DSAVarData DVar =
20477 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
20478 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
20479 // A list item that appears in the inclusive or exclusive clause must appear
20480 // in a reduction clause with the inscan modifier on the enclosing
20481 // worksharing-loop, worksharing-loop SIMD, or simd construct.
20482 if (DVar.CKind != OMPC_reduction ||
20483 DVar.Modifier != OMPC_REDUCTION_inscan)
20484 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
20485 << RefExpr->getSourceRange();
20486
20487 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
20488 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
20489 Vars.push_back(RefExpr);
20490 }
20491
20492 if (Vars.empty())
20493 return nullptr;
20494
20495 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
20496}
20497
20498OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
20499 SourceLocation StartLoc,
20500 SourceLocation LParenLoc,
20501 SourceLocation EndLoc) {
20502 SmallVector<Expr *, 8> Vars;
20503 for (Expr *RefExpr : VarList) {
20504 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20504, __PRETTY_FUNCTION__))
;
20505 SourceLocation ELoc;
20506 SourceRange ERange;
20507 Expr *SimpleRefExpr = RefExpr;
20508 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20509 /*AllowArraySection=*/true);
20510 if (Res.second)
20511 // It will be analyzed later.
20512 Vars.push_back(RefExpr);
20513 ValueDecl *D = Res.first;
20514 if (!D)
20515 continue;
20516
20517 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
20518 DSAStackTy::DSAVarData DVar;
20519 if (ParentDirective != OMPD_unknown)
20520 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
20521 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
20522 // A list item that appears in the inclusive or exclusive clause must appear
20523 // in a reduction clause with the inscan modifier on the enclosing
20524 // worksharing-loop, worksharing-loop SIMD, or simd construct.
20525 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
20526 DVar.Modifier != OMPC_REDUCTION_inscan) {
20527 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
20528 << RefExpr->getSourceRange();
20529 } else {
20530 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
20531 }
20532 Vars.push_back(RefExpr);
20533 }
20534
20535 if (Vars.empty())
20536 return nullptr;
20537
20538 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
20539}
20540
20541/// Tries to find omp_alloctrait_t type.
20542static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
20543 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
20544 if (!OMPAlloctraitT.isNull())
20545 return true;
20546 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
20547 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
20548 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20549 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
20550 return false;
20551 }
20552 Stack->setOMPAlloctraitT(PT.get());
20553 return true;
20554}
20555
20556OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
20557 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
20558 ArrayRef<UsesAllocatorsData> Data) {
20559 // OpenMP [2.12.5, target Construct]
20560 // allocator is an identifier of omp_allocator_handle_t type.
20561 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
20562 return nullptr;
20563 // OpenMP [2.12.5, target Construct]
20564 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
20565 if (llvm::any_of(
20566 Data,
20567 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
20568 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
20569 return nullptr;
20570 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
20571 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
20572 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
20573 StringRef Allocator =
20574 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
20575 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
20576 PredefinedAllocators.insert(LookupSingleName(
20577 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
20578 }
20579
20580 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
20581 for (const UsesAllocatorsData &D : Data) {
20582 Expr *AllocatorExpr = nullptr;
20583 // Check allocator expression.
20584 if (D.Allocator->isTypeDependent()) {
20585 AllocatorExpr = D.Allocator;
20586 } else {
20587 // Traits were specified - need to assign new allocator to the specified
20588 // allocator, so it must be an lvalue.
20589 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
20590 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
20591 bool IsPredefinedAllocator = false;
20592 if (DRE)
20593 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
20594 if (!DRE ||
20595 !(Context.hasSameUnqualifiedType(
20596 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
20597 Context.typesAreCompatible(AllocatorExpr->getType(),
20598 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
20599 /*CompareUnqualified=*/true)) ||
20600 (!IsPredefinedAllocator &&
20601 (AllocatorExpr->getType().isConstant(Context) ||
20602 !AllocatorExpr->isLValue()))) {
20603 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
20604 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
20605 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
20606 continue;
20607 }
20608 // OpenMP [2.12.5, target Construct]
20609 // Predefined allocators appearing in a uses_allocators clause cannot have
20610 // traits specified.
20611 if (IsPredefinedAllocator && D.AllocatorTraits) {
20612 Diag(D.AllocatorTraits->getExprLoc(),
20613 diag::err_omp_predefined_allocator_with_traits)
20614 << D.AllocatorTraits->getSourceRange();
20615 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
20616 << cast<NamedDecl>(DRE->getDecl())->getName()
20617 << D.Allocator->getSourceRange();
20618 continue;
20619 }
20620 // OpenMP [2.12.5, target Construct]
20621 // Non-predefined allocators appearing in a uses_allocators clause must
20622 // have traits specified.
20623 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
20624 Diag(D.Allocator->getExprLoc(),
20625 diag::err_omp_nonpredefined_allocator_without_traits);
20626 continue;
20627 }
20628 // No allocator traits - just convert it to rvalue.
20629 if (!D.AllocatorTraits)
20630 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
20631 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
20632 DRE->getDecl(),
20633 IsPredefinedAllocator
20634 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
20635 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
20636 }
20637 Expr *AllocatorTraitsExpr = nullptr;
20638 if (D.AllocatorTraits) {
20639 if (D.AllocatorTraits->isTypeDependent()) {
20640 AllocatorTraitsExpr = D.AllocatorTraits;
20641 } else {
20642 // OpenMP [2.12.5, target Construct]
20643 // Arrays that contain allocator traits that appear in a uses_allocators
20644 // clause must be constant arrays, have constant values and be defined
20645 // in the same scope as the construct in which the clause appears.
20646 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
20647 // Check that traits expr is a constant array.
20648 QualType TraitTy;
20649 if (const ArrayType *Ty =
20650 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
20651 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
20652 TraitTy = ConstArrayTy->getElementType();
20653 if (TraitTy.isNull() ||
20654 !(Context.hasSameUnqualifiedType(TraitTy,
20655 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
20656 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
20657 /*CompareUnqualified=*/true))) {
20658 Diag(D.AllocatorTraits->getExprLoc(),
20659 diag::err_omp_expected_array_alloctraits)
20660 << AllocatorTraitsExpr->getType();
20661 continue;
20662 }
20663 // Do not map by default allocator traits if it is a standalone
20664 // variable.
20665 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
20666 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
20667 DRE->getDecl(),
20668 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
20669 }
20670 }
20671 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
20672 NewD.Allocator = AllocatorExpr;
20673 NewD.AllocatorTraits = AllocatorTraitsExpr;
20674 NewD.LParenLoc = D.LParenLoc;
20675 NewD.RParenLoc = D.RParenLoc;
20676 }
20677 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20678 NewData);
20679}
20680
20681OMPClause *Sema::ActOnOpenMPAffinityClause(
20682 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
20683 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
20684 SmallVector<Expr *, 8> Vars;
20685 for (Expr *RefExpr : Locators) {
20686 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~++20210405022414+5f57793c4fe4/clang/lib/Sema/SemaOpenMP.cpp"
, 20686, __PRETTY_FUNCTION__))
;
20687 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
20688 // It will be analyzed later.
20689 Vars.push_back(RefExpr);
20690 continue;
20691 }
20692
20693 SourceLocation ELoc = RefExpr->getExprLoc();
20694 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
20695
20696 if (!SimpleExpr->isLValue()) {
20697 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20698 << 1 << 0 << RefExpr->getSourceRange();
20699 continue;
20700 }
20701
20702 ExprResult Res;
20703 {
20704 Sema::TentativeAnalysisScope Trap(*this);
20705 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
20706 }
20707 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20708 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20709 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20710 << 1 << 0 << RefExpr->getSourceRange();
20711 continue;
20712 }
20713 Vars.push_back(SimpleExpr);
20714 }
20715
20716 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20717 EndLoc, Modifier, Vars);
20718}