Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/include -I /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-13/lib/clang/13.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2021-02-16-140612-21885-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 1941, __PRETTY_FUNCTION__))
;
1942 FunctionEmissionStatus FES = getEmissionStatus(FD);
1943 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944 switch (FES) {
1945 case FunctionEmissionStatus::Emitted:
1946 Kind = SemaDiagnosticBuilder::K_Immediate;
1947 break;
1948 case FunctionEmissionStatus::Unknown:
1949 Kind = SemaDiagnosticBuilder::K_Deferred;
1950 break;
1951 case FunctionEmissionStatus::TemplateDiscarded:
1952 case FunctionEmissionStatus::OMPDiscarded:
1953 case FunctionEmissionStatus::CUDADiscarded:
1954 Kind = SemaDiagnosticBuilder::K_Nop;
1955 break;
1956 }
1957
1958 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1959}
1960
1961static OpenMPDefaultmapClauseKind
1962getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1963 if (LO.OpenMP <= 45) {
1964 if (VD->getType().getNonReferenceType()->isScalarType())
1965 return OMPC_DEFAULTMAP_scalar;
1966 return OMPC_DEFAULTMAP_aggregate;
1967 }
1968 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1969 return OMPC_DEFAULTMAP_pointer;
1970 if (VD->getType().getNonReferenceType()->isScalarType())
1971 return OMPC_DEFAULTMAP_scalar;
1972 return OMPC_DEFAULTMAP_aggregate;
1973}
1974
1975bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1976 unsigned OpenMPCaptureLevel) const {
1977 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 1977, __PRETTY_FUNCTION__))
;
1978
1979 ASTContext &Ctx = getASTContext();
1980 bool IsByRef = true;
1981
1982 // Find the directive that is associated with the provided scope.
1983 D = cast<ValueDecl>(D->getCanonicalDecl());
1984 QualType Ty = D->getType();
1985
1986 bool IsVariableUsedInMapClause = false;
1987 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1988 // This table summarizes how a given variable should be passed to the device
1989 // given its type and the clauses where it appears. This table is based on
1990 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1991 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1992 //
1993 // =========================================================================
1994 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1995 // | |(tofrom:scalar)| | pvt | | | |
1996 // =========================================================================
1997 // | scl | | | | - | | bycopy|
1998 // | scl | | - | x | - | - | bycopy|
1999 // | scl | | x | - | - | - | null |
2000 // | scl | x | | | - | | byref |
2001 // | scl | x | - | x | - | - | bycopy|
2002 // | scl | x | x | - | - | - | null |
2003 // | scl | | - | - | - | x | byref |
2004 // | scl | x | - | - | - | x | byref |
2005 //
2006 // | agg | n.a. | | | - | | byref |
2007 // | agg | n.a. | - | x | - | - | byref |
2008 // | agg | n.a. | x | - | - | - | null |
2009 // | agg | n.a. | - | - | - | x | byref |
2010 // | agg | n.a. | - | - | - | x[] | byref |
2011 //
2012 // | ptr | n.a. | | | - | | bycopy|
2013 // | ptr | n.a. | - | x | - | - | bycopy|
2014 // | ptr | n.a. | x | - | - | - | null |
2015 // | ptr | n.a. | - | - | - | x | byref |
2016 // | ptr | n.a. | - | - | - | x[] | bycopy|
2017 // | ptr | n.a. | - | - | x | | bycopy|
2018 // | ptr | n.a. | - | - | x | x | bycopy|
2019 // | ptr | n.a. | - | - | x | x[] | bycopy|
2020 // =========================================================================
2021 // Legend:
2022 // scl - scalar
2023 // ptr - pointer
2024 // agg - aggregate
2025 // x - applies
2026 // - - invalid in this combination
2027 // [] - mapped with an array section
2028 // byref - should be mapped by reference
2029 // byval - should be mapped by value
2030 // null - initialize a local variable to null on the device
2031 //
2032 // Observations:
2033 // - All scalar declarations that show up in a map clause have to be passed
2034 // by reference, because they may have been mapped in the enclosing data
2035 // environment.
2036 // - If the scalar value does not fit the size of uintptr, it has to be
2037 // passed by reference, regardless the result in the table above.
2038 // - For pointers mapped by value that have either an implicit map or an
2039 // array section, the runtime library may pass the NULL value to the
2040 // device instead of the value passed to it by the compiler.
2041
2042 if (Ty->isReferenceType())
2043 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2044
2045 // Locate map clauses and see if the variable being captured is referred to
2046 // in any of those clauses. Here we only care about variables, not fields,
2047 // because fields are part of aggregates.
2048 bool IsVariableAssociatedWithSection = false;
2049
2050 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2051 D, Level,
2052 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2053 OMPClauseMappableExprCommon::MappableExprComponentListRef
2054 MapExprComponents,
2055 OpenMPClauseKind WhereFoundClauseKind) {
2056 // Only the map clause information influences how a variable is
2057 // captured. E.g. is_device_ptr does not require changing the default
2058 // behavior.
2059 if (WhereFoundClauseKind != OMPC_map)
2060 return false;
2061
2062 auto EI = MapExprComponents.rbegin();
2063 auto EE = MapExprComponents.rend();
2064
2065 assert(EI != EE && "Invalid map expression!")((EI != EE && "Invalid map expression!") ? static_cast
<void> (0) : __assert_fail ("EI != EE && \"Invalid map expression!\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2065, __PRETTY_FUNCTION__))
;
2066
2067 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2068 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2069
2070 ++EI;
2071 if (EI == EE)
2072 return false;
2073
2074 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2075 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2076 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2077 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2078 IsVariableAssociatedWithSection = true;
2079 // There is nothing more we need to know about this variable.
2080 return true;
2081 }
2082
2083 // Keep looking for more map info.
2084 return false;
2085 });
2086
2087 if (IsVariableUsedInMapClause) {
2088 // If variable is identified in a map clause it is always captured by
2089 // reference except if it is a pointer that is dereferenced somehow.
2090 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2091 } else {
2092 // By default, all the data that has a scalar type is mapped by copy
2093 // (except for reduction variables).
2094 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2095 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2096 !Ty->isAnyPointerType()) ||
2097 !Ty->isScalarType() ||
2098 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2099 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2100 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2101 D,
2102 [](OpenMPClauseKind K, bool AppliedToPointee) {
2103 return K == OMPC_reduction && !AppliedToPointee;
2104 },
2105 Level);
2106 }
2107 }
2108
2109 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2110 IsByRef =
2111 ((IsVariableUsedInMapClause &&
2112 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2113 OMPD_target) ||
2114 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2115 D,
2116 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2117 return K == OMPC_firstprivate ||
2118 (K == OMPC_reduction && AppliedToPointee);
2119 },
2120 Level, /*NotLastprivate=*/true) ||
2121 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2122 // If the variable is artificial and must be captured by value - try to
2123 // capture by value.
2124 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2125 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2126 // If the variable is implicitly firstprivate and scalar - capture by
2127 // copy
2128 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2129 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2130 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2131 Level) &&
2132 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2133 }
2134
2135 // When passing data by copy, we need to make sure it fits the uintptr size
2136 // and alignment, because the runtime library only deals with uintptr types.
2137 // If it does not fit the uintptr size, we need to pass the data by reference
2138 // instead.
2139 if (!IsByRef &&
2140 (Ctx.getTypeSizeInChars(Ty) >
2141 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2142 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2143 IsByRef = true;
2144 }
2145
2146 return IsByRef;
2147}
2148
2149unsigned Sema::getOpenMPNestingLevel() const {
2150 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2150, __PRETTY_FUNCTION__))
;
2151 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2152}
2153
2154bool Sema::isInOpenMPTargetExecutionDirective() const {
2155 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2156 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2157 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2158 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2159 SourceLocation) -> bool {
2160 return isOpenMPTargetExecutionDirective(K);
2161 },
2162 false);
2163}
2164
2165VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2166 unsigned StopAt) {
2167 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2167, __PRETTY_FUNCTION__))
;
2168 D = getCanonicalDecl(D);
2169
2170 auto *VD = dyn_cast<VarDecl>(D);
2171 // Do not capture constexpr variables.
2172 if (VD && VD->isConstexpr())
2173 return nullptr;
2174
2175 // If we want to determine whether the variable should be captured from the
2176 // perspective of the current capturing scope, and we've already left all the
2177 // capturing scopes of the top directive on the stack, check from the
2178 // perspective of its parent directive (if any) instead.
2179 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2180 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2181
2182 // If we are attempting to capture a global variable in a directive with
2183 // 'target' we return true so that this global is also mapped to the device.
2184 //
2185 if (VD && !VD->hasLocalStorage() &&
2186 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2187 if (isInOpenMPDeclareTargetContext()) {
2188 // Try to mark variable as declare target if it is used in capturing
2189 // regions.
2190 if (LangOpts.OpenMP <= 45 &&
2191 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2192 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2193 return nullptr;
2194 }
2195 if (isInOpenMPTargetExecutionDirective()) {
2196 // If the declaration is enclosed in a 'declare target' directive,
2197 // then it should not be captured.
2198 //
2199 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2200 return nullptr;
2201 CapturedRegionScopeInfo *CSI = nullptr;
2202 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2203 llvm::reverse(FunctionScopes),
2204 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2205 if (!isa<CapturingScopeInfo>(FSI))
2206 return nullptr;
2207 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2208 if (RSI->CapRegionKind == CR_OpenMP) {
2209 CSI = RSI;
2210 break;
2211 }
2212 }
2213 assert(CSI && "Failed to find CapturedRegionScopeInfo")((CSI && "Failed to find CapturedRegionScopeInfo") ? static_cast
<void> (0) : __assert_fail ("CSI && \"Failed to find CapturedRegionScopeInfo\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2213, __PRETTY_FUNCTION__))
;
2214 SmallVector<OpenMPDirectiveKind, 4> Regions;
2215 getOpenMPCaptureRegions(Regions,
2216 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2217 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2218 return VD;
2219 }
2220 }
2221
2222 if (CheckScopeInfo) {
2223 bool OpenMPFound = false;
2224 for (unsigned I = StopAt + 1; I > 0; --I) {
2225 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2226 if(!isa<CapturingScopeInfo>(FSI))
2227 return nullptr;
2228 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2229 if (RSI->CapRegionKind == CR_OpenMP) {
2230 OpenMPFound = true;
2231 break;
2232 }
2233 }
2234 if (!OpenMPFound)
2235 return nullptr;
2236 }
2237
2238 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2239 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2240 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2241 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2242 if (Info.first ||
2243 (VD && VD->hasLocalStorage() &&
2244 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2245 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2246 return VD ? VD : Info.second;
2247 DSAStackTy::DSAVarData DVarTop =
2248 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2249 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2250 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2251 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2252 // Threadprivate variables must not be captured.
2253 if (isOpenMPThreadPrivate(DVarTop.CKind))
2254 return nullptr;
2255 // The variable is not private or it is the variable in the directive with
2256 // default(none) clause and not used in any clause.
2257 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2258 D,
2259 [](OpenMPClauseKind C, bool AppliedToPointee) {
2260 return isOpenMPPrivate(C) && !AppliedToPointee;
2261 },
2262 [](OpenMPDirectiveKind) { return true; },
2263 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2264 // Global shared must not be captured.
2265 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2266 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2267 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2268 DVarTop.CKind == OMPC_shared))
2269 return nullptr;
2270 if (DVarPrivate.CKind != OMPC_unknown ||
2271 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2272 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2273 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2274 }
2275 return nullptr;
2276}
2277
2278void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2279 unsigned Level) const {
2280 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2281}
2282
2283void Sema::startOpenMPLoop() {
2284 assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2284, __PRETTY_FUNCTION__))
;
2285 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2286 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2287}
2288
2289void Sema::startOpenMPCXXRangeFor() {
2290 assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2290, __PRETTY_FUNCTION__))
;
2291 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2292 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2293 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2294 }
2295}
2296
2297OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2298 unsigned CapLevel) const {
2299 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2299, __PRETTY_FUNCTION__))
;
2300 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2301 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2302 Level)) {
2303 bool IsTriviallyCopyable =
2304 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2305 !D->getType()
2306 .getNonReferenceType()
2307 .getCanonicalType()
2308 ->getAsCXXRecordDecl();
2309 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2310 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2311 getOpenMPCaptureRegions(CaptureRegions, DKind);
2312 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2313 (IsTriviallyCopyable ||
2314 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2315 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2316 D,
2317 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2318 Level, /*NotLastprivate=*/true))
2319 return OMPC_firstprivate;
2320 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2321 if (DVar.CKind != OMPC_shared &&
2322 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2323 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2324 return OMPC_firstprivate;
2325 }
2326 }
2327 }
2328 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2329 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2330 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2331 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2332 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2333 return OMPC_private;
2334 }
2335 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2336 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2337 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2338 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2339 Level) &&
2340 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2341 return OMPC_private;
2342 }
2343 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2344 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2345 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2346 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2347 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2348 Level))
2349 return OMPC_private;
2350 }
2351 // User-defined allocators are private since they must be defined in the
2352 // context of target region.
2353 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2354 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2355 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2356 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2357 return OMPC_private;
2358 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2359 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2360 Level) ||
2361 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2362 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2363 // Consider taskgroup reduction descriptor variable a private
2364 // to avoid possible capture in the region.
2365 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2366 [](OpenMPDirectiveKind K) {
2367 return K == OMPD_taskgroup ||
2368 ((isOpenMPParallelDirective(K) ||
2369 isOpenMPWorksharingDirective(K)) &&
2370 !isOpenMPSimdDirective(K));
2371 },
2372 Level) &&
2373 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2374 ? OMPC_private
2375 : OMPC_unknown;
2376}
2377
2378void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2379 unsigned Level) {
2380 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2380, __PRETTY_FUNCTION__))
;
2381 D = getCanonicalDecl(D);
2382 OpenMPClauseKind OMPC = OMPC_unknown;
2383 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2384 const unsigned NewLevel = I - 1;
2385 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2386 D,
2387 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2388 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2389 OMPC = K;
2390 return true;
2391 }
2392 return false;
2393 },
2394 NewLevel))
2395 break;
2396 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2397 D, NewLevel,
2398 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2399 OpenMPClauseKind) { return true; })) {
2400 OMPC = OMPC_map;
2401 break;
2402 }
2403 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2404 NewLevel)) {
2405 OMPC = OMPC_map;
2406 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2407 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2408 OMPC = OMPC_firstprivate;
2409 break;
2410 }
2411 }
2412 if (OMPC != OMPC_unknown)
2413 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2414}
2415
2416bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2417 unsigned CaptureLevel) const {
2418 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2418, __PRETTY_FUNCTION__))
;
2419 // Return true if the current level is no longer enclosed in a target region.
2420
2421 SmallVector<OpenMPDirectiveKind, 4> Regions;
2422 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2423 const auto *VD = dyn_cast<VarDecl>(D);
2424 return VD && !VD->hasLocalStorage() &&
2425 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2426 Level) &&
2427 Regions[CaptureLevel] != OMPD_task;
2428}
2429
2430bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2431 unsigned CaptureLevel) const {
2432 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2432, __PRETTY_FUNCTION__))
;
2433 // Return true if the current level is no longer enclosed in a target region.
2434
2435 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2436 if (!VD->hasLocalStorage()) {
2437 if (isInOpenMPTargetExecutionDirective())
2438 return true;
2439 DSAStackTy::DSAVarData TopDVar =
2440 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2441 unsigned NumLevels =
2442 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2443 if (Level == 0)
2444 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2445 do {
2446 --Level;
2447 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2448 if (DVar.CKind != OMPC_shared)
2449 return true;
2450 } while (Level > 0);
2451 }
2452 }
2453 return true;
2454}
2455
2456void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2457
2458void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2459 OMPTraitInfo &TI) {
2460 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2461}
2462
2463void Sema::ActOnOpenMPEndDeclareVariant() {
2464 assert(isInOpenMPDeclareVariantScope() &&((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2465, __PRETTY_FUNCTION__))
2465 "Not in OpenMP declare variant scope!")((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2465, __PRETTY_FUNCTION__))
;
2466
2467 OMPDeclareVariantScopes.pop_back();
2468}
2469
2470void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2471 const FunctionDecl *Callee,
2472 SourceLocation Loc) {
2473 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.")((LangOpts.OpenMP && "Expected OpenMP compilation mode."
) ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP compilation mode.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2473, __PRETTY_FUNCTION__))
;
2474 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2475 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2476 // Ignore host functions during device analyzis.
2477 if (LangOpts.OpenMPIsDevice && DevTy &&
2478 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2479 return;
2480 // Ignore nohost functions during host analyzis.
2481 if (!LangOpts.OpenMPIsDevice && DevTy &&
2482 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2483 return;
2484 const FunctionDecl *FD = Callee->getMostRecentDecl();
2485 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2486 if (LangOpts.OpenMPIsDevice && DevTy &&
2487 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2488 // Diagnose host function called during device codegen.
2489 StringRef HostDevTy =
2490 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2491 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2492 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2493 diag::note_omp_marked_device_type_here)
2494 << HostDevTy;
2495 return;
2496 }
2497 if (!LangOpts.OpenMPIsDevice && DevTy &&
2498 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2499 // Diagnose nohost function called during host codegen.
2500 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2501 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2502 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2503 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2504 diag::note_omp_marked_device_type_here)
2505 << NoHostDevTy;
2506 }
2507}
2508
2509void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2510 const DeclarationNameInfo &DirName,
2511 Scope *CurScope, SourceLocation Loc) {
2512 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2513 PushExpressionEvaluationContext(
2514 ExpressionEvaluationContext::PotentiallyEvaluated);
2515}
2516
2517void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2518 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2519}
2520
2521void Sema::EndOpenMPClause() {
2522 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2523}
2524
2525static std::pair<ValueDecl *, bool>
2526getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2527 SourceRange &ERange, bool AllowArraySection = false);
2528
2529/// Check consistency of the reduction clauses.
2530static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2531 ArrayRef<OMPClause *> Clauses) {
2532 bool InscanFound = false;
2533 SourceLocation InscanLoc;
2534 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2535 // A reduction clause without the inscan reduction-modifier may not appear on
2536 // a construct on which a reduction clause with the inscan reduction-modifier
2537 // appears.
2538 for (OMPClause *C : Clauses) {
2539 if (C->getClauseKind() != OMPC_reduction)
2540 continue;
2541 auto *RC = cast<OMPReductionClause>(C);
2542 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2543 InscanFound = true;
2544 InscanLoc = RC->getModifierLoc();
2545 continue;
2546 }
2547 if (RC->getModifier() == OMPC_REDUCTION_task) {
2548 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2549 // A reduction clause with the task reduction-modifier may only appear on
2550 // a parallel construct, a worksharing construct or a combined or
2551 // composite construct for which any of the aforementioned constructs is a
2552 // constituent construct and simd or loop are not constituent constructs.
2553 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2554 if (!(isOpenMPParallelDirective(CurDir) ||
2555 isOpenMPWorksharingDirective(CurDir)) ||
2556 isOpenMPSimdDirective(CurDir))
2557 S.Diag(RC->getModifierLoc(),
2558 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2559 continue;
2560 }
2561 }
2562 if (InscanFound) {
2563 for (OMPClause *C : Clauses) {
2564 if (C->getClauseKind() != OMPC_reduction)
2565 continue;
2566 auto *RC = cast<OMPReductionClause>(C);
2567 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2568 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2569 ? RC->getBeginLoc()
2570 : RC->getModifierLoc(),
2571 diag::err_omp_inscan_reduction_expected);
2572 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2573 continue;
2574 }
2575 for (Expr *Ref : RC->varlists()) {
2576 assert(Ref && "NULL expr in OpenMP nontemporal clause.")((Ref && "NULL expr in OpenMP nontemporal clause.") ?
static_cast<void> (0) : __assert_fail ("Ref && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2576, __PRETTY_FUNCTION__))
;
2577 SourceLocation ELoc;
2578 SourceRange ERange;
2579 Expr *SimpleRefExpr = Ref;
2580 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2581 /*AllowArraySection=*/true);
2582 ValueDecl *D = Res.first;
2583 if (!D)
2584 continue;
2585 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2586 S.Diag(Ref->getExprLoc(),
2587 diag::err_omp_reduction_not_inclusive_exclusive)
2588 << Ref->getSourceRange();
2589 }
2590 }
2591 }
2592 }
2593}
2594
2595static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2596 ArrayRef<OMPClause *> Clauses);
2597static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2598 bool WithInit);
2599
2600static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2601 const ValueDecl *D,
2602 const DSAStackTy::DSAVarData &DVar,
2603 bool IsLoopIterVar = false);
2604
2605void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2606 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2607 // A variable of class type (or array thereof) that appears in a lastprivate
2608 // clause requires an accessible, unambiguous default constructor for the
2609 // class type, unless the list item is also specified in a firstprivate
2610 // clause.
2611 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2612 for (OMPClause *C : D->clauses()) {
2613 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2614 SmallVector<Expr *, 8> PrivateCopies;
2615 for (Expr *DE : Clause->varlists()) {
2616 if (DE->isValueDependent() || DE->isTypeDependent()) {
2617 PrivateCopies.push_back(nullptr);
2618 continue;
2619 }
2620 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2621 auto *VD = cast<VarDecl>(DRE->getDecl());
2622 QualType Type = VD->getType().getNonReferenceType();
2623 const DSAStackTy::DSAVarData DVar =
2624 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2625 if (DVar.CKind == OMPC_lastprivate) {
2626 // Generate helper private variable and initialize it with the
2627 // default value. The address of the original variable is replaced
2628 // by the address of the new private variable in CodeGen. This new
2629 // variable is not added to IdResolver, so the code in the OpenMP
2630 // region uses original variable for proper diagnostics.
2631 VarDecl *VDPrivate = buildVarDecl(
2632 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2633 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2634 ActOnUninitializedDecl(VDPrivate);
2635 if (VDPrivate->isInvalidDecl()) {
2636 PrivateCopies.push_back(nullptr);
2637 continue;
2638 }
2639 PrivateCopies.push_back(buildDeclRefExpr(
2640 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2641 } else {
2642 // The variable is also a firstprivate, so initialization sequence
2643 // for private copy is generated already.
2644 PrivateCopies.push_back(nullptr);
2645 }
2646 }
2647 Clause->setPrivateCopies(PrivateCopies);
2648 continue;
2649 }
2650 // Finalize nontemporal clause by handling private copies, if any.
2651 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2652 SmallVector<Expr *, 8> PrivateRefs;
2653 for (Expr *RefExpr : Clause->varlists()) {
2654 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 2654, __PRETTY_FUNCTION__))
;
2655 SourceLocation ELoc;
2656 SourceRange ERange;
2657 Expr *SimpleRefExpr = RefExpr;
2658 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2659 if (Res.second)
2660 // It will be analyzed later.
2661 PrivateRefs.push_back(RefExpr);
2662 ValueDecl *D = Res.first;
2663 if (!D)
2664 continue;
2665
2666 const DSAStackTy::DSAVarData DVar =
2667 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2668 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2669 : SimpleRefExpr);
2670 }
2671 Clause->setPrivateRefs(PrivateRefs);
2672 continue;
2673 }
2674 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2675 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2676 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2677 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2678 if (!DRE)
2679 continue;
2680 ValueDecl *VD = DRE->getDecl();
2681 if (!VD || !isa<VarDecl>(VD))
2682 continue;
2683 DSAStackTy::DSAVarData DVar =
2684 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2685 // OpenMP [2.12.5, target Construct]
2686 // Memory allocators that appear in a uses_allocators clause cannot
2687 // appear in other data-sharing attribute clauses or data-mapping
2688 // attribute clauses in the same construct.
2689 Expr *MapExpr = nullptr;
2690 if (DVar.RefExpr ||
2691 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2692 VD, /*CurrentRegionOnly=*/true,
2693 [VD, &MapExpr](
2694 OMPClauseMappableExprCommon::MappableExprComponentListRef
2695 MapExprComponents,
2696 OpenMPClauseKind C) {
2697 auto MI = MapExprComponents.rbegin();
2698 auto ME = MapExprComponents.rend();
2699 if (MI != ME &&
2700 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2701 VD->getCanonicalDecl()) {
2702 MapExpr = MI->getAssociatedExpression();
2703 return true;
2704 }
2705 return false;
2706 })) {
2707 Diag(D.Allocator->getExprLoc(),
2708 diag::err_omp_allocator_used_in_clauses)
2709 << D.Allocator->getSourceRange();
2710 if (DVar.RefExpr)
2711 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2712 else
2713 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2714 << MapExpr->getSourceRange();
2715 }
2716 }
2717 continue;
2718 }
2719 }
2720 // Check allocate clauses.
2721 if (!CurContext->isDependentContext())
2722 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2723 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2724 }
2725
2726 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2727 DiscardCleanupsInEvaluationContext();
2728 PopExpressionEvaluationContext();
2729}
2730
2731static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2732 Expr *NumIterations, Sema &SemaRef,
2733 Scope *S, DSAStackTy *Stack);
2734
2735namespace {
2736
2737class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2738private:
2739 Sema &SemaRef;
2740
2741public:
2742 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2743 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2744 NamedDecl *ND = Candidate.getCorrectionDecl();
2745 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2746 return VD->hasGlobalStorage() &&
2747 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2748 SemaRef.getCurScope());
2749 }
2750 return false;
2751 }
2752
2753 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2754 return std::make_unique<VarDeclFilterCCC>(*this);
2755 }
2756
2757};
2758
2759class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2760private:
2761 Sema &SemaRef;
2762
2763public:
2764 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2765 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2766 NamedDecl *ND = Candidate.getCorrectionDecl();
2767 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2768 isa<FunctionDecl>(ND))) {
2769 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2770 SemaRef.getCurScope());
2771 }
2772 return false;
2773 }
2774
2775 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2776 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2777 }
2778};
2779
2780} // namespace
2781
2782ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2783 CXXScopeSpec &ScopeSpec,
2784 const DeclarationNameInfo &Id,
2785 OpenMPDirectiveKind Kind) {
2786 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2787 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2788
2789 if (Lookup.isAmbiguous())
2790 return ExprError();
2791
2792 VarDecl *VD;
2793 if (!Lookup.isSingleResult()) {
2794 VarDeclFilterCCC CCC(*this);
2795 if (TypoCorrection Corrected =
2796 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2797 CTK_ErrorRecovery)) {
2798 diagnoseTypo(Corrected,
2799 PDiag(Lookup.empty()
2800 ? diag::err_undeclared_var_use_suggest
2801 : diag::err_omp_expected_var_arg_suggest)
2802 << Id.getName());
2803 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2804 } else {
2805 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2806 : diag::err_omp_expected_var_arg)
2807 << Id.getName();
2808 return ExprError();
2809 }
2810 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2811 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2812 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2813 return ExprError();
2814 }
2815 Lookup.suppressDiagnostics();
2816
2817 // OpenMP [2.9.2, Syntax, C/C++]
2818 // Variables must be file-scope, namespace-scope, or static block-scope.
2819 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2820 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2821 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2822 bool IsDecl =
2823 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2824 Diag(VD->getLocation(),
2825 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2826 << VD;
2827 return ExprError();
2828 }
2829
2830 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2831 NamedDecl *ND = CanonicalVD;
2832 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2833 // A threadprivate directive for file-scope variables must appear outside
2834 // any definition or declaration.
2835 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2836 !getCurLexicalContext()->isTranslationUnit()) {
2837 Diag(Id.getLoc(), diag::err_omp_var_scope)
2838 << getOpenMPDirectiveName(Kind) << VD;
2839 bool IsDecl =
2840 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2841 Diag(VD->getLocation(),
2842 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2843 << VD;
2844 return ExprError();
2845 }
2846 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2847 // A threadprivate directive for static class member variables must appear
2848 // in the class definition, in the same scope in which the member
2849 // variables are declared.
2850 if (CanonicalVD->isStaticDataMember() &&
2851 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2852 Diag(Id.getLoc(), diag::err_omp_var_scope)
2853 << getOpenMPDirectiveName(Kind) << VD;
2854 bool IsDecl =
2855 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2856 Diag(VD->getLocation(),
2857 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2858 << VD;
2859 return ExprError();
2860 }
2861 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2862 // A threadprivate directive for namespace-scope variables must appear
2863 // outside any definition or declaration other than the namespace
2864 // definition itself.
2865 if (CanonicalVD->getDeclContext()->isNamespace() &&
2866 (!getCurLexicalContext()->isFileContext() ||
2867 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2868 Diag(Id.getLoc(), diag::err_omp_var_scope)
2869 << getOpenMPDirectiveName(Kind) << VD;
2870 bool IsDecl =
2871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2872 Diag(VD->getLocation(),
2873 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2874 << VD;
2875 return ExprError();
2876 }
2877 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2878 // A threadprivate directive for static block-scope variables must appear
2879 // in the scope of the variable and not in a nested scope.
2880 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2881 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2882 Diag(Id.getLoc(), diag::err_omp_var_scope)
2883 << getOpenMPDirectiveName(Kind) << VD;
2884 bool IsDecl =
2885 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2886 Diag(VD->getLocation(),
2887 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2888 << VD;
2889 return ExprError();
2890 }
2891
2892 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2893 // A threadprivate directive must lexically precede all references to any
2894 // of the variables in its list.
2895 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2896 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2897 Diag(Id.getLoc(), diag::err_omp_var_used)
2898 << getOpenMPDirectiveName(Kind) << VD;
2899 return ExprError();
2900 }
2901
2902 QualType ExprType = VD->getType().getNonReferenceType();
2903 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2904 SourceLocation(), VD,
2905 /*RefersToEnclosingVariableOrCapture=*/false,
2906 Id.getLoc(), ExprType, VK_LValue);
2907}
2908
2909Sema::DeclGroupPtrTy
2910Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2911 ArrayRef<Expr *> VarList) {
2912 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2913 CurContext->addDecl(D);
2914 return DeclGroupPtrTy::make(DeclGroupRef(D));
2915 }
2916 return nullptr;
2917}
2918
2919namespace {
2920class LocalVarRefChecker final
2921 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2922 Sema &SemaRef;
2923
2924public:
2925 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2926 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2927 if (VD->hasLocalStorage()) {
2928 SemaRef.Diag(E->getBeginLoc(),
2929 diag::err_omp_local_var_in_threadprivate_init)
2930 << E->getSourceRange();
2931 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2932 << VD << VD->getSourceRange();
2933 return true;
2934 }
2935 }
2936 return false;
2937 }
2938 bool VisitStmt(const Stmt *S) {
2939 for (const Stmt *Child : S->children()) {
2940 if (Child && Visit(Child))
2941 return true;
2942 }
2943 return false;
2944 }
2945 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2946};
2947} // namespace
2948
2949OMPThreadPrivateDecl *
2950Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2951 SmallVector<Expr *, 8> Vars;
2952 for (Expr *RefExpr : VarList) {
2953 auto *DE = cast<DeclRefExpr>(RefExpr);
2954 auto *VD = cast<VarDecl>(DE->getDecl());
2955 SourceLocation ILoc = DE->getExprLoc();
2956
2957 // Mark variable as used.
2958 VD->setReferenced();
2959 VD->markUsed(Context);
2960
2961 QualType QType = VD->getType();
2962 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2963 // It will be analyzed later.
2964 Vars.push_back(DE);
2965 continue;
2966 }
2967
2968 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2969 // A threadprivate variable must not have an incomplete type.
2970 if (RequireCompleteType(ILoc, VD->getType(),
2971 diag::err_omp_threadprivate_incomplete_type)) {
2972 continue;
2973 }
2974
2975 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2976 // A threadprivate variable must not have a reference type.
2977 if (VD->getType()->isReferenceType()) {
2978 Diag(ILoc, diag::err_omp_ref_type_arg)
2979 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2980 bool IsDecl =
2981 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2982 Diag(VD->getLocation(),
2983 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2984 << VD;
2985 continue;
2986 }
2987
2988 // Check if this is a TLS variable. If TLS is not being supported, produce
2989 // the corresponding diagnostic.
2990 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2991 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2992 getLangOpts().OpenMPUseTLS &&
2993 getASTContext().getTargetInfo().isTLSSupported())) ||
2994 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2995 !VD->isLocalVarDecl())) {
2996 Diag(ILoc, diag::err_omp_var_thread_local)
2997 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2998 bool IsDecl =
2999 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3000 Diag(VD->getLocation(),
3001 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3002 << VD;
3003 continue;
3004 }
3005
3006 // Check if initial value of threadprivate variable reference variable with
3007 // local storage (it is not supported by runtime).
3008 if (const Expr *Init = VD->getAnyInitializer()) {
3009 LocalVarRefChecker Checker(*this);
3010 if (Checker.Visit(Init))
3011 continue;
3012 }
3013
3014 Vars.push_back(RefExpr);
3015 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3016 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3017 Context, SourceRange(Loc, Loc)));
3018 if (ASTMutationListener *ML = Context.getASTMutationListener())
3019 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3020 }
3021 OMPThreadPrivateDecl *D = nullptr;
3022 if (!Vars.empty()) {
3023 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3024 Vars);
3025 D->setAccess(AS_public);
3026 }
3027 return D;
3028}
3029
3030static OMPAllocateDeclAttr::AllocatorTypeTy
3031getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3032 if (!Allocator)
3033 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3034 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3035 Allocator->isInstantiationDependent() ||
3036 Allocator->containsUnexpandedParameterPack())
3037 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3038 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3039 const Expr *AE = Allocator->IgnoreParenImpCasts();
3040 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3041 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3042 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3043 llvm::FoldingSetNodeID AEId, DAEId;
3044 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3045 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3046 if (AEId == DAEId) {
3047 AllocatorKindRes = AllocatorKind;
3048 break;
3049 }
3050 }
3051 return AllocatorKindRes;
3052}
3053
3054static bool checkPreviousOMPAllocateAttribute(
3055 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3056 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3057 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3058 return false;
3059 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3060 Expr *PrevAllocator = A->getAllocator();
3061 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3062 getAllocatorKind(S, Stack, PrevAllocator);
3063 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3064 if (AllocatorsMatch &&
3065 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3066 Allocator && PrevAllocator) {
3067 const Expr *AE = Allocator->IgnoreParenImpCasts();
3068 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3069 llvm::FoldingSetNodeID AEId, PAEId;
3070 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3071 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3072 AllocatorsMatch = AEId == PAEId;
3073 }
3074 if (!AllocatorsMatch) {
3075 SmallString<256> AllocatorBuffer;
3076 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3077 if (Allocator)
3078 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3079 SmallString<256> PrevAllocatorBuffer;
3080 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3081 if (PrevAllocator)
3082 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3083 S.getPrintingPolicy());
3084
3085 SourceLocation AllocatorLoc =
3086 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3087 SourceRange AllocatorRange =
3088 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3089 SourceLocation PrevAllocatorLoc =
3090 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3091 SourceRange PrevAllocatorRange =
3092 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3093 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3094 << (Allocator ? 1 : 0) << AllocatorStream.str()
3095 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3096 << AllocatorRange;
3097 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3098 << PrevAllocatorRange;
3099 return true;
3100 }
3101 return false;
3102}
3103
3104static void
3105applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3106 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3107 Expr *Allocator, SourceRange SR) {
3108 if (VD->hasAttr<OMPAllocateDeclAttr>())
3109 return;
3110 if (Allocator &&
3111 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3112 Allocator->isInstantiationDependent() ||
3113 Allocator->containsUnexpandedParameterPack()))
3114 return;
3115 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3116 Allocator, SR);
3117 VD->addAttr(A);
3118 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3119 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3120}
3121
3122Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3123 SourceLocation Loc, ArrayRef<Expr *> VarList,
3124 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3125 assert(Clauses.size() <= 1 && "Expected at most one clause.")((Clauses.size() <= 1 && "Expected at most one clause."
) ? static_cast<void> (0) : __assert_fail ("Clauses.size() <= 1 && \"Expected at most one clause.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 3125, __PRETTY_FUNCTION__))
;
3126 Expr *Allocator = nullptr;
3127 if (Clauses.empty()) {
3128 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3129 // allocate directives that appear in a target region must specify an
3130 // allocator clause unless a requires directive with the dynamic_allocators
3131 // clause is present in the same compilation unit.
3132 if (LangOpts.OpenMPIsDevice &&
3133 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3134 targetDiag(Loc, diag::err_expected_allocator_clause);
3135 } else {
3136 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3137 }
3138 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3139 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3140 SmallVector<Expr *, 8> Vars;
3141 for (Expr *RefExpr : VarList) {
3142 auto *DE = cast<DeclRefExpr>(RefExpr);
3143 auto *VD = cast<VarDecl>(DE->getDecl());
3144
3145 // Check if this is a TLS variable or global register.
3146 if (VD->getTLSKind() != VarDecl::TLS_None ||
3147 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3148 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3149 !VD->isLocalVarDecl()))
3150 continue;
3151
3152 // If the used several times in the allocate directive, the same allocator
3153 // must be used.
3154 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3155 AllocatorKind, Allocator))
3156 continue;
3157
3158 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3159 // If a list item has a static storage type, the allocator expression in the
3160 // allocator clause must be a constant expression that evaluates to one of
3161 // the predefined memory allocator values.
3162 if (Allocator && VD->hasGlobalStorage()) {
3163 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3164 Diag(Allocator->getExprLoc(),
3165 diag::err_omp_expected_predefined_allocator)
3166 << Allocator->getSourceRange();
3167 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3168 VarDecl::DeclarationOnly;
3169 Diag(VD->getLocation(),
3170 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3171 << VD;
3172 continue;
3173 }
3174 }
3175
3176 Vars.push_back(RefExpr);
3177 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3178 DE->getSourceRange());
3179 }
3180 if (Vars.empty())
3181 return nullptr;
3182 if (!Owner)
3183 Owner = getCurLexicalContext();
3184 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3185 D->setAccess(AS_public);
3186 Owner->addDecl(D);
3187 return DeclGroupPtrTy::make(DeclGroupRef(D));
3188}
3189
3190Sema::DeclGroupPtrTy
3191Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3192 ArrayRef<OMPClause *> ClauseList) {
3193 OMPRequiresDecl *D = nullptr;
3194 if (!CurContext->isFileContext()) {
3195 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3196 } else {
3197 D = CheckOMPRequiresDecl(Loc, ClauseList);
3198 if (D) {
3199 CurContext->addDecl(D);
3200 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3201 }
3202 }
3203 return DeclGroupPtrTy::make(DeclGroupRef(D));
3204}
3205
3206void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3207 OpenMPDirectiveKind DKind,
3208 ArrayRef<StringRef> Assumptions,
3209 bool SkippedClauses) {
3210 if (!SkippedClauses && Assumptions.empty())
3211 Diag(Loc, diag::err_omp_no_clause_for_directive)
3212 << llvm::omp::getAllAssumeClauseOptions()
3213 << llvm::omp::getOpenMPDirectiveName(DKind);
3214
3215 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3216 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3217 OMPAssumeScoped.push_back(AA);
3218 return;
3219 }
3220
3221 // Global assumes without assumption clauses are ignored.
3222 if (Assumptions.empty())
3223 return;
3224
3225 assert(DKind == llvm::omp::Directive::OMPD_assumes &&((DKind == llvm::omp::Directive::OMPD_assumes && "Unexpected omp assumption directive!"
) ? static_cast<void> (0) : __assert_fail ("DKind == llvm::omp::Directive::OMPD_assumes && \"Unexpected omp assumption directive!\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 3226, __PRETTY_FUNCTION__))
3226 "Unexpected omp assumption directive!")((DKind == llvm::omp::Directive::OMPD_assumes && "Unexpected omp assumption directive!"
) ? static_cast<void> (0) : __assert_fail ("DKind == llvm::omp::Directive::OMPD_assumes && \"Unexpected omp assumption directive!\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 3226, __PRETTY_FUNCTION__))
;
3227 OMPAssumeGlobal.push_back(AA);
3228
3229 // The OMPAssumeGlobal scope above will take care of new declarations but
3230 // we also want to apply the assumption to existing ones, e.g., to
3231 // declarations in included headers. To this end, we traverse all existing
3232 // declaration contexts and annotate function declarations here.
3233 SmallVector<DeclContext *, 8> DeclContexts;
3234 auto *Ctx = CurContext;
3235 while (Ctx->getLexicalParent())
3236 Ctx = Ctx->getLexicalParent();
3237 DeclContexts.push_back(Ctx);
3238 while (!DeclContexts.empty()) {
3239 DeclContext *DC = DeclContexts.pop_back_val();
3240 for (auto *SubDC : DC->decls()) {
3241 if (SubDC->isInvalidDecl())
3242 continue;
3243 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3244 DeclContexts.push_back(CTD->getTemplatedDecl());
3245 for (auto *S : CTD->specializations())
3246 DeclContexts.push_back(S);
3247 continue;
3248 }
3249 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3250 DeclContexts.push_back(DC);
3251 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3252 F->addAttr(AA);
3253 continue;
3254 }
3255 }
3256 }
3257}
3258
3259void Sema::ActOnOpenMPEndAssumesDirective() {
3260 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!")((isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPAssumeScope() && \"Not in OpenMP assumes scope!\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 3260, __PRETTY_FUNCTION__))
;
3261 OMPAssumeScoped.pop_back();
3262}
3263
3264OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3265 ArrayRef<OMPClause *> ClauseList) {
3266 /// For target specific clauses, the requires directive cannot be
3267 /// specified after the handling of any of the target regions in the
3268 /// current compilation unit.
3269 ArrayRef<SourceLocation> TargetLocations =
3270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3271 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3272 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3273 for (const OMPClause *CNew : ClauseList) {
3274 // Check if any of the requires clauses affect target regions.
3275 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3276 isa<OMPUnifiedAddressClause>(CNew) ||
3277 isa<OMPReverseOffloadClause>(CNew) ||
3278 isa<OMPDynamicAllocatorsClause>(CNew)) {
3279 Diag(Loc, diag::err_omp_directive_before_requires)
3280 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3281 for (SourceLocation TargetLoc : TargetLocations) {
3282 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3283 << "target";
3284 }
3285 } else if (!AtomicLoc.isInvalid() &&
3286 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3287 Diag(Loc, diag::err_omp_directive_before_requires)
3288 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3289 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3290 << "atomic";
3291 }
3292 }
3293 }
3294
3295 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3296 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3297 ClauseList);
3298 return nullptr;
3299}
3300
3301static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3302 const ValueDecl *D,
3303 const DSAStackTy::DSAVarData &DVar,
3304 bool IsLoopIterVar) {
3305 if (DVar.RefExpr) {
3306 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3307 << getOpenMPClauseName(DVar.CKind);
3308 return;
3309 }
3310 enum {
3311 PDSA_StaticMemberShared,
3312 PDSA_StaticLocalVarShared,
3313 PDSA_LoopIterVarPrivate,
3314 PDSA_LoopIterVarLinear,
3315 PDSA_LoopIterVarLastprivate,
3316 PDSA_ConstVarShared,
3317 PDSA_GlobalVarShared,
3318 PDSA_TaskVarFirstprivate,
3319 PDSA_LocalVarPrivate,
3320 PDSA_Implicit
3321 } Reason = PDSA_Implicit;
3322 bool ReportHint = false;
3323 auto ReportLoc = D->getLocation();
3324 auto *VD = dyn_cast<VarDecl>(D);
3325 if (IsLoopIterVar) {
3326 if (DVar.CKind == OMPC_private)
3327 Reason = PDSA_LoopIterVarPrivate;
3328 else if (DVar.CKind == OMPC_lastprivate)
3329 Reason = PDSA_LoopIterVarLastprivate;
3330 else
3331 Reason = PDSA_LoopIterVarLinear;
3332 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3333 DVar.CKind == OMPC_firstprivate) {
3334 Reason = PDSA_TaskVarFirstprivate;
3335 ReportLoc = DVar.ImplicitDSALoc;
3336 } else if (VD && VD->isStaticLocal())
3337 Reason = PDSA_StaticLocalVarShared;
3338 else if (VD && VD->isStaticDataMember())
3339 Reason = PDSA_StaticMemberShared;
3340 else if (VD && VD->isFileVarDecl())
3341 Reason = PDSA_GlobalVarShared;
3342 else if (D->getType().isConstant(SemaRef.getASTContext()))
3343 Reason = PDSA_ConstVarShared;
3344 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3345 ReportHint = true;
3346 Reason = PDSA_LocalVarPrivate;
3347 }
3348 if (Reason != PDSA_Implicit) {
3349 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3350 << Reason << ReportHint
3351 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3352 } else if (DVar.ImplicitDSALoc.isValid()) {
3353 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3354 << getOpenMPClauseName(DVar.CKind);
3355 }
3356}
3357
3358static OpenMPMapClauseKind
3359getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3360 bool IsAggregateOrDeclareTarget) {
3361 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3362 switch (M) {
3363 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3364 Kind = OMPC_MAP_alloc;
3365 break;
3366 case OMPC_DEFAULTMAP_MODIFIER_to:
3367 Kind = OMPC_MAP_to;
3368 break;
3369 case OMPC_DEFAULTMAP_MODIFIER_from:
3370 Kind = OMPC_MAP_from;
3371 break;
3372 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3373 Kind = OMPC_MAP_tofrom;
3374 break;
3375 case OMPC_DEFAULTMAP_MODIFIER_present:
3376 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3377 // If implicit-behavior is present, each variable referenced in the
3378 // construct in the category specified by variable-category is treated as if
3379 // it had been listed in a map clause with the map-type of alloc and
3380 // map-type-modifier of present.
3381 Kind = OMPC_MAP_alloc;
3382 break;
3383 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3384 case OMPC_DEFAULTMAP_MODIFIER_last:
3385 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 3385)
;
3386 case OMPC_DEFAULTMAP_MODIFIER_none:
3387 case OMPC_DEFAULTMAP_MODIFIER_default:
3388 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3389 // IsAggregateOrDeclareTarget could be true if:
3390 // 1. the implicit behavior for aggregate is tofrom
3391 // 2. it's a declare target link
3392 if (IsAggregateOrDeclareTarget) {
3393 Kind = OMPC_MAP_tofrom;
3394 break;
3395 }
3396 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 3396)
;
3397 }
3398 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known")((Kind != OMPC_MAP_unknown && "Expect map kind to be known"
) ? static_cast<void> (0) : __assert_fail ("Kind != OMPC_MAP_unknown && \"Expect map kind to be known\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 3398, __PRETTY_FUNCTION__))
;
3399 return Kind;
3400}
3401
3402namespace {
3403class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3404 DSAStackTy *Stack;
3405 Sema &SemaRef;
3406 bool ErrorFound = false;
3407 bool TryCaptureCXXThisMembers = false;
3408 CapturedStmt *CS = nullptr;
3409 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3410 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3411 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3412 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3413 ImplicitMapModifier[DefaultmapKindNum];
3414 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3415 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3416
3417 void VisitSubCaptures(OMPExecutableDirective *S) {
3418 // Check implicitly captured variables.
3419 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3420 return;
3421 if (S->getDirectiveKind() == OMPD_atomic ||
3422 S->getDirectiveKind() == OMPD_critical ||
3423 S->getDirectiveKind() == OMPD_section ||
3424 S->getDirectiveKind() == OMPD_master) {
3425 Visit(S->getAssociatedStmt());
3426 return;
3427 }
3428 visitSubCaptures(S->getInnermostCapturedStmt());
3429 // Try to capture inner this->member references to generate correct mappings
3430 // and diagnostics.
3431 if (TryCaptureCXXThisMembers ||
3432 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3433 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3434 [](const CapturedStmt::Capture &C) {
3435 return C.capturesThis();
3436 }))) {
3437 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3438 TryCaptureCXXThisMembers = true;
3439 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3440 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3441 }
3442 // In tasks firstprivates are not captured anymore, need to analyze them
3443 // explicitly.
3444 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3445 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3446 for (OMPClause *C : S->clauses())
3447 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3448 for (Expr *Ref : FC->varlists())
3449 Visit(Ref);
3450 }
3451 }
3452 }
3453
3454public:
3455 void VisitDeclRefExpr(DeclRefExpr *E) {
3456 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3457 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3458 E->isInstantiationDependent())
3459 return;
3460 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3461 // Check the datasharing rules for the expressions in the clauses.
3462 if (!CS) {
3463 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3464 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3465 Visit(CED->getInit());
3466 return;
3467 }
3468 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3469 // Do not analyze internal variables and do not enclose them into
3470 // implicit clauses.
3471 return;
3472 VD = VD->getCanonicalDecl();
3473 // Skip internally declared variables.
3474 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3475 !Stack->isImplicitTaskFirstprivate(VD))
3476 return;
3477 // Skip allocators in uses_allocators clauses.
3478 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3479 return;
3480
3481 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3482 // Check if the variable has explicit DSA set and stop analysis if it so.
3483 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3484 return;
3485
3486 // Skip internally declared static variables.
3487 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3488 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3489 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3490 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3491 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3492 !Stack->isImplicitTaskFirstprivate(VD))
3493 return;
3494
3495 SourceLocation ELoc = E->getExprLoc();
3496 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3497 // The default(none) clause requires that each variable that is referenced
3498 // in the construct, and does not have a predetermined data-sharing
3499 // attribute, must have its data-sharing attribute explicitly determined
3500 // by being listed in a data-sharing attribute clause.
3501 if (DVar.CKind == OMPC_unknown &&
3502 (Stack->getDefaultDSA() == DSA_none ||
3503 Stack->getDefaultDSA() == DSA_firstprivate) &&
3504 isImplicitOrExplicitTaskingRegion(DKind) &&
3505 VarsWithInheritedDSA.count(VD) == 0) {
3506 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3507 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3508 DSAStackTy::DSAVarData DVar =
3509 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3510 InheritedDSA = DVar.CKind == OMPC_unknown;
3511 }
3512 if (InheritedDSA)
3513 VarsWithInheritedDSA[VD] = E;
3514 return;
3515 }
3516
3517 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3518 // If implicit-behavior is none, each variable referenced in the
3519 // construct that does not have a predetermined data-sharing attribute
3520 // and does not appear in a to or link clause on a declare target
3521 // directive must be listed in a data-mapping attribute clause, a
3522 // data-haring attribute clause (including a data-sharing attribute
3523 // clause on a combined construct where target. is one of the
3524 // constituent constructs), or an is_device_ptr clause.
3525 OpenMPDefaultmapClauseKind ClauseKind =
3526 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3527 if (SemaRef.getLangOpts().OpenMP >= 50) {
3528 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3529 OMPC_DEFAULTMAP_MODIFIER_none;
3530 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3531 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3532 // Only check for data-mapping attribute and is_device_ptr here
3533 // since we have already make sure that the declaration does not
3534 // have a data-sharing attribute above
3535 if (!Stack->checkMappableExprComponentListsForDecl(
3536 VD, /*CurrentRegionOnly=*/true,
3537 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3538 MapExprComponents,
3539 OpenMPClauseKind) {
3540 auto MI = MapExprComponents.rbegin();
3541 auto ME = MapExprComponents.rend();
3542 return MI != ME && MI->getAssociatedDeclaration() == VD;
3543 })) {
3544 VarsWithInheritedDSA[VD] = E;
3545 return;
3546 }
3547 }
3548 }
3549 if (SemaRef.getLangOpts().OpenMP > 50) {
3550 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3551 OMPC_DEFAULTMAP_MODIFIER_present;
3552 if (IsModifierPresent) {
3553 if (llvm::find(ImplicitMapModifier[ClauseKind],
3554 OMPC_MAP_MODIFIER_present) ==
3555 std::end(ImplicitMapModifier[ClauseKind])) {
3556 ImplicitMapModifier[ClauseKind].push_back(
3557 OMPC_MAP_MODIFIER_present);
3558 }
3559 }
3560 }
3561
3562 if (isOpenMPTargetExecutionDirective(DKind) &&
3563 !Stack->isLoopControlVariable(VD).first) {
3564 if (!Stack->checkMappableExprComponentListsForDecl(
3565 VD, /*CurrentRegionOnly=*/true,
3566 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3567 StackComponents,
3568 OpenMPClauseKind) {
3569 // Variable is used if it has been marked as an array, array
3570 // section, array shaping or the variable iself.
3571 return StackComponents.size() == 1 ||
3572 std::all_of(
3573 std::next(StackComponents.rbegin()),
3574 StackComponents.rend(),
3575 [](const OMPClauseMappableExprCommon::
3576 MappableComponent &MC) {
3577 return MC.getAssociatedDeclaration() ==
3578 nullptr &&
3579 (isa<OMPArraySectionExpr>(
3580 MC.getAssociatedExpression()) ||
3581 isa<OMPArrayShapingExpr>(
3582 MC.getAssociatedExpression()) ||
3583 isa<ArraySubscriptExpr>(
3584 MC.getAssociatedExpression()));
3585 });
3586 })) {
3587 bool IsFirstprivate = false;
3588 // By default lambdas are captured as firstprivates.
3589 if (const auto *RD =
3590 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3591 IsFirstprivate = RD->isLambda();
3592 IsFirstprivate =
3593 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3594 if (IsFirstprivate) {
3595 ImplicitFirstprivate.emplace_back(E);
3596 } else {
3597 OpenMPDefaultmapClauseModifier M =
3598 Stack->getDefaultmapModifier(ClauseKind);
3599 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3600 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3601 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3602 }
3603 return;
3604 }
3605 }
3606
3607 // OpenMP [2.9.3.6, Restrictions, p.2]
3608 // A list item that appears in a reduction clause of the innermost
3609 // enclosing worksharing or parallel construct may not be accessed in an
3610 // explicit task.
3611 DVar = Stack->hasInnermostDSA(
3612 VD,
3613 [](OpenMPClauseKind C, bool AppliedToPointee) {
3614 return C == OMPC_reduction && !AppliedToPointee;
3615 },
3616 [](OpenMPDirectiveKind K) {
3617 return isOpenMPParallelDirective(K) ||
3618 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3619 },
3620 /*FromParent=*/true);
3621 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3622 ErrorFound = true;
3623 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3624 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3625 return;
3626 }
3627
3628 // Define implicit data-sharing attributes for task.
3629 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3630 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3631 (Stack->getDefaultDSA() == DSA_firstprivate &&
3632 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3633 !Stack->isLoopControlVariable(VD).first) {
3634 ImplicitFirstprivate.push_back(E);
3635 return;
3636 }
3637
3638 // Store implicitly used globals with declare target link for parent
3639 // target.
3640 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3641 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3642 Stack->addToParentTargetRegionLinkGlobals(E);
3643 return;
3644 }
3645 }
3646 }
3647 void VisitMemberExpr(MemberExpr *E) {
3648 if (E->isTypeDependent() || E->isValueDependent() ||
3649 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3650 return;
3651 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3652 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3653 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3654 if (!FD)
3655 return;
3656 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3657 // Check if the variable has explicit DSA set and stop analysis if it
3658 // so.
3659 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3660 return;
3661
3662 if (isOpenMPTargetExecutionDirective(DKind) &&
3663 !Stack->isLoopControlVariable(FD).first &&
3664 !Stack->checkMappableExprComponentListsForDecl(
3665 FD, /*CurrentRegionOnly=*/true,
3666 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3667 StackComponents,
3668 OpenMPClauseKind) {
3669 return isa<CXXThisExpr>(
3670 cast<MemberExpr>(
3671 StackComponents.back().getAssociatedExpression())
3672 ->getBase()
3673 ->IgnoreParens());
3674 })) {
3675 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3676 // A bit-field cannot appear in a map clause.
3677 //
3678 if (FD->isBitField())
3679 return;
3680
3681 // Check to see if the member expression is referencing a class that
3682 // has already been explicitly mapped
3683 if (Stack->isClassPreviouslyMapped(TE->getType()))
3684 return;
3685
3686 OpenMPDefaultmapClauseModifier Modifier =
3687 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3688 OpenMPDefaultmapClauseKind ClauseKind =
3689 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3690 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3691 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3692 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3693 return;
3694 }
3695
3696 SourceLocation ELoc = E->getExprLoc();
3697 // OpenMP [2.9.3.6, Restrictions, p.2]
3698 // A list item that appears in a reduction clause of the innermost
3699 // enclosing worksharing or parallel construct may not be accessed in
3700 // an explicit task.
3701 DVar = Stack->hasInnermostDSA(
3702 FD,
3703 [](OpenMPClauseKind C, bool AppliedToPointee) {
3704 return C == OMPC_reduction && !AppliedToPointee;
3705 },
3706 [](OpenMPDirectiveKind K) {
3707 return isOpenMPParallelDirective(K) ||
3708 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3709 },
3710 /*FromParent=*/true);
3711 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3712 ErrorFound = true;
3713 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3714 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3715 return;
3716 }
3717
3718 // Define implicit data-sharing attributes for task.
3719 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3720 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3721 !Stack->isLoopControlVariable(FD).first) {
3722 // Check if there is a captured expression for the current field in the
3723 // region. Do not mark it as firstprivate unless there is no captured
3724 // expression.
3725 // TODO: try to make it firstprivate.
3726 if (DVar.CKind != OMPC_unknown)
3727 ImplicitFirstprivate.push_back(E);
3728 }
3729 return;
3730 }
3731 if (isOpenMPTargetExecutionDirective(DKind)) {
3732 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3733 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3734 Stack->getCurrentDirective(),
3735 /*NoDiagnose=*/true))
3736 return;
3737 const auto *VD = cast<ValueDecl>(
3738 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3739 if (!Stack->checkMappableExprComponentListsForDecl(
3740 VD, /*CurrentRegionOnly=*/true,
3741 [&CurComponents](
3742 OMPClauseMappableExprCommon::MappableExprComponentListRef
3743 StackComponents,
3744 OpenMPClauseKind) {
3745 auto CCI = CurComponents.rbegin();
3746 auto CCE = CurComponents.rend();
3747 for (const auto &SC : llvm::reverse(StackComponents)) {
3748 // Do both expressions have the same kind?
3749 if (CCI->getAssociatedExpression()->getStmtClass() !=
3750 SC.getAssociatedExpression()->getStmtClass())
3751 if (!((isa<OMPArraySectionExpr>(
3752 SC.getAssociatedExpression()) ||
3753 isa<OMPArrayShapingExpr>(
3754 SC.getAssociatedExpression())) &&
3755 isa<ArraySubscriptExpr>(
3756 CCI->getAssociatedExpression())))
3757 return false;
3758
3759 const Decl *CCD = CCI->getAssociatedDeclaration();
3760 const Decl *SCD = SC.getAssociatedDeclaration();
3761 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3762 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3763 if (SCD != CCD)
3764 return false;
3765 std::advance(CCI, 1);
3766 if (CCI == CCE)
3767 break;
3768 }
3769 return true;
3770 })) {
3771 Visit(E->getBase());
3772 }
3773 } else if (!TryCaptureCXXThisMembers) {
3774 Visit(E->getBase());
3775 }
3776 }
3777 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3778 for (OMPClause *C : S->clauses()) {
3779 // Skip analysis of arguments of implicitly defined firstprivate clause
3780 // for task|target directives.
3781 // Skip analysis of arguments of implicitly defined map clause for target
3782 // directives.
3783 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3784 C->isImplicit() &&
3785 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3786 for (Stmt *CC : C->children()) {
3787 if (CC)
3788 Visit(CC);
3789 }
3790 }
3791 }
3792 // Check implicitly captured variables.
3793 VisitSubCaptures(S);
3794 }
3795 void VisitStmt(Stmt *S) {
3796 for (Stmt *C : S->children()) {
3797 if (C) {
3798 // Check implicitly captured variables in the task-based directives to
3799 // check if they must be firstprivatized.
3800 Visit(C);
3801 }
3802 }
3803 }
3804
3805 void visitSubCaptures(CapturedStmt *S) {
3806 for (const CapturedStmt::Capture &Cap : S->captures()) {
3807 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3808 continue;
3809 VarDecl *VD = Cap.getCapturedVar();
3810 // Do not try to map the variable if it or its sub-component was mapped
3811 // already.
3812 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3813 Stack->checkMappableExprComponentListsForDecl(
3814 VD, /*CurrentRegionOnly=*/true,
3815 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3816 OpenMPClauseKind) { return true; }))
3817 continue;
3818 DeclRefExpr *DRE = buildDeclRefExpr(
3819 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3820 Cap.getLocation(), /*RefersToCapture=*/true);
3821 Visit(DRE);
3822 }
3823 }
3824 bool isErrorFound() const { return ErrorFound; }
3825 ArrayRef<Expr *> getImplicitFirstprivate() const {
3826 return ImplicitFirstprivate;
3827 }
3828 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3829 OpenMPMapClauseKind MK) const {
3830 return ImplicitMap[DK][MK];
3831 }
3832 ArrayRef<OpenMPMapModifierKind>
3833 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3834 return ImplicitMapModifier[Kind];
3835 }
3836 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3837 return VarsWithInheritedDSA;
3838 }
3839
3840 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3841 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3842 // Process declare target link variables for the target directives.
3843 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3844 for (DeclRefExpr *E : Stack->getLinkGlobals())
3845 Visit(E);
3846 }
3847 }
3848};
3849} // namespace
3850
3851void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3852 switch (DKind) {
3853 case OMPD_parallel:
3854 case OMPD_parallel_for:
3855 case OMPD_parallel_for_simd:
3856 case OMPD_parallel_sections:
3857 case OMPD_parallel_master:
3858 case OMPD_teams:
3859 case OMPD_teams_distribute:
3860 case OMPD_teams_distribute_simd: {
3861 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3862 QualType KmpInt32PtrTy =
3863 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3864 Sema::CapturedParamNameType Params[] = {
3865 std::make_pair(".global_tid.", KmpInt32PtrTy),
3866 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3867 std::make_pair(StringRef(), QualType()) // __context with shared vars
3868 };
3869 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3870 Params);
3871 break;
3872 }
3873 case OMPD_target_teams:
3874 case OMPD_target_parallel:
3875 case OMPD_target_parallel_for:
3876 case OMPD_target_parallel_for_simd:
3877 case OMPD_target_teams_distribute:
3878 case OMPD_target_teams_distribute_simd: {
3879 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3880 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3881 QualType KmpInt32PtrTy =
3882 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3883 QualType Args[] = {VoidPtrTy};
3884 FunctionProtoType::ExtProtoInfo EPI;
3885 EPI.Variadic = true;
3886 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3887 Sema::CapturedParamNameType Params[] = {
3888 std::make_pair(".global_tid.", KmpInt32Ty),
3889 std::make_pair(".part_id.", KmpInt32PtrTy),
3890 std::make_pair(".privates.", VoidPtrTy),
3891 std::make_pair(
3892 ".copy_fn.",
3893 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3894 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3895 std::make_pair(StringRef(), QualType()) // __context with shared vars
3896 };
3897 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3898 Params, /*OpenMPCaptureLevel=*/0);
3899 // Mark this captured region as inlined, because we don't use outlined
3900 // function directly.
3901 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3902 AlwaysInlineAttr::CreateImplicit(
3903 Context, {}, AttributeCommonInfo::AS_Keyword,
3904 AlwaysInlineAttr::Keyword_forceinline));
3905 Sema::CapturedParamNameType ParamsTarget[] = {
3906 std::make_pair(StringRef(), QualType()) // __context with shared vars
3907 };
3908 // Start a captured region for 'target' with no implicit parameters.
3909 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3910 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3911 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3912 std::make_pair(".global_tid.", KmpInt32PtrTy),
3913 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3914 std::make_pair(StringRef(), QualType()) // __context with shared vars
3915 };
3916 // Start a captured region for 'teams' or 'parallel'. Both regions have
3917 // the same implicit parameters.
3918 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3919 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3920 break;
3921 }
3922 case OMPD_target:
3923 case OMPD_target_simd: {
3924 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3925 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3926 QualType KmpInt32PtrTy =
3927 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3928 QualType Args[] = {VoidPtrTy};
3929 FunctionProtoType::ExtProtoInfo EPI;
3930 EPI.Variadic = true;
3931 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3932 Sema::CapturedParamNameType Params[] = {
3933 std::make_pair(".global_tid.", KmpInt32Ty),
3934 std::make_pair(".part_id.", KmpInt32PtrTy),
3935 std::make_pair(".privates.", VoidPtrTy),
3936 std::make_pair(
3937 ".copy_fn.",
3938 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3939 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3940 std::make_pair(StringRef(), QualType()) // __context with shared vars
3941 };
3942 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3943 Params, /*OpenMPCaptureLevel=*/0);
3944 // Mark this captured region as inlined, because we don't use outlined
3945 // function directly.
3946 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3947 AlwaysInlineAttr::CreateImplicit(
3948 Context, {}, AttributeCommonInfo::AS_Keyword,
3949 AlwaysInlineAttr::Keyword_forceinline));
3950 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3951 std::make_pair(StringRef(), QualType()),
3952 /*OpenMPCaptureLevel=*/1);
3953 break;
3954 }
3955 case OMPD_atomic:
3956 case OMPD_critical:
3957 case OMPD_section:
3958 case OMPD_master:
3959 break;
3960 case OMPD_simd:
3961 case OMPD_for:
3962 case OMPD_for_simd:
3963 case OMPD_sections:
3964 case OMPD_single:
3965 case OMPD_taskgroup:
3966 case OMPD_distribute:
3967 case OMPD_distribute_simd:
3968 case OMPD_ordered:
3969 case OMPD_target_data: {
3970 Sema::CapturedParamNameType Params[] = {
3971 std::make_pair(StringRef(), QualType()) // __context with shared vars
3972 };
3973 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3974 Params);
3975 break;
3976 }
3977 case OMPD_task: {
3978 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3979 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3980 QualType KmpInt32PtrTy =
3981 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3982 QualType Args[] = {VoidPtrTy};
3983 FunctionProtoType::ExtProtoInfo EPI;
3984 EPI.Variadic = true;
3985 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3986 Sema::CapturedParamNameType Params[] = {
3987 std::make_pair(".global_tid.", KmpInt32Ty),
3988 std::make_pair(".part_id.", KmpInt32PtrTy),
3989 std::make_pair(".privates.", VoidPtrTy),
3990 std::make_pair(
3991 ".copy_fn.",
3992 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3993 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3994 std::make_pair(StringRef(), QualType()) // __context with shared vars
3995 };
3996 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3997 Params);
3998 // Mark this captured region as inlined, because we don't use outlined
3999 // function directly.
4000 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4001 AlwaysInlineAttr::CreateImplicit(
4002 Context, {}, AttributeCommonInfo::AS_Keyword,
4003 AlwaysInlineAttr::Keyword_forceinline));
4004 break;
4005 }
4006 case OMPD_taskloop:
4007 case OMPD_taskloop_simd:
4008 case OMPD_master_taskloop:
4009 case OMPD_master_taskloop_simd: {
4010 QualType KmpInt32Ty =
4011 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4012 .withConst();
4013 QualType KmpUInt64Ty =
4014 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4015 .withConst();
4016 QualType KmpInt64Ty =
4017 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4018 .withConst();
4019 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4020 QualType KmpInt32PtrTy =
4021 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4022 QualType Args[] = {VoidPtrTy};
4023 FunctionProtoType::ExtProtoInfo EPI;
4024 EPI.Variadic = true;
4025 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4026 Sema::CapturedParamNameType Params[] = {
4027 std::make_pair(".global_tid.", KmpInt32Ty),
4028 std::make_pair(".part_id.", KmpInt32PtrTy),
4029 std::make_pair(".privates.", VoidPtrTy),
4030 std::make_pair(
4031 ".copy_fn.",
4032 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4033 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4034 std::make_pair(".lb.", KmpUInt64Ty),
4035 std::make_pair(".ub.", KmpUInt64Ty),
4036 std::make_pair(".st.", KmpInt64Ty),
4037 std::make_pair(".liter.", KmpInt32Ty),
4038 std::make_pair(".reductions.", VoidPtrTy),
4039 std::make_pair(StringRef(), QualType()) // __context with shared vars
4040 };
4041 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4042 Params);
4043 // Mark this captured region as inlined, because we don't use outlined
4044 // function directly.
4045 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4046 AlwaysInlineAttr::CreateImplicit(
4047 Context, {}, AttributeCommonInfo::AS_Keyword,
4048 AlwaysInlineAttr::Keyword_forceinline));
4049 break;
4050 }
4051 case OMPD_parallel_master_taskloop:
4052 case OMPD_parallel_master_taskloop_simd: {
4053 QualType KmpInt32Ty =
4054 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4055 .withConst();
4056 QualType KmpUInt64Ty =
4057 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4058 .withConst();
4059 QualType KmpInt64Ty =
4060 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4061 .withConst();
4062 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4063 QualType KmpInt32PtrTy =
4064 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4065 Sema::CapturedParamNameType ParamsParallel[] = {
4066 std::make_pair(".global_tid.", KmpInt32PtrTy),
4067 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4068 std::make_pair(StringRef(), QualType()) // __context with shared vars
4069 };
4070 // Start a captured region for 'parallel'.
4071 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4072 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4073 QualType Args[] = {VoidPtrTy};
4074 FunctionProtoType::ExtProtoInfo EPI;
4075 EPI.Variadic = true;
4076 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4077 Sema::CapturedParamNameType Params[] = {
4078 std::make_pair(".global_tid.", KmpInt32Ty),
4079 std::make_pair(".part_id.", KmpInt32PtrTy),
4080 std::make_pair(".privates.", VoidPtrTy),
4081 std::make_pair(
4082 ".copy_fn.",
4083 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4084 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4085 std::make_pair(".lb.", KmpUInt64Ty),
4086 std::make_pair(".ub.", KmpUInt64Ty),
4087 std::make_pair(".st.", KmpInt64Ty),
4088 std::make_pair(".liter.", KmpInt32Ty),
4089 std::make_pair(".reductions.", VoidPtrTy),
4090 std::make_pair(StringRef(), QualType()) // __context with shared vars
4091 };
4092 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4093 Params, /*OpenMPCaptureLevel=*/1);
4094 // Mark this captured region as inlined, because we don't use outlined
4095 // function directly.
4096 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4097 AlwaysInlineAttr::CreateImplicit(
4098 Context, {}, AttributeCommonInfo::AS_Keyword,
4099 AlwaysInlineAttr::Keyword_forceinline));
4100 break;
4101 }
4102 case OMPD_distribute_parallel_for_simd:
4103 case OMPD_distribute_parallel_for: {
4104 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4105 QualType KmpInt32PtrTy =
4106 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4107 Sema::CapturedParamNameType Params[] = {
4108 std::make_pair(".global_tid.", KmpInt32PtrTy),
4109 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4110 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4111 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4112 std::make_pair(StringRef(), QualType()) // __context with shared vars
4113 };
4114 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4115 Params);
4116 break;
4117 }
4118 case OMPD_target_teams_distribute_parallel_for:
4119 case OMPD_target_teams_distribute_parallel_for_simd: {
4120 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4121 QualType KmpInt32PtrTy =
4122 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4123 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4124
4125 QualType Args[] = {VoidPtrTy};
4126 FunctionProtoType::ExtProtoInfo EPI;
4127 EPI.Variadic = true;
4128 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4129 Sema::CapturedParamNameType Params[] = {
4130 std::make_pair(".global_tid.", KmpInt32Ty),
4131 std::make_pair(".part_id.", KmpInt32PtrTy),
4132 std::make_pair(".privates.", VoidPtrTy),
4133 std::make_pair(
4134 ".copy_fn.",
4135 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4136 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4137 std::make_pair(StringRef(), QualType()) // __context with shared vars
4138 };
4139 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4140 Params, /*OpenMPCaptureLevel=*/0);
4141 // Mark this captured region as inlined, because we don't use outlined
4142 // function directly.
4143 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4144 AlwaysInlineAttr::CreateImplicit(
4145 Context, {}, AttributeCommonInfo::AS_Keyword,
4146 AlwaysInlineAttr::Keyword_forceinline));
4147 Sema::CapturedParamNameType ParamsTarget[] = {
4148 std::make_pair(StringRef(), QualType()) // __context with shared vars
4149 };
4150 // Start a captured region for 'target' with no implicit parameters.
4151 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4152 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4153
4154 Sema::CapturedParamNameType ParamsTeams[] = {
4155 std::make_pair(".global_tid.", KmpInt32PtrTy),
4156 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4157 std::make_pair(StringRef(), QualType()) // __context with shared vars
4158 };
4159 // Start a captured region for 'target' with no implicit parameters.
4160 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4161 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4162
4163 Sema::CapturedParamNameType ParamsParallel[] = {
4164 std::make_pair(".global_tid.", KmpInt32PtrTy),
4165 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4166 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4167 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4168 std::make_pair(StringRef(), QualType()) // __context with shared vars
4169 };
4170 // Start a captured region for 'teams' or 'parallel'. Both regions have
4171 // the same implicit parameters.
4172 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4173 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4174 break;
4175 }
4176
4177 case OMPD_teams_distribute_parallel_for:
4178 case OMPD_teams_distribute_parallel_for_simd: {
4179 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4180 QualType KmpInt32PtrTy =
4181 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4182
4183 Sema::CapturedParamNameType ParamsTeams[] = {
4184 std::make_pair(".global_tid.", KmpInt32PtrTy),
4185 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4186 std::make_pair(StringRef(), QualType()) // __context with shared vars
4187 };
4188 // Start a captured region for 'target' with no implicit parameters.
4189 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4190 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4191
4192 Sema::CapturedParamNameType ParamsParallel[] = {
4193 std::make_pair(".global_tid.", KmpInt32PtrTy),
4194 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4195 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4196 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4197 std::make_pair(StringRef(), QualType()) // __context with shared vars
4198 };
4199 // Start a captured region for 'teams' or 'parallel'. Both regions have
4200 // the same implicit parameters.
4201 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4202 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4203 break;
4204 }
4205 case OMPD_target_update:
4206 case OMPD_target_enter_data:
4207 case OMPD_target_exit_data: {
4208 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4210 QualType KmpInt32PtrTy =
4211 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4212 QualType Args[] = {VoidPtrTy};
4213 FunctionProtoType::ExtProtoInfo EPI;
4214 EPI.Variadic = true;
4215 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4216 Sema::CapturedParamNameType Params[] = {
4217 std::make_pair(".global_tid.", KmpInt32Ty),
4218 std::make_pair(".part_id.", KmpInt32PtrTy),
4219 std::make_pair(".privates.", VoidPtrTy),
4220 std::make_pair(
4221 ".copy_fn.",
4222 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4223 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4224 std::make_pair(StringRef(), QualType()) // __context with shared vars
4225 };
4226 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4227 Params);
4228 // Mark this captured region as inlined, because we don't use outlined
4229 // function directly.
4230 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4231 AlwaysInlineAttr::CreateImplicit(
4232 Context, {}, AttributeCommonInfo::AS_Keyword,
4233 AlwaysInlineAttr::Keyword_forceinline));
4234 break;
4235 }
4236 case OMPD_threadprivate:
4237 case OMPD_allocate:
4238 case OMPD_taskyield:
4239 case OMPD_barrier:
4240 case OMPD_taskwait:
4241 case OMPD_cancellation_point:
4242 case OMPD_cancel:
4243 case OMPD_flush:
4244 case OMPD_depobj:
4245 case OMPD_scan:
4246 case OMPD_declare_reduction:
4247 case OMPD_declare_mapper:
4248 case OMPD_declare_simd:
4249 case OMPD_declare_target:
4250 case OMPD_end_declare_target:
4251 case OMPD_requires:
4252 case OMPD_declare_variant:
4253 case OMPD_begin_declare_variant:
4254 case OMPD_end_declare_variant:
4255 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 4255)
;
4256 case OMPD_unknown:
4257 default:
4258 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 4258)
;
4259 }
4260 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setContext(CurContext);
4261}
4262
4263int Sema::getNumberOfConstructScopes(unsigned Level) const {
4264 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4265}
4266
4267int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4268 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4269 getOpenMPCaptureRegions(CaptureRegions, DKind);
4270 return CaptureRegions.size();
4271}
4272
4273static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4274 Expr *CaptureExpr, bool WithInit,
4275 bool AsExpression) {
4276 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 4276, __PRETTY_FUNCTION__))
;
4277 ASTContext &C = S.getASTContext();
4278 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4279 QualType Ty = Init->getType();
4280 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4281 if (S.getLangOpts().CPlusPlus) {
4282 Ty = C.getLValueReferenceType(Ty);
4283 } else {
4284 Ty = C.getPointerType(Ty);
4285 ExprResult Res =
4286 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4287 if (!Res.isUsable())
4288 return nullptr;
4289 Init = Res.get();
4290 }
4291 WithInit = true;
4292 }
4293 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4294 CaptureExpr->getBeginLoc());
4295 if (!WithInit)
4296 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4297 S.CurContext->addHiddenDecl(CED);
4298 Sema::TentativeAnalysisScope Trap(S);
4299 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4300 return CED;
4301}
4302
4303static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4304 bool WithInit) {
4305 OMPCapturedExprDecl *CD;
4306 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4307 CD = cast<OMPCapturedExprDecl>(VD);
4308 else
4309 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4310 /*AsExpression=*/false);
4311 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4312 CaptureExpr->getExprLoc());
4313}
4314
4315static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4316 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4317 if (!Ref) {
4318 OMPCapturedExprDecl *CD = buildCaptureDecl(
4319 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4320 /*WithInit=*/true, /*AsExpression=*/true);
4321 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4322 CaptureExpr->getExprLoc());
4323 }
4324 ExprResult Res = Ref;
4325 if (!S.getLangOpts().CPlusPlus &&
4326 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4327 Ref->getType()->isPointerType()) {
4328 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4329 if (!Res.isUsable())
4330 return ExprError();
4331 }
4332 return S.DefaultLvalueConversion(Res.get());
4333}
4334
4335namespace {
4336// OpenMP directives parsed in this section are represented as a
4337// CapturedStatement with an associated statement. If a syntax error
4338// is detected during the parsing of the associated statement, the
4339// compiler must abort processing and close the CapturedStatement.
4340//
4341// Combined directives such as 'target parallel' have more than one
4342// nested CapturedStatements. This RAII ensures that we unwind out
4343// of all the nested CapturedStatements when an error is found.
4344class CaptureRegionUnwinderRAII {
4345private:
4346 Sema &S;
4347 bool &ErrorFound;
4348 OpenMPDirectiveKind DKind = OMPD_unknown;
4349
4350public:
4351 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4352 OpenMPDirectiveKind DKind)
4353 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4354 ~CaptureRegionUnwinderRAII() {
4355 if (ErrorFound) {
4356 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4357 while (--ThisCaptureLevel >= 0)
4358 S.ActOnCapturedRegionError();
4359 }
4360 }
4361};
4362} // namespace
4363
4364void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4365 // Capture variables captured by reference in lambdas for target-based
4366 // directives.
4367 if (!CurContext->isDependentContext() &&
4368 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4369 isOpenMPTargetDataManagementDirective(
4370 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4371 QualType Type = V->getType();
4372 if (const auto *RD = Type.getCanonicalType()
4373 .getNonReferenceType()
4374 ->getAsCXXRecordDecl()) {
4375 bool SavedForceCaptureByReferenceInTargetExecutable =
4376 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4377 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4378 /*V=*/true);
4379 if (RD->isLambda()) {
4380 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4381 FieldDecl *ThisCapture;
4382 RD->getCaptureFields(Captures, ThisCapture);
4383 for (const LambdaCapture &LC : RD->captures()) {
4384 if (LC.getCaptureKind() == LCK_ByRef) {
4385 VarDecl *VD = LC.getCapturedVar();
4386 DeclContext *VDC = VD->getDeclContext();
4387 if (!VDC->Encloses(CurContext))
4388 continue;
4389 MarkVariableReferenced(LC.getLocation(), VD);
4390 } else if (LC.getCaptureKind() == LCK_This) {
4391 QualType ThisTy = getCurrentThisType();
4392 if (!ThisTy.isNull() &&
4393 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4394 CheckCXXThisCapture(LC.getLocation());
4395 }
4396 }
4397 }
4398 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4399 SavedForceCaptureByReferenceInTargetExecutable);
4400 }
4401 }
4402}
4403
4404static bool checkOrderedOrderSpecified(Sema &S,
4405 const ArrayRef<OMPClause *> Clauses) {
4406 const OMPOrderedClause *Ordered = nullptr;
4407 const OMPOrderClause *Order = nullptr;
4408
4409 for (const OMPClause *Clause : Clauses) {
4410 if (Clause->getClauseKind() == OMPC_ordered)
4411 Ordered = cast<OMPOrderedClause>(Clause);
4412 else if (Clause->getClauseKind() == OMPC_order) {
4413 Order = cast<OMPOrderClause>(Clause);
4414 if (Order->getKind() != OMPC_ORDER_concurrent)
4415 Order = nullptr;
4416 }
4417 if (Ordered && Order)
4418 break;
4419 }
4420
4421 if (Ordered && Order) {
4422 S.Diag(Order->getKindKwLoc(),
4423 diag::err_omp_simple_clause_incompatible_with_ordered)
4424 << getOpenMPClauseName(OMPC_order)
4425 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4426 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4427 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4428 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4429 return true;
4430 }
4431 return false;
4432}
4433
4434StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4435 ArrayRef<OMPClause *> Clauses) {
4436 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4437 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4438 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4439 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master)
4440 return S;
4441
4442 bool ErrorFound = false;
4443 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4444 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4445 if (!S.isUsable()) {
4446 ErrorFound = true;
4447 return StmtError();
4448 }
4449
4450 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4451 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4452 OMPOrderedClause *OC = nullptr;
4453 OMPScheduleClause *SC = nullptr;
4454 SmallVector<const OMPLinearClause *, 4> LCs;
4455 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4456 // This is required for proper codegen.
4457 for (OMPClause *Clause : Clauses) {
4458 if (!LangOpts.OpenMPSimd &&
4459 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4460 Clause->getClauseKind() == OMPC_in_reduction) {
4461 // Capture taskgroup task_reduction descriptors inside the tasking regions
4462 // with the corresponding in_reduction items.
4463 auto *IRC = cast<OMPInReductionClause>(Clause);
4464 for (Expr *E : IRC->taskgroup_descriptors())
4465 if (E)
4466 MarkDeclarationsReferencedInExpr(E);
4467 }
4468 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4469 Clause->getClauseKind() == OMPC_copyprivate ||
4470 (getLangOpts().OpenMPUseTLS &&
4471 getASTContext().getTargetInfo().isTLSSupported() &&
4472 Clause->getClauseKind() == OMPC_copyin)) {
4473 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4474 // Mark all variables in private list clauses as used in inner region.
4475 for (Stmt *VarRef : Clause->children()) {
4476 if (auto *E = cast_or_null<Expr>(VarRef)) {
4477 MarkDeclarationsReferencedInExpr(E);
4478 }
4479 }
4480 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4481 } else if (CaptureRegions.size() > 1 ||
4482 CaptureRegions.back() != OMPD_unknown) {
4483 if (auto *C = OMPClauseWithPreInit::get(Clause))
4484 PICs.push_back(C);
4485 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4486 if (Expr *E = C->getPostUpdateExpr())
4487 MarkDeclarationsReferencedInExpr(E);
4488 }
4489 }
4490 if (Clause->getClauseKind() == OMPC_schedule)
4491 SC = cast<OMPScheduleClause>(Clause);
4492 else if (Clause->getClauseKind() == OMPC_ordered)
4493 OC = cast<OMPOrderedClause>(Clause);
4494 else if (Clause->getClauseKind() == OMPC_linear)
4495 LCs.push_back(cast<OMPLinearClause>(Clause));
4496 }
4497 // Capture allocator expressions if used.
4498 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4499 MarkDeclarationsReferencedInExpr(E);
4500 // OpenMP, 2.7.1 Loop Construct, Restrictions
4501 // The nonmonotonic modifier cannot be specified if an ordered clause is
4502 // specified.
4503 if (SC &&
4504 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4505 SC->getSecondScheduleModifier() ==
4506 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4507 OC) {
4508 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4509 ? SC->getFirstScheduleModifierLoc()
4510 : SC->getSecondScheduleModifierLoc(),
4511 diag::err_omp_simple_clause_incompatible_with_ordered)
4512 << getOpenMPClauseName(OMPC_schedule)
4513 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4514 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4515 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4516 ErrorFound = true;
4517 }
4518 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4519 // If an order(concurrent) clause is present, an ordered clause may not appear
4520 // on the same directive.
4521 if (checkOrderedOrderSpecified(*this, Clauses))
4522 ErrorFound = true;
4523 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4524 for (const OMPLinearClause *C : LCs) {
4525 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4526 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4527 }
4528 ErrorFound = true;
4529 }
4530 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4531 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4532 OC->getNumForLoops()) {
4533 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4534 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4535 ErrorFound = true;
4536 }
4537 if (ErrorFound) {
4538 return StmtError();
4539 }
4540 StmtResult SR = S;
4541 unsigned CompletedRegions = 0;
4542 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4543 // Mark all variables in private list clauses as used in inner region.
4544 // Required for proper codegen of combined directives.
4545 // TODO: add processing for other clauses.
4546 if (ThisCaptureRegion != OMPD_unknown) {
4547 for (const clang::OMPClauseWithPreInit *C : PICs) {
4548 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4549 // Find the particular capture region for the clause if the
4550 // directive is a combined one with multiple capture regions.
4551 // If the directive is not a combined one, the capture region
4552 // associated with the clause is OMPD_unknown and is generated
4553 // only once.
4554 if (CaptureRegion == ThisCaptureRegion ||
4555 CaptureRegion == OMPD_unknown) {
4556 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4557 for (Decl *D : DS->decls())
4558 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4559 }
4560 }
4561 }
4562 }
4563 if (ThisCaptureRegion == OMPD_target) {
4564 // Capture allocator traits in the target region. They are used implicitly
4565 // and, thus, are not captured by default.
4566 for (OMPClause *C : Clauses) {
4567 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4568 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4569 ++I) {
4570 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4571 if (Expr *E = D.AllocatorTraits)
4572 MarkDeclarationsReferencedInExpr(E);
4573 }
4574 continue;
4575 }
4576 }
4577 }
4578 if (++CompletedRegions == CaptureRegions.size())
4579 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4580 SR = ActOnCapturedRegionEnd(SR.get());
4581 }
4582 return SR;
4583}
4584
4585static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4586 OpenMPDirectiveKind CancelRegion,
4587 SourceLocation StartLoc) {
4588 // CancelRegion is only needed for cancel and cancellation_point.
4589 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4590 return false;
4591
4592 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4593 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4594 return false;
4595
4596 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4597 << getOpenMPDirectiveName(CancelRegion);
4598 return true;
4599}
4600
4601static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4602 OpenMPDirectiveKind CurrentRegion,
4603 const DeclarationNameInfo &CurrentName,
4604 OpenMPDirectiveKind CancelRegion,
4605 SourceLocation StartLoc) {
4606 if (Stack->getCurScope()) {
4607 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4608 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4609 bool NestingProhibited = false;
4610 bool CloseNesting = true;
4611 bool OrphanSeen = false;
4612 enum {
4613 NoRecommend,
4614 ShouldBeInParallelRegion,
4615 ShouldBeInOrderedRegion,
4616 ShouldBeInTargetRegion,
4617 ShouldBeInTeamsRegion,
4618 ShouldBeInLoopSimdRegion,
4619 } Recommend = NoRecommend;
4620 if (isOpenMPSimdDirective(ParentRegion) &&
4621 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4622 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4623 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4624 CurrentRegion != OMPD_scan))) {
4625 // OpenMP [2.16, Nesting of Regions]
4626 // OpenMP constructs may not be nested inside a simd region.
4627 // OpenMP [2.8.1,simd Construct, Restrictions]
4628 // An ordered construct with the simd clause is the only OpenMP
4629 // construct that can appear in the simd region.
4630 // Allowing a SIMD construct nested in another SIMD construct is an
4631 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4632 // message.
4633 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4634 // The only OpenMP constructs that can be encountered during execution of
4635 // a simd region are the atomic construct, the loop construct, the simd
4636 // construct and the ordered construct with the simd clause.
4637 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4638 ? diag::err_omp_prohibited_region_simd
4639 : diag::warn_omp_nesting_simd)
4640 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4641 return CurrentRegion != OMPD_simd;
4642 }
4643 if (ParentRegion == OMPD_atomic) {
4644 // OpenMP [2.16, Nesting of Regions]
4645 // OpenMP constructs may not be nested inside an atomic region.
4646 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4647 return true;
4648 }
4649 if (CurrentRegion == OMPD_section) {
4650 // OpenMP [2.7.2, sections Construct, Restrictions]
4651 // Orphaned section directives are prohibited. That is, the section
4652 // directives must appear within the sections construct and must not be
4653 // encountered elsewhere in the sections region.
4654 if (ParentRegion != OMPD_sections &&
4655 ParentRegion != OMPD_parallel_sections) {
4656 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4657 << (ParentRegion != OMPD_unknown)
4658 << getOpenMPDirectiveName(ParentRegion);
4659 return true;
4660 }
4661 return false;
4662 }
4663 // Allow some constructs (except teams and cancellation constructs) to be
4664 // orphaned (they could be used in functions, called from OpenMP regions
4665 // with the required preconditions).
4666 if (ParentRegion == OMPD_unknown &&
4667 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4668 CurrentRegion != OMPD_cancellation_point &&
4669 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4670 return false;
4671 if (CurrentRegion == OMPD_cancellation_point ||
4672 CurrentRegion == OMPD_cancel) {
4673 // OpenMP [2.16, Nesting of Regions]
4674 // A cancellation point construct for which construct-type-clause is
4675 // taskgroup must be nested inside a task construct. A cancellation
4676 // point construct for which construct-type-clause is not taskgroup must
4677 // be closely nested inside an OpenMP construct that matches the type
4678 // specified in construct-type-clause.
4679 // A cancel construct for which construct-type-clause is taskgroup must be
4680 // nested inside a task construct. A cancel construct for which
4681 // construct-type-clause is not taskgroup must be closely nested inside an
4682 // OpenMP construct that matches the type specified in
4683 // construct-type-clause.
4684 NestingProhibited =
4685 !((CancelRegion == OMPD_parallel &&
4686 (ParentRegion == OMPD_parallel ||
4687 ParentRegion == OMPD_target_parallel)) ||
4688 (CancelRegion == OMPD_for &&
4689 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4690 ParentRegion == OMPD_target_parallel_for ||
4691 ParentRegion == OMPD_distribute_parallel_for ||
4692 ParentRegion == OMPD_teams_distribute_parallel_for ||
4693 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4694 (CancelRegion == OMPD_taskgroup &&
4695 (ParentRegion == OMPD_task ||
4696 (SemaRef.getLangOpts().OpenMP >= 50 &&
4697 (ParentRegion == OMPD_taskloop ||
4698 ParentRegion == OMPD_master_taskloop ||
4699 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4700 (CancelRegion == OMPD_sections &&
4701 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4702 ParentRegion == OMPD_parallel_sections)));
4703 OrphanSeen = ParentRegion == OMPD_unknown;
4704 } else if (CurrentRegion == OMPD_master) {
4705 // OpenMP [2.16, Nesting of Regions]
4706 // A master region may not be closely nested inside a worksharing,
4707 // atomic, or explicit task region.
4708 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4709 isOpenMPTaskingDirective(ParentRegion);
4710 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4711 // OpenMP [2.16, Nesting of Regions]
4712 // A critical region may not be nested (closely or otherwise) inside a
4713 // critical region with the same name. Note that this restriction is not
4714 // sufficient to prevent deadlock.
4715 SourceLocation PreviousCriticalLoc;
4716 bool DeadLock = Stack->hasDirective(
4717 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4718 const DeclarationNameInfo &DNI,
4719 SourceLocation Loc) {
4720 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4721 PreviousCriticalLoc = Loc;
4722 return true;
4723 }
4724 return false;
4725 },
4726 false /* skip top directive */);
4727 if (DeadLock) {
4728 SemaRef.Diag(StartLoc,
4729 diag::err_omp_prohibited_region_critical_same_name)
4730 << CurrentName.getName();
4731 if (PreviousCriticalLoc.isValid())
4732 SemaRef.Diag(PreviousCriticalLoc,
4733 diag::note_omp_previous_critical_region);
4734 return true;
4735 }
4736 } else if (CurrentRegion == OMPD_barrier) {
4737 // OpenMP [2.16, Nesting of Regions]
4738 // A barrier region may not be closely nested inside a worksharing,
4739 // explicit task, critical, ordered, atomic, or master region.
4740 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4741 isOpenMPTaskingDirective(ParentRegion) ||
4742 ParentRegion == OMPD_master ||
4743 ParentRegion == OMPD_parallel_master ||
4744 ParentRegion == OMPD_critical ||
4745 ParentRegion == OMPD_ordered;
4746 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4747 !isOpenMPParallelDirective(CurrentRegion) &&
4748 !isOpenMPTeamsDirective(CurrentRegion)) {
4749 // OpenMP [2.16, Nesting of Regions]
4750 // A worksharing region may not be closely nested inside a worksharing,
4751 // explicit task, critical, ordered, atomic, or master region.
4752 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4753 isOpenMPTaskingDirective(ParentRegion) ||
4754 ParentRegion == OMPD_master ||
4755 ParentRegion == OMPD_parallel_master ||
4756 ParentRegion == OMPD_critical ||
4757 ParentRegion == OMPD_ordered;
4758 Recommend = ShouldBeInParallelRegion;
4759 } else if (CurrentRegion == OMPD_ordered) {
4760 // OpenMP [2.16, Nesting of Regions]
4761 // An ordered region may not be closely nested inside a critical,
4762 // atomic, or explicit task region.
4763 // An ordered region must be closely nested inside a loop region (or
4764 // parallel loop region) with an ordered clause.
4765 // OpenMP [2.8.1,simd Construct, Restrictions]
4766 // An ordered construct with the simd clause is the only OpenMP construct
4767 // that can appear in the simd region.
4768 NestingProhibited = ParentRegion == OMPD_critical ||
4769 isOpenMPTaskingDirective(ParentRegion) ||
4770 !(isOpenMPSimdDirective(ParentRegion) ||
4771 Stack->isParentOrderedRegion());
4772 Recommend = ShouldBeInOrderedRegion;
4773 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4774 // OpenMP [2.16, Nesting of Regions]
4775 // If specified, a teams construct must be contained within a target
4776 // construct.
4777 NestingProhibited =
4778 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4779 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4780 ParentRegion != OMPD_target);
4781 OrphanSeen = ParentRegion == OMPD_unknown;
4782 Recommend = ShouldBeInTargetRegion;
4783 } else if (CurrentRegion == OMPD_scan) {
4784 // OpenMP [2.16, Nesting of Regions]
4785 // If specified, a teams construct must be contained within a target
4786 // construct.
4787 NestingProhibited =
4788 SemaRef.LangOpts.OpenMP < 50 ||
4789 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4790 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4791 ParentRegion != OMPD_parallel_for_simd);
4792 OrphanSeen = ParentRegion == OMPD_unknown;
4793 Recommend = ShouldBeInLoopSimdRegion;
4794 }
4795 if (!NestingProhibited &&
4796 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4797 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4798 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4799 // OpenMP [2.16, Nesting of Regions]
4800 // distribute, parallel, parallel sections, parallel workshare, and the
4801 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4802 // constructs that can be closely nested in the teams region.
4803 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4804 !isOpenMPDistributeDirective(CurrentRegion);
4805 Recommend = ShouldBeInParallelRegion;
4806 }
4807 if (!NestingProhibited &&
4808 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4809 // OpenMP 4.5 [2.17 Nesting of Regions]
4810 // The region associated with the distribute construct must be strictly
4811 // nested inside a teams region
4812 NestingProhibited =
4813 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4814 Recommend = ShouldBeInTeamsRegion;
4815 }
4816 if (!NestingProhibited &&
4817 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4818 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4819 // OpenMP 4.5 [2.17 Nesting of Regions]
4820 // If a target, target update, target data, target enter data, or
4821 // target exit data construct is encountered during execution of a
4822 // target region, the behavior is unspecified.
4823 NestingProhibited = Stack->hasDirective(
4824 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4825 SourceLocation) {
4826 if (isOpenMPTargetExecutionDirective(K)) {
4827 OffendingRegion = K;
4828 return true;
4829 }
4830 return false;
4831 },
4832 false /* don't skip top directive */);
4833 CloseNesting = false;
4834 }
4835 if (NestingProhibited) {
4836 if (OrphanSeen) {
4837 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4838 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4839 } else {
4840 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4841 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4842 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4843 }
4844 return true;
4845 }
4846 }
4847 return false;
4848}
4849
4850struct Kind2Unsigned {
4851 using argument_type = OpenMPDirectiveKind;
4852 unsigned operator()(argument_type DK) { return unsigned(DK); }
4853};
4854static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4855 ArrayRef<OMPClause *> Clauses,
4856 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4857 bool ErrorFound = false;
4858 unsigned NamedModifiersNumber = 0;
4859 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4860 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4861 SmallVector<SourceLocation, 4> NameModifierLoc;
4862 for (const OMPClause *C : Clauses) {
4863 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4864 // At most one if clause without a directive-name-modifier can appear on
4865 // the directive.
4866 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4867 if (FoundNameModifiers[CurNM]) {
4868 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4869 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4870 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4871 ErrorFound = true;
4872 } else if (CurNM != OMPD_unknown) {
4873 NameModifierLoc.push_back(IC->getNameModifierLoc());
4874 ++NamedModifiersNumber;
4875 }
4876 FoundNameModifiers[CurNM] = IC;
4877 if (CurNM == OMPD_unknown)
4878 continue;
4879 // Check if the specified name modifier is allowed for the current
4880 // directive.
4881 // At most one if clause with the particular directive-name-modifier can
4882 // appear on the directive.
4883 bool MatchFound = false;
4884 for (auto NM : AllowedNameModifiers) {
4885 if (CurNM == NM) {
4886 MatchFound = true;
4887 break;
4888 }
4889 }
4890 if (!MatchFound) {
4891 S.Diag(IC->getNameModifierLoc(),
4892 diag::err_omp_wrong_if_directive_name_modifier)
4893 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4894 ErrorFound = true;
4895 }
4896 }
4897 }
4898 // If any if clause on the directive includes a directive-name-modifier then
4899 // all if clauses on the directive must include a directive-name-modifier.
4900 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4901 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4902 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4903 diag::err_omp_no_more_if_clause);
4904 } else {
4905 std::string Values;
4906 std::string Sep(", ");
4907 unsigned AllowedCnt = 0;
4908 unsigned TotalAllowedNum =
4909 AllowedNameModifiers.size() - NamedModifiersNumber;
4910 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4911 ++Cnt) {
4912 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4913 if (!FoundNameModifiers[NM]) {
4914 Values += "'";
4915 Values += getOpenMPDirectiveName(NM);
4916 Values += "'";
4917 if (AllowedCnt + 2 == TotalAllowedNum)
4918 Values += " or ";
4919 else if (AllowedCnt + 1 != TotalAllowedNum)
4920 Values += Sep;
4921 ++AllowedCnt;
4922 }
4923 }
4924 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4925 diag::err_omp_unnamed_if_clause)
4926 << (TotalAllowedNum > 1) << Values;
4927 }
4928 for (SourceLocation Loc : NameModifierLoc) {
4929 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4930 }
4931 ErrorFound = true;
4932 }
4933 return ErrorFound;
4934}
4935
4936static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4937 SourceLocation &ELoc,
4938 SourceRange &ERange,
4939 bool AllowArraySection) {
4940 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4941 RefExpr->containsUnexpandedParameterPack())
4942 return std::make_pair(nullptr, true);
4943
4944 // OpenMP [3.1, C/C++]
4945 // A list item is a variable name.
4946 // OpenMP [2.9.3.3, Restrictions, p.1]
4947 // A variable that is part of another variable (as an array or
4948 // structure element) cannot appear in a private clause.
4949 RefExpr = RefExpr->IgnoreParens();
4950 enum {
4951 NoArrayExpr = -1,
4952 ArraySubscript = 0,
4953 OMPArraySection = 1
4954 } IsArrayExpr = NoArrayExpr;
4955 if (AllowArraySection) {
4956 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4957 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4958 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4959 Base = TempASE->getBase()->IgnoreParenImpCasts();
4960 RefExpr = Base;
4961 IsArrayExpr = ArraySubscript;
4962 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4963 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4964 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4965 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4966 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4967 Base = TempASE->getBase()->IgnoreParenImpCasts();
4968 RefExpr = Base;
4969 IsArrayExpr = OMPArraySection;
4970 }
4971 }
4972 ELoc = RefExpr->getExprLoc();
4973 ERange = RefExpr->getSourceRange();
4974 RefExpr = RefExpr->IgnoreParenImpCasts();
4975 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4976 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4977 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4978 (S.getCurrentThisType().isNull() || !ME ||
4979 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4980 !isa<FieldDecl>(ME->getMemberDecl()))) {
4981 if (IsArrayExpr != NoArrayExpr) {
4982 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4983 << ERange;
4984 } else {
4985 S.Diag(ELoc,
4986 AllowArraySection
4987 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4988 : diag::err_omp_expected_var_name_member_expr)
4989 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4990 }
4991 return std::make_pair(nullptr, false);
4992 }
4993 return std::make_pair(
4994 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4995}
4996
4997namespace {
4998/// Checks if the allocator is used in uses_allocators clause to be allowed in
4999/// target regions.
5000class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5001 DSAStackTy *S = nullptr;
5002
5003public:
5004 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5005 return S->isUsesAllocatorsDecl(E->getDecl())
5006 .getValueOr(
5007 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5008 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5009 }
5010 bool VisitStmt(const Stmt *S) {
5011 for (const Stmt *Child : S->children()) {
5012 if (Child && Visit(Child))
5013 return true;
5014 }
5015 return false;
5016 }
5017 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5018};
5019} // namespace
5020
5021static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5022 ArrayRef<OMPClause *> Clauses) {
5023 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5024, __PRETTY_FUNCTION__))
5024 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5024, __PRETTY_FUNCTION__))
;
5025 auto AllocateRange =
5026 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5027 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5028 DeclToCopy;
5029 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5030 return isOpenMPPrivate(C->getClauseKind());
5031 });
5032 for (OMPClause *Cl : PrivateRange) {
5033 MutableArrayRef<Expr *>::iterator I, It, Et;
5034 if (Cl->getClauseKind() == OMPC_private) {
5035 auto *PC = cast<OMPPrivateClause>(Cl);
5036 I = PC->private_copies().begin();
5037 It = PC->varlist_begin();
5038 Et = PC->varlist_end();
5039 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5040 auto *PC = cast<OMPFirstprivateClause>(Cl);
5041 I = PC->private_copies().begin();
5042 It = PC->varlist_begin();
5043 Et = PC->varlist_end();
5044 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5045 auto *PC = cast<OMPLastprivateClause>(Cl);
5046 I = PC->private_copies().begin();
5047 It = PC->varlist_begin();
5048 Et = PC->varlist_end();
5049 } else if (Cl->getClauseKind() == OMPC_linear) {
5050 auto *PC = cast<OMPLinearClause>(Cl);
5051 I = PC->privates().begin();
5052 It = PC->varlist_begin();
5053 Et = PC->varlist_end();
5054 } else if (Cl->getClauseKind() == OMPC_reduction) {
5055 auto *PC = cast<OMPReductionClause>(Cl);
5056 I = PC->privates().begin();
5057 It = PC->varlist_begin();
5058 Et = PC->varlist_end();
5059 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5060 auto *PC = cast<OMPTaskReductionClause>(Cl);
5061 I = PC->privates().begin();
5062 It = PC->varlist_begin();
5063 Et = PC->varlist_end();
5064 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5065 auto *PC = cast<OMPInReductionClause>(Cl);
5066 I = PC->privates().begin();
5067 It = PC->varlist_begin();
5068 Et = PC->varlist_end();
5069 } else {
5070 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5070)
;
5071 }
5072 for (Expr *E : llvm::make_range(It, Et)) {
5073 if (!*I) {
5074 ++I;
5075 continue;
5076 }
5077 SourceLocation ELoc;
5078 SourceRange ERange;
5079 Expr *SimpleRefExpr = E;
5080 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5081 /*AllowArraySection=*/true);
5082 DeclToCopy.try_emplace(Res.first,
5083 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5084 ++I;
5085 }
5086 }
5087 for (OMPClause *C : AllocateRange) {
5088 auto *AC = cast<OMPAllocateClause>(C);
5089 if (S.getLangOpts().OpenMP >= 50 &&
5090 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5091 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5092 AC->getAllocator()) {
5093 Expr *Allocator = AC->getAllocator();
5094 // OpenMP, 2.12.5 target Construct
5095 // Memory allocators that do not appear in a uses_allocators clause cannot
5096 // appear as an allocator in an allocate clause or be used in the target
5097 // region unless a requires directive with the dynamic_allocators clause
5098 // is present in the same compilation unit.
5099 AllocatorChecker Checker(Stack);
5100 if (Checker.Visit(Allocator))
5101 S.Diag(Allocator->getExprLoc(),
5102 diag::err_omp_allocator_not_in_uses_allocators)
5103 << Allocator->getSourceRange();
5104 }
5105 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5106 getAllocatorKind(S, Stack, AC->getAllocator());
5107 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5108 // For task, taskloop or target directives, allocation requests to memory
5109 // allocators with the trait access set to thread result in unspecified
5110 // behavior.
5111 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5112 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5113 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5114 S.Diag(AC->getAllocator()->getExprLoc(),
5115 diag::warn_omp_allocate_thread_on_task_target_directive)
5116 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5117 }
5118 for (Expr *E : AC->varlists()) {
5119 SourceLocation ELoc;
5120 SourceRange ERange;
5121 Expr *SimpleRefExpr = E;
5122 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5123 ValueDecl *VD = Res.first;
5124 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5125 if (!isOpenMPPrivate(Data.CKind)) {
5126 S.Diag(E->getExprLoc(),
5127 diag::err_omp_expected_private_copy_for_allocate);
5128 continue;
5129 }
5130 VarDecl *PrivateVD = DeclToCopy[VD];
5131 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5132 AllocatorKind, AC->getAllocator()))
5133 continue;
5134 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5135 E->getSourceRange());
5136 }
5137 }
5138}
5139
5140StmtResult Sema::ActOnOpenMPExecutableDirective(
5141 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5142 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5143 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5144 StmtResult Res = StmtError();
5145 // First check CancelRegion which is then used in checkNestingOfRegions.
5146 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5147 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5148 StartLoc))
5149 return StmtError();
5150
5151 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5152 VarsWithInheritedDSAType VarsWithInheritedDSA;
5153 bool ErrorFound = false;
5154 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5155 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5156 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5157 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5157, __PRETTY_FUNCTION__))
;
5158
5159 // Check default data sharing attributes for referenced variables.
5160 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5161 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5162 Stmt *S = AStmt;
5163 while (--ThisCaptureLevel >= 0)
5164 S = cast<CapturedStmt>(S)->getCapturedStmt();
5165 DSAChecker.Visit(S);
5166 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5167 !isOpenMPTaskingDirective(Kind)) {
5168 // Visit subcaptures to generate implicit clauses for captured vars.
5169 auto *CS = cast<CapturedStmt>(AStmt);
5170 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5171 getOpenMPCaptureRegions(CaptureRegions, Kind);
5172 // Ignore outer tasking regions for target directives.
5173 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5174 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5175 DSAChecker.visitSubCaptures(CS);
5176 }
5177 if (DSAChecker.isErrorFound())
5178 return StmtError();
5179 // Generate list of implicitly defined firstprivate variables.
5180 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5181
5182 SmallVector<Expr *, 4> ImplicitFirstprivates(
5183 DSAChecker.getImplicitFirstprivate().begin(),
5184 DSAChecker.getImplicitFirstprivate().end());
5185 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5186 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5187 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5188 ImplicitMapModifiers[DefaultmapKindNum];
5189 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5190 ImplicitMapModifiersLoc[DefaultmapKindNum];
5191 // Get the original location of present modifier from Defaultmap clause.
5192 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5193 for (OMPClause *C : Clauses) {
5194 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5195 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5196 PresentModifierLocs[DMC->getDefaultmapKind()] =
5197 DMC->getDefaultmapModifierLoc();
5198 }
5199 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5200 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5201 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5202 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5203 Kind, static_cast<OpenMPMapClauseKind>(I));
5204 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5205 }
5206 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5207 DSAChecker.getImplicitMapModifier(Kind);
5208 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5209 ImplicitModifier.end());
5210 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5211 ImplicitModifier.size(), PresentModifierLocs[VC]);
5212 }
5213 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5214 for (OMPClause *C : Clauses) {
5215 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5216 for (Expr *E : IRC->taskgroup_descriptors())
5217 if (E)
5218 ImplicitFirstprivates.emplace_back(E);
5219 }
5220 // OpenMP 5.0, 2.10.1 task Construct
5221 // [detach clause]... The event-handle will be considered as if it was
5222 // specified on a firstprivate clause.
5223 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5224 ImplicitFirstprivates.push_back(DC->getEventHandler());
5225 }
5226 if (!ImplicitFirstprivates.empty()) {
5227 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5228 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5229 SourceLocation())) {
5230 ClausesWithImplicit.push_back(Implicit);
5231 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5232 ImplicitFirstprivates.size();
5233 } else {
5234 ErrorFound = true;
5235 }
5236 }
5237 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5238 int ClauseKindCnt = -1;
5239 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5240 ++ClauseKindCnt;
5241 if (ImplicitMap.empty())
5242 continue;
5243 CXXScopeSpec MapperIdScopeSpec;
5244 DeclarationNameInfo MapperId;
5245 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5246 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5247 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5248 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5249 SourceLocation(), SourceLocation(), ImplicitMap,
5250 OMPVarListLocTy())) {
5251 ClausesWithImplicit.emplace_back(Implicit);
5252 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5253 ImplicitMap.size();
5254 } else {
5255 ErrorFound = true;
5256 }
5257 }
5258 }
5259 }
5260
5261 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5262 switch (Kind) {
5263 case OMPD_parallel:
5264 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5265 EndLoc);
5266 AllowedNameModifiers.push_back(OMPD_parallel);
5267 break;
5268 case OMPD_simd:
5269 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5270 VarsWithInheritedDSA);
5271 if (LangOpts.OpenMP >= 50)
5272 AllowedNameModifiers.push_back(OMPD_simd);
5273 break;
5274 case OMPD_for:
5275 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5276 VarsWithInheritedDSA);
5277 break;
5278 case OMPD_for_simd:
5279 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5280 EndLoc, VarsWithInheritedDSA);
5281 if (LangOpts.OpenMP >= 50)
5282 AllowedNameModifiers.push_back(OMPD_simd);
5283 break;
5284 case OMPD_sections:
5285 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5286 EndLoc);
5287 break;
5288 case OMPD_section:
5289 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5290, __PRETTY_FUNCTION__))
5290 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5290, __PRETTY_FUNCTION__))
;
5291 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5292 break;
5293 case OMPD_single:
5294 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5295 EndLoc);
5296 break;
5297 case OMPD_master:
5298 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5299, __PRETTY_FUNCTION__))
5299 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5299, __PRETTY_FUNCTION__))
;
5300 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5301 break;
5302 case OMPD_critical:
5303 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5304 StartLoc, EndLoc);
5305 break;
5306 case OMPD_parallel_for:
5307 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5308 EndLoc, VarsWithInheritedDSA);
5309 AllowedNameModifiers.push_back(OMPD_parallel);
5310 break;
5311 case OMPD_parallel_for_simd:
5312 Res = ActOnOpenMPParallelForSimdDirective(
5313 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5314 AllowedNameModifiers.push_back(OMPD_parallel);
5315 if (LangOpts.OpenMP >= 50)
5316 AllowedNameModifiers.push_back(OMPD_simd);
5317 break;
5318 case OMPD_parallel_master:
5319 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5320 StartLoc, EndLoc);
5321 AllowedNameModifiers.push_back(OMPD_parallel);
5322 break;
5323 case OMPD_parallel_sections:
5324 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5325 StartLoc, EndLoc);
5326 AllowedNameModifiers.push_back(OMPD_parallel);
5327 break;
5328 case OMPD_task:
5329 Res =
5330 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5331 AllowedNameModifiers.push_back(OMPD_task);
5332 break;
5333 case OMPD_taskyield:
5334 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5335, __PRETTY_FUNCTION__))
5335 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5335, __PRETTY_FUNCTION__))
;
5336 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5337, __PRETTY_FUNCTION__))
5337 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5337, __PRETTY_FUNCTION__))
;
5338 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5339 break;
5340 case OMPD_barrier:
5341 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5342, __PRETTY_FUNCTION__))
5342 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5342, __PRETTY_FUNCTION__))
;
5343 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5344, __PRETTY_FUNCTION__))
5344 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5344, __PRETTY_FUNCTION__))
;
5345 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5346 break;
5347 case OMPD_taskwait:
5348 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5349, __PRETTY_FUNCTION__))
5349 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5349, __PRETTY_FUNCTION__))
;
5350 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5351, __PRETTY_FUNCTION__))
5351 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5351, __PRETTY_FUNCTION__))
;
5352 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5353 break;
5354 case OMPD_taskgroup:
5355 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5356 EndLoc);
5357 break;
5358 case OMPD_flush:
5359 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5360, __PRETTY_FUNCTION__))
5360 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5360, __PRETTY_FUNCTION__))
;
5361 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5362 break;
5363 case OMPD_depobj:
5364 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5365, __PRETTY_FUNCTION__))
5365 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5365, __PRETTY_FUNCTION__))
;
5366 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5367 break;
5368 case OMPD_scan:
5369 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5370, __PRETTY_FUNCTION__))
5370 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5370, __PRETTY_FUNCTION__))
;
5371 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5372 break;
5373 case OMPD_ordered:
5374 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5375 EndLoc);
5376 break;
5377 case OMPD_atomic:
5378 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5379 EndLoc);
5380 break;
5381 case OMPD_teams:
5382 Res =
5383 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5384 break;
5385 case OMPD_target:
5386 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5387 EndLoc);
5388 AllowedNameModifiers.push_back(OMPD_target);
5389 break;
5390 case OMPD_target_parallel:
5391 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5392 StartLoc, EndLoc);
5393 AllowedNameModifiers.push_back(OMPD_target);
5394 AllowedNameModifiers.push_back(OMPD_parallel);
5395 break;
5396 case OMPD_target_parallel_for:
5397 Res = ActOnOpenMPTargetParallelForDirective(
5398 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5399 AllowedNameModifiers.push_back(OMPD_target);
5400 AllowedNameModifiers.push_back(OMPD_parallel);
5401 break;
5402 case OMPD_cancellation_point:
5403 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5404, __PRETTY_FUNCTION__))
5404 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5404, __PRETTY_FUNCTION__))
;
5405 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5406, __PRETTY_FUNCTION__))
5406 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5406, __PRETTY_FUNCTION__))
;
5407 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5408 break;
5409 case OMPD_cancel:
5410 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5411, __PRETTY_FUNCTION__))
5411 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5411, __PRETTY_FUNCTION__))
;
5412 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5413 CancelRegion);
5414 AllowedNameModifiers.push_back(OMPD_cancel);
5415 break;
5416 case OMPD_target_data:
5417 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5418 EndLoc);
5419 AllowedNameModifiers.push_back(OMPD_target_data);
5420 break;
5421 case OMPD_target_enter_data:
5422 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5423 EndLoc, AStmt);
5424 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5425 break;
5426 case OMPD_target_exit_data:
5427 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5428 EndLoc, AStmt);
5429 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5430 break;
5431 case OMPD_taskloop:
5432 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5433 EndLoc, VarsWithInheritedDSA);
5434 AllowedNameModifiers.push_back(OMPD_taskloop);
5435 break;
5436 case OMPD_taskloop_simd:
5437 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5438 EndLoc, VarsWithInheritedDSA);
5439 AllowedNameModifiers.push_back(OMPD_taskloop);
5440 if (LangOpts.OpenMP >= 50)
5441 AllowedNameModifiers.push_back(OMPD_simd);
5442 break;
5443 case OMPD_master_taskloop:
5444 Res = ActOnOpenMPMasterTaskLoopDirective(
5445 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5446 AllowedNameModifiers.push_back(OMPD_taskloop);
5447 break;
5448 case OMPD_master_taskloop_simd:
5449 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5450 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5451 AllowedNameModifiers.push_back(OMPD_taskloop);
5452 if (LangOpts.OpenMP >= 50)
5453 AllowedNameModifiers.push_back(OMPD_simd);
5454 break;
5455 case OMPD_parallel_master_taskloop:
5456 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5457 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5458 AllowedNameModifiers.push_back(OMPD_taskloop);
5459 AllowedNameModifiers.push_back(OMPD_parallel);
5460 break;
5461 case OMPD_parallel_master_taskloop_simd:
5462 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5463 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5464 AllowedNameModifiers.push_back(OMPD_taskloop);
5465 AllowedNameModifiers.push_back(OMPD_parallel);
5466 if (LangOpts.OpenMP >= 50)
5467 AllowedNameModifiers.push_back(OMPD_simd);
5468 break;
5469 case OMPD_distribute:
5470 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5471 EndLoc, VarsWithInheritedDSA);
5472 break;
5473 case OMPD_target_update:
5474 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5475 EndLoc, AStmt);
5476 AllowedNameModifiers.push_back(OMPD_target_update);
5477 break;
5478 case OMPD_distribute_parallel_for:
5479 Res = ActOnOpenMPDistributeParallelForDirective(
5480 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5481 AllowedNameModifiers.push_back(OMPD_parallel);
5482 break;
5483 case OMPD_distribute_parallel_for_simd:
5484 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5485 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5486 AllowedNameModifiers.push_back(OMPD_parallel);
5487 if (LangOpts.OpenMP >= 50)
5488 AllowedNameModifiers.push_back(OMPD_simd);
5489 break;
5490 case OMPD_distribute_simd:
5491 Res = ActOnOpenMPDistributeSimdDirective(
5492 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5493 if (LangOpts.OpenMP >= 50)
5494 AllowedNameModifiers.push_back(OMPD_simd);
5495 break;
5496 case OMPD_target_parallel_for_simd:
5497 Res = ActOnOpenMPTargetParallelForSimdDirective(
5498 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5499 AllowedNameModifiers.push_back(OMPD_target);
5500 AllowedNameModifiers.push_back(OMPD_parallel);
5501 if (LangOpts.OpenMP >= 50)
5502 AllowedNameModifiers.push_back(OMPD_simd);
5503 break;
5504 case OMPD_target_simd:
5505 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5506 EndLoc, VarsWithInheritedDSA);
5507 AllowedNameModifiers.push_back(OMPD_target);
5508 if (LangOpts.OpenMP >= 50)
5509 AllowedNameModifiers.push_back(OMPD_simd);
5510 break;
5511 case OMPD_teams_distribute:
5512 Res = ActOnOpenMPTeamsDistributeDirective(
5513 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5514 break;
5515 case OMPD_teams_distribute_simd:
5516 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5517 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5518 if (LangOpts.OpenMP >= 50)
5519 AllowedNameModifiers.push_back(OMPD_simd);
5520 break;
5521 case OMPD_teams_distribute_parallel_for_simd:
5522 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5523 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5524 AllowedNameModifiers.push_back(OMPD_parallel);
5525 if (LangOpts.OpenMP >= 50)
5526 AllowedNameModifiers.push_back(OMPD_simd);
5527 break;
5528 case OMPD_teams_distribute_parallel_for:
5529 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5530 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5531 AllowedNameModifiers.push_back(OMPD_parallel);
5532 break;
5533 case OMPD_target_teams:
5534 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5535 EndLoc);
5536 AllowedNameModifiers.push_back(OMPD_target);
5537 break;
5538 case OMPD_target_teams_distribute:
5539 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5540 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5541 AllowedNameModifiers.push_back(OMPD_target);
5542 break;
5543 case OMPD_target_teams_distribute_parallel_for:
5544 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5545 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5546 AllowedNameModifiers.push_back(OMPD_target);
5547 AllowedNameModifiers.push_back(OMPD_parallel);
5548 break;
5549 case OMPD_target_teams_distribute_parallel_for_simd:
5550 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5551 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5552 AllowedNameModifiers.push_back(OMPD_target);
5553 AllowedNameModifiers.push_back(OMPD_parallel);
5554 if (LangOpts.OpenMP >= 50)
5555 AllowedNameModifiers.push_back(OMPD_simd);
5556 break;
5557 case OMPD_target_teams_distribute_simd:
5558 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5559 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5560 AllowedNameModifiers.push_back(OMPD_target);
5561 if (LangOpts.OpenMP >= 50)
5562 AllowedNameModifiers.push_back(OMPD_simd);
5563 break;
5564 case OMPD_declare_target:
5565 case OMPD_end_declare_target:
5566 case OMPD_threadprivate:
5567 case OMPD_allocate:
5568 case OMPD_declare_reduction:
5569 case OMPD_declare_mapper:
5570 case OMPD_declare_simd:
5571 case OMPD_requires:
5572 case OMPD_declare_variant:
5573 case OMPD_begin_declare_variant:
5574 case OMPD_end_declare_variant:
5575 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5575)
;
5576 case OMPD_unknown:
5577 default:
5578 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5578)
;
5579 }
5580
5581 ErrorFound = Res.isInvalid() || ErrorFound;
5582
5583 // Check variables in the clauses if default(none) or
5584 // default(firstprivate) was specified.
5585 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5586 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5587 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
5588 for (OMPClause *C : Clauses) {
5589 switch (C->getClauseKind()) {
5590 case OMPC_num_threads:
5591 case OMPC_dist_schedule:
5592 // Do not analyse if no parent teams directive.
5593 if (isOpenMPTeamsDirective(Kind))
5594 break;
5595 continue;
5596 case OMPC_if:
5597 if (isOpenMPTeamsDirective(Kind) &&
5598 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5599 break;
5600 if (isOpenMPParallelDirective(Kind) &&
5601 isOpenMPTaskLoopDirective(Kind) &&
5602 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5603 break;
5604 continue;
5605 case OMPC_schedule:
5606 case OMPC_detach:
5607 break;
5608 case OMPC_grainsize:
5609 case OMPC_num_tasks:
5610 case OMPC_final:
5611 case OMPC_priority:
5612 // Do not analyze if no parent parallel directive.
5613 if (isOpenMPParallelDirective(Kind))
5614 break;
5615 continue;
5616 case OMPC_ordered:
5617 case OMPC_device:
5618 case OMPC_num_teams:
5619 case OMPC_thread_limit:
5620 case OMPC_hint:
5621 case OMPC_collapse:
5622 case OMPC_safelen:
5623 case OMPC_simdlen:
5624 case OMPC_default:
5625 case OMPC_proc_bind:
5626 case OMPC_private:
5627 case OMPC_firstprivate:
5628 case OMPC_lastprivate:
5629 case OMPC_shared:
5630 case OMPC_reduction:
5631 case OMPC_task_reduction:
5632 case OMPC_in_reduction:
5633 case OMPC_linear:
5634 case OMPC_aligned:
5635 case OMPC_copyin:
5636 case OMPC_copyprivate:
5637 case OMPC_nowait:
5638 case OMPC_untied:
5639 case OMPC_mergeable:
5640 case OMPC_allocate:
5641 case OMPC_read:
5642 case OMPC_write:
5643 case OMPC_update:
5644 case OMPC_capture:
5645 case OMPC_seq_cst:
5646 case OMPC_acq_rel:
5647 case OMPC_acquire:
5648 case OMPC_release:
5649 case OMPC_relaxed:
5650 case OMPC_depend:
5651 case OMPC_threads:
5652 case OMPC_simd:
5653 case OMPC_map:
5654 case OMPC_nogroup:
5655 case OMPC_defaultmap:
5656 case OMPC_to:
5657 case OMPC_from:
5658 case OMPC_use_device_ptr:
5659 case OMPC_use_device_addr:
5660 case OMPC_is_device_ptr:
5661 case OMPC_nontemporal:
5662 case OMPC_order:
5663 case OMPC_destroy:
5664 case OMPC_inclusive:
5665 case OMPC_exclusive:
5666 case OMPC_uses_allocators:
5667 case OMPC_affinity:
5668 continue;
5669 case OMPC_allocator:
5670 case OMPC_flush:
5671 case OMPC_depobj:
5672 case OMPC_threadprivate:
5673 case OMPC_uniform:
5674 case OMPC_unknown:
5675 case OMPC_unified_address:
5676 case OMPC_unified_shared_memory:
5677 case OMPC_reverse_offload:
5678 case OMPC_dynamic_allocators:
5679 case OMPC_atomic_default_mem_order:
5680 case OMPC_device_type:
5681 case OMPC_match:
5682 default:
5683 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5683)
;
5684 }
5685 for (Stmt *CC : C->children()) {
5686 if (CC)
5687 DSAChecker.Visit(CC);
5688 }
5689 }
5690 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5691 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5692 }
5693 for (const auto &P : VarsWithInheritedDSA) {
5694 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5695 continue;
5696 ErrorFound = true;
5697 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5698 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5699 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5700 << P.first << P.second->getSourceRange();
5701 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5702 } else if (getLangOpts().OpenMP >= 50) {
5703 Diag(P.second->getExprLoc(),
5704 diag::err_omp_defaultmap_no_attr_for_variable)
5705 << P.first << P.second->getSourceRange();
5706 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
5707 diag::note_omp_defaultmap_attr_none);
5708 }
5709 }
5710
5711 if (!AllowedNameModifiers.empty())
5712 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5713 ErrorFound;
5714
5715 if (ErrorFound)
5716 return StmtError();
5717
5718 if (!CurContext->isDependentContext() &&
5719 isOpenMPTargetExecutionDirective(Kind) &&
5720 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5721 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5722 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5723 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5724 // Register target to DSA Stack.
5725 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
5726 }
5727
5728 return Res;
5729}
5730
5731Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5732 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5733 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5734 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5735 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5736 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5736, __PRETTY_FUNCTION__))
;
5737 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5737, __PRETTY_FUNCTION__))
;
5738 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5738, __PRETTY_FUNCTION__))
;
5739 if (!DG || DG.get().isNull())
5740 return DeclGroupPtrTy();
5741
5742 const int SimdId = 0;
5743 if (!DG.get().isSingleDecl()) {
5744 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5745 << SimdId;
5746 return DG;
5747 }
5748 Decl *ADecl = DG.get().getSingleDecl();
5749 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5750 ADecl = FTD->getTemplatedDecl();
5751
5752 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5753 if (!FD) {
5754 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5755 return DeclGroupPtrTy();
5756 }
5757
5758 // OpenMP [2.8.2, declare simd construct, Description]
5759 // The parameter of the simdlen clause must be a constant positive integer
5760 // expression.
5761 ExprResult SL;
5762 if (Simdlen)
5763 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5764 // OpenMP [2.8.2, declare simd construct, Description]
5765 // The special this pointer can be used as if was one of the arguments to the
5766 // function in any of the linear, aligned, or uniform clauses.
5767 // The uniform clause declares one or more arguments to have an invariant
5768 // value for all concurrent invocations of the function in the execution of a
5769 // single SIMD loop.
5770 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5771 const Expr *UniformedLinearThis = nullptr;
5772 for (const Expr *E : Uniforms) {
5773 E = E->IgnoreParenImpCasts();
5774 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5775 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5776 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5777 FD->getParamDecl(PVD->getFunctionScopeIndex())
5778 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5779 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5780 continue;
5781 }
5782 if (isa<CXXThisExpr>(E)) {
5783 UniformedLinearThis = E;
5784 continue;
5785 }
5786 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5787 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5788 }
5789 // OpenMP [2.8.2, declare simd construct, Description]
5790 // The aligned clause declares that the object to which each list item points
5791 // is aligned to the number of bytes expressed in the optional parameter of
5792 // the aligned clause.
5793 // The special this pointer can be used as if was one of the arguments to the
5794 // function in any of the linear, aligned, or uniform clauses.
5795 // The type of list items appearing in the aligned clause must be array,
5796 // pointer, reference to array, or reference to pointer.
5797 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5798 const Expr *AlignedThis = nullptr;
5799 for (const Expr *E : Aligneds) {
5800 E = E->IgnoreParenImpCasts();
5801 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5802 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5803 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5804 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5805 FD->getParamDecl(PVD->getFunctionScopeIndex())
5806 ->getCanonicalDecl() == CanonPVD) {
5807 // OpenMP [2.8.1, simd construct, Restrictions]
5808 // A list-item cannot appear in more than one aligned clause.
5809 if (AlignedArgs.count(CanonPVD) > 0) {
5810 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5811 << 1 << getOpenMPClauseName(OMPC_aligned)
5812 << E->getSourceRange();
5813 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5814 diag::note_omp_explicit_dsa)
5815 << getOpenMPClauseName(OMPC_aligned);
5816 continue;
5817 }
5818 AlignedArgs[CanonPVD] = E;
5819 QualType QTy = PVD->getType()
5820 .getNonReferenceType()
5821 .getUnqualifiedType()
5822 .getCanonicalType();
5823 const Type *Ty = QTy.getTypePtrOrNull();
5824 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5825 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5826 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5827 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5828 }
5829 continue;
5830 }
5831 }
5832 if (isa<CXXThisExpr>(E)) {
5833 if (AlignedThis) {
5834 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5835 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5836 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5837 << getOpenMPClauseName(OMPC_aligned);
5838 }
5839 AlignedThis = E;
5840 continue;
5841 }
5842 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5843 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5844 }
5845 // The optional parameter of the aligned clause, alignment, must be a constant
5846 // positive integer expression. If no optional parameter is specified,
5847 // implementation-defined default alignments for SIMD instructions on the
5848 // target platforms are assumed.
5849 SmallVector<const Expr *, 4> NewAligns;
5850 for (Expr *E : Alignments) {
5851 ExprResult Align;
5852 if (E)
5853 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5854 NewAligns.push_back(Align.get());
5855 }
5856 // OpenMP [2.8.2, declare simd construct, Description]
5857 // The linear clause declares one or more list items to be private to a SIMD
5858 // lane and to have a linear relationship with respect to the iteration space
5859 // of a loop.
5860 // The special this pointer can be used as if was one of the arguments to the
5861 // function in any of the linear, aligned, or uniform clauses.
5862 // When a linear-step expression is specified in a linear clause it must be
5863 // either a constant integer expression or an integer-typed parameter that is
5864 // specified in a uniform clause on the directive.
5865 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5866 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5867 auto MI = LinModifiers.begin();
5868 for (const Expr *E : Linears) {
5869 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5870 ++MI;
5871 E = E->IgnoreParenImpCasts();
5872 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5873 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5874 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5875 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5876 FD->getParamDecl(PVD->getFunctionScopeIndex())
5877 ->getCanonicalDecl() == CanonPVD) {
5878 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5879 // A list-item cannot appear in more than one linear clause.
5880 if (LinearArgs.count(CanonPVD) > 0) {
5881 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5882 << getOpenMPClauseName(OMPC_linear)
5883 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5884 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5885 diag::note_omp_explicit_dsa)
5886 << getOpenMPClauseName(OMPC_linear);
5887 continue;
5888 }
5889 // Each argument can appear in at most one uniform or linear clause.
5890 if (UniformedArgs.count(CanonPVD) > 0) {
5891 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5892 << getOpenMPClauseName(OMPC_linear)
5893 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5894 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5895 diag::note_omp_explicit_dsa)
5896 << getOpenMPClauseName(OMPC_uniform);
5897 continue;
5898 }
5899 LinearArgs[CanonPVD] = E;
5900 if (E->isValueDependent() || E->isTypeDependent() ||
5901 E->isInstantiationDependent() ||
5902 E->containsUnexpandedParameterPack())
5903 continue;
5904 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5905 PVD->getOriginalType(),
5906 /*IsDeclareSimd=*/true);
5907 continue;
5908 }
5909 }
5910 if (isa<CXXThisExpr>(E)) {
5911 if (UniformedLinearThis) {
5912 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5913 << getOpenMPClauseName(OMPC_linear)
5914 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5915 << E->getSourceRange();
5916 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5917 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5918 : OMPC_linear);
5919 continue;
5920 }
5921 UniformedLinearThis = E;
5922 if (E->isValueDependent() || E->isTypeDependent() ||
5923 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5924 continue;
5925 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5926 E->getType(), /*IsDeclareSimd=*/true);
5927 continue;
5928 }
5929 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5930 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5931 }
5932 Expr *Step = nullptr;
5933 Expr *NewStep = nullptr;
5934 SmallVector<Expr *, 4> NewSteps;
5935 for (Expr *E : Steps) {
5936 // Skip the same step expression, it was checked already.
5937 if (Step == E || !E) {
5938 NewSteps.push_back(E ? NewStep : nullptr);
5939 continue;
5940 }
5941 Step = E;
5942 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5943 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5944 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5945 if (UniformedArgs.count(CanonPVD) == 0) {
5946 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5947 << Step->getSourceRange();
5948 } else if (E->isValueDependent() || E->isTypeDependent() ||
5949 E->isInstantiationDependent() ||
5950 E->containsUnexpandedParameterPack() ||
5951 CanonPVD->getType()->hasIntegerRepresentation()) {
5952 NewSteps.push_back(Step);
5953 } else {
5954 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5955 << Step->getSourceRange();
5956 }
5957 continue;
5958 }
5959 NewStep = Step;
5960 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5961 !Step->isInstantiationDependent() &&
5962 !Step->containsUnexpandedParameterPack()) {
5963 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5964 .get();
5965 if (NewStep)
5966 NewStep =
5967 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
5968 }
5969 NewSteps.push_back(NewStep);
5970 }
5971 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5972 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5973 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5974 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5975 const_cast<Expr **>(Linears.data()), Linears.size(),
5976 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5977 NewSteps.data(), NewSteps.size(), SR);
5978 ADecl->addAttr(NewAttr);
5979 return DG;
5980}
5981
5982static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5983 QualType NewType) {
5984 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5985, __PRETTY_FUNCTION__))
5985 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5985, __PRETTY_FUNCTION__))
;
5986 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5987, __PRETTY_FUNCTION__))
5987 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5987, __PRETTY_FUNCTION__))
;
5988 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5989, __PRETTY_FUNCTION__))
5989 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 5989, __PRETTY_FUNCTION__))
;
5990 // Synthesize parameters with the same types.
5991 FD->setType(NewType);
5992 SmallVector<ParmVarDecl *, 16> Params;
5993 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5994 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5995 SourceLocation(), nullptr, P->getType(),
5996 /*TInfo=*/nullptr, SC_None, nullptr);
5997 Param->setScopeInfo(0, Params.size());
5998 Param->setImplicit();
5999 Params.push_back(Param);
6000 }
6001
6002 FD->setParams(Params);
6003}
6004
6005void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6006 if (D->isInvalidDecl())
6007 return;
6008 FunctionDecl *FD = nullptr;
6009 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6010 FD = UTemplDecl->getTemplatedDecl();
6011 else
6012 FD = cast<FunctionDecl>(D);
6013 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6013, __PRETTY_FUNCTION__))
;
6014
6015 // If we are intantiating templates we do *not* apply scoped assumptions but
6016 // only global ones. We apply scoped assumption to the template definition
6017 // though.
6018 if (!inTemplateInstantiation()) {
6019 for (AssumptionAttr *AA : OMPAssumeScoped)
6020 FD->addAttr(AA);
6021 }
6022 for (AssumptionAttr *AA : OMPAssumeGlobal)
6023 FD->addAttr(AA);
6024}
6025
6026Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6027 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6028
6029void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6030 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6031 SmallVectorImpl<FunctionDecl *> &Bases) {
6032 if (!D.getIdentifier())
6033 return;
6034
6035 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6036
6037 // Template specialization is an extension, check if we do it.
6038 bool IsTemplated = !TemplateParamLists.empty();
6039 if (IsTemplated &
6040 !DVScope.TI->isExtensionActive(
6041 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6042 return;
6043
6044 IdentifierInfo *BaseII = D.getIdentifier();
6045 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6046 LookupOrdinaryName);
6047 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6048
6049 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6050 QualType FType = TInfo->getType();
6051
6052 bool IsConstexpr =
6053 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6054 bool IsConsteval =
6055 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6056
6057 for (auto *Candidate : Lookup) {
6058 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6059 FunctionDecl *UDecl = nullptr;
6060 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6061 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6062 else if (!IsTemplated)
6063 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6064 if (!UDecl)
6065 continue;
6066
6067 // Don't specialize constexpr/consteval functions with
6068 // non-constexpr/consteval functions.
6069 if (UDecl->isConstexpr() && !IsConstexpr)
6070 continue;
6071 if (UDecl->isConsteval() && !IsConsteval)
6072 continue;
6073
6074 QualType UDeclTy = UDecl->getType();
6075 if (!UDeclTy->isDependentType()) {
6076 QualType NewType = Context.mergeFunctionTypes(
6077 FType, UDeclTy, /* OfBlockPointer */ false,
6078 /* Unqualified */ false, /* AllowCXX */ true);
6079 if (NewType.isNull())
6080 continue;
6081 }
6082
6083 // Found a base!
6084 Bases.push_back(UDecl);
6085 }
6086
6087 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6088 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6089 // If no base was found we create a declaration that we use as base.
6090 if (Bases.empty() && UseImplicitBase) {
6091 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6092 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6093 BaseD->setImplicit(true);
6094 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6095 Bases.push_back(BaseTemplD->getTemplatedDecl());
6096 else
6097 Bases.push_back(cast<FunctionDecl>(BaseD));
6098 }
6099
6100 std::string MangledName;
6101 MangledName += D.getIdentifier()->getName();
6102 MangledName += getOpenMPVariantManglingSeparatorStr();
6103 MangledName += DVScope.NameSuffix;
6104 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6105
6106 VariantII.setMangledOpenMPVariantName(true);
6107 D.SetIdentifier(&VariantII, D.getBeginLoc());
6108}
6109
6110void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6111 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6112 // Do not mark function as is used to prevent its emission if this is the
6113 // only place where it is used.
6114 EnterExpressionEvaluationContext Unevaluated(
6115 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6116
6117 FunctionDecl *FD = nullptr;
6118 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6119 FD = UTemplDecl->getTemplatedDecl();
6120 else
6121 FD = cast<FunctionDecl>(D);
6122 auto *VariantFuncRef = DeclRefExpr::Create(
6123 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6124 /* RefersToEnclosingVariableOrCapture */ false,
6125 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
6126
6127 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6128 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6129 Context, VariantFuncRef, DVScope.TI);
6130 for (FunctionDecl *BaseFD : Bases)
6131 BaseFD->addAttr(OMPDeclareVariantA);
6132}
6133
6134ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6135 SourceLocation LParenLoc,
6136 MultiExprArg ArgExprs,
6137 SourceLocation RParenLoc, Expr *ExecConfig) {
6138 // The common case is a regular call we do not want to specialize at all. Try
6139 // to make that case fast by bailing early.
6140 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6141 if (!CE)
6142 return Call;
6143
6144 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6145 if (!CalleeFnDecl)
6146 return Call;
6147
6148 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6149 return Call;
6150
6151 ASTContext &Context = getASTContext();
6152 std::function<void(StringRef)> DiagUnknownTrait = [this,
6153 CE](StringRef ISATrait) {
6154 // TODO Track the selector locations in a way that is accessible here to
6155 // improve the diagnostic location.
6156 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6157 << ISATrait;
6158 };
6159 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6160 getCurFunctionDecl());
6161
6162 QualType CalleeFnType = CalleeFnDecl->getType();
6163
6164 SmallVector<Expr *, 4> Exprs;
6165 SmallVector<VariantMatchInfo, 4> VMIs;
6166 while (CalleeFnDecl) {
6167 for (OMPDeclareVariantAttr *A :
6168 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6169 Expr *VariantRef = A->getVariantFuncRef();
6170
6171 VariantMatchInfo VMI;
6172 OMPTraitInfo &TI = A->getTraitInfo();
6173 TI.getAsVariantMatchInfo(Context, VMI);
6174 if (!isVariantApplicableInContext(VMI, OMPCtx,
6175 /* DeviceSetOnly */ false))
6176 continue;
6177
6178 VMIs.push_back(VMI);
6179 Exprs.push_back(VariantRef);
6180 }
6181
6182 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6183 }
6184
6185 ExprResult NewCall;
6186 do {
6187 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6188 if (BestIdx < 0)
6189 return Call;
6190 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6191 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6192
6193 {
6194 // Try to build a (member) call expression for the current best applicable
6195 // variant expression. We allow this to fail in which case we continue
6196 // with the next best variant expression. The fail case is part of the
6197 // implementation defined behavior in the OpenMP standard when it talks
6198 // about what differences in the function prototypes: "Any differences
6199 // that the specific OpenMP context requires in the prototype of the
6200 // variant from the base function prototype are implementation defined."
6201 // This wording is there to allow the specialized variant to have a
6202 // different type than the base function. This is intended and OK but if
6203 // we cannot create a call the difference is not in the "implementation
6204 // defined range" we allow.
6205 Sema::TentativeAnalysisScope Trap(*this);
6206
6207 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6208 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6209 BestExpr = MemberExpr::CreateImplicit(
6210 Context, MemberCall->getImplicitObjectArgument(),
6211 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6212 MemberCall->getValueKind(), MemberCall->getObjectKind());
6213 }
6214 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6215 ExecConfig);
6216 if (NewCall.isUsable()) {
6217 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6218 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6219 QualType NewType = Context.mergeFunctionTypes(
6220 CalleeFnType, NewCalleeFnDecl->getType(),
6221 /* OfBlockPointer */ false,
6222 /* Unqualified */ false, /* AllowCXX */ true);
6223 if (!NewType.isNull())
6224 break;
6225 // Don't use the call if the function type was not compatible.
6226 NewCall = nullptr;
6227 }
6228 }
6229 }
6230
6231 VMIs.erase(VMIs.begin() + BestIdx);
6232 Exprs.erase(Exprs.begin() + BestIdx);
6233 } while (!VMIs.empty());
6234
6235 if (!NewCall.isUsable())
6236 return Call;
6237 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6238}
6239
6240Optional<std::pair<FunctionDecl *, Expr *>>
6241Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6242 Expr *VariantRef, OMPTraitInfo &TI,
6243 SourceRange SR) {
6244 if (!DG || DG.get().isNull())
6245 return None;
6246
6247 const int VariantId = 1;
6248 // Must be applied only to single decl.
6249 if (!DG.get().isSingleDecl()) {
6250 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6251 << VariantId << SR;
6252 return None;
6253 }
6254 Decl *ADecl = DG.get().getSingleDecl();
6255 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6256 ADecl = FTD->getTemplatedDecl();
6257
6258 // Decl must be a function.
6259 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6260 if (!FD) {
6261 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6262 << VariantId << SR;
6263 return None;
6264 }
6265
6266 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6267 return FD->hasAttrs() &&
6268 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6269 FD->hasAttr<TargetAttr>());
6270 };
6271 // OpenMP is not compatible with CPU-specific attributes.
6272 if (HasMultiVersionAttributes(FD)) {
6273 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6274 << SR;
6275 return None;
6276 }
6277
6278 // Allow #pragma omp declare variant only if the function is not used.
6279 if (FD->isUsed(false))
6280 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6281 << FD->getLocation();
6282
6283 // Check if the function was emitted already.
6284 const FunctionDecl *Definition;
6285 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6286 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6287 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6288 << FD->getLocation();
6289
6290 // The VariantRef must point to function.
6291 if (!VariantRef) {
6292 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6293 return None;
6294 }
6295
6296 auto ShouldDelayChecks = [](Expr *&E, bool) {
6297 return E && (E->isTypeDependent() || E->isValueDependent() ||
6298 E->containsUnexpandedParameterPack() ||
6299 E->isInstantiationDependent());
6300 };
6301 // Do not check templates, wait until instantiation.
6302 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6303 TI.anyScoreOrCondition(ShouldDelayChecks))
6304 return std::make_pair(FD, VariantRef);
6305
6306 // Deal with non-constant score and user condition expressions.
6307 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6308 bool IsScore) -> bool {
6309 if (!E || E->isIntegerConstantExpr(Context))
6310 return false;
6311
6312 if (IsScore) {
6313 // We warn on non-constant scores and pretend they were not present.
6314 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6315 << E;
6316 E = nullptr;
6317 } else {
6318 // We could replace a non-constant user condition with "false" but we
6319 // will soon need to handle these anyway for the dynamic version of
6320 // OpenMP context selectors.
6321 Diag(E->getExprLoc(),
6322 diag::err_omp_declare_variant_user_condition_not_constant)
6323 << E;
6324 }
6325 return true;
6326 };
6327 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6328 return None;
6329
6330 // Convert VariantRef expression to the type of the original function to
6331 // resolve possible conflicts.
6332 ExprResult VariantRefCast = VariantRef;
6333 if (LangOpts.CPlusPlus) {
6334 QualType FnPtrType;
6335 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6336 if (Method && !Method->isStatic()) {
6337 const Type *ClassType =
6338 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6339 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6340 ExprResult ER;
6341 {
6342 // Build adrr_of unary op to correctly handle type checks for member
6343 // functions.
6344 Sema::TentativeAnalysisScope Trap(*this);
6345 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6346 VariantRef);
6347 }
6348 if (!ER.isUsable()) {
6349 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6350 << VariantId << VariantRef->getSourceRange();
6351 return None;
6352 }
6353 VariantRef = ER.get();
6354 } else {
6355 FnPtrType = Context.getPointerType(FD->getType());
6356 }
6357 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6358 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6359 ImplicitConversionSequence ICS = TryImplicitConversion(
6360 VariantRef, FnPtrType.getUnqualifiedType(),
6361 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6362 /*InOverloadResolution=*/false,
6363 /*CStyle=*/false,
6364 /*AllowObjCWritebackConversion=*/false);
6365 if (ICS.isFailure()) {
6366 Diag(VariantRef->getExprLoc(),
6367 diag::err_omp_declare_variant_incompat_types)
6368 << VariantRef->getType()
6369 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6370 << VariantRef->getSourceRange();
6371 return None;
6372 }
6373 VariantRefCast = PerformImplicitConversion(
6374 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6375 if (!VariantRefCast.isUsable())
6376 return None;
6377 }
6378 // Drop previously built artificial addr_of unary op for member functions.
6379 if (Method && !Method->isStatic()) {
6380 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6381 if (auto *UO = dyn_cast<UnaryOperator>(
6382 PossibleAddrOfVariantRef->IgnoreImplicit()))
6383 VariantRefCast = UO->getSubExpr();
6384 }
6385 }
6386
6387 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6388 if (!ER.isUsable() ||
6389 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6390 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6391 << VariantId << VariantRef->getSourceRange();
6392 return None;
6393 }
6394
6395 // The VariantRef must point to function.
6396 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6397 if (!DRE) {
6398 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6399 << VariantId << VariantRef->getSourceRange();
6400 return None;
6401 }
6402 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6403 if (!NewFD) {
6404 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6405 << VariantId << VariantRef->getSourceRange();
6406 return None;
6407 }
6408
6409 // Check if function types are compatible in C.
6410 if (!LangOpts.CPlusPlus) {
6411 QualType NewType =
6412 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6413 if (NewType.isNull()) {
6414 Diag(VariantRef->getExprLoc(),
6415 diag::err_omp_declare_variant_incompat_types)
6416 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6417 return None;
6418 }
6419 if (NewType->isFunctionProtoType()) {
6420 if (FD->getType()->isFunctionNoProtoType())
6421 setPrototype(*this, FD, NewFD, NewType);
6422 else if (NewFD->getType()->isFunctionNoProtoType())
6423 setPrototype(*this, NewFD, FD, NewType);
6424 }
6425 }
6426
6427 // Check if variant function is not marked with declare variant directive.
6428 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6429 Diag(VariantRef->getExprLoc(),
6430 diag::warn_omp_declare_variant_marked_as_declare_variant)
6431 << VariantRef->getSourceRange();
6432 SourceRange SR =
6433 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6434 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6435 return None;
6436 }
6437
6438 enum DoesntSupport {
6439 VirtFuncs = 1,
6440 Constructors = 3,
6441 Destructors = 4,
6442 DeletedFuncs = 5,
6443 DefaultedFuncs = 6,
6444 ConstexprFuncs = 7,
6445 ConstevalFuncs = 8,
6446 };
6447 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6448 if (CXXFD->isVirtual()) {
6449 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6450 << VirtFuncs;
6451 return None;
6452 }
6453
6454 if (isa<CXXConstructorDecl>(FD)) {
6455 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6456 << Constructors;
6457 return None;
6458 }
6459
6460 if (isa<CXXDestructorDecl>(FD)) {
6461 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6462 << Destructors;
6463 return None;
6464 }
6465 }
6466
6467 if (FD->isDeleted()) {
6468 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6469 << DeletedFuncs;
6470 return None;
6471 }
6472
6473 if (FD->isDefaulted()) {
6474 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6475 << DefaultedFuncs;
6476 return None;
6477 }
6478
6479 if (FD->isConstexpr()) {
6480 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6481 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6482 return None;
6483 }
6484
6485 // Check general compatibility.
6486 if (areMultiversionVariantFunctionsCompatible(
6487 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6488 PartialDiagnosticAt(SourceLocation(),
6489 PartialDiagnostic::NullDiagnostic()),
6490 PartialDiagnosticAt(
6491 VariantRef->getExprLoc(),
6492 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6493 PartialDiagnosticAt(VariantRef->getExprLoc(),
6494 PDiag(diag::err_omp_declare_variant_diff)
6495 << FD->getLocation()),
6496 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6497 /*CLinkageMayDiffer=*/true))
6498 return None;
6499 return std::make_pair(FD, cast<Expr>(DRE));
6500}
6501
6502void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6503 Expr *VariantRef,
6504 OMPTraitInfo &TI,
6505 SourceRange SR) {
6506 auto *NewAttr =
6507 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6508 FD->addAttr(NewAttr);
6509}
6510
6511StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6512 Stmt *AStmt,
6513 SourceLocation StartLoc,
6514 SourceLocation EndLoc) {
6515 if (!AStmt)
6516 return StmtError();
6517
6518 auto *CS = cast<CapturedStmt>(AStmt);
6519 // 1.2.2 OpenMP Language Terminology
6520 // Structured block - An executable statement with a single entry at the
6521 // top and a single exit at the bottom.
6522 // The point of exit cannot be a branch out of the structured block.
6523 // longjmp() and throw() must not violate the entry/exit criteria.
6524 CS->getCapturedDecl()->setNothrow();
6525
6526 setFunctionHasBranchProtectedScope();
6527
6528 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6529 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
6530 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6531}
6532
6533namespace {
6534/// Iteration space of a single for loop.
6535struct LoopIterationSpace final {
6536 /// True if the condition operator is the strict compare operator (<, > or
6537 /// !=).
6538 bool IsStrictCompare = false;
6539 /// Condition of the loop.
6540 Expr *PreCond = nullptr;
6541 /// This expression calculates the number of iterations in the loop.
6542 /// It is always possible to calculate it before starting the loop.
6543 Expr *NumIterations = nullptr;
6544 /// The loop counter variable.
6545 Expr *CounterVar = nullptr;
6546 /// Private loop counter variable.
6547 Expr *PrivateCounterVar = nullptr;
6548 /// This is initializer for the initial value of #CounterVar.
6549 Expr *CounterInit = nullptr;
6550 /// This is step for the #CounterVar used to generate its update:
6551 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6552 Expr *CounterStep = nullptr;
6553 /// Should step be subtracted?
6554 bool Subtract = false;
6555 /// Source range of the loop init.
6556 SourceRange InitSrcRange;
6557 /// Source range of the loop condition.
6558 SourceRange CondSrcRange;
6559 /// Source range of the loop increment.
6560 SourceRange IncSrcRange;
6561 /// Minimum value that can have the loop control variable. Used to support
6562 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6563 /// since only such variables can be used in non-loop invariant expressions.
6564 Expr *MinValue = nullptr;
6565 /// Maximum value that can have the loop control variable. Used to support
6566 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6567 /// since only such variables can be used in non-loop invariant expressions.
6568 Expr *MaxValue = nullptr;
6569 /// true, if the lower bound depends on the outer loop control var.
6570 bool IsNonRectangularLB = false;
6571 /// true, if the upper bound depends on the outer loop control var.
6572 bool IsNonRectangularUB = false;
6573 /// Index of the loop this loop depends on and forms non-rectangular loop
6574 /// nest.
6575 unsigned LoopDependentIdx = 0;
6576 /// Final condition for the non-rectangular loop nest support. It is used to
6577 /// check that the number of iterations for this particular counter must be
6578 /// finished.
6579 Expr *FinalCondition = nullptr;
6580};
6581
6582/// Helper class for checking canonical form of the OpenMP loops and
6583/// extracting iteration space of each loop in the loop nest, that will be used
6584/// for IR generation.
6585class OpenMPIterationSpaceChecker {
6586 /// Reference to Sema.
6587 Sema &SemaRef;
6588 /// Data-sharing stack.
6589 DSAStackTy &Stack;
6590 /// A location for diagnostics (when there is no some better location).
6591 SourceLocation DefaultLoc;
6592 /// A location for diagnostics (when increment is not compatible).
6593 SourceLocation ConditionLoc;
6594 /// A source location for referring to loop init later.
6595 SourceRange InitSrcRange;
6596 /// A source location for referring to condition later.
6597 SourceRange ConditionSrcRange;
6598 /// A source location for referring to increment later.
6599 SourceRange IncrementSrcRange;
6600 /// Loop variable.
6601 ValueDecl *LCDecl = nullptr;
6602 /// Reference to loop variable.
6603 Expr *LCRef = nullptr;
6604 /// Lower bound (initializer for the var).
6605 Expr *LB = nullptr;
6606 /// Upper bound.
6607 Expr *UB = nullptr;
6608 /// Loop step (increment).
6609 Expr *Step = nullptr;
6610 /// This flag is true when condition is one of:
6611 /// Var < UB
6612 /// Var <= UB
6613 /// UB > Var
6614 /// UB >= Var
6615 /// This will have no value when the condition is !=
6616 llvm::Optional<bool> TestIsLessOp;
6617 /// This flag is true when condition is strict ( < or > ).
6618 bool TestIsStrictOp = false;
6619 /// This flag is true when step is subtracted on each iteration.
6620 bool SubtractStep = false;
6621 /// The outer loop counter this loop depends on (if any).
6622 const ValueDecl *DepDecl = nullptr;
6623 /// Contains number of loop (starts from 1) on which loop counter init
6624 /// expression of this loop depends on.
6625 Optional<unsigned> InitDependOnLC;
6626 /// Contains number of loop (starts from 1) on which loop counter condition
6627 /// expression of this loop depends on.
6628 Optional<unsigned> CondDependOnLC;
6629 /// Checks if the provide statement depends on the loop counter.
6630 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6631 /// Original condition required for checking of the exit condition for
6632 /// non-rectangular loop.
6633 Expr *Condition = nullptr;
6634
6635public:
6636 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6637 SourceLocation DefaultLoc)
6638 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6639 ConditionLoc(DefaultLoc) {}
6640 /// Check init-expr for canonical loop form and save loop counter
6641 /// variable - #Var and its initialization value - #LB.
6642 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6643 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6644 /// for less/greater and for strict/non-strict comparison.
6645 bool checkAndSetCond(Expr *S);
6646 /// Check incr-expr for canonical loop form and return true if it
6647 /// does not conform, otherwise save loop step (#Step).
6648 bool checkAndSetInc(Expr *S);
6649 /// Return the loop counter variable.
6650 ValueDecl *getLoopDecl() const { return LCDecl; }
6651 /// Return the reference expression to loop counter variable.
6652 Expr *getLoopDeclRefExpr() const { return LCRef; }
6653 /// Source range of the loop init.
6654 SourceRange getInitSrcRange() const { return InitSrcRange; }
6655 /// Source range of the loop condition.
6656 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6657 /// Source range of the loop increment.
6658 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6659 /// True if the step should be subtracted.
6660 bool shouldSubtractStep() const { return SubtractStep; }
6661 /// True, if the compare operator is strict (<, > or !=).
6662 bool isStrictTestOp() const { return TestIsStrictOp; }
6663 /// Build the expression to calculate the number of iterations.
6664 Expr *buildNumIterations(
6665 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6666 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6667 /// Build the precondition expression for the loops.
6668 Expr *
6669 buildPreCond(Scope *S, Expr *Cond,
6670 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6671 /// Build reference expression to the counter be used for codegen.
6672 DeclRefExpr *
6673 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6674 DSAStackTy &DSA) const;
6675 /// Build reference expression to the private counter be used for
6676 /// codegen.
6677 Expr *buildPrivateCounterVar() const;
6678 /// Build initialization of the counter be used for codegen.
6679 Expr *buildCounterInit() const;
6680 /// Build step of the counter be used for codegen.
6681 Expr *buildCounterStep() const;
6682 /// Build loop data with counter value for depend clauses in ordered
6683 /// directives.
6684 Expr *
6685 buildOrderedLoopData(Scope *S, Expr *Counter,
6686 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6687 SourceLocation Loc, Expr *Inc = nullptr,
6688 OverloadedOperatorKind OOK = OO_Amp);
6689 /// Builds the minimum value for the loop counter.
6690 std::pair<Expr *, Expr *> buildMinMaxValues(
6691 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6692 /// Builds final condition for the non-rectangular loops.
6693 Expr *buildFinalCondition(Scope *S) const;
6694 /// Return true if any expression is dependent.
6695 bool dependent() const;
6696 /// Returns true if the initializer forms non-rectangular loop.
6697 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6698 /// Returns true if the condition forms non-rectangular loop.
6699 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6700 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
6701 unsigned getLoopDependentIdx() const {
6702 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6703 }
6704
6705private:
6706 /// Check the right-hand side of an assignment in the increment
6707 /// expression.
6708 bool checkAndSetIncRHS(Expr *RHS);
6709 /// Helper to set loop counter variable and its initializer.
6710 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6711 bool EmitDiags);
6712 /// Helper to set upper bound.
6713 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6714 SourceRange SR, SourceLocation SL);
6715 /// Helper to set loop increment.
6716 bool setStep(Expr *NewStep, bool Subtract);
6717};
6718
6719bool OpenMPIterationSpaceChecker::dependent() const {
6720 if (!LCDecl) {
6721 assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void>
(0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6721, __PRETTY_FUNCTION__))
;
6722 return false;
6723 }
6724 return LCDecl->getType()->isDependentType() ||
6725 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6726 (Step && Step->isValueDependent());
6727}
6728
6729bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6730 Expr *NewLCRefExpr,
6731 Expr *NewLB, bool EmitDiags) {
6732 // State consistency checking to ensure correct usage.
6733 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6734, __PRETTY_FUNCTION__))
6734 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6734, __PRETTY_FUNCTION__))
;
6735 if (!NewLCDecl || !NewLB)
6736 return true;
6737 LCDecl = getCanonicalDecl(NewLCDecl);
6738 LCRef = NewLCRefExpr;
6739 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6740 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6741 if ((Ctor->isCopyOrMoveConstructor() ||
6742 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6743 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6744 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6745 LB = NewLB;
6746 if (EmitDiags)
6747 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6748 return false;
6749}
6750
6751bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6752 llvm::Optional<bool> LessOp,
6753 bool StrictOp, SourceRange SR,
6754 SourceLocation SL) {
6755 // State consistency checking to ensure correct usage.
6756 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6757, __PRETTY_FUNCTION__))
6757 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6757, __PRETTY_FUNCTION__))
;
6758 if (!NewUB)
6759 return true;
6760 UB = NewUB;
6761 if (LessOp)
6762 TestIsLessOp = LessOp;
6763 TestIsStrictOp = StrictOp;
6764 ConditionSrcRange = SR;
6765 ConditionLoc = SL;
6766 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6767 return false;
6768}
6769
6770bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6771 // State consistency checking to ensure correct usage.
6772 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6772, __PRETTY_FUNCTION__))
;
6773 if (!NewStep)
6774 return true;
6775 if (!NewStep->isValueDependent()) {
6776 // Check that the step is integer expression.
6777 SourceLocation StepLoc = NewStep->getBeginLoc();
6778 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6779 StepLoc, getExprAsWritten(NewStep));
6780 if (Val.isInvalid())
6781 return true;
6782 NewStep = Val.get();
6783
6784 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6785 // If test-expr is of form var relational-op b and relational-op is < or
6786 // <= then incr-expr must cause var to increase on each iteration of the
6787 // loop. If test-expr is of form var relational-op b and relational-op is
6788 // > or >= then incr-expr must cause var to decrease on each iteration of
6789 // the loop.
6790 // If test-expr is of form b relational-op var and relational-op is < or
6791 // <= then incr-expr must cause var to decrease on each iteration of the
6792 // loop. If test-expr is of form b relational-op var and relational-op is
6793 // > or >= then incr-expr must cause var to increase on each iteration of
6794 // the loop.
6795 Optional<llvm::APSInt> Result =
6796 NewStep->getIntegerConstantExpr(SemaRef.Context);
6797 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6798 bool IsConstNeg =
6799 Result && Result->isSigned() && (Subtract != Result->isNegative());
6800 bool IsConstPos =
6801 Result && Result->isSigned() && (Subtract == Result->isNegative());
6802 bool IsConstZero = Result && !Result->getBoolValue();
6803
6804 // != with increment is treated as <; != with decrement is treated as >
6805 if (!TestIsLessOp.hasValue())
6806 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6807 if (UB && (IsConstZero ||
6808 (TestIsLessOp.getValue() ?
6809 (IsConstNeg || (IsUnsigned && Subtract)) :
6810 (IsConstPos || (IsUnsigned && !Subtract))))) {
6811 SemaRef.Diag(NewStep->getExprLoc(),
6812 diag::err_omp_loop_incr_not_compatible)
6813 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6814 SemaRef.Diag(ConditionLoc,
6815 diag::note_omp_loop_cond_requres_compatible_incr)
6816 << TestIsLessOp.getValue() << ConditionSrcRange;
6817 return true;
6818 }
6819 if (TestIsLessOp.getValue() == Subtract) {
6820 NewStep =
6821 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6822 .get();
6823 Subtract = !Subtract;
6824 }
6825 }
6826
6827 Step = NewStep;
6828 SubtractStep = Subtract;
6829 return false;
6830}
6831
6832namespace {
6833/// Checker for the non-rectangular loops. Checks if the initializer or
6834/// condition expression references loop counter variable.
6835class LoopCounterRefChecker final
6836 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6837 Sema &SemaRef;
6838 DSAStackTy &Stack;
6839 const ValueDecl *CurLCDecl = nullptr;
6840 const ValueDecl *DepDecl = nullptr;
6841 const ValueDecl *PrevDepDecl = nullptr;
6842 bool IsInitializer = true;
6843 unsigned BaseLoopId = 0;
6844 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6845 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6846 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6847 << (IsInitializer ? 0 : 1);
6848 return false;
6849 }
6850 const auto &&Data = Stack.isLoopControlVariable(VD);
6851 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6852 // The type of the loop iterator on which we depend may not have a random
6853 // access iterator type.
6854 if (Data.first && VD->getType()->isRecordType()) {
6855 SmallString<128> Name;
6856 llvm::raw_svector_ostream OS(Name);
6857 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6858 /*Qualified=*/true);
6859 SemaRef.Diag(E->getExprLoc(),
6860 diag::err_omp_wrong_dependency_iterator_type)
6861 << OS.str();
6862 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6863 return false;
6864 }
6865 if (Data.first &&
6866 (DepDecl || (PrevDepDecl &&
6867 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6868 if (!DepDecl && PrevDepDecl)
6869 DepDecl = PrevDepDecl;
6870 SmallString<128> Name;
6871 llvm::raw_svector_ostream OS(Name);
6872 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6873 /*Qualified=*/true);
6874 SemaRef.Diag(E->getExprLoc(),
6875 diag::err_omp_invariant_or_linear_dependency)
6876 << OS.str();
6877 return false;
6878 }
6879 if (Data.first) {
6880 DepDecl = VD;
6881 BaseLoopId = Data.first;
6882 }
6883 return Data.first;
6884 }
6885
6886public:
6887 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6888 const ValueDecl *VD = E->getDecl();
6889 if (isa<VarDecl>(VD))
6890 return checkDecl(E, VD);
6891 return false;
6892 }
6893 bool VisitMemberExpr(const MemberExpr *E) {
6894 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6895 const ValueDecl *VD = E->getMemberDecl();
6896 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6897 return checkDecl(E, VD);
6898 }
6899 return false;
6900 }
6901 bool VisitStmt(const Stmt *S) {
6902 bool Res = false;
6903 for (const Stmt *Child : S->children())
6904 Res = (Child && Visit(Child)) || Res;
6905 return Res;
6906 }
6907 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6908 const ValueDecl *CurLCDecl, bool IsInitializer,
6909 const ValueDecl *PrevDepDecl = nullptr)
6910 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6911 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
6912 unsigned getBaseLoopId() const {
6913 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6913, __PRETTY_FUNCTION__))
;
6914 return BaseLoopId;
6915 }
6916 const ValueDecl *getDepDecl() const {
6917 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 6917, __PRETTY_FUNCTION__))
;
6918 return DepDecl;
6919 }
6920};
6921} // namespace
6922
6923Optional<unsigned>
6924OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6925 bool IsInitializer) {
6926 // Check for the non-rectangular loops.
6927 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6928 DepDecl);
6929 if (LoopStmtChecker.Visit(S)) {
6930 DepDecl = LoopStmtChecker.getDepDecl();
6931 return LoopStmtChecker.getBaseLoopId();
6932 }
6933 return llvm::None;
6934}
6935
6936bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6937 // Check init-expr for canonical loop form and save loop counter
6938 // variable - #Var and its initialization value - #LB.
6939 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6940 // var = lb
6941 // integer-type var = lb
6942 // random-access-iterator-type var = lb
6943 // pointer-type var = lb
6944 //
6945 if (!S) {
6946 if (EmitDiags) {
6947 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6948 }
6949 return true;
6950 }
6951 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6952 if (!ExprTemp->cleanupsHaveSideEffects())
6953 S = ExprTemp->getSubExpr();
6954
6955 InitSrcRange = S->getSourceRange();
6956 if (Expr *E = dyn_cast<Expr>(S))
6957 S = E->IgnoreParens();
6958 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6959 if (BO->getOpcode() == BO_Assign) {
6960 Expr *LHS = BO->getLHS()->IgnoreParens();
6961 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6962 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6963 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6964 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6965 EmitDiags);
6966 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6967 }
6968 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6969 if (ME->isArrow() &&
6970 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6971 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6972 EmitDiags);
6973 }
6974 }
6975 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6976 if (DS->isSingleDecl()) {
6977 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6978 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6979 // Accept non-canonical init form here but emit ext. warning.
6980 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6981 SemaRef.Diag(S->getBeginLoc(),
6982 diag::ext_omp_loop_not_canonical_init)
6983 << S->getSourceRange();
6984 return setLCDeclAndLB(
6985 Var,
6986 buildDeclRefExpr(SemaRef, Var,
6987 Var->getType().getNonReferenceType(),
6988 DS->getBeginLoc()),
6989 Var->getInit(), EmitDiags);
6990 }
6991 }
6992 }
6993 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6994 if (CE->getOperator() == OO_Equal) {
6995 Expr *LHS = CE->getArg(0);
6996 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6997 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6998 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6999 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7000 EmitDiags);
7001 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7002 }
7003 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7004 if (ME->isArrow() &&
7005 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7006 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7007 EmitDiags);
7008 }
7009 }
7010 }
7011
7012 if (dependent() || SemaRef.CurContext->isDependentContext())
7013 return false;
7014 if (EmitDiags) {
7015 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7016 << S->getSourceRange();
7017 }
7018 return true;
7019}
7020
7021/// Ignore parenthesizes, implicit casts, copy constructor and return the
7022/// variable (which may be the loop variable) if possible.
7023static const ValueDecl *getInitLCDecl(const Expr *E) {
7024 if (!E)
7025 return nullptr;
7026 E = getExprAsWritten(E);
7027 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7028 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7029 if ((Ctor->isCopyOrMoveConstructor() ||
7030 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7031 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7032 E = CE->getArg(0)->IgnoreParenImpCasts();
7033 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7034 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7035 return getCanonicalDecl(VD);
7036 }
7037 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7038 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7039 return getCanonicalDecl(ME->getMemberDecl());
7040 return nullptr;
7041}
7042
7043bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7044 // Check test-expr for canonical form, save upper-bound UB, flags for
7045 // less/greater and for strict/non-strict comparison.
7046 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7047 // var relational-op b
7048 // b relational-op var
7049 //
7050 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7051 if (!S) {
7052 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7053 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7054 return true;
7055 }
7056 Condition = S;
7057 S = getExprAsWritten(S);
7058 SourceLocation CondLoc = S->getBeginLoc();
7059 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7060 if (BO->isRelationalOp()) {
7061 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7062 return setUB(BO->getRHS(),
7063 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
7064 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7065 BO->getSourceRange(), BO->getOperatorLoc());
7066 if (getInitLCDecl(BO->getRHS()) == LCDecl)
7067 return setUB(BO->getLHS(),
7068 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
7069 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7070 BO->getSourceRange(), BO->getOperatorLoc());
7071 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
7072 return setUB(
7073 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
7074 /*LessOp=*/llvm::None,
7075 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
7076 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7077 if (CE->getNumArgs() == 2) {
7078 auto Op = CE->getOperator();
7079 switch (Op) {
7080 case OO_Greater:
7081 case OO_GreaterEqual:
7082 case OO_Less:
7083 case OO_LessEqual:
7084 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7085 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
7086 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7087 CE->getOperatorLoc());
7088 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
7089 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
7090 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7091 CE->getOperatorLoc());
7092 break;
7093 case OO_ExclaimEqual:
7094 if (IneqCondIsCanonical)
7095 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
7096 : CE->getArg(0),
7097 /*LessOp=*/llvm::None,
7098 /*StrictOp=*/true, CE->getSourceRange(),
7099 CE->getOperatorLoc());
7100 break;
7101 default:
7102 break;
7103 }
7104 }
7105 }
7106 if (dependent() || SemaRef.CurContext->isDependentContext())
7107 return false;
7108 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7109 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7110 return true;
7111}
7112
7113bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7114 // RHS of canonical loop form increment can be:
7115 // var + incr
7116 // incr + var
7117 // var - incr
7118 //
7119 RHS = RHS->IgnoreParenImpCasts();
7120 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7121 if (BO->isAdditiveOp()) {
7122 bool IsAdd = BO->getOpcode() == BO_Add;
7123 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7124 return setStep(BO->getRHS(), !IsAdd);
7125 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7126 return setStep(BO->getLHS(), /*Subtract=*/false);
7127 }
7128 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7129 bool IsAdd = CE->getOperator() == OO_Plus;
7130 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7131 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7132 return setStep(CE->getArg(1), !IsAdd);
7133 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7134 return setStep(CE->getArg(0), /*Subtract=*/false);
7135 }
7136 }
7137 if (dependent() || SemaRef.CurContext->isDependentContext())
7138 return false;
7139 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7140 << RHS->getSourceRange() << LCDecl;
7141 return true;
7142}
7143
7144bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7145 // Check incr-expr for canonical loop form and return true if it
7146 // does not conform.
7147 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7148 // ++var
7149 // var++
7150 // --var
7151 // var--
7152 // var += incr
7153 // var -= incr
7154 // var = var + incr
7155 // var = incr + var
7156 // var = var - incr
7157 //
7158 if (!S) {
7159 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7160 return true;
7161 }
7162 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7163 if (!ExprTemp->cleanupsHaveSideEffects())
7164 S = ExprTemp->getSubExpr();
7165
7166 IncrementSrcRange = S->getSourceRange();
7167 S = S->IgnoreParens();
7168 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7169 if (UO->isIncrementDecrementOp() &&
7170 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7171 return setStep(SemaRef
7172 .ActOnIntegerConstant(UO->getBeginLoc(),
7173 (UO->isDecrementOp() ? -1 : 1))
7174 .get(),
7175 /*Subtract=*/false);
7176 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7177 switch (BO->getOpcode()) {
7178 case BO_AddAssign:
7179 case BO_SubAssign:
7180 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7181 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7182 break;
7183 case BO_Assign:
7184 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7185 return checkAndSetIncRHS(BO->getRHS());
7186 break;
7187 default:
7188 break;
7189 }
7190 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7191 switch (CE->getOperator()) {
7192 case OO_PlusPlus:
7193 case OO_MinusMinus:
7194 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7195 return setStep(SemaRef
7196 .ActOnIntegerConstant(
7197 CE->getBeginLoc(),
7198 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7199 .get(),
7200 /*Subtract=*/false);
7201 break;
7202 case OO_PlusEqual:
7203 case OO_MinusEqual:
7204 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7205 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7206 break;
7207 case OO_Equal:
7208 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7209 return checkAndSetIncRHS(CE->getArg(1));
7210 break;
7211 default:
7212 break;
7213 }
7214 }
7215 if (dependent() || SemaRef.CurContext->isDependentContext())
7216 return false;
7217 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7218 << S->getSourceRange() << LCDecl;
7219 return true;
7220}
7221
7222static ExprResult
7223tryBuildCapture(Sema &SemaRef, Expr *Capture,
7224 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7225 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7226 return Capture;
7227 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7228 return SemaRef.PerformImplicitConversion(
7229 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7230 /*AllowExplicit=*/true);
7231 auto I = Captures.find(Capture);
7232 if (I != Captures.end())
7233 return buildCapture(SemaRef, Capture, I->second);
7234 DeclRefExpr *Ref = nullptr;
7235 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7236 Captures[Capture] = Ref;
7237 return Res;
7238}
7239
7240/// Calculate number of iterations, transforming to unsigned, if number of
7241/// iterations may be larger than the original type.
7242static Expr *
7243calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7244 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7245 bool TestIsStrictOp, bool RoundToStep,
7246 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7247 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7248 if (!NewStep.isUsable())
7249 return nullptr;
7250 llvm::APSInt LRes, SRes;
7251 bool IsLowerConst = false, IsStepConst = false;
7252 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7253 LRes = *Res;
7254 IsLowerConst = true;
7255 }
7256 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7257 SRes = *Res;
7258 IsStepConst = true;
7259 }
7260 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7261 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7262 (TestIsStrictOp && LRes.isStrictlyPositive()));
7263 bool NeedToReorganize = false;
7264 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7265 if (!NoNeedToConvert && IsLowerConst &&
7266 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7267 NoNeedToConvert = true;
7268 if (RoundToStep) {
7269 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7270 ? LRes.getBitWidth()
7271 : SRes.getBitWidth();
7272 LRes = LRes.extend(BW + 1);
7273 LRes.setIsSigned(true);
7274 SRes = SRes.extend(BW + 1);
7275 SRes.setIsSigned(true);
7276 LRes -= SRes;
7277 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7278 LRes = LRes.trunc(BW);
7279 }
7280 if (TestIsStrictOp) {
7281 unsigned BW = LRes.getBitWidth();
7282 LRes = LRes.extend(BW + 1);
7283 LRes.setIsSigned(true);
7284 ++LRes;
7285 NoNeedToConvert =
7286 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7287 // truncate to the original bitwidth.
7288 LRes = LRes.trunc(BW);
7289 }
7290 NeedToReorganize = NoNeedToConvert;
7291 }
7292 llvm::APSInt URes;
7293 bool IsUpperConst = false;
7294 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7295 URes = *Res;
7296 IsUpperConst = true;
7297 }
7298 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7299 (!RoundToStep || IsStepConst)) {
7300 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7301 : URes.getBitWidth();
7302 LRes = LRes.extend(BW + 1);
7303 LRes.setIsSigned(true);
7304 URes = URes.extend(BW + 1);
7305 URes.setIsSigned(true);
7306 URes -= LRes;
7307 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7308 NeedToReorganize = NoNeedToConvert;
7309 }
7310 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7311 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7312 // unsigned.
7313 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7314 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7315 QualType LowerTy = Lower->getType();
7316 QualType UpperTy = Upper->getType();
7317 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7318 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7319 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7320 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7321 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7322 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7323 Upper =
7324 SemaRef
7325 .PerformImplicitConversion(
7326 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7327 CastType, Sema::AA_Converting)
7328 .get();
7329 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7330 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7331 }
7332 }
7333 if (!Lower || !Upper || NewStep.isInvalid())
7334 return nullptr;
7335
7336 ExprResult Diff;
7337 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7338 // 1]).
7339 if (NeedToReorganize) {
7340 Diff = Lower;
7341
7342 if (RoundToStep) {
7343 // Lower - Step
7344 Diff =
7345 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7346 if (!Diff.isUsable())
7347 return nullptr;
7348 }
7349
7350 // Lower - Step [+ 1]
7351 if (TestIsStrictOp)
7352 Diff = SemaRef.BuildBinOp(
7353 S, DefaultLoc, BO_Add, Diff.get(),
7354 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7355 if (!Diff.isUsable())
7356 return nullptr;
7357
7358 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7359 if (!Diff.isUsable())
7360 return nullptr;
7361
7362 // Upper - (Lower - Step [+ 1]).
7363 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7364 if (!Diff.isUsable())
7365 return nullptr;
7366 } else {
7367 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7368
7369 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7370 // BuildBinOp already emitted error, this one is to point user to upper
7371 // and lower bound, and to tell what is passed to 'operator-'.
7372 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7373 << Upper->getSourceRange() << Lower->getSourceRange();
7374 return nullptr;
7375 }
7376
7377 if (!Diff.isUsable())
7378 return nullptr;
7379
7380 // Upper - Lower [- 1]
7381 if (TestIsStrictOp)
7382 Diff = SemaRef.BuildBinOp(
7383 S, DefaultLoc, BO_Sub, Diff.get(),
7384 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7385 if (!Diff.isUsable())
7386 return nullptr;
7387
7388 if (RoundToStep) {
7389 // Upper - Lower [- 1] + Step
7390 Diff =
7391 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7392 if (!Diff.isUsable())
7393 return nullptr;
7394 }
7395 }
7396
7397 // Parentheses (for dumping/debugging purposes only).
7398 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7399 if (!Diff.isUsable())
7400 return nullptr;
7401
7402 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7403 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7404 if (!Diff.isUsable())
7405 return nullptr;
7406
7407 return Diff.get();
7408}
7409
7410/// Build the expression to calculate the number of iterations.
7411Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7412 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7413 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7414 QualType VarType = LCDecl->getType().getNonReferenceType();
7415 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7416 !SemaRef.getLangOpts().CPlusPlus)
7417 return nullptr;
7418 Expr *LBVal = LB;
7419 Expr *UBVal = UB;
7420 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7421 // max(LB(MinVal), LB(MaxVal))
7422 if (InitDependOnLC) {
7423 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
7424 if (!IS.MinValue || !IS.MaxValue)
7425 return nullptr;
7426 // OuterVar = Min
7427 ExprResult MinValue =
7428 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7429 if (!MinValue.isUsable())
7430 return nullptr;
7431
7432 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7433 IS.CounterVar, MinValue.get());
7434 if (!LBMinVal.isUsable())
7435 return nullptr;
7436 // OuterVar = Min, LBVal
7437 LBMinVal =
7438 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7439 if (!LBMinVal.isUsable())
7440 return nullptr;
7441 // (OuterVar = Min, LBVal)
7442 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7443 if (!LBMinVal.isUsable())
7444 return nullptr;
7445
7446 // OuterVar = Max
7447 ExprResult MaxValue =
7448 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7449 if (!MaxValue.isUsable())
7450 return nullptr;
7451
7452 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7453 IS.CounterVar, MaxValue.get());
7454 if (!LBMaxVal.isUsable())
7455 return nullptr;
7456 // OuterVar = Max, LBVal
7457 LBMaxVal =
7458 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7459 if (!LBMaxVal.isUsable())
7460 return nullptr;
7461 // (OuterVar = Max, LBVal)
7462 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7463 if (!LBMaxVal.isUsable())
7464 return nullptr;
7465
7466 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7467 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7468 if (!LBMin || !LBMax)
7469 return nullptr;
7470 // LB(MinVal) < LB(MaxVal)
7471 ExprResult MinLessMaxRes =
7472 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7473 if (!MinLessMaxRes.isUsable())
7474 return nullptr;
7475 Expr *MinLessMax =
7476 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7477 if (!MinLessMax)
7478 return nullptr;
7479 if (TestIsLessOp.getValue()) {
7480 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7481 // LB(MaxVal))
7482 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7483 MinLessMax, LBMin, LBMax);
7484 if (!MinLB.isUsable())
7485 return nullptr;
7486 LBVal = MinLB.get();
7487 } else {
7488 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7489 // LB(MaxVal))
7490 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7491 MinLessMax, LBMax, LBMin);
7492 if (!MaxLB.isUsable())
7493 return nullptr;
7494 LBVal = MaxLB.get();
7495 }
7496 }
7497 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7498 // min(UB(MinVal), UB(MaxVal))
7499 if (CondDependOnLC) {
7500 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
7501 if (!IS.MinValue || !IS.MaxValue)
7502 return nullptr;
7503 // OuterVar = Min
7504 ExprResult MinValue =
7505 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7506 if (!MinValue.isUsable())
7507 return nullptr;
7508
7509 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7510 IS.CounterVar, MinValue.get());
7511 if (!UBMinVal.isUsable())
7512 return nullptr;
7513 // OuterVar = Min, UBVal
7514 UBMinVal =
7515 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7516 if (!UBMinVal.isUsable())
7517 return nullptr;
7518 // (OuterVar = Min, UBVal)
7519 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7520 if (!UBMinVal.isUsable())
7521 return nullptr;
7522
7523 // OuterVar = Max
7524 ExprResult MaxValue =
7525 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7526 if (!MaxValue.isUsable())
7527 return nullptr;
7528
7529 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7530 IS.CounterVar, MaxValue.get());
7531 if (!UBMaxVal.isUsable())
7532 return nullptr;
7533 // OuterVar = Max, UBVal
7534 UBMaxVal =
7535 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7536 if (!UBMaxVal.isUsable())
7537 return nullptr;
7538 // (OuterVar = Max, UBVal)
7539 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7540 if (!UBMaxVal.isUsable())
7541 return nullptr;
7542
7543 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7544 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7545 if (!UBMin || !UBMax)
7546 return nullptr;
7547 // UB(MinVal) > UB(MaxVal)
7548 ExprResult MinGreaterMaxRes =
7549 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7550 if (!MinGreaterMaxRes.isUsable())
7551 return nullptr;
7552 Expr *MinGreaterMax =
7553 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7554 if (!MinGreaterMax)
7555 return nullptr;
7556 if (TestIsLessOp.getValue()) {
7557 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7558 // UB(MaxVal))
7559 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7560 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7561 if (!MaxUB.isUsable())
7562 return nullptr;
7563 UBVal = MaxUB.get();
7564 } else {
7565 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7566 // UB(MaxVal))
7567 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7568 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7569 if (!MinUB.isUsable())
7570 return nullptr;
7571 UBVal = MinUB.get();
7572 }
7573 }
7574 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7575 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7576 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7577 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7578 if (!Upper || !Lower)
7579 return nullptr;
7580
7581 ExprResult Diff =
7582 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7583 TestIsStrictOp, /*RoundToStep=*/true, Captures);
7584 if (!Diff.isUsable())
7585 return nullptr;
7586
7587 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7588 QualType Type = Diff.get()->getType();
7589 ASTContext &C = SemaRef.Context;
7590 bool UseVarType = VarType->hasIntegerRepresentation() &&
7591 C.getTypeSize(Type) > C.getTypeSize(VarType);
7592 if (!Type->isIntegerType() || UseVarType) {
7593 unsigned NewSize =
7594 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7595 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7596 : Type->hasSignedIntegerRepresentation();
7597 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7598 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7599 Diff = SemaRef.PerformImplicitConversion(
7600 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7601 if (!Diff.isUsable())
7602 return nullptr;
7603 }
7604 }
7605 if (LimitedType) {
7606 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7607 if (NewSize != C.getTypeSize(Type)) {
7608 if (NewSize < C.getTypeSize(Type)) {
7609 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 7609, __PRETTY_FUNCTION__))
;
7610 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7611 << InitSrcRange << ConditionSrcRange;
7612 }
7613 QualType NewType = C.getIntTypeForBitwidth(
7614 NewSize, Type->hasSignedIntegerRepresentation() ||
7615 C.getTypeSize(Type) < NewSize);
7616 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7617 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7618 Sema::AA_Converting, true);
7619 if (!Diff.isUsable())
7620 return nullptr;
7621 }
7622 }
7623 }
7624
7625 return Diff.get();
7626}
7627
7628std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7629 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7630 // Do not build for iterators, they cannot be used in non-rectangular loop
7631 // nests.
7632 if (LCDecl->getType()->isRecordType())
7633 return std::make_pair(nullptr, nullptr);
7634 // If we subtract, the min is in the condition, otherwise the min is in the
7635 // init value.
7636 Expr *MinExpr = nullptr;
7637 Expr *MaxExpr = nullptr;
7638 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7639 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7640 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7641 : CondDependOnLC.hasValue();
7642 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7643 : InitDependOnLC.hasValue();
7644 Expr *Lower =
7645 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7646 Expr *Upper =
7647 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7648 if (!Upper || !Lower)
7649 return std::make_pair(nullptr, nullptr);
7650
7651 if (TestIsLessOp.getValue())
7652 MinExpr = Lower;
7653 else
7654 MaxExpr = Upper;
7655
7656 // Build minimum/maximum value based on number of iterations.
7657 QualType VarType = LCDecl->getType().getNonReferenceType();
7658
7659 ExprResult Diff =
7660 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7661 TestIsStrictOp, /*RoundToStep=*/false, Captures);
7662 if (!Diff.isUsable())
7663 return std::make_pair(nullptr, nullptr);
7664
7665 // ((Upper - Lower [- 1]) / Step) * Step
7666 // Parentheses (for dumping/debugging purposes only).
7667 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7668 if (!Diff.isUsable())
7669 return std::make_pair(nullptr, nullptr);
7670
7671 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7672 if (!NewStep.isUsable())
7673 return std::make_pair(nullptr, nullptr);
7674 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7675 if (!Diff.isUsable())
7676 return std::make_pair(nullptr, nullptr);
7677
7678 // Parentheses (for dumping/debugging purposes only).
7679 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7680 if (!Diff.isUsable())
7681 return std::make_pair(nullptr, nullptr);
7682
7683 // Convert to the ptrdiff_t, if original type is pointer.
7684 if (VarType->isAnyPointerType() &&
7685 !SemaRef.Context.hasSameType(
7686 Diff.get()->getType(),
7687 SemaRef.Context.getUnsignedPointerDiffType())) {
7688 Diff = SemaRef.PerformImplicitConversion(
7689 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7690 Sema::AA_Converting, /*AllowExplicit=*/true);
7691 }
7692 if (!Diff.isUsable())
7693 return std::make_pair(nullptr, nullptr);
7694
7695 if (TestIsLessOp.getValue()) {
7696 // MinExpr = Lower;
7697 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7698 Diff = SemaRef.BuildBinOp(
7699 S, DefaultLoc, BO_Add,
7700 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7701 Diff.get());
7702 if (!Diff.isUsable())
7703 return std::make_pair(nullptr, nullptr);
7704 } else {
7705 // MaxExpr = Upper;
7706 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7707 Diff = SemaRef.BuildBinOp(
7708 S, DefaultLoc, BO_Sub,
7709 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7710 Diff.get());
7711 if (!Diff.isUsable())
7712 return std::make_pair(nullptr, nullptr);
7713 }
7714
7715 // Convert to the original type.
7716 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7717 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7718 Sema::AA_Converting,
7719 /*AllowExplicit=*/true);
7720 if (!Diff.isUsable())
7721 return std::make_pair(nullptr, nullptr);
7722
7723 Sema::TentativeAnalysisScope Trap(SemaRef);
7724 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7725 if (!Diff.isUsable())
7726 return std::make_pair(nullptr, nullptr);
7727
7728 if (TestIsLessOp.getValue())
7729 MaxExpr = Diff.get();
7730 else
7731 MinExpr = Diff.get();
7732
7733 return std::make_pair(MinExpr, MaxExpr);
7734}
7735
7736Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7737 if (InitDependOnLC || CondDependOnLC)
7738 return Condition;
7739 return nullptr;
7740}
7741
7742Expr *OpenMPIterationSpaceChecker::buildPreCond(
7743 Scope *S, Expr *Cond,
7744 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7745 // Do not build a precondition when the condition/initialization is dependent
7746 // to prevent pessimistic early loop exit.
7747 // TODO: this can be improved by calculating min/max values but not sure that
7748 // it will be very effective.
7749 if (CondDependOnLC || InitDependOnLC)
7750 return SemaRef.PerformImplicitConversion(
7751 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7752 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7753 /*AllowExplicit=*/true).get();
7754
7755 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7756 Sema::TentativeAnalysisScope Trap(SemaRef);
7757
7758 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7759 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7760 if (!NewLB.isUsable() || !NewUB.isUsable())
7761 return nullptr;
7762
7763 ExprResult CondExpr =
7764 SemaRef.BuildBinOp(S, DefaultLoc,
7765 TestIsLessOp.getValue() ?
7766 (TestIsStrictOp ? BO_LT : BO_LE) :
7767 (TestIsStrictOp ? BO_GT : BO_GE),
7768 NewLB.get(), NewUB.get());
7769 if (CondExpr.isUsable()) {
7770 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7771 SemaRef.Context.BoolTy))
7772 CondExpr = SemaRef.PerformImplicitConversion(
7773 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7774 /*AllowExplicit=*/true);
7775 }
7776
7777 // Otherwise use original loop condition and evaluate it in runtime.
7778 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7779}
7780
7781/// Build reference expression to the counter be used for codegen.
7782DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7783 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7784 DSAStackTy &DSA) const {
7785 auto *VD = dyn_cast<VarDecl>(LCDecl);
7786 if (!VD) {
7787 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7788 DeclRefExpr *Ref = buildDeclRefExpr(
7789 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7790 const DSAStackTy::DSAVarData Data =
7791 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7792 // If the loop control decl is explicitly marked as private, do not mark it
7793 // as captured again.
7794 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7795 Captures.insert(std::make_pair(LCRef, Ref));
7796 return Ref;
7797 }
7798 return cast<DeclRefExpr>(LCRef);
7799}
7800
7801Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7802 if (LCDecl && !LCDecl->isInvalidDecl()) {
7803 QualType Type = LCDecl->getType().getNonReferenceType();
7804 VarDecl *PrivateVar = buildVarDecl(
7805 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7806 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7807 isa<VarDecl>(LCDecl)
7808 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7809 : nullptr);
7810 if (PrivateVar->isInvalidDecl())
7811 return nullptr;
7812 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7813 }
7814 return nullptr;
7815}
7816
7817/// Build initialization of the counter to be used for codegen.
7818Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7819
7820/// Build step of the counter be used for codegen.
7821Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7822
7823Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7824 Scope *S, Expr *Counter,
7825 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7826 Expr *Inc, OverloadedOperatorKind OOK) {
7827 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7828 if (!Cnt)
7829 return nullptr;
7830 if (Inc) {
7831 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 7832, __PRETTY_FUNCTION__))
7832 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 7832, __PRETTY_FUNCTION__))
;
7833 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7834 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7835 if (!Cnt)
7836 return nullptr;
7837 }
7838 QualType VarType = LCDecl->getType().getNonReferenceType();
7839 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7840 !SemaRef.getLangOpts().CPlusPlus)
7841 return nullptr;
7842 // Upper - Lower
7843 Expr *Upper = TestIsLessOp.getValue()
7844 ? Cnt
7845 : tryBuildCapture(SemaRef, LB, Captures).get();
7846 Expr *Lower = TestIsLessOp.getValue()
7847 ? tryBuildCapture(SemaRef, LB, Captures).get()
7848 : Cnt;
7849 if (!Upper || !Lower)
7850 return nullptr;
7851
7852 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7853 Step, VarType, /*TestIsStrictOp=*/false,
7854 /*RoundToStep=*/false, Captures);
7855 if (!Diff.isUsable())
7856 return nullptr;
7857
7858 return Diff.get();
7859}
7860} // namespace
7861
7862void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7863 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 7863, __PRETTY_FUNCTION__))
;
7864 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 7864, __PRETTY_FUNCTION__))
;
7865 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
7866 if (AssociatedLoops > 0 &&
7867 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
7868 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
7869 OpenMPIterationSpaceChecker ISC(*this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
7870 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7871 if (ValueDecl *D = ISC.getLoopDecl()) {
7872 auto *VD = dyn_cast<VarDecl>(D);
7873 DeclRefExpr *PrivateRef = nullptr;
7874 if (!VD) {
7875 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7876 VD = Private;
7877 } else {
7878 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7879 /*WithInit=*/false);
7880 VD = cast<VarDecl>(PrivateRef->getDecl());
7881 }
7882 }
7883 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
7884 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
7885 if (LD != D->getCanonicalDecl()) {
7886 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
7887 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7888 MarkDeclarationsReferencedInExpr(
7889 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7890 Var->getType().getNonLValueExprType(Context),
7891 ForLoc, /*RefersToCapture=*/true));
7892 }
7893 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
7894 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7895 // Referenced in a Construct, C/C++]. The loop iteration variable in the
7896 // associated for-loop of a simd construct with just one associated
7897 // for-loop may be listed in a linear clause with a constant-linear-step
7898 // that is the increment of the associated for-loop. The loop iteration
7899 // variable(s) in the associated for-loop(s) of a for or parallel for
7900 // construct may be listed in a private or lastprivate clause.
7901 DSAStackTy::DSAVarData DVar =
7902 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
7903 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7904 // is declared in the loop and it is predetermined as a private.
7905 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7906 OpenMPClauseKind PredeterminedCKind =
7907 isOpenMPSimdDirective(DKind)
7908 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7909 : OMPC_private;
7910 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7911 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7912 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7913 DVar.CKind != OMPC_private))) ||
7914 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7915 DKind == OMPD_master_taskloop ||
7916 DKind == OMPD_parallel_master_taskloop ||
7917 isOpenMPDistributeDirective(DKind)) &&
7918 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7919 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7920 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7921 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7922 << getOpenMPClauseName(DVar.CKind)
7923 << getOpenMPDirectiveName(DKind)
7924 << getOpenMPClauseName(PredeterminedCKind);
7925 if (DVar.RefExpr == nullptr)
7926 DVar.CKind = PredeterminedCKind;
7927 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
7928 /*IsLoopIterVar=*/true);
7929 } else if (LoopDeclRefExpr) {
7930 // Make the loop iteration variable private (for worksharing
7931 // constructs), linear (for simd directives with the only one
7932 // associated loop) or lastprivate (for simd directives with several
7933 // collapsed or ordered loops).
7934 if (DVar.CKind == OMPC_unknown)
7935 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7936 PrivateRef);
7937 }
7938 }
7939 }
7940 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
7941 }
7942}
7943
7944/// Called on a for stmt to check and extract its iteration space
7945/// for further processing (such as collapsing).
7946static bool checkOpenMPIterationSpace(
7947 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7948 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7949 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7950 Expr *OrderedLoopCountExpr,
7951 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7952 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7953 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7954 // OpenMP [2.9.1, Canonical Loop Form]
7955 // for (init-expr; test-expr; incr-expr) structured-block
7956 // for (range-decl: range-expr) structured-block
7957 auto *For = dyn_cast_or_null<ForStmt>(S);
9
Assuming null pointer is passed into cast
10
Assuming pointer value is null
7958 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
11
Assuming null pointer is passed into cast
7959 // Ranged for is supported only in OpenMP 5.0.
7960 if (!For
11.1
'For' is null
&& (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
12
Assuming field 'OpenMP' is <= 45
7961 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
13
Called C++ object pointer is null
7962 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7963 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7964 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7965 if (TotalNestedLoopCount > 1) {
7966 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7967 SemaRef.Diag(DSA.getConstructLoc(),
7968 diag::note_omp_collapse_ordered_expr)
7969 << 2 << CollapseLoopCountExpr->getSourceRange()
7970 << OrderedLoopCountExpr->getSourceRange();
7971 else if (CollapseLoopCountExpr)
7972 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7973 diag::note_omp_collapse_ordered_expr)
7974 << 0 << CollapseLoopCountExpr->getSourceRange();
7975 else
7976 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7977 diag::note_omp_collapse_ordered_expr)
7978 << 1 << OrderedLoopCountExpr->getSourceRange();
7979 }
7980 return true;
7981 }
7982 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 7983, __PRETTY_FUNCTION__))
7983 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 7983, __PRETTY_FUNCTION__))
;
7984
7985 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7986 For ? For->getForLoc() : CXXFor->getForLoc());
7987
7988 // Check init.
7989 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7990 if (ISC.checkAndSetInit(Init))
7991 return true;
7992
7993 bool HasErrors = false;
7994
7995 // Check loop variable's type.
7996 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
7997 // OpenMP [2.6, Canonical Loop Form]
7998 // Var is one of the following:
7999 // A variable of signed or unsigned integer type.
8000 // For C++, a variable of a random access iterator type.
8001 // For C, a variable of a pointer type.
8002 QualType VarType = LCDecl->getType().getNonReferenceType();
8003 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8004 !VarType->isPointerType() &&
8005 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8006 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8007 << SemaRef.getLangOpts().CPlusPlus;
8008 HasErrors = true;
8009 }
8010
8011 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8012 // a Construct
8013 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8014 // parallel for construct is (are) private.
8015 // The loop iteration variable in the associated for-loop of a simd
8016 // construct with just one associated for-loop is linear with a
8017 // constant-linear-step that is the increment of the associated for-loop.
8018 // Exclude loop var from the list of variables with implicitly defined data
8019 // sharing attributes.
8020 VarsWithImplicitDSA.erase(LCDecl);
8021
8022 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8022, __PRETTY_FUNCTION__))
;
8023
8024 // Check test-expr.
8025 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8026
8027 // Check incr-expr.
8028 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8029 }
8030
8031 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8032 return HasErrors;
8033
8034 // Build the loop's iteration space representation.
8035 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8036 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8037 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8038 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8039 (isOpenMPWorksharingDirective(DKind) ||
8040 isOpenMPTaskLoopDirective(DKind) ||
8041 isOpenMPDistributeDirective(DKind)),
8042 Captures);
8043 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8044 ISC.buildCounterVar(Captures, DSA);
8045 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8046 ISC.buildPrivateCounterVar();
8047 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8048 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8049 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8050 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8051 ISC.getConditionSrcRange();
8052 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8053 ISC.getIncrementSrcRange();
8054 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8055 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8056 ISC.isStrictTestOp();
8057 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8058 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8059 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8060 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8061 ISC.buildFinalCondition(DSA.getCurScope());
8062 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8063 ISC.doesInitDependOnLC();
8064 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8065 ISC.doesCondDependOnLC();
8066 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8067 ISC.getLoopDependentIdx();
8068
8069 HasErrors |=
8070 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8071 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8072 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8073 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8074 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8075 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8076 if (!HasErrors && DSA.isOrderedRegion()) {
8077 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8078 if (CurrentNestedLoopCount <
8079 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8080 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8081 CurrentNestedLoopCount,
8082 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8083 DSA.getOrderedRegionParam().second->setLoopCounter(
8084 CurrentNestedLoopCount,
8085 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8086 }
8087 }
8088 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8089 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8090 // Erroneous case - clause has some problems.
8091 continue;
8092 }
8093 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8094 Pair.second.size() <= CurrentNestedLoopCount) {
8095 // Erroneous case - clause has some problems.
8096 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8097 continue;
8098 }
8099 Expr *CntValue;
8100 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8101 CntValue = ISC.buildOrderedLoopData(
8102 DSA.getCurScope(),
8103 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8104 Pair.first->getDependencyLoc());
8105 else
8106 CntValue = ISC.buildOrderedLoopData(
8107 DSA.getCurScope(),
8108 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8109 Pair.first->getDependencyLoc(),
8110 Pair.second[CurrentNestedLoopCount].first,
8111 Pair.second[CurrentNestedLoopCount].second);
8112 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8113 }
8114 }
8115
8116 return HasErrors;
8117}
8118
8119/// Build 'VarRef = Start.
8120static ExprResult
8121buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8122 ExprResult Start, bool IsNonRectangularLB,
8123 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8124 // Build 'VarRef = Start.
8125 ExprResult NewStart = IsNonRectangularLB
8126 ? Start.get()
8127 : tryBuildCapture(SemaRef, Start.get(), Captures);
8128 if (!NewStart.isUsable())
8129 return ExprError();
8130 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8131 VarRef.get()->getType())) {
8132 NewStart = SemaRef.PerformImplicitConversion(
8133 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8134 /*AllowExplicit=*/true);
8135 if (!NewStart.isUsable())
8136 return ExprError();
8137 }
8138
8139 ExprResult Init =
8140 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8141 return Init;
8142}
8143
8144/// Build 'VarRef = Start + Iter * Step'.
8145static ExprResult buildCounterUpdate(
8146 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8147 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8148 bool IsNonRectangularLB,
8149 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8150 // Add parentheses (for debugging purposes only).
8151 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8152 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8153 !Step.isUsable())
8154 return ExprError();
8155
8156 ExprResult NewStep = Step;
8157 if (Captures)
8158 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8159 if (NewStep.isInvalid())
8160 return ExprError();
8161 ExprResult Update =
8162 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8163 if (!Update.isUsable())
8164 return ExprError();
8165
8166 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8167 // 'VarRef = Start (+|-) Iter * Step'.
8168 if (!Start.isUsable())
8169 return ExprError();
8170 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8171 if (!NewStart.isUsable())
8172 return ExprError();
8173 if (Captures && !IsNonRectangularLB)
8174 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8175 if (NewStart.isInvalid())
8176 return ExprError();
8177
8178 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8179 ExprResult SavedUpdate = Update;
8180 ExprResult UpdateVal;
8181 if (VarRef.get()->getType()->isOverloadableType() ||
8182 NewStart.get()->getType()->isOverloadableType() ||
8183 Update.get()->getType()->isOverloadableType()) {
8184 Sema::TentativeAnalysisScope Trap(SemaRef);
8185
8186 Update =
8187 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8188 if (Update.isUsable()) {
8189 UpdateVal =
8190 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8191 VarRef.get(), SavedUpdate.get());
8192 if (UpdateVal.isUsable()) {
8193 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8194 UpdateVal.get());
8195 }
8196 }
8197 }
8198
8199 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8200 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8201 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8202 NewStart.get(), SavedUpdate.get());
8203 if (!Update.isUsable())
8204 return ExprError();
8205
8206 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8207 VarRef.get()->getType())) {
8208 Update = SemaRef.PerformImplicitConversion(
8209 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8210 if (!Update.isUsable())
8211 return ExprError();
8212 }
8213
8214 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8215 }
8216 return Update;
8217}
8218
8219/// Convert integer expression \a E to make it have at least \a Bits
8220/// bits.
8221static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8222 if (E == nullptr)
8223 return ExprError();
8224 ASTContext &C = SemaRef.Context;
8225 QualType OldType = E->getType();
8226 unsigned HasBits = C.getTypeSize(OldType);
8227 if (HasBits >= Bits)
8228 return ExprResult(E);
8229 // OK to convert to signed, because new type has more bits than old.
8230 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8231 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8232 true);
8233}
8234
8235/// Check if the given expression \a E is a constant integer that fits
8236/// into \a Bits bits.
8237static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8238 if (E == nullptr)
8239 return false;
8240 if (Optional<llvm::APSInt> Result =
8241 E->getIntegerConstantExpr(SemaRef.Context))
8242 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8243 return false;
8244}
8245
8246/// Build preinits statement for the given declarations.
8247static Stmt *buildPreInits(ASTContext &Context,
8248 MutableArrayRef<Decl *> PreInits) {
8249 if (!PreInits.empty()) {
8250 return new (Context) DeclStmt(
8251 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8252 SourceLocation(), SourceLocation());
8253 }
8254 return nullptr;
8255}
8256
8257/// Build preinits statement for the given declarations.
8258static Stmt *
8259buildPreInits(ASTContext &Context,
8260 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8261 if (!Captures.empty()) {
8262 SmallVector<Decl *, 16> PreInits;
8263 for (const auto &Pair : Captures)
8264 PreInits.push_back(Pair.second->getDecl());
8265 return buildPreInits(Context, PreInits);
8266 }
8267 return nullptr;
8268}
8269
8270/// Build postupdate expression for the given list of postupdates expressions.
8271static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8272 Expr *PostUpdate = nullptr;
8273 if (!PostUpdates.empty()) {
8274 for (Expr *E : PostUpdates) {
8275 Expr *ConvE = S.BuildCStyleCastExpr(
8276 E->getExprLoc(),
8277 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8278 E->getExprLoc(), E)
8279 .get();
8280 PostUpdate = PostUpdate
8281 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8282 PostUpdate, ConvE)
8283 .get()
8284 : ConvE;
8285 }
8286 }
8287 return PostUpdate;
8288}
8289
8290/// Called on a for stmt to check itself and nested loops (if any).
8291/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8292/// number of collapsed loops otherwise.
8293static unsigned
8294checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8295 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8296 DSAStackTy &DSA,
8297 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8298 OMPLoopDirective::HelperExprs &Built) {
8299 unsigned NestedLoopCount = 1;
8300 if (CollapseLoopCountExpr) {
1
Assuming 'CollapseLoopCountExpr' is null
2
Taking false branch
8301 // Found 'collapse' clause - calculate collapse number.
8302 Expr::EvalResult Result;
8303 if (!CollapseLoopCountExpr->isValueDependent() &&
8304 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8305 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8306 } else {
8307 Built.clear(/*Size=*/1);
8308 return 1;
8309 }
8310 }
8311 unsigned OrderedLoopCount = 1;
8312 if (OrderedLoopCountExpr) {
3
Assuming 'OrderedLoopCountExpr' is null
4
Taking false branch
8313 // Found 'ordered' clause - calculate collapse number.
8314 Expr::EvalResult EVResult;
8315 if (!OrderedLoopCountExpr->isValueDependent() &&
8316 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8317 SemaRef.getASTContext())) {
8318 llvm::APSInt Result = EVResult.Val.getInt();
8319 if (Result.getLimitedValue() < NestedLoopCount) {
8320 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8321 diag::err_omp_wrong_ordered_loop_count)
8322 << OrderedLoopCountExpr->getSourceRange();
8323 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8324 diag::note_collapse_loop_count)
8325 << CollapseLoopCountExpr->getSourceRange();
8326 }
8327 OrderedLoopCount = Result.getLimitedValue();
8328 } else {
8329 Built.clear(/*Size=*/1);
8330 return 1;
8331 }
8332 }
8333 // This is helper routine for loop directives (e.g., 'for', 'simd',
8334 // 'for simd', etc.).
8335 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8336 SmallVector<LoopIterationSpace, 4> IterSpaces(
8337 std::max(OrderedLoopCount, NestedLoopCount));
8338 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
5
'CurStmt' initialized here
8339 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
6
Loop condition is true. Entering loop body
8340 if (checkOpenMPIterationSpace(
8
Calling 'checkOpenMPIterationSpace'
8341 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
7
Passing value via 2nd parameter 'S'
8342 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8343 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8344 return 0;
8345 // Move on to the next nested for loop, or to the loop body.
8346 // OpenMP [2.8.1, simd construct, Restrictions]
8347 // All loops associated with the construct must be perfectly nested; that
8348 // is, there must be no intervening code nor any OpenMP directive between
8349 // any two loops.
8350 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8351 CurStmt = For->getBody();
8352 } else {
8353 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8354, __PRETTY_FUNCTION__))
8354 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8354, __PRETTY_FUNCTION__))
;
8355 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8356 }
8357 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8358 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8359 }
8360 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8361 if (checkOpenMPIterationSpace(
8362 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8363 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8364 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8365 return 0;
8366 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8367 // Handle initialization of captured loop iterator variables.
8368 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8369 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8370 Captures[DRE] = DRE;
8371 }
8372 }
8373 // Move on to the next nested for loop, or to the loop body.
8374 // OpenMP [2.8.1, simd construct, Restrictions]
8375 // All loops associated with the construct must be perfectly nested; that
8376 // is, there must be no intervening code nor any OpenMP directive between
8377 // any two loops.
8378 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8379 CurStmt = For->getBody();
8380 } else {
8381 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8382, __PRETTY_FUNCTION__))
8382 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8382, __PRETTY_FUNCTION__))
;
8383 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8384 }
8385 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8386 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8387 }
8388
8389 Built.clear(/* size */ NestedLoopCount);
8390
8391 if (SemaRef.CurContext->isDependentContext())
8392 return NestedLoopCount;
8393
8394 // An example of what is generated for the following code:
8395 //
8396 // #pragma omp simd collapse(2) ordered(2)
8397 // for (i = 0; i < NI; ++i)
8398 // for (k = 0; k < NK; ++k)
8399 // for (j = J0; j < NJ; j+=2) {
8400 // <loop body>
8401 // }
8402 //
8403 // We generate the code below.
8404 // Note: the loop body may be outlined in CodeGen.
8405 // Note: some counters may be C++ classes, operator- is used to find number of
8406 // iterations and operator+= to calculate counter value.
8407 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8408 // or i64 is currently supported).
8409 //
8410 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8411 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8412 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8413 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8414 // // similar updates for vars in clauses (e.g. 'linear')
8415 // <loop body (using local i and j)>
8416 // }
8417 // i = NI; // assign final values of counters
8418 // j = NJ;
8419 //
8420
8421 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8422 // the iteration counts of the collapsed for loops.
8423 // Precondition tests if there is at least one iteration (all conditions are
8424 // true).
8425 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8426 Expr *N0 = IterSpaces[0].NumIterations;
8427 ExprResult LastIteration32 =
8428 widenIterationCount(/*Bits=*/32,
8429 SemaRef
8430 .PerformImplicitConversion(
8431 N0->IgnoreImpCasts(), N0->getType(),
8432 Sema::AA_Converting, /*AllowExplicit=*/true)
8433 .get(),
8434 SemaRef);
8435 ExprResult LastIteration64 = widenIterationCount(
8436 /*Bits=*/64,
8437 SemaRef
8438 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8439 Sema::AA_Converting,
8440 /*AllowExplicit=*/true)
8441 .get(),
8442 SemaRef);
8443
8444 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8445 return NestedLoopCount;
8446
8447 ASTContext &C = SemaRef.Context;
8448 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8449
8450 Scope *CurScope = DSA.getCurScope();
8451 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8452 if (PreCond.isUsable()) {
8453 PreCond =
8454 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8455 PreCond.get(), IterSpaces[Cnt].PreCond);
8456 }
8457 Expr *N = IterSpaces[Cnt].NumIterations;
8458 SourceLocation Loc = N->getExprLoc();
8459 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8460 if (LastIteration32.isUsable())
8461 LastIteration32 = SemaRef.BuildBinOp(
8462 CurScope, Loc, BO_Mul, LastIteration32.get(),
8463 SemaRef
8464 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8465 Sema::AA_Converting,
8466 /*AllowExplicit=*/true)
8467 .get());
8468 if (LastIteration64.isUsable())
8469 LastIteration64 = SemaRef.BuildBinOp(
8470 CurScope, Loc, BO_Mul, LastIteration64.get(),
8471 SemaRef
8472 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8473 Sema::AA_Converting,
8474 /*AllowExplicit=*/true)
8475 .get());
8476 }
8477
8478 // Choose either the 32-bit or 64-bit version.
8479 ExprResult LastIteration = LastIteration64;
8480 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8481 (LastIteration32.isUsable() &&
8482 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8483 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8484 fitsInto(
8485 /*Bits=*/32,
8486 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8487 LastIteration64.get(), SemaRef))))
8488 LastIteration = LastIteration32;
8489 QualType VType = LastIteration.get()->getType();
8490 QualType RealVType = VType;
8491 QualType StrideVType = VType;
8492 if (isOpenMPTaskLoopDirective(DKind)) {
8493 VType =
8494 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8495 StrideVType =
8496 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8497 }
8498
8499 if (!LastIteration.isUsable())
8500 return 0;
8501
8502 // Save the number of iterations.
8503 ExprResult NumIterations = LastIteration;
8504 {
8505 LastIteration = SemaRef.BuildBinOp(
8506 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8507 LastIteration.get(),
8508 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8509 if (!LastIteration.isUsable())
8510 return 0;
8511 }
8512
8513 // Calculate the last iteration number beforehand instead of doing this on
8514 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8515 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8516 ExprResult CalcLastIteration;
8517 if (!IsConstant) {
8518 ExprResult SaveRef =
8519 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8520 LastIteration = SaveRef;
8521
8522 // Prepare SaveRef + 1.
8523 NumIterations = SemaRef.BuildBinOp(
8524 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8525 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8526 if (!NumIterations.isUsable())
8527 return 0;
8528 }
8529
8530 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8531
8532 // Build variables passed into runtime, necessary for worksharing directives.
8533 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8534 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8535 isOpenMPDistributeDirective(DKind)) {
8536 // Lower bound variable, initialized with zero.
8537 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8538 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8539 SemaRef.AddInitializerToDecl(LBDecl,
8540 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8541 /*DirectInit*/ false);
8542
8543 // Upper bound variable, initialized with last iteration number.
8544 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8545 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8546 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8547 /*DirectInit*/ false);
8548
8549 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8550 // This will be used to implement clause 'lastprivate'.
8551 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8552 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8553 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8554 SemaRef.AddInitializerToDecl(ILDecl,
8555 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8556 /*DirectInit*/ false);
8557
8558 // Stride variable returned by runtime (we initialize it to 1 by default).
8559 VarDecl *STDecl =
8560 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8561 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8562 SemaRef.AddInitializerToDecl(STDecl,
8563 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8564 /*DirectInit*/ false);
8565
8566 // Build expression: UB = min(UB, LastIteration)
8567 // It is necessary for CodeGen of directives with static scheduling.
8568 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8569 UB.get(), LastIteration.get());
8570 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8571 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8572 LastIteration.get(), UB.get());
8573 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8574 CondOp.get());
8575 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8576
8577 // If we have a combined directive that combines 'distribute', 'for' or
8578 // 'simd' we need to be able to access the bounds of the schedule of the
8579 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8580 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8581 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8582 // Lower bound variable, initialized with zero.
8583 VarDecl *CombLBDecl =
8584 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8585 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8586 SemaRef.AddInitializerToDecl(
8587 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8588 /*DirectInit*/ false);
8589
8590 // Upper bound variable, initialized with last iteration number.
8591 VarDecl *CombUBDecl =
8592 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8593 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8594 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8595 /*DirectInit*/ false);
8596
8597 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8598 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8599 ExprResult CombCondOp =
8600 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8601 LastIteration.get(), CombUB.get());
8602 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8603 CombCondOp.get());
8604 CombEUB =
8605 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8606
8607 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8608 // We expect to have at least 2 more parameters than the 'parallel'
8609 // directive does - the lower and upper bounds of the previous schedule.
8610 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8611, __PRETTY_FUNCTION__))
8611 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8611, __PRETTY_FUNCTION__))
;
8612
8613 // Set the proper type for the bounds given what we learned from the
8614 // enclosed loops.
8615 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8616 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8617
8618 // Previous lower and upper bounds are obtained from the region
8619 // parameters.
8620 PrevLB =
8621 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8622 PrevUB =
8623 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8624 }
8625 }
8626
8627 // Build the iteration variable and its initialization before loop.
8628 ExprResult IV;
8629 ExprResult Init, CombInit;
8630 {
8631 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8632 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8633 Expr *RHS =
8634 (isOpenMPWorksharingDirective(DKind) ||
8635 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8636 ? LB.get()
8637 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8638 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8639 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8640
8641 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8642 Expr *CombRHS =
8643 (isOpenMPWorksharingDirective(DKind) ||
8644 isOpenMPTaskLoopDirective(DKind) ||
8645 isOpenMPDistributeDirective(DKind))
8646 ? CombLB.get()
8647 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8648 CombInit =
8649 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8650 CombInit =
8651 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8652 }
8653 }
8654
8655 bool UseStrictCompare =
8656 RealVType->hasUnsignedIntegerRepresentation() &&
8657 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8658 return LIS.IsStrictCompare;
8659 });
8660 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8661 // unsigned IV)) for worksharing loops.
8662 SourceLocation CondLoc = AStmt->getBeginLoc();
8663 Expr *BoundUB = UB.get();
8664 if (UseStrictCompare) {
8665 BoundUB =
8666 SemaRef
8667 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8668 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8669 .get();
8670 BoundUB =
8671 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8672 }
8673 ExprResult Cond =
8674 (isOpenMPWorksharingDirective(DKind) ||
8675 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8676 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8677 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8678 BoundUB)
8679 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8680 NumIterations.get());
8681 ExprResult CombDistCond;
8682 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8683 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8684 NumIterations.get());
8685 }
8686
8687 ExprResult CombCond;
8688 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8689 Expr *BoundCombUB = CombUB.get();
8690 if (UseStrictCompare) {
8691 BoundCombUB =
8692 SemaRef
8693 .BuildBinOp(
8694 CurScope, CondLoc, BO_Add, BoundCombUB,
8695 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8696 .get();
8697 BoundCombUB =
8698 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8699 .get();
8700 }
8701 CombCond =
8702 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8703 IV.get(), BoundCombUB);
8704 }
8705 // Loop increment (IV = IV + 1)
8706 SourceLocation IncLoc = AStmt->getBeginLoc();
8707 ExprResult Inc =
8708 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8709 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8710 if (!Inc.isUsable())
8711 return 0;
8712 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8713 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8714 if (!Inc.isUsable())
8715 return 0;
8716
8717 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8718 // Used for directives with static scheduling.
8719 // In combined construct, add combined version that use CombLB and CombUB
8720 // base variables for the update
8721 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8722 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8723 isOpenMPDistributeDirective(DKind)) {
8724 // LB + ST
8725 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8726 if (!NextLB.isUsable())
8727 return 0;
8728 // LB = LB + ST
8729 NextLB =
8730 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8731 NextLB =
8732 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8733 if (!NextLB.isUsable())
8734 return 0;
8735 // UB + ST
8736 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8737 if (!NextUB.isUsable())
8738 return 0;
8739 // UB = UB + ST
8740 NextUB =
8741 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8742 NextUB =
8743 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8744 if (!NextUB.isUsable())
8745 return 0;
8746 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8747 CombNextLB =
8748 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8749 if (!NextLB.isUsable())
8750 return 0;
8751 // LB = LB + ST
8752 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8753 CombNextLB.get());
8754 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8755 /*DiscardedValue*/ false);
8756 if (!CombNextLB.isUsable())
8757 return 0;
8758 // UB + ST
8759 CombNextUB =
8760 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8761 if (!CombNextUB.isUsable())
8762 return 0;
8763 // UB = UB + ST
8764 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8765 CombNextUB.get());
8766 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8767 /*DiscardedValue*/ false);
8768 if (!CombNextUB.isUsable())
8769 return 0;
8770 }
8771 }
8772
8773 // Create increment expression for distribute loop when combined in a same
8774 // directive with for as IV = IV + ST; ensure upper bound expression based
8775 // on PrevUB instead of NumIterations - used to implement 'for' when found
8776 // in combination with 'distribute', like in 'distribute parallel for'
8777 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8778 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8779 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8780 DistCond = SemaRef.BuildBinOp(
8781 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8782 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8782, __PRETTY_FUNCTION__))
;
8783
8784 DistInc =
8785 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8786 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8786, __PRETTY_FUNCTION__))
;
8787 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8788 DistInc.get());
8789 DistInc =
8790 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8791 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 8791, __PRETTY_FUNCTION__))
;
8792
8793 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8794 // construct
8795 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8796 ExprResult IsUBGreater =
8797 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8798 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8799 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8800 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8801 CondOp.get());
8802 PrevEUB =
8803 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8804
8805 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8806 // parallel for is in combination with a distribute directive with
8807 // schedule(static, 1)
8808 Expr *BoundPrevUB = PrevUB.get();
8809 if (UseStrictCompare) {
8810 BoundPrevUB =
8811 SemaRef
8812 .BuildBinOp(
8813 CurScope, CondLoc, BO_Add, BoundPrevUB,
8814 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8815 .get();
8816 BoundPrevUB =
8817 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8818 .get();
8819 }
8820 ParForInDistCond =
8821 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8822 IV.get(), BoundPrevUB);
8823 }
8824
8825 // Build updates and final values of the loop counters.
8826 bool HasErrors = false;
8827 Built.Counters.resize(NestedLoopCount);
8828 Built.Inits.resize(NestedLoopCount);
8829 Built.Updates.resize(NestedLoopCount);
8830 Built.Finals.resize(NestedLoopCount);
8831 Built.DependentCounters.resize(NestedLoopCount);
8832 Built.DependentInits.resize(NestedLoopCount);
8833 Built.FinalsConditions.resize(NestedLoopCount);
8834 {
8835 // We implement the following algorithm for obtaining the
8836 // original loop iteration variable values based on the
8837 // value of the collapsed loop iteration variable IV.
8838 //
8839 // Let n+1 be the number of collapsed loops in the nest.
8840 // Iteration variables (I0, I1, .... In)
8841 // Iteration counts (N0, N1, ... Nn)
8842 //
8843 // Acc = IV;
8844 //
8845 // To compute Ik for loop k, 0 <= k <= n, generate:
8846 // Prod = N(k+1) * N(k+2) * ... * Nn;
8847 // Ik = Acc / Prod;
8848 // Acc -= Ik * Prod;
8849 //
8850 ExprResult Acc = IV;
8851 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8852 LoopIterationSpace &IS = IterSpaces[Cnt];
8853 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8854 ExprResult Iter;
8855
8856 // Compute prod
8857 ExprResult Prod =
8858 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8859 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8860 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8861 IterSpaces[K].NumIterations);
8862
8863 // Iter = Acc / Prod
8864 // If there is at least one more inner loop to avoid
8865 // multiplication by 1.
8866 if (Cnt + 1 < NestedLoopCount)
8867 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8868 Acc.get(), Prod.get());
8869 else
8870 Iter = Acc;
8871 if (!Iter.isUsable()) {
8872 HasErrors = true;
8873 break;
8874 }
8875
8876 // Update Acc:
8877 // Acc -= Iter * Prod
8878 // Check if there is at least one more inner loop to avoid
8879 // multiplication by 1.
8880 if (Cnt + 1 < NestedLoopCount)
8881 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8882 Iter.get(), Prod.get());
8883 else
8884 Prod = Iter;
8885 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8886 Acc.get(), Prod.get());
8887
8888 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8889 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8890 DeclRefExpr *CounterVar = buildDeclRefExpr(
8891 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8892 /*RefersToCapture=*/true);
8893 ExprResult Init =
8894 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8895 IS.CounterInit, IS.IsNonRectangularLB, Captures);
8896 if (!Init.isUsable()) {
8897 HasErrors = true;
8898 break;
8899 }
8900 ExprResult Update = buildCounterUpdate(
8901 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8902 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8903 if (!Update.isUsable()) {
8904 HasErrors = true;
8905 break;
8906 }
8907
8908 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8909 ExprResult Final =
8910 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8911 IS.CounterInit, IS.NumIterations, IS.CounterStep,
8912 IS.Subtract, IS.IsNonRectangularLB, &Captures);
8913 if (!Final.isUsable()) {
8914 HasErrors = true;
8915 break;
8916 }
8917
8918 if (!Update.isUsable() || !Final.isUsable()) {
8919 HasErrors = true;
8920 break;
8921 }
8922 // Save results
8923 Built.Counters[Cnt] = IS.CounterVar;
8924 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8925 Built.Inits[Cnt] = Init.get();
8926 Built.Updates[Cnt] = Update.get();
8927 Built.Finals[Cnt] = Final.get();
8928 Built.DependentCounters[Cnt] = nullptr;
8929 Built.DependentInits[Cnt] = nullptr;
8930 Built.FinalsConditions[Cnt] = nullptr;
8931 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8932 Built.DependentCounters[Cnt] =
8933 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8934 Built.DependentInits[Cnt] =
8935 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8936 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8937 }
8938 }
8939 }
8940
8941 if (HasErrors)
8942 return 0;
8943
8944 // Save results
8945 Built.IterationVarRef = IV.get();
8946 Built.LastIteration = LastIteration.get();
8947 Built.NumIterations = NumIterations.get();
8948 Built.CalcLastIteration = SemaRef
8949 .ActOnFinishFullExpr(CalcLastIteration.get(),
8950 /*DiscardedValue=*/false)
8951 .get();
8952 Built.PreCond = PreCond.get();
8953 Built.PreInits = buildPreInits(C, Captures);
8954 Built.Cond = Cond.get();
8955 Built.Init = Init.get();
8956 Built.Inc = Inc.get();
8957 Built.LB = LB.get();
8958 Built.UB = UB.get();
8959 Built.IL = IL.get();
8960 Built.ST = ST.get();
8961 Built.EUB = EUB.get();
8962 Built.NLB = NextLB.get();
8963 Built.NUB = NextUB.get();
8964 Built.PrevLB = PrevLB.get();
8965 Built.PrevUB = PrevUB.get();
8966 Built.DistInc = DistInc.get();
8967 Built.PrevEUB = PrevEUB.get();
8968 Built.DistCombinedFields.LB = CombLB.get();
8969 Built.DistCombinedFields.UB = CombUB.get();
8970 Built.DistCombinedFields.EUB = CombEUB.get();
8971 Built.DistCombinedFields.Init = CombInit.get();
8972 Built.DistCombinedFields.Cond = CombCond.get();
8973 Built.DistCombinedFields.NLB = CombNextLB.get();
8974 Built.DistCombinedFields.NUB = CombNextUB.get();
8975 Built.DistCombinedFields.DistCond = CombDistCond.get();
8976 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8977
8978 return NestedLoopCount;
8979}
8980
8981static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8982 auto CollapseClauses =
8983 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8984 if (CollapseClauses.begin() != CollapseClauses.end())
8985 return (*CollapseClauses.begin())->getNumForLoops();
8986 return nullptr;
8987}
8988
8989static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8990 auto OrderedClauses =
8991 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8992 if (OrderedClauses.begin() != OrderedClauses.end())
8993 return (*OrderedClauses.begin())->getNumForLoops();
8994 return nullptr;
8995}
8996
8997static bool checkSimdlenSafelenSpecified(Sema &S,
8998 const ArrayRef<OMPClause *> Clauses) {
8999 const OMPSafelenClause *Safelen = nullptr;
9000 const OMPSimdlenClause *Simdlen = nullptr;
9001
9002 for (const OMPClause *Clause : Clauses) {
9003 if (Clause->getClauseKind() == OMPC_safelen)
9004 Safelen = cast<OMPSafelenClause>(Clause);
9005 else if (Clause->getClauseKind() == OMPC_simdlen)
9006 Simdlen = cast<OMPSimdlenClause>(Clause);
9007 if (Safelen && Simdlen)
9008 break;
9009 }
9010
9011 if (Simdlen && Safelen) {
9012 const Expr *SimdlenLength = Simdlen->getSimdlen();
9013 const Expr *SafelenLength = Safelen->getSafelen();
9014 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9015 SimdlenLength->isInstantiationDependent() ||
9016 SimdlenLength->containsUnexpandedParameterPack())
9017 return false;
9018 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9019 SafelenLength->isInstantiationDependent() ||
9020 SafelenLength->containsUnexpandedParameterPack())
9021 return false;
9022 Expr::EvalResult SimdlenResult, SafelenResult;
9023 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9024 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9025 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9026 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9027 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9028 // If both simdlen and safelen clauses are specified, the value of the
9029 // simdlen parameter must be less than or equal to the value of the safelen
9030 // parameter.
9031 if (SimdlenRes > SafelenRes) {
9032 S.Diag(SimdlenLength->getExprLoc(),
9033 diag::err_omp_wrong_simdlen_safelen_values)
9034 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9035 return true;
9036 }
9037 }
9038 return false;
9039}
9040
9041StmtResult
9042Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9043 SourceLocation StartLoc, SourceLocation EndLoc,
9044 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9045 if (!AStmt)
9046 return StmtError();
9047
9048 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9048, __PRETTY_FUNCTION__))
;
9049 OMPLoopDirective::HelperExprs B;
9050 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9051 // define the nested loops number.
9052 unsigned NestedLoopCount = checkOpenMPLoop(
9053 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9054 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9055 if (NestedLoopCount == 0)
9056 return StmtError();
9057
9058 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9059, __PRETTY_FUNCTION__))
9059 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9059, __PRETTY_FUNCTION__))
;
9060
9061 if (!CurContext->isDependentContext()) {
9062 // Finalize the clauses that need pre-built expressions for CodeGen.
9063 for (OMPClause *C : Clauses) {
9064 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9065 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9066 B.NumIterations, *this, CurScope,
9067 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9068 return StmtError();
9069 }
9070 }
9071
9072 if (checkSimdlenSafelenSpecified(*this, Clauses))
9073 return StmtError();
9074
9075 setFunctionHasBranchProtectedScope();
9076 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9077 Clauses, AStmt, B);
9078}
9079
9080StmtResult
9081Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9082 SourceLocation StartLoc, SourceLocation EndLoc,
9083 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9084 if (!AStmt)
9085 return StmtError();
9086
9087 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9087, __PRETTY_FUNCTION__))
;
9088 OMPLoopDirective::HelperExprs B;
9089 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9090 // define the nested loops number.
9091 unsigned NestedLoopCount = checkOpenMPLoop(
9092 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9093 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9094 if (NestedLoopCount == 0)
9095 return StmtError();
9096
9097 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9098, __PRETTY_FUNCTION__))
9098 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9098, __PRETTY_FUNCTION__))
;
9099
9100 if (!CurContext->isDependentContext()) {
9101 // Finalize the clauses that need pre-built expressions for CodeGen.
9102 for (OMPClause *C : Clauses) {
9103 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9104 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9105 B.NumIterations, *this, CurScope,
9106 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9107 return StmtError();
9108 }
9109 }
9110
9111 setFunctionHasBranchProtectedScope();
9112 return OMPForDirective::Create(
9113 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9114 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9115}
9116
9117StmtResult Sema::ActOnOpenMPForSimdDirective(
9118 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9119 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9120 if (!AStmt)
9121 return StmtError();
9122
9123 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9123, __PRETTY_FUNCTION__))
;
9124 OMPLoopDirective::HelperExprs B;
9125 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9126 // define the nested loops number.
9127 unsigned NestedLoopCount =
9128 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9129 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9130 VarsWithImplicitDSA, B);
9131 if (NestedLoopCount == 0)
9132 return StmtError();
9133
9134 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9135, __PRETTY_FUNCTION__))
9135 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9135, __PRETTY_FUNCTION__))
;
9136
9137 if (!CurContext->isDependentContext()) {
9138 // Finalize the clauses that need pre-built expressions for CodeGen.
9139 for (OMPClause *C : Clauses) {
9140 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9141 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9142 B.NumIterations, *this, CurScope,
9143 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9144 return StmtError();
9145 }
9146 }
9147
9148 if (checkSimdlenSafelenSpecified(*this, Clauses))
9149 return StmtError();
9150
9151 setFunctionHasBranchProtectedScope();
9152 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9153 Clauses, AStmt, B);
9154}
9155
9156StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9157 Stmt *AStmt,
9158 SourceLocation StartLoc,
9159 SourceLocation EndLoc) {
9160 if (!AStmt)
9161 return StmtError();
9162
9163 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9163, __PRETTY_FUNCTION__))
;
9164 auto BaseStmt = AStmt;
9165 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9166 BaseStmt = CS->getCapturedStmt();
9167 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9168 auto S = C->children();
9169 if (S.begin() == S.end())
9170 return StmtError();
9171 // All associated statements must be '#pragma omp section' except for
9172 // the first one.
9173 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9174 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9175 if (SectionStmt)
9176 Diag(SectionStmt->getBeginLoc(),
9177 diag::err_omp_sections_substmt_not_section);
9178 return StmtError();
9179 }
9180 cast<OMPSectionDirective>(SectionStmt)
9181 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9182 }
9183 } else {
9184 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9185 return StmtError();
9186 }
9187
9188 setFunctionHasBranchProtectedScope();
9189
9190 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9191 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
9192 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9193}
9194
9195StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9196 SourceLocation StartLoc,
9197 SourceLocation EndLoc) {
9198 if (!AStmt)
9199 return StmtError();
9200
9201 setFunctionHasBranchProtectedScope();
9202 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9203
9204 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9205 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9206}
9207
9208StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9209 Stmt *AStmt,
9210 SourceLocation StartLoc,
9211 SourceLocation EndLoc) {
9212 if (!AStmt)
9213 return StmtError();
9214
9215 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9215, __PRETTY_FUNCTION__))
;
9216
9217 setFunctionHasBranchProtectedScope();
9218
9219 // OpenMP [2.7.3, single Construct, Restrictions]
9220 // The copyprivate clause must not be used with the nowait clause.
9221 const OMPClause *Nowait = nullptr;
9222 const OMPClause *Copyprivate = nullptr;
9223 for (const OMPClause *Clause : Clauses) {
9224 if (Clause->getClauseKind() == OMPC_nowait)
9225 Nowait = Clause;
9226 else if (Clause->getClauseKind() == OMPC_copyprivate)
9227 Copyprivate = Clause;
9228 if (Copyprivate && Nowait) {
9229 Diag(Copyprivate->getBeginLoc(),
9230 diag::err_omp_single_copyprivate_with_nowait);
9231 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9232 return StmtError();
9233 }
9234 }
9235
9236 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9237}
9238
9239StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9240 SourceLocation StartLoc,
9241 SourceLocation EndLoc) {
9242 if (!AStmt)
9243 return StmtError();
9244
9245 setFunctionHasBranchProtectedScope();
9246
9247 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9248}
9249
9250StmtResult Sema::ActOnOpenMPCriticalDirective(
9251 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9252 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9253 if (!AStmt)
9254 return StmtError();
9255
9256 bool ErrorFound = false;
9257 llvm::APSInt Hint;
9258 SourceLocation HintLoc;
9259 bool DependentHint = false;
9260 for (const OMPClause *C : Clauses) {
9261 if (C->getClauseKind() == OMPC_hint) {
9262 if (!DirName.getName()) {
9263 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9264 ErrorFound = true;
9265 }
9266 Expr *E = cast<OMPHintClause>(C)->getHint();
9267 if (E->isTypeDependent() || E->isValueDependent() ||
9268 E->isInstantiationDependent()) {
9269 DependentHint = true;
9270 } else {
9271 Hint = E->EvaluateKnownConstInt(Context);
9272 HintLoc = C->getBeginLoc();
9273 }
9274 }
9275 }
9276 if (ErrorFound)
9277 return StmtError();
9278 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
9279 if (Pair.first && DirName.getName() && !DependentHint) {
9280 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9281 Diag(StartLoc, diag::err_omp_critical_with_hint);
9282 if (HintLoc.isValid())
9283 Diag(HintLoc, diag::note_omp_critical_hint_here)
9284 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9285 else
9286 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9287 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9288 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9289 << 1
9290 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9291 /*Radix=*/10, /*Signed=*/false);
9292 } else {
9293 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9294 }
9295 }
9296 }
9297
9298 setFunctionHasBranchProtectedScope();
9299
9300 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9301 Clauses, AStmt);
9302 if (!Pair.first && DirName.getName() && !DependentHint)
9303 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
9304 return Dir;
9305}
9306
9307StmtResult Sema::ActOnOpenMPParallelForDirective(
9308 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9309 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9310 if (!AStmt)
9311 return StmtError();
9312
9313 auto *CS = cast<CapturedStmt>(AStmt);
9314 // 1.2.2 OpenMP Language Terminology
9315 // Structured block - An executable statement with a single entry at the
9316 // top and a single exit at the bottom.
9317 // The point of exit cannot be a branch out of the structured block.
9318 // longjmp() and throw() must not violate the entry/exit criteria.
9319 CS->getCapturedDecl()->setNothrow();
9320
9321 OMPLoopDirective::HelperExprs B;
9322 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9323 // define the nested loops number.
9324 unsigned NestedLoopCount =
9325 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9326 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9327 VarsWithImplicitDSA, B);
9328 if (NestedLoopCount == 0)
9329 return StmtError();
9330
9331 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9332, __PRETTY_FUNCTION__))
9332 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9332, __PRETTY_FUNCTION__))
;
9333
9334 if (!CurContext->isDependentContext()) {
9335 // Finalize the clauses that need pre-built expressions for CodeGen.
9336 for (OMPClause *C : Clauses) {
9337 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9338 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9339 B.NumIterations, *this, CurScope,
9340 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9341 return StmtError();
9342 }
9343 }
9344
9345 setFunctionHasBranchProtectedScope();
9346 return OMPParallelForDirective::Create(
9347 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9348 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9349}
9350
9351StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9352 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9353 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9354 if (!AStmt)
9355 return StmtError();
9356
9357 auto *CS = cast<CapturedStmt>(AStmt);
9358 // 1.2.2 OpenMP Language Terminology
9359 // Structured block - An executable statement with a single entry at the
9360 // top and a single exit at the bottom.
9361 // The point of exit cannot be a branch out of the structured block.
9362 // longjmp() and throw() must not violate the entry/exit criteria.
9363 CS->getCapturedDecl()->setNothrow();
9364
9365 OMPLoopDirective::HelperExprs B;
9366 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9367 // define the nested loops number.
9368 unsigned NestedLoopCount =
9369 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9370 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9371 VarsWithImplicitDSA, B);
9372 if (NestedLoopCount == 0)
9373 return StmtError();
9374
9375 if (!CurContext->isDependentContext()) {
9376 // Finalize the clauses that need pre-built expressions for CodeGen.
9377 for (OMPClause *C : Clauses) {
9378 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9379 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9380 B.NumIterations, *this, CurScope,
9381 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9382 return StmtError();
9383 }
9384 }
9385
9386 if (checkSimdlenSafelenSpecified(*this, Clauses))
9387 return StmtError();
9388
9389 setFunctionHasBranchProtectedScope();
9390 return OMPParallelForSimdDirective::Create(
9391 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9392}
9393
9394StmtResult
9395Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9396 Stmt *AStmt, SourceLocation StartLoc,
9397 SourceLocation EndLoc) {
9398 if (!AStmt)
9399 return StmtError();
9400
9401 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9401, __PRETTY_FUNCTION__))
;
9402 auto *CS = cast<CapturedStmt>(AStmt);
9403 // 1.2.2 OpenMP Language Terminology
9404 // Structured block - An executable statement with a single entry at the
9405 // top and a single exit at the bottom.
9406 // The point of exit cannot be a branch out of the structured block.
9407 // longjmp() and throw() must not violate the entry/exit criteria.
9408 CS->getCapturedDecl()->setNothrow();
9409
9410 setFunctionHasBranchProtectedScope();
9411
9412 return OMPParallelMasterDirective::Create(
9413 Context, StartLoc, EndLoc, Clauses, AStmt,
9414 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9415}
9416
9417StmtResult
9418Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9419 Stmt *AStmt, SourceLocation StartLoc,
9420 SourceLocation EndLoc) {
9421 if (!AStmt)
9422 return StmtError();
9423
9424 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9424, __PRETTY_FUNCTION__))
;
9425 auto BaseStmt = AStmt;
9426 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9427 BaseStmt = CS->getCapturedStmt();
9428 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9429 auto S = C->children();
9430 if (S.begin() == S.end())
9431 return StmtError();
9432 // All associated statements must be '#pragma omp section' except for
9433 // the first one.
9434 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9435 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9436 if (SectionStmt)
9437 Diag(SectionStmt->getBeginLoc(),
9438 diag::err_omp_parallel_sections_substmt_not_section);
9439 return StmtError();
9440 }
9441 cast<OMPSectionDirective>(SectionStmt)
9442 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9443 }
9444 } else {
9445 Diag(AStmt->getBeginLoc(),
9446 diag::err_omp_parallel_sections_not_compound_stmt);
9447 return StmtError();
9448 }
9449
9450 setFunctionHasBranchProtectedScope();
9451
9452 return OMPParallelSectionsDirective::Create(
9453 Context, StartLoc, EndLoc, Clauses, AStmt,
9454 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9455}
9456
9457/// detach and mergeable clauses are mutially exclusive, check for it.
9458static bool checkDetachMergeableClauses(Sema &S,
9459 ArrayRef<OMPClause *> Clauses) {
9460 const OMPClause *PrevClause = nullptr;
9461 bool ErrorFound = false;
9462 for (const OMPClause *C : Clauses) {
9463 if (C->getClauseKind() == OMPC_detach ||
9464 C->getClauseKind() == OMPC_mergeable) {
9465 if (!PrevClause) {
9466 PrevClause = C;
9467 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9468 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9469 << getOpenMPClauseName(C->getClauseKind())
9470 << getOpenMPClauseName(PrevClause->getClauseKind());
9471 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9472 << getOpenMPClauseName(PrevClause->getClauseKind());
9473 ErrorFound = true;
9474 }
9475 }
9476 }
9477 return ErrorFound;
9478}
9479
9480StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9481 Stmt *AStmt, SourceLocation StartLoc,
9482 SourceLocation EndLoc) {
9483 if (!AStmt)
9484 return StmtError();
9485
9486 // OpenMP 5.0, 2.10.1 task Construct
9487 // If a detach clause appears on the directive, then a mergeable clause cannot
9488 // appear on the same directive.
9489 if (checkDetachMergeableClauses(*this, Clauses))
9490 return StmtError();
9491
9492 auto *CS = cast<CapturedStmt>(AStmt);
9493 // 1.2.2 OpenMP Language Terminology
9494 // Structured block - An executable statement with a single entry at the
9495 // top and a single exit at the bottom.
9496 // The point of exit cannot be a branch out of the structured block.
9497 // longjmp() and throw() must not violate the entry/exit criteria.
9498 CS->getCapturedDecl()->setNothrow();
9499
9500 setFunctionHasBranchProtectedScope();
9501
9502 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9503 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9504}
9505
9506StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9507 SourceLocation EndLoc) {
9508 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9509}
9510
9511StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9512 SourceLocation EndLoc) {
9513 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9514}
9515
9516StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9517 SourceLocation EndLoc) {
9518 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9519}
9520
9521StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9522 Stmt *AStmt,
9523 SourceLocation StartLoc,
9524 SourceLocation EndLoc) {
9525 if (!AStmt)
9526 return StmtError();
9527
9528 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9528, __PRETTY_FUNCTION__))
;
9529
9530 setFunctionHasBranchProtectedScope();
9531
9532 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9533 AStmt,
9534 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9535}
9536
9537StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9538 SourceLocation StartLoc,
9539 SourceLocation EndLoc) {
9540 OMPFlushClause *FC = nullptr;
9541 OMPClause *OrderClause = nullptr;
9542 for (OMPClause *C : Clauses) {
9543 if (C->getClauseKind() == OMPC_flush)
9544 FC = cast<OMPFlushClause>(C);
9545 else
9546 OrderClause = C;
9547 }
9548 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9549 SourceLocation MemOrderLoc;
9550 for (const OMPClause *C : Clauses) {
9551 if (C->getClauseKind() == OMPC_acq_rel ||
9552 C->getClauseKind() == OMPC_acquire ||
9553 C->getClauseKind() == OMPC_release) {
9554 if (MemOrderKind != OMPC_unknown) {
9555 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9556 << getOpenMPDirectiveName(OMPD_flush) << 1
9557 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9558 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9559 << getOpenMPClauseName(MemOrderKind);
9560 } else {
9561 MemOrderKind = C->getClauseKind();
9562 MemOrderLoc = C->getBeginLoc();
9563 }
9564 }
9565 }
9566 if (FC && OrderClause) {
9567 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9568 << getOpenMPClauseName(OrderClause->getClauseKind());
9569 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9570 << getOpenMPClauseName(OrderClause->getClauseKind());
9571 return StmtError();
9572 }
9573 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9574}
9575
9576StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9577 SourceLocation StartLoc,
9578 SourceLocation EndLoc) {
9579 if (Clauses.empty()) {
9580 Diag(StartLoc, diag::err_omp_depobj_expected);
9581 return StmtError();
9582 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9583 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9584 return StmtError();
9585 }
9586 // Only depobj expression and another single clause is allowed.
9587 if (Clauses.size() > 2) {
9588 Diag(Clauses[2]->getBeginLoc(),
9589 diag::err_omp_depobj_single_clause_expected);
9590 return StmtError();
9591 } else if (Clauses.size() < 1) {
9592 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9593 return StmtError();
9594 }
9595 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9596}
9597
9598StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9599 SourceLocation StartLoc,
9600 SourceLocation EndLoc) {
9601 // Check that exactly one clause is specified.
9602 if (Clauses.size() != 1) {
9603 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9604 diag::err_omp_scan_single_clause_expected);
9605 return StmtError();
9606 }
9607 // Check that scan directive is used in the scopeof the OpenMP loop body.
9608 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
9609 Scope *ParentS = S->getParent();
9610 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9611 !ParentS->getBreakParent()->isOpenMPLoopScope())
9612 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9613 << getOpenMPDirectiveName(OMPD_scan) << 5);
9614 }
9615 // Check that only one instance of scan directives is used in the same outer
9616 // region.
9617 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
9618 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9619 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
9620 diag::note_omp_previous_directive)
9621 << "scan";
9622 return StmtError();
9623 }
9624 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
9625 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9626}
9627
9628StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9629 Stmt *AStmt,
9630 SourceLocation StartLoc,
9631 SourceLocation EndLoc) {
9632 const OMPClause *DependFound = nullptr;
9633 const OMPClause *DependSourceClause = nullptr;
9634 const OMPClause *DependSinkClause = nullptr;
9635 bool ErrorFound = false;
9636 const OMPThreadsClause *TC = nullptr;
9637 const OMPSIMDClause *SC = nullptr;
9638 for (const OMPClause *C : Clauses) {
9639 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9640 DependFound = C;
9641 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9642 if (DependSourceClause) {
9643 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9644 << getOpenMPDirectiveName(OMPD_ordered)
9645 << getOpenMPClauseName(OMPC_depend) << 2;
9646 ErrorFound = true;
9647 } else {
9648 DependSourceClause = C;
9649 }
9650 if (DependSinkClause) {
9651 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9652 << 0;
9653 ErrorFound = true;
9654 }
9655 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9656 if (DependSourceClause) {
9657 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9658 << 1;
9659 ErrorFound = true;
9660 }
9661 DependSinkClause = C;
9662 }
9663 } else if (C->getClauseKind() == OMPC_threads) {
9664 TC = cast<OMPThreadsClause>(C);
9665 } else if (C->getClauseKind() == OMPC_simd) {
9666 SC = cast<OMPSIMDClause>(C);
9667 }
9668 }
9669 if (!ErrorFound && !SC &&
9670 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
9671 // OpenMP [2.8.1,simd Construct, Restrictions]
9672 // An ordered construct with the simd clause is the only OpenMP construct
9673 // that can appear in the simd region.
9674 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9675 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9676 ErrorFound = true;
9677 } else if (DependFound && (TC || SC)) {
9678 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9679 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9680 ErrorFound = true;
9681 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9682 Diag(DependFound->getBeginLoc(),
9683 diag::err_omp_ordered_directive_without_param);
9684 ErrorFound = true;
9685 } else if (TC || Clauses.empty()) {
9686 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9687 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9688 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9689 << (TC != nullptr);
9690 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9691 ErrorFound = true;
9692 }
9693 }
9694 if ((!AStmt && !DependFound) || ErrorFound)
9695 return StmtError();
9696
9697 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9698 // During execution of an iteration of a worksharing-loop or a loop nest
9699 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9700 // must not execute more than one ordered region corresponding to an ordered
9701 // construct without a depend clause.
9702 if (!DependFound) {
9703 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
9704 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9705 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
9706 diag::note_omp_previous_directive)
9707 << "ordered";
9708 return StmtError();
9709 }
9710 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
9711 }
9712
9713 if (AStmt) {
9714 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 9714, __PRETTY_FUNCTION__))
;
9715
9716 setFunctionHasBranchProtectedScope();
9717 }
9718
9719 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9720}
9721
9722namespace {
9723/// Helper class for checking expression in 'omp atomic [update]'
9724/// construct.
9725class OpenMPAtomicUpdateChecker {
9726 /// Error results for atomic update expressions.
9727 enum ExprAnalysisErrorCode {
9728 /// A statement is not an expression statement.
9729 NotAnExpression,
9730 /// Expression is not builtin binary or unary operation.
9731 NotABinaryOrUnaryExpression,
9732 /// Unary operation is not post-/pre- increment/decrement operation.
9733 NotAnUnaryIncDecExpression,
9734 /// An expression is not of scalar type.
9735 NotAScalarType,
9736 /// A binary operation is not an assignment operation.
9737 NotAnAssignmentOp,
9738 /// RHS part of the binary operation is not a binary expression.
9739 NotABinaryExpression,
9740 /// RHS part is not additive/multiplicative/shift/biwise binary
9741 /// expression.
9742 NotABinaryOperator,
9743 /// RHS binary operation does not have reference to the updated LHS
9744 /// part.
9745 NotAnUpdateExpression,
9746 /// No errors is found.
9747 NoError
9748 };
9749 /// Reference to Sema.
9750 Sema &SemaRef;
9751 /// A location for note diagnostics (when error is found).
9752 SourceLocation NoteLoc;
9753 /// 'x' lvalue part of the source atomic expression.
9754 Expr *X;
9755 /// 'expr' rvalue part of the source atomic expression.
9756 Expr *E;
9757 /// Helper expression of the form
9758 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9759 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9760 Expr *UpdateExpr;
9761 /// Is 'x' a LHS in a RHS part of full update expression. It is
9762 /// important for non-associative operations.
9763 bool IsXLHSInRHSPart;
9764 BinaryOperatorKind Op;
9765 SourceLocation OpLoc;
9766 /// true if the source expression is a postfix unary operation, false
9767 /// if it is a prefix unary operation.
9768 bool IsPostfixUpdate;
9769
9770public:
9771 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9772 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9773 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9774 /// Check specified statement that it is suitable for 'atomic update'
9775 /// constructs and extract 'x', 'expr' and Operation from the original
9776 /// expression. If DiagId and NoteId == 0, then only check is performed
9777 /// without error notification.
9778 /// \param DiagId Diagnostic which should be emitted if error is found.
9779 /// \param NoteId Diagnostic note for the main error message.
9780 /// \return true if statement is not an update expression, false otherwise.
9781 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9782 /// Return the 'x' lvalue part of the source atomic expression.
9783 Expr *getX() const { return X; }
9784 /// Return the 'expr' rvalue part of the source atomic expression.
9785 Expr *getExpr() const { return E; }
9786 /// Return the update expression used in calculation of the updated
9787 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9788 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9789 Expr *getUpdateExpr() const { return UpdateExpr; }
9790 /// Return true if 'x' is LHS in RHS part of full update expression,
9791 /// false otherwise.
9792 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9793
9794 /// true if the source expression is a postfix unary operation, false
9795 /// if it is a prefix unary operation.
9796 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9797
9798private:
9799 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9800 unsigned NoteId = 0);
9801};
9802} // namespace
9803
9804bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9805 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9806 ExprAnalysisErrorCode ErrorFound = NoError;
9807 SourceLocation ErrorLoc, NoteLoc;
9808 SourceRange ErrorRange, NoteRange;
9809 // Allowed constructs are:
9810 // x = x binop expr;
9811 // x = expr binop x;
9812 if (AtomicBinOp->getOpcode() == BO_Assign) {
9813 X = AtomicBinOp->getLHS();
9814 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9815 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9816 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9817 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9818 AtomicInnerBinOp->isBitwiseOp()) {
9819 Op = AtomicInnerBinOp->getOpcode();
9820 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9821 Expr *LHS = AtomicInnerBinOp->getLHS();
9822 Expr *RHS = AtomicInnerBinOp->getRHS();
9823 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9824 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9825 /*Canonical=*/true);
9826 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9827 /*Canonical=*/true);
9828 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9829 /*Canonical=*/true);
9830 if (XId == LHSId) {
9831 E = RHS;
9832 IsXLHSInRHSPart = true;
9833 } else if (XId == RHSId) {
9834 E = LHS;
9835 IsXLHSInRHSPart = false;
9836 } else {
9837 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9838 ErrorRange = AtomicInnerBinOp->getSourceRange();
9839 NoteLoc = X->getExprLoc();
9840 NoteRange = X->getSourceRange();
9841 ErrorFound = NotAnUpdateExpression;
9842 }
9843 } else {
9844 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9845 ErrorRange = AtomicInnerBinOp->getSourceRange();
9846 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9847 NoteRange = SourceRange(NoteLoc, NoteLoc);
9848 ErrorFound = NotABinaryOperator;
9849 }
9850 } else {
9851 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9852 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9853 ErrorFound = NotABinaryExpression;
9854 }
9855 } else {
9856 ErrorLoc = AtomicBinOp->getExprLoc();
9857 ErrorRange = AtomicBinOp->getSourceRange();
9858 NoteLoc = AtomicBinOp->getOperatorLoc();
9859 NoteRange = SourceRange(NoteLoc, NoteLoc);
9860 ErrorFound = NotAnAssignmentOp;
9861 }
9862 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9863 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9864 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9865 return true;
9866 }
9867 if (SemaRef.CurContext->isDependentContext())
9868 E = X = UpdateExpr = nullptr;
9869 return ErrorFound != NoError;
9870}
9871
9872bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9873 unsigned NoteId) {
9874 ExprAnalysisErrorCode ErrorFound = NoError;
9875 SourceLocation ErrorLoc, NoteLoc;
9876 SourceRange ErrorRange, NoteRange;
9877 // Allowed constructs are:
9878 // x++;
9879 // x--;
9880 // ++x;
9881 // --x;
9882 // x binop= expr;
9883 // x = x binop expr;
9884 // x = expr binop x;
9885 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9886 AtomicBody = AtomicBody->IgnoreParenImpCasts();
9887 if (AtomicBody->getType()->isScalarType() ||
9888 AtomicBody->isInstantiationDependent()) {
9889 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9890 AtomicBody->IgnoreParenImpCasts())) {
9891 // Check for Compound Assignment Operation
9892 Op = BinaryOperator::getOpForCompoundAssignment(
9893 AtomicCompAssignOp->getOpcode());
9894 OpLoc = AtomicCompAssignOp->getOperatorLoc();
9895 E = AtomicCompAssignOp->getRHS();
9896 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9897 IsXLHSInRHSPart = true;
9898 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9899 AtomicBody->IgnoreParenImpCasts())) {
9900 // Check for Binary Operation
9901 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9902 return true;
9903 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9904 AtomicBody->IgnoreParenImpCasts())) {
9905 // Check for Unary Operation
9906 if (AtomicUnaryOp->isIncrementDecrementOp()) {
9907 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9908 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9909 OpLoc = AtomicUnaryOp->getOperatorLoc();
9910 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9911 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9912 IsXLHSInRHSPart = true;
9913 } else {
9914 ErrorFound = NotAnUnaryIncDecExpression;
9915 ErrorLoc = AtomicUnaryOp->getExprLoc();
9916 ErrorRange = AtomicUnaryOp->getSourceRange();
9917 NoteLoc = AtomicUnaryOp->getOperatorLoc();
9918 NoteRange = SourceRange(NoteLoc, NoteLoc);
9919 }
9920 } else if (!AtomicBody->isInstantiationDependent()) {
9921 ErrorFound = NotABinaryOrUnaryExpression;
9922 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9923 NoteRange = ErrorRange = AtomicBody->getSourceRange();
9924 }
9925 } else {
9926 ErrorFound = NotAScalarType;
9927 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9928 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9929 }
9930 } else {
9931 ErrorFound = NotAnExpression;
9932 NoteLoc = ErrorLoc = S->getBeginLoc();
9933 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9934 }
9935 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9936 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9937 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9938 return true;
9939 }
9940 if (SemaRef.CurContext->isDependentContext())
9941 E = X = UpdateExpr = nullptr;
9942 if (ErrorFound == NoError && E && X) {
9943 // Build an update expression of form 'OpaqueValueExpr(x) binop
9944 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9945 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9946 auto *OVEX = new (SemaRef.getASTContext())
9947 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9948 auto *OVEExpr = new (SemaRef.getASTContext())
9949 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9950 ExprResult Update =
9951 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9952 IsXLHSInRHSPart ? OVEExpr : OVEX);
9953 if (Update.isInvalid())
9954 return true;
9955 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9956 Sema::AA_Casting);
9957 if (Update.isInvalid())
9958 return true;
9959 UpdateExpr = Update.get();
9960 }
9961 return ErrorFound != NoError;
9962}
9963
9964StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9965 Stmt *AStmt,
9966 SourceLocation StartLoc,
9967 SourceLocation EndLoc) {
9968 // Register location of the first atomic directive.
9969 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
9970 if (!AStmt)
9971 return StmtError();
9972
9973 // 1.2.2 OpenMP Language Terminology
9974 // Structured block - An executable statement with a single entry at the
9975 // top and a single exit at the bottom.
9976 // The point of exit cannot be a branch out of the structured block.
9977 // longjmp() and throw() must not violate the entry/exit criteria.
9978 OpenMPClauseKind AtomicKind = OMPC_unknown;
9979 SourceLocation AtomicKindLoc;
9980 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9981 SourceLocation MemOrderLoc;
9982 for (const OMPClause *C : Clauses) {
9983 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9984 C->getClauseKind() == OMPC_update ||
9985 C->getClauseKind() == OMPC_capture) {
9986 if (AtomicKind != OMPC_unknown) {
9987 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9988 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9989 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9990 << getOpenMPClauseName(AtomicKind);
9991 } else {
9992 AtomicKind = C->getClauseKind();
9993 AtomicKindLoc = C->getBeginLoc();
9994 }
9995 }
9996 if (C->getClauseKind() == OMPC_seq_cst ||
9997 C->getClauseKind() == OMPC_acq_rel ||
9998 C->getClauseKind() == OMPC_acquire ||
9999 C->getClauseKind() == OMPC_release ||
10000 C->getClauseKind() == OMPC_relaxed) {
10001 if (MemOrderKind != OMPC_unknown) {
10002 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10003 << getOpenMPDirectiveName(OMPD_atomic) << 0
10004 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10005 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10006 << getOpenMPClauseName(MemOrderKind);
10007 } else {
10008 MemOrderKind = C->getClauseKind();
10009 MemOrderLoc = C->getBeginLoc();
10010 }
10011 }
10012 }
10013 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10014 // If atomic-clause is read then memory-order-clause must not be acq_rel or
10015 // release.
10016 // If atomic-clause is write then memory-order-clause must not be acq_rel or
10017 // acquire.
10018 // If atomic-clause is update or not present then memory-order-clause must not
10019 // be acq_rel or acquire.
10020 if ((AtomicKind == OMPC_read &&
10021 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10022 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10023 AtomicKind == OMPC_unknown) &&
10024 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10025 SourceLocation Loc = AtomicKindLoc;
10026 if (AtomicKind == OMPC_unknown)
10027 Loc = StartLoc;
10028 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10029 << getOpenMPClauseName(AtomicKind)
10030 << (AtomicKind == OMPC_unknown ? 1 : 0)
10031 << getOpenMPClauseName(MemOrderKind);
10032 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10033 << getOpenMPClauseName(MemOrderKind);
10034 }
10035
10036 Stmt *Body = AStmt;
10037 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10038 Body = EWC->getSubExpr();
10039
10040 Expr *X = nullptr;
10041 Expr *V = nullptr;
10042 Expr *E = nullptr;
10043 Expr *UE = nullptr;
10044 bool IsXLHSInRHSPart = false;
10045 bool IsPostfixUpdate = false;
10046 // OpenMP [2.12.6, atomic Construct]
10047 // In the next expressions:
10048 // * x and v (as applicable) are both l-value expressions with scalar type.
10049 // * During the execution of an atomic region, multiple syntactic
10050 // occurrences of x must designate the same storage location.
10051 // * Neither of v and expr (as applicable) may access the storage location
10052 // designated by x.
10053 // * Neither of x and expr (as applicable) may access the storage location
10054 // designated by v.
10055 // * expr is an expression with scalar type.
10056 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10057 // * binop, binop=, ++, and -- are not overloaded operators.
10058 // * The expression x binop expr must be numerically equivalent to x binop
10059 // (expr). This requirement is satisfied if the operators in expr have
10060 // precedence greater than binop, or by using parentheses around expr or
10061 // subexpressions of expr.
10062 // * The expression expr binop x must be numerically equivalent to (expr)
10063 // binop x. This requirement is satisfied if the operators in expr have
10064 // precedence equal to or greater than binop, or by using parentheses around
10065 // expr or subexpressions of expr.
10066 // * For forms that allow multiple occurrences of x, the number of times
10067 // that x is evaluated is unspecified.
10068 if (AtomicKind == OMPC_read) {
10069 enum {
10070 NotAnExpression,
10071 NotAnAssignmentOp,
10072 NotAScalarType,
10073 NotAnLValue,
10074 NoError
10075 } ErrorFound = NoError;
10076 SourceLocation ErrorLoc, NoteLoc;
10077 SourceRange ErrorRange, NoteRange;
10078 // If clause is read:
10079 // v = x;
10080 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10081 const auto *AtomicBinOp =
10082 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10083 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10084 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10085 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10086 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10087 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10088 if (!X->isLValue() || !V->isLValue()) {
10089 const Expr *NotLValueExpr = X->isLValue() ? V : X;
10090 ErrorFound = NotAnLValue;
10091 ErrorLoc = AtomicBinOp->getExprLoc();
10092 ErrorRange = AtomicBinOp->getSourceRange();
10093 NoteLoc = NotLValueExpr->getExprLoc();
10094 NoteRange = NotLValueExpr->getSourceRange();
10095 }
10096 } else if (!X->isInstantiationDependent() ||
10097 !V->isInstantiationDependent()) {
10098 const Expr *NotScalarExpr =
10099 (X->isInstantiationDependent() || X->getType()->isScalarType())
10100 ? V
10101 : X;
10102 ErrorFound = NotAScalarType;
10103 ErrorLoc = AtomicBinOp->getExprLoc();
10104 ErrorRange = AtomicBinOp->getSourceRange();
10105 NoteLoc = NotScalarExpr->getExprLoc();
10106 NoteRange = NotScalarExpr->getSourceRange();
10107 }
10108 } else if (!AtomicBody->isInstantiationDependent()) {
10109 ErrorFound = NotAnAssignmentOp;
10110 ErrorLoc = AtomicBody->getExprLoc();
10111 ErrorRange = AtomicBody->getSourceRange();
10112 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10113 : AtomicBody->getExprLoc();
10114 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10115 : AtomicBody->getSourceRange();
10116 }
10117 } else {
10118 ErrorFound = NotAnExpression;
10119 NoteLoc = ErrorLoc = Body->getBeginLoc();
10120 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10121 }
10122 if (ErrorFound != NoError) {
10123 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10124 << ErrorRange;
10125 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10126 << NoteRange;
10127 return StmtError();
10128 }
10129 if (CurContext->isDependentContext())
10130 V = X = nullptr;
10131 } else if (AtomicKind == OMPC_write) {
10132 enum {
10133 NotAnExpression,
10134 NotAnAssignmentOp,
10135 NotAScalarType,
10136 NotAnLValue,
10137 NoError
10138 } ErrorFound = NoError;
10139 SourceLocation ErrorLoc, NoteLoc;
10140 SourceRange ErrorRange, NoteRange;
10141 // If clause is write:
10142 // x = expr;
10143 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10144 const auto *AtomicBinOp =
10145 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10146 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10147 X = AtomicBinOp->getLHS();
10148 E = AtomicBinOp->getRHS();
10149 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10150 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10151 if (!X->isLValue()) {
10152 ErrorFound = NotAnLValue;
10153 ErrorLoc = AtomicBinOp->getExprLoc();
10154 ErrorRange = AtomicBinOp->getSourceRange();
10155 NoteLoc = X->getExprLoc();
10156 NoteRange = X->getSourceRange();
10157 }
10158 } else if (!X->isInstantiationDependent() ||
10159 !E->isInstantiationDependent()) {
10160 const Expr *NotScalarExpr =
10161 (X->isInstantiationDependent() || X->getType()->isScalarType())
10162 ? E
10163 : X;
10164 ErrorFound = NotAScalarType;
10165 ErrorLoc = AtomicBinOp->getExprLoc();
10166 ErrorRange = AtomicBinOp->getSourceRange();
10167 NoteLoc = NotScalarExpr->getExprLoc();
10168 NoteRange = NotScalarExpr->getSourceRange();
10169 }
10170 } else if (!AtomicBody->isInstantiationDependent()) {
10171 ErrorFound = NotAnAssignmentOp;
10172 ErrorLoc = AtomicBody->getExprLoc();
10173 ErrorRange = AtomicBody->getSourceRange();
10174 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10175 : AtomicBody->getExprLoc();
10176 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10177 : AtomicBody->getSourceRange();
10178 }
10179 } else {
10180 ErrorFound = NotAnExpression;
10181 NoteLoc = ErrorLoc = Body->getBeginLoc();
10182 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10183 }
10184 if (ErrorFound != NoError) {
10185 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10186 << ErrorRange;
10187 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10188 << NoteRange;
10189 return StmtError();
10190 }
10191 if (CurContext->isDependentContext())
10192 E = X = nullptr;
10193 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10194 // If clause is update:
10195 // x++;
10196 // x--;
10197 // ++x;
10198 // --x;
10199 // x binop= expr;
10200 // x = x binop expr;
10201 // x = expr binop x;
10202 OpenMPAtomicUpdateChecker Checker(*this);
10203 if (Checker.checkStatement(
10204 Body, (AtomicKind == OMPC_update)
10205 ? diag::err_omp_atomic_update_not_expression_statement
10206 : diag::err_omp_atomic_not_expression_statement,
10207 diag::note_omp_atomic_update))
10208 return StmtError();
10209 if (!CurContext->isDependentContext()) {
10210 E = Checker.getExpr();
10211 X = Checker.getX();
10212 UE = Checker.getUpdateExpr();
10213 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10214 }
10215 } else if (AtomicKind == OMPC_capture) {
10216 enum {
10217 NotAnAssignmentOp,
10218 NotACompoundStatement,
10219 NotTwoSubstatements,
10220 NotASpecificExpression,
10221 NoError
10222 } ErrorFound = NoError;
10223 SourceLocation ErrorLoc, NoteLoc;
10224 SourceRange ErrorRange, NoteRange;
10225 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10226 // If clause is a capture:
10227 // v = x++;
10228 // v = x--;
10229 // v = ++x;
10230 // v = --x;
10231 // v = x binop= expr;
10232 // v = x = x binop expr;
10233 // v = x = expr binop x;
10234 const auto *AtomicBinOp =
10235 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10236 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10237 V = AtomicBinOp->getLHS();
10238 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10239 OpenMPAtomicUpdateChecker Checker(*this);
10240 if (Checker.checkStatement(
10241 Body, diag::err_omp_atomic_capture_not_expression_statement,
10242 diag::note_omp_atomic_update))
10243 return StmtError();
10244 E = Checker.getExpr();
10245 X = Checker.getX();
10246 UE = Checker.getUpdateExpr();
10247 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10248 IsPostfixUpdate = Checker.isPostfixUpdate();
10249 } else if (!AtomicBody->isInstantiationDependent()) {
10250 ErrorLoc = AtomicBody->getExprLoc();
10251 ErrorRange = AtomicBody->getSourceRange();
10252 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10253 : AtomicBody->getExprLoc();
10254 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10255 : AtomicBody->getSourceRange();
10256 ErrorFound = NotAnAssignmentOp;
10257 }
10258 if (ErrorFound != NoError) {
10259 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10260 << ErrorRange;
10261 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10262 return StmtError();
10263 }
10264 if (CurContext->isDependentContext())
10265 UE = V = E = X = nullptr;
10266 } else {
10267 // If clause is a capture:
10268 // { v = x; x = expr; }
10269 // { v = x; x++; }
10270 // { v = x; x--; }
10271 // { v = x; ++x; }
10272 // { v = x; --x; }
10273 // { v = x; x binop= expr; }
10274 // { v = x; x = x binop expr; }
10275 // { v = x; x = expr binop x; }
10276 // { x++; v = x; }
10277 // { x--; v = x; }
10278 // { ++x; v = x; }
10279 // { --x; v = x; }
10280 // { x binop= expr; v = x; }
10281 // { x = x binop expr; v = x; }
10282 // { x = expr binop x; v = x; }
10283 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10284 // Check that this is { expr1; expr2; }
10285 if (CS->size() == 2) {
10286 Stmt *First = CS->body_front();
10287 Stmt *Second = CS->body_back();
10288 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10289 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10290 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10291 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10292 // Need to find what subexpression is 'v' and what is 'x'.
10293 OpenMPAtomicUpdateChecker Checker(*this);
10294 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10295 BinaryOperator *BinOp = nullptr;
10296 if (IsUpdateExprFound) {
10297 BinOp = dyn_cast<BinaryOperator>(First);
10298 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10299 }
10300 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10301 // { v = x; x++; }
10302 // { v = x; x--; }
10303 // { v = x; ++x; }
10304 // { v = x; --x; }
10305 // { v = x; x binop= expr; }
10306 // { v = x; x = x binop expr; }
10307 // { v = x; x = expr binop x; }
10308 // Check that the first expression has form v = x.
10309 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10310 llvm::FoldingSetNodeID XId, PossibleXId;
10311 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10312 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10313 IsUpdateExprFound = XId == PossibleXId;
10314 if (IsUpdateExprFound) {
10315 V = BinOp->getLHS();
10316 X = Checker.getX();
10317 E = Checker.getExpr();
10318 UE = Checker.getUpdateExpr();
10319 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10320 IsPostfixUpdate = true;
10321 }
10322 }
10323 if (!IsUpdateExprFound) {
10324 IsUpdateExprFound = !Checker.checkStatement(First);
10325 BinOp = nullptr;
10326 if (IsUpdateExprFound) {
10327 BinOp = dyn_cast<BinaryOperator>(Second);
10328 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10329 }
10330 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10331 // { x++; v = x; }
10332 // { x--; v = x; }
10333 // { ++x; v = x; }
10334 // { --x; v = x; }
10335 // { x binop= expr; v = x; }
10336 // { x = x binop expr; v = x; }
10337 // { x = expr binop x; v = x; }
10338 // Check that the second expression has form v = x.
10339 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10340 llvm::FoldingSetNodeID XId, PossibleXId;
10341 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10342 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10343 IsUpdateExprFound = XId == PossibleXId;
10344 if (IsUpdateExprFound) {
10345 V = BinOp->getLHS();
10346 X = Checker.getX();
10347 E = Checker.getExpr();
10348 UE = Checker.getUpdateExpr();
10349 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10350 IsPostfixUpdate = false;
10351 }
10352 }
10353 }
10354 if (!IsUpdateExprFound) {
10355 // { v = x; x = expr; }
10356 auto *FirstExpr = dyn_cast<Expr>(First);
10357 auto *SecondExpr = dyn_cast<Expr>(Second);
10358 if (!FirstExpr || !SecondExpr ||
10359 !(FirstExpr->isInstantiationDependent() ||
10360 SecondExpr->isInstantiationDependent())) {
10361 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10362 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10363 ErrorFound = NotAnAssignmentOp;
10364 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10365 : First->getBeginLoc();
10366 NoteRange = ErrorRange = FirstBinOp
10367 ? FirstBinOp->getSourceRange()
10368 : SourceRange(ErrorLoc, ErrorLoc);
10369 } else {
10370 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10371 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10372 ErrorFound = NotAnAssignmentOp;
10373 NoteLoc = ErrorLoc = SecondBinOp
10374 ? SecondBinOp->getOperatorLoc()
10375 : Second->getBeginLoc();
10376 NoteRange = ErrorRange =
10377 SecondBinOp ? SecondBinOp->getSourceRange()
10378 : SourceRange(ErrorLoc, ErrorLoc);
10379 } else {
10380 Expr *PossibleXRHSInFirst =
10381 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10382 Expr *PossibleXLHSInSecond =
10383 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10384 llvm::FoldingSetNodeID X1Id, X2Id;
10385 PossibleXRHSInFirst->Profile(X1Id, Context,
10386 /*Canonical=*/true);
10387 PossibleXLHSInSecond->Profile(X2Id, Context,
10388 /*Canonical=*/true);
10389 IsUpdateExprFound = X1Id == X2Id;
10390 if (IsUpdateExprFound) {
10391 V = FirstBinOp->getLHS();
10392 X = SecondBinOp->getLHS();
10393 E = SecondBinOp->getRHS();
10394 UE = nullptr;
10395 IsXLHSInRHSPart = false;
10396 IsPostfixUpdate = true;
10397 } else {
10398 ErrorFound = NotASpecificExpression;
10399 ErrorLoc = FirstBinOp->getExprLoc();
10400 ErrorRange = FirstBinOp->getSourceRange();
10401 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10402 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10403 }
10404 }
10405 }
10406 }
10407 }
10408 } else {
10409 NoteLoc = ErrorLoc = Body->getBeginLoc();
10410 NoteRange = ErrorRange =
10411 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10412 ErrorFound = NotTwoSubstatements;
10413 }
10414 } else {
10415 NoteLoc = ErrorLoc = Body->getBeginLoc();
10416 NoteRange = ErrorRange =
10417 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10418 ErrorFound = NotACompoundStatement;
10419 }
10420 if (ErrorFound != NoError) {
10421 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10422 << ErrorRange;
10423 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10424 return StmtError();
10425 }
10426 if (CurContext->isDependentContext())
10427 UE = V = E = X = nullptr;
10428 }
10429 }
10430
10431 setFunctionHasBranchProtectedScope();
10432
10433 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10434 X, V, E, UE, IsXLHSInRHSPart,
10435 IsPostfixUpdate);
10436}
10437
10438StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10439 Stmt *AStmt,
10440 SourceLocation StartLoc,
10441 SourceLocation EndLoc) {
10442 if (!AStmt)
10443 return StmtError();
10444
10445 auto *CS = cast<CapturedStmt>(AStmt);
10446 // 1.2.2 OpenMP Language Terminology
10447 // Structured block - An executable statement with a single entry at the
10448 // top and a single exit at the bottom.
10449 // The point of exit cannot be a branch out of the structured block.
10450 // longjmp() and throw() must not violate the entry/exit criteria.
10451 CS->getCapturedDecl()->setNothrow();
10452 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10453 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10454 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10455 // 1.2.2 OpenMP Language Terminology
10456 // Structured block - An executable statement with a single entry at the
10457 // top and a single exit at the bottom.
10458 // The point of exit cannot be a branch out of the structured block.
10459 // longjmp() and throw() must not violate the entry/exit criteria.
10460 CS->getCapturedDecl()->setNothrow();
10461 }
10462
10463 // OpenMP [2.16, Nesting of Regions]
10464 // If specified, a teams construct must be contained within a target
10465 // construct. That target construct must contain no statements or directives
10466 // outside of the teams construct.
10467 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
10468 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10469 bool OMPTeamsFound = true;
10470 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10471 auto I = CS->body_begin();
10472 while (I != CS->body_end()) {
10473 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10474 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10475 OMPTeamsFound) {
10476
10477 OMPTeamsFound = false;
10478 break;
10479 }
10480 ++I;
10481 }
10482 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10482, __PRETTY_FUNCTION__))
;
10483 S = *I;
10484 } else {
10485 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10486 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10487 }
10488 if (!OMPTeamsFound) {
10489 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10490 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
10491 diag::note_omp_nested_teams_construct_here);
10492 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10493 << isa<OMPExecutableDirective>(S);
10494 return StmtError();
10495 }
10496 }
10497
10498 setFunctionHasBranchProtectedScope();
10499
10500 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10501}
10502
10503StmtResult
10504Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10505 Stmt *AStmt, SourceLocation StartLoc,
10506 SourceLocation EndLoc) {
10507 if (!AStmt)
10508 return StmtError();
10509
10510 auto *CS = cast<CapturedStmt>(AStmt);
10511 // 1.2.2 OpenMP Language Terminology
10512 // Structured block - An executable statement with a single entry at the
10513 // top and a single exit at the bottom.
10514 // The point of exit cannot be a branch out of the structured block.
10515 // longjmp() and throw() must not violate the entry/exit criteria.
10516 CS->getCapturedDecl()->setNothrow();
10517 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10518 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10519 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10520 // 1.2.2 OpenMP Language Terminology
10521 // Structured block - An executable statement with a single entry at the
10522 // top and a single exit at the bottom.
10523 // The point of exit cannot be a branch out of the structured block.
10524 // longjmp() and throw() must not violate the entry/exit criteria.
10525 CS->getCapturedDecl()->setNothrow();
10526 }
10527
10528 setFunctionHasBranchProtectedScope();
10529
10530 return OMPTargetParallelDirective::Create(
10531 Context, StartLoc, EndLoc, Clauses, AStmt,
10532 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10533}
10534
10535StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10536 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10537 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10538 if (!AStmt)
10539 return StmtError();
10540
10541 auto *CS = cast<CapturedStmt>(AStmt);
10542 // 1.2.2 OpenMP Language Terminology
10543 // Structured block - An executable statement with a single entry at the
10544 // top and a single exit at the bottom.
10545 // The point of exit cannot be a branch out of the structured block.
10546 // longjmp() and throw() must not violate the entry/exit criteria.
10547 CS->getCapturedDecl()->setNothrow();
10548 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10549 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10550 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10551 // 1.2.2 OpenMP Language Terminology
10552 // Structured block - An executable statement with a single entry at the
10553 // top and a single exit at the bottom.
10554 // The point of exit cannot be a branch out of the structured block.
10555 // longjmp() and throw() must not violate the entry/exit criteria.
10556 CS->getCapturedDecl()->setNothrow();
10557 }
10558
10559 OMPLoopDirective::HelperExprs B;
10560 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10561 // define the nested loops number.
10562 unsigned NestedLoopCount =
10563 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10564 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10565 VarsWithImplicitDSA, B);
10566 if (NestedLoopCount == 0)
10567 return StmtError();
10568
10569 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10570, __PRETTY_FUNCTION__))
10570 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10570, __PRETTY_FUNCTION__))
;
10571
10572 if (!CurContext->isDependentContext()) {
10573 // Finalize the clauses that need pre-built expressions for CodeGen.
10574 for (OMPClause *C : Clauses) {
10575 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10576 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10577 B.NumIterations, *this, CurScope,
10578 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10579 return StmtError();
10580 }
10581 }
10582
10583 setFunctionHasBranchProtectedScope();
10584 return OMPTargetParallelForDirective::Create(
10585 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10586 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10587}
10588
10589/// Check for existence of a map clause in the list of clauses.
10590static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10591 const OpenMPClauseKind K) {
10592 return llvm::any_of(
10593 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10594}
10595
10596template <typename... Params>
10597static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10598 const Params... ClauseTypes) {
10599 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10600}
10601
10602StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10603 Stmt *AStmt,
10604 SourceLocation StartLoc,
10605 SourceLocation EndLoc) {
10606 if (!AStmt)
10607 return StmtError();
10608
10609 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10609, __PRETTY_FUNCTION__))
;
10610
10611 // OpenMP [2.12.2, target data Construct, Restrictions]
10612 // At least one map, use_device_addr or use_device_ptr clause must appear on
10613 // the directive.
10614 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10615 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10616 StringRef Expected;
10617 if (LangOpts.OpenMP < 50)
10618 Expected = "'map' or 'use_device_ptr'";
10619 else
10620 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10621 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10622 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10623 return StmtError();
10624 }
10625
10626 setFunctionHasBranchProtectedScope();
10627
10628 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10629 AStmt);
10630}
10631
10632StmtResult
10633Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10634 SourceLocation StartLoc,
10635 SourceLocation EndLoc, Stmt *AStmt) {
10636 if (!AStmt)
10637 return StmtError();
10638
10639 auto *CS = cast<CapturedStmt>(AStmt);
10640 // 1.2.2 OpenMP Language Terminology
10641 // Structured block - An executable statement with a single entry at the
10642 // top and a single exit at the bottom.
10643 // The point of exit cannot be a branch out of the structured block.
10644 // longjmp() and throw() must not violate the entry/exit criteria.
10645 CS->getCapturedDecl()->setNothrow();
10646 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10647 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10648 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10649 // 1.2.2 OpenMP Language Terminology
10650 // Structured block - An executable statement with a single entry at the
10651 // top and a single exit at the bottom.
10652 // The point of exit cannot be a branch out of the structured block.
10653 // longjmp() and throw() must not violate the entry/exit criteria.
10654 CS->getCapturedDecl()->setNothrow();
10655 }
10656
10657 // OpenMP [2.10.2, Restrictions, p. 99]
10658 // At least one map clause must appear on the directive.
10659 if (!hasClauses(Clauses, OMPC_map)) {
10660 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10661 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10662 return StmtError();
10663 }
10664
10665 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10666 AStmt);
10667}
10668
10669StmtResult
10670Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10671 SourceLocation StartLoc,
10672 SourceLocation EndLoc, Stmt *AStmt) {
10673 if (!AStmt)
10674 return StmtError();
10675
10676 auto *CS = cast<CapturedStmt>(AStmt);
10677 // 1.2.2 OpenMP Language Terminology
10678 // Structured block - An executable statement with a single entry at the
10679 // top and a single exit at the bottom.
10680 // The point of exit cannot be a branch out of the structured block.
10681 // longjmp() and throw() must not violate the entry/exit criteria.
10682 CS->getCapturedDecl()->setNothrow();
10683 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10684 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10685 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10686 // 1.2.2 OpenMP Language Terminology
10687 // Structured block - An executable statement with a single entry at the
10688 // top and a single exit at the bottom.
10689 // The point of exit cannot be a branch out of the structured block.
10690 // longjmp() and throw() must not violate the entry/exit criteria.
10691 CS->getCapturedDecl()->setNothrow();
10692 }
10693
10694 // OpenMP [2.10.3, Restrictions, p. 102]
10695 // At least one map clause must appear on the directive.
10696 if (!hasClauses(Clauses, OMPC_map)) {
10697 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10698 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10699 return StmtError();
10700 }
10701
10702 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10703 AStmt);
10704}
10705
10706StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10707 SourceLocation StartLoc,
10708 SourceLocation EndLoc,
10709 Stmt *AStmt) {
10710 if (!AStmt)
10711 return StmtError();
10712
10713 auto *CS = cast<CapturedStmt>(AStmt);
10714 // 1.2.2 OpenMP Language Terminology
10715 // Structured block - An executable statement with a single entry at the
10716 // top and a single exit at the bottom.
10717 // The point of exit cannot be a branch out of the structured block.
10718 // longjmp() and throw() must not violate the entry/exit criteria.
10719 CS->getCapturedDecl()->setNothrow();
10720 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10721 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10722 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10723 // 1.2.2 OpenMP Language Terminology
10724 // Structured block - An executable statement with a single entry at the
10725 // top and a single exit at the bottom.
10726 // The point of exit cannot be a branch out of the structured block.
10727 // longjmp() and throw() must not violate the entry/exit criteria.
10728 CS->getCapturedDecl()->setNothrow();
10729 }
10730
10731 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10732 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10733 return StmtError();
10734 }
10735 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10736 AStmt);
10737}
10738
10739StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10740 Stmt *AStmt, SourceLocation StartLoc,
10741 SourceLocation EndLoc) {
10742 if (!AStmt)
10743 return StmtError();
10744
10745 auto *CS = cast<CapturedStmt>(AStmt);
10746 // 1.2.2 OpenMP Language Terminology
10747 // Structured block - An executable statement with a single entry at the
10748 // top and a single exit at the bottom.
10749 // The point of exit cannot be a branch out of the structured block.
10750 // longjmp() and throw() must not violate the entry/exit criteria.
10751 CS->getCapturedDecl()->setNothrow();
10752
10753 setFunctionHasBranchProtectedScope();
10754
10755 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10756
10757 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10758}
10759
10760StmtResult
10761Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10762 SourceLocation EndLoc,
10763 OpenMPDirectiveKind CancelRegion) {
10764 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10765 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10766 return StmtError();
10767 }
10768 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10769 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10770 return StmtError();
10771 }
10772 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10773 CancelRegion);
10774}
10775
10776StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10777 SourceLocation StartLoc,
10778 SourceLocation EndLoc,
10779 OpenMPDirectiveKind CancelRegion) {
10780 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10781 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10782 return StmtError();
10783 }
10784 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10785 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10786 return StmtError();
10787 }
10788 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
10789 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10790 CancelRegion);
10791}
10792
10793static bool checkGrainsizeNumTasksClauses(Sema &S,
10794 ArrayRef<OMPClause *> Clauses) {
10795 const OMPClause *PrevClause = nullptr;
10796 bool ErrorFound = false;
10797 for (const OMPClause *C : Clauses) {
10798 if (C->getClauseKind() == OMPC_grainsize ||
10799 C->getClauseKind() == OMPC_num_tasks) {
10800 if (!PrevClause)
10801 PrevClause = C;
10802 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10803 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10804 << getOpenMPClauseName(C->getClauseKind())
10805 << getOpenMPClauseName(PrevClause->getClauseKind());
10806 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10807 << getOpenMPClauseName(PrevClause->getClauseKind());
10808 ErrorFound = true;
10809 }
10810 }
10811 }
10812 return ErrorFound;
10813}
10814
10815static bool checkReductionClauseWithNogroup(Sema &S,
10816 ArrayRef<OMPClause *> Clauses) {
10817 const OMPClause *ReductionClause = nullptr;
10818 const OMPClause *NogroupClause = nullptr;
10819 for (const OMPClause *C : Clauses) {
10820 if (C->getClauseKind() == OMPC_reduction) {
10821 ReductionClause = C;
10822 if (NogroupClause)
10823 break;
10824 continue;
10825 }
10826 if (C->getClauseKind() == OMPC_nogroup) {
10827 NogroupClause = C;
10828 if (ReductionClause)
10829 break;
10830 continue;
10831 }
10832 }
10833 if (ReductionClause && NogroupClause) {
10834 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10835 << SourceRange(NogroupClause->getBeginLoc(),
10836 NogroupClause->getEndLoc());
10837 return true;
10838 }
10839 return false;
10840}
10841
10842StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10843 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10844 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10845 if (!AStmt)
10846 return StmtError();
10847
10848 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10848, __PRETTY_FUNCTION__))
;
10849 OMPLoopDirective::HelperExprs B;
10850 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10851 // define the nested loops number.
10852 unsigned NestedLoopCount =
10853 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10854 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10855 VarsWithImplicitDSA, B);
10856 if (NestedLoopCount == 0)
10857 return StmtError();
10858
10859 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10860, __PRETTY_FUNCTION__))
10860 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10860, __PRETTY_FUNCTION__))
;
10861
10862 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10863 // The grainsize clause and num_tasks clause are mutually exclusive and may
10864 // not appear on the same taskloop directive.
10865 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10866 return StmtError();
10867 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10868 // If a reduction clause is present on the taskloop directive, the nogroup
10869 // clause must not be specified.
10870 if (checkReductionClauseWithNogroup(*this, Clauses))
10871 return StmtError();
10872
10873 setFunctionHasBranchProtectedScope();
10874 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10875 NestedLoopCount, Clauses, AStmt, B,
10876 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10877}
10878
10879StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10880 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10881 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10882 if (!AStmt)
10883 return StmtError();
10884
10885 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10885, __PRETTY_FUNCTION__))
;
10886 OMPLoopDirective::HelperExprs B;
10887 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10888 // define the nested loops number.
10889 unsigned NestedLoopCount =
10890 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10891 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10892 VarsWithImplicitDSA, B);
10893 if (NestedLoopCount == 0)
10894 return StmtError();
10895
10896 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10897, __PRETTY_FUNCTION__))
10897 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10897, __PRETTY_FUNCTION__))
;
10898
10899 if (!CurContext->isDependentContext()) {
10900 // Finalize the clauses that need pre-built expressions for CodeGen.
10901 for (OMPClause *C : Clauses) {
10902 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10903 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10904 B.NumIterations, *this, CurScope,
10905 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10906 return StmtError();
10907 }
10908 }
10909
10910 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10911 // The grainsize clause and num_tasks clause are mutually exclusive and may
10912 // not appear on the same taskloop directive.
10913 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10914 return StmtError();
10915 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10916 // If a reduction clause is present on the taskloop directive, the nogroup
10917 // clause must not be specified.
10918 if (checkReductionClauseWithNogroup(*this, Clauses))
10919 return StmtError();
10920 if (checkSimdlenSafelenSpecified(*this, Clauses))
10921 return StmtError();
10922
10923 setFunctionHasBranchProtectedScope();
10924 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10925 NestedLoopCount, Clauses, AStmt, B);
10926}
10927
10928StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10929 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10930 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10931 if (!AStmt)
10932 return StmtError();
10933
10934 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10934, __PRETTY_FUNCTION__))
;
10935 OMPLoopDirective::HelperExprs B;
10936 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10937 // define the nested loops number.
10938 unsigned NestedLoopCount =
10939 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10940 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10941 VarsWithImplicitDSA, B);
10942 if (NestedLoopCount == 0)
10943 return StmtError();
10944
10945 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10946, __PRETTY_FUNCTION__))
10946 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10946, __PRETTY_FUNCTION__))
;
10947
10948 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10949 // The grainsize clause and num_tasks clause are mutually exclusive and may
10950 // not appear on the same taskloop directive.
10951 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10952 return StmtError();
10953 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10954 // If a reduction clause is present on the taskloop directive, the nogroup
10955 // clause must not be specified.
10956 if (checkReductionClauseWithNogroup(*this, Clauses))
10957 return StmtError();
10958
10959 setFunctionHasBranchProtectedScope();
10960 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10961 NestedLoopCount, Clauses, AStmt, B,
10962 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10963}
10964
10965StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10966 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10967 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10968 if (!AStmt)
10969 return StmtError();
10970
10971 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10971, __PRETTY_FUNCTION__))
;
10972 OMPLoopDirective::HelperExprs B;
10973 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10974 // define the nested loops number.
10975 unsigned NestedLoopCount =
10976 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10977 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10978 VarsWithImplicitDSA, B);
10979 if (NestedLoopCount == 0)
10980 return StmtError();
10981
10982 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10983, __PRETTY_FUNCTION__))
10983 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 10983, __PRETTY_FUNCTION__))
;
10984
10985 if (!CurContext->isDependentContext()) {
10986 // Finalize the clauses that need pre-built expressions for CodeGen.
10987 for (OMPClause *C : Clauses) {
10988 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10989 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10990 B.NumIterations, *this, CurScope,
10991 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10992 return StmtError();
10993 }
10994 }
10995
10996 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10997 // The grainsize clause and num_tasks clause are mutually exclusive and may
10998 // not appear on the same taskloop directive.
10999 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11000 return StmtError();
11001 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11002 // If a reduction clause is present on the taskloop directive, the nogroup
11003 // clause must not be specified.
11004 if (checkReductionClauseWithNogroup(*this, Clauses))
11005 return StmtError();
11006 if (checkSimdlenSafelenSpecified(*this, Clauses))
11007 return StmtError();
11008
11009 setFunctionHasBranchProtectedScope();
11010 return OMPMasterTaskLoopSimdDirective::Create(
11011 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11012}
11013
11014StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11015 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11016 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11017 if (!AStmt)
11018 return StmtError();
11019
11020 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11020, __PRETTY_FUNCTION__))
;
11021 auto *CS = cast<CapturedStmt>(AStmt);
11022 // 1.2.2 OpenMP Language Terminology
11023 // Structured block - An executable statement with a single entry at the
11024 // top and a single exit at the bottom.
11025 // The point of exit cannot be a branch out of the structured block.
11026 // longjmp() and throw() must not violate the entry/exit criteria.
11027 CS->getCapturedDecl()->setNothrow();
11028 for (int ThisCaptureLevel =
11029 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11030 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11031 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11032 // 1.2.2 OpenMP Language Terminology
11033 // Structured block - An executable statement with a single entry at the
11034 // top and a single exit at the bottom.
11035 // The point of exit cannot be a branch out of the structured block.
11036 // longjmp() and throw() must not violate the entry/exit criteria.
11037 CS->getCapturedDecl()->setNothrow();
11038 }
11039
11040 OMPLoopDirective::HelperExprs B;
11041 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11042 // define the nested loops number.
11043 unsigned NestedLoopCount = checkOpenMPLoop(
11044 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11045 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11046 VarsWithImplicitDSA, B);
11047 if (NestedLoopCount == 0)
11048 return StmtError();
11049
11050 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11051, __PRETTY_FUNCTION__))
11051 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11051, __PRETTY_FUNCTION__))
;
11052
11053 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11054 // The grainsize clause and num_tasks clause are mutually exclusive and may
11055 // not appear on the same taskloop directive.
11056 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11057 return StmtError();
11058 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11059 // If a reduction clause is present on the taskloop directive, the nogroup
11060 // clause must not be specified.
11061 if (checkReductionClauseWithNogroup(*this, Clauses))
11062 return StmtError();
11063
11064 setFunctionHasBranchProtectedScope();
11065 return OMPParallelMasterTaskLoopDirective::Create(
11066 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11067 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11068}
11069
11070StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11071 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11072 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11073 if (!AStmt)
11074 return StmtError();
11075
11076 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11076, __PRETTY_FUNCTION__))
;
11077 auto *CS = cast<CapturedStmt>(AStmt);
11078 // 1.2.2 OpenMP Language Terminology
11079 // Structured block - An executable statement with a single entry at the
11080 // top and a single exit at the bottom.
11081 // The point of exit cannot be a branch out of the structured block.
11082 // longjmp() and throw() must not violate the entry/exit criteria.
11083 CS->getCapturedDecl()->setNothrow();
11084 for (int ThisCaptureLevel =
11085 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11086 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11087 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11088 // 1.2.2 OpenMP Language Terminology
11089 // Structured block - An executable statement with a single entry at the
11090 // top and a single exit at the bottom.
11091 // The point of exit cannot be a branch out of the structured block.
11092 // longjmp() and throw() must not violate the entry/exit criteria.
11093 CS->getCapturedDecl()->setNothrow();
11094 }
11095
11096 OMPLoopDirective::HelperExprs B;
11097 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11098 // define the nested loops number.
11099 unsigned NestedLoopCount = checkOpenMPLoop(
11100 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11101 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11102 VarsWithImplicitDSA, B);
11103 if (NestedLoopCount == 0)
11104 return StmtError();
11105
11106 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11107, __PRETTY_FUNCTION__))
11107 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11107, __PRETTY_FUNCTION__))
;
11108
11109 if (!CurContext->isDependentContext()) {
11110 // Finalize the clauses that need pre-built expressions for CodeGen.
11111 for (OMPClause *C : Clauses) {
11112 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11113 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11114 B.NumIterations, *this, CurScope,
11115 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11116 return StmtError();
11117 }
11118 }
11119
11120 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11121 // The grainsize clause and num_tasks clause are mutually exclusive and may
11122 // not appear on the same taskloop directive.
11123 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11124 return StmtError();
11125 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11126 // If a reduction clause is present on the taskloop directive, the nogroup
11127 // clause must not be specified.
11128 if (checkReductionClauseWithNogroup(*this, Clauses))
11129 return StmtError();
11130 if (checkSimdlenSafelenSpecified(*this, Clauses))
11131 return StmtError();
11132
11133 setFunctionHasBranchProtectedScope();
11134 return OMPParallelMasterTaskLoopSimdDirective::Create(
11135 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11136}
11137
11138StmtResult Sema::ActOnOpenMPDistributeDirective(
11139 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11140 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11141 if (!AStmt)
11142 return StmtError();
11143
11144 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11144, __PRETTY_FUNCTION__))
;
11145 OMPLoopDirective::HelperExprs B;
11146 // In presence of clause 'collapse' with number of loops, it will
11147 // define the nested loops number.
11148 unsigned NestedLoopCount =
11149 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11150 nullptr /*ordered not a clause on distribute*/, AStmt,
11151 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11152 if (NestedLoopCount == 0)
11153 return StmtError();
11154
11155 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11156, __PRETTY_FUNCTION__))
11156 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11156, __PRETTY_FUNCTION__))
;
11157
11158 setFunctionHasBranchProtectedScope();
11159 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11160 NestedLoopCount, Clauses, AStmt, B);
11161}
11162
11163StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11164 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11165 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11166 if (!AStmt)
11167 return StmtError();
11168
11169 auto *CS = cast<CapturedStmt>(AStmt);
11170 // 1.2.2 OpenMP Language Terminology
11171 // Structured block - An executable statement with a single entry at the
11172 // top and a single exit at the bottom.
11173 // The point of exit cannot be a branch out of the structured block.
11174 // longjmp() and throw() must not violate the entry/exit criteria.
11175 CS->getCapturedDecl()->setNothrow();
11176 for (int ThisCaptureLevel =
11177 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11178 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11179 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11180 // 1.2.2 OpenMP Language Terminology
11181 // Structured block - An executable statement with a single entry at the
11182 // top and a single exit at the bottom.
11183 // The point of exit cannot be a branch out of the structured block.
11184 // longjmp() and throw() must not violate the entry/exit criteria.
11185 CS->getCapturedDecl()->setNothrow();
11186 }
11187
11188 OMPLoopDirective::HelperExprs B;
11189 // In presence of clause 'collapse' with number of loops, it will
11190 // define the nested loops number.
11191 unsigned NestedLoopCount = checkOpenMPLoop(
11192 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11193 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11194 VarsWithImplicitDSA, B);
11195 if (NestedLoopCount == 0)
11196 return StmtError();
11197
11198 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11199, __PRETTY_FUNCTION__))
11199 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11199, __PRETTY_FUNCTION__))
;
11200
11201 setFunctionHasBranchProtectedScope();
11202 return OMPDistributeParallelForDirective::Create(
11203 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11204 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11205}
11206
11207StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11208 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11209 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11210 if (!AStmt)
11211 return StmtError();
11212
11213 auto *CS = cast<CapturedStmt>(AStmt);
11214 // 1.2.2 OpenMP Language Terminology
11215 // Structured block - An executable statement with a single entry at the
11216 // top and a single exit at the bottom.
11217 // The point of exit cannot be a branch out of the structured block.
11218 // longjmp() and throw() must not violate the entry/exit criteria.
11219 CS->getCapturedDecl()->setNothrow();
11220 for (int ThisCaptureLevel =
11221 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11222 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11223 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11224 // 1.2.2 OpenMP Language Terminology
11225 // Structured block - An executable statement with a single entry at the
11226 // top and a single exit at the bottom.
11227 // The point of exit cannot be a branch out of the structured block.
11228 // longjmp() and throw() must not violate the entry/exit criteria.
11229 CS->getCapturedDecl()->setNothrow();
11230 }
11231
11232 OMPLoopDirective::HelperExprs B;
11233 // In presence of clause 'collapse' with number of loops, it will
11234 // define the nested loops number.
11235 unsigned NestedLoopCount = checkOpenMPLoop(
11236 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11237 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11238 VarsWithImplicitDSA, B);
11239 if (NestedLoopCount == 0)
11240 return StmtError();
11241
11242 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11243, __PRETTY_FUNCTION__))
11243 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11243, __PRETTY_FUNCTION__))
;
11244
11245 if (!CurContext->isDependentContext()) {
11246 // Finalize the clauses that need pre-built expressions for CodeGen.
11247 for (OMPClause *C : Clauses) {
11248 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11249 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11250 B.NumIterations, *this, CurScope,
11251 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11252 return StmtError();
11253 }
11254 }
11255
11256 if (checkSimdlenSafelenSpecified(*this, Clauses))
11257 return StmtError();
11258
11259 setFunctionHasBranchProtectedScope();
11260 return OMPDistributeParallelForSimdDirective::Create(
11261 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11262}
11263
11264StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11265 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11266 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11267 if (!AStmt)
11268 return StmtError();
11269
11270 auto *CS = cast<CapturedStmt>(AStmt);
11271 // 1.2.2 OpenMP Language Terminology
11272 // Structured block - An executable statement with a single entry at the
11273 // top and a single exit at the bottom.
11274 // The point of exit cannot be a branch out of the structured block.
11275 // longjmp() and throw() must not violate the entry/exit criteria.
11276 CS->getCapturedDecl()->setNothrow();
11277 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11278 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11279 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11280 // 1.2.2 OpenMP Language Terminology
11281 // Structured block - An executable statement with a single entry at the
11282 // top and a single exit at the bottom.
11283 // The point of exit cannot be a branch out of the structured block.
11284 // longjmp() and throw() must not violate the entry/exit criteria.
11285 CS->getCapturedDecl()->setNothrow();
11286 }
11287
11288 OMPLoopDirective::HelperExprs B;
11289 // In presence of clause 'collapse' with number of loops, it will
11290 // define the nested loops number.
11291 unsigned NestedLoopCount =
11292 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11293 nullptr /*ordered not a clause on distribute*/, CS, *this,
11294 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11295 if (NestedLoopCount == 0)
11296 return StmtError();
11297
11298 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11299, __PRETTY_FUNCTION__))
11299 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11299, __PRETTY_FUNCTION__))
;
11300
11301 if (!CurContext->isDependentContext()) {
11302 // Finalize the clauses that need pre-built expressions for CodeGen.
11303 for (OMPClause *C : Clauses) {
11304 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11305 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11306 B.NumIterations, *this, CurScope,
11307 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11308 return StmtError();
11309 }
11310 }
11311
11312 if (checkSimdlenSafelenSpecified(*this, Clauses))
11313 return StmtError();
11314
11315 setFunctionHasBranchProtectedScope();
11316 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11317 NestedLoopCount, Clauses, AStmt, B);
11318}
11319
11320StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11321 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11322 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11323 if (!AStmt)
11324 return StmtError();
11325
11326 auto *CS = cast<CapturedStmt>(AStmt);
11327 // 1.2.2 OpenMP Language Terminology
11328 // Structured block - An executable statement with a single entry at the
11329 // top and a single exit at the bottom.
11330 // The point of exit cannot be a branch out of the structured block.
11331 // longjmp() and throw() must not violate the entry/exit criteria.
11332 CS->getCapturedDecl()->setNothrow();
11333 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11334 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11335 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11336 // 1.2.2 OpenMP Language Terminology
11337 // Structured block - An executable statement with a single entry at the
11338 // top and a single exit at the bottom.
11339 // The point of exit cannot be a branch out of the structured block.
11340 // longjmp() and throw() must not violate the entry/exit criteria.
11341 CS->getCapturedDecl()->setNothrow();
11342 }
11343
11344 OMPLoopDirective::HelperExprs B;
11345 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11346 // define the nested loops number.
11347 unsigned NestedLoopCount = checkOpenMPLoop(
11348 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11349 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11350 VarsWithImplicitDSA, B);
11351 if (NestedLoopCount == 0)
11352 return StmtError();
11353
11354 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11355, __PRETTY_FUNCTION__))
11355 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11355, __PRETTY_FUNCTION__))
;
11356
11357 if (!CurContext->isDependentContext()) {
11358 // Finalize the clauses that need pre-built expressions for CodeGen.
11359 for (OMPClause *C : Clauses) {
11360 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11361 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11362 B.NumIterations, *this, CurScope,
11363 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11364 return StmtError();
11365 }
11366 }
11367 if (checkSimdlenSafelenSpecified(*this, Clauses))
11368 return StmtError();
11369
11370 setFunctionHasBranchProtectedScope();
11371 return OMPTargetParallelForSimdDirective::Create(
11372 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11373}
11374
11375StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11376 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11377 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11378 if (!AStmt)
11379 return StmtError();
11380
11381 auto *CS = cast<CapturedStmt>(AStmt);
11382 // 1.2.2 OpenMP Language Terminology
11383 // Structured block - An executable statement with a single entry at the
11384 // top and a single exit at the bottom.
11385 // The point of exit cannot be a branch out of the structured block.
11386 // longjmp() and throw() must not violate the entry/exit criteria.
11387 CS->getCapturedDecl()->setNothrow();
11388 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11389 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11390 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11391 // 1.2.2 OpenMP Language Terminology
11392 // Structured block - An executable statement with a single entry at the
11393 // top and a single exit at the bottom.
11394 // The point of exit cannot be a branch out of the structured block.
11395 // longjmp() and throw() must not violate the entry/exit criteria.
11396 CS->getCapturedDecl()->setNothrow();
11397 }
11398
11399 OMPLoopDirective::HelperExprs B;
11400 // In presence of clause 'collapse' with number of loops, it will define the
11401 // nested loops number.
11402 unsigned NestedLoopCount =
11403 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11404 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11405 VarsWithImplicitDSA, B);
11406 if (NestedLoopCount == 0)
11407 return StmtError();
11408
11409 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11410, __PRETTY_FUNCTION__))
11410 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11410, __PRETTY_FUNCTION__))
;
11411
11412 if (!CurContext->isDependentContext()) {
11413 // Finalize the clauses that need pre-built expressions for CodeGen.
11414 for (OMPClause *C : Clauses) {
11415 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11416 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11417 B.NumIterations, *this, CurScope,
11418 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11419 return StmtError();
11420 }
11421 }
11422
11423 if (checkSimdlenSafelenSpecified(*this, Clauses))
11424 return StmtError();
11425
11426 setFunctionHasBranchProtectedScope();
11427 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11428 NestedLoopCount, Clauses, AStmt, B);
11429}
11430
11431StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11432 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11433 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11434 if (!AStmt)
11435 return StmtError();
11436
11437 auto *CS = cast<CapturedStmt>(AStmt);
11438 // 1.2.2 OpenMP Language Terminology
11439 // Structured block - An executable statement with a single entry at the
11440 // top and a single exit at the bottom.
11441 // The point of exit cannot be a branch out of the structured block.
11442 // longjmp() and throw() must not violate the entry/exit criteria.
11443 CS->getCapturedDecl()->setNothrow();
11444 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11445 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11446 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11447 // 1.2.2 OpenMP Language Terminology
11448 // Structured block - An executable statement with a single entry at the
11449 // top and a single exit at the bottom.
11450 // The point of exit cannot be a branch out of the structured block.
11451 // longjmp() and throw() must not violate the entry/exit criteria.
11452 CS->getCapturedDecl()->setNothrow();
11453 }
11454
11455 OMPLoopDirective::HelperExprs B;
11456 // In presence of clause 'collapse' with number of loops, it will
11457 // define the nested loops number.
11458 unsigned NestedLoopCount =
11459 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11460 nullptr /*ordered not a clause on distribute*/, CS, *this,
11461 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11462 if (NestedLoopCount == 0)
11463 return StmtError();
11464
11465 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11466, __PRETTY_FUNCTION__))
11466 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11466, __PRETTY_FUNCTION__))
;
11467
11468 setFunctionHasBranchProtectedScope();
11469
11470 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11471
11472 return OMPTeamsDistributeDirective::Create(
11473 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11474}
11475
11476StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11477 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11478 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11479 if (!AStmt)
11480 return StmtError();
11481
11482 auto *CS = cast<CapturedStmt>(AStmt);
11483 // 1.2.2 OpenMP Language Terminology
11484 // Structured block - An executable statement with a single entry at the
11485 // top and a single exit at the bottom.
11486 // The point of exit cannot be a branch out of the structured block.
11487 // longjmp() and throw() must not violate the entry/exit criteria.
11488 CS->getCapturedDecl()->setNothrow();
11489 for (int ThisCaptureLevel =
11490 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11491 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11492 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11493 // 1.2.2 OpenMP Language Terminology
11494 // Structured block - An executable statement with a single entry at the
11495 // top and a single exit at the bottom.
11496 // The point of exit cannot be a branch out of the structured block.
11497 // longjmp() and throw() must not violate the entry/exit criteria.
11498 CS->getCapturedDecl()->setNothrow();
11499 }
11500
11501 OMPLoopDirective::HelperExprs B;
11502 // In presence of clause 'collapse' with number of loops, it will
11503 // define the nested loops number.
11504 unsigned NestedLoopCount = checkOpenMPLoop(
11505 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11506 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11507 VarsWithImplicitDSA, B);
11508
11509 if (NestedLoopCount == 0)
11510 return StmtError();
11511
11512 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11513, __PRETTY_FUNCTION__))
11513 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11513, __PRETTY_FUNCTION__))
;
11514
11515 if (!CurContext->isDependentContext()) {
11516 // Finalize the clauses that need pre-built expressions for CodeGen.
11517 for (OMPClause *C : Clauses) {
11518 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11519 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11520 B.NumIterations, *this, CurScope,
11521 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11522 return StmtError();
11523 }
11524 }
11525
11526 if (checkSimdlenSafelenSpecified(*this, Clauses))
11527 return StmtError();
11528
11529 setFunctionHasBranchProtectedScope();
11530
11531 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11532
11533 return OMPTeamsDistributeSimdDirective::Create(
11534 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11535}
11536
11537StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11538 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11539 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11540 if (!AStmt)
11541 return StmtError();
11542
11543 auto *CS = cast<CapturedStmt>(AStmt);
11544 // 1.2.2 OpenMP Language Terminology
11545 // Structured block - An executable statement with a single entry at the
11546 // top and a single exit at the bottom.
11547 // The point of exit cannot be a branch out of the structured block.
11548 // longjmp() and throw() must not violate the entry/exit criteria.
11549 CS->getCapturedDecl()->setNothrow();
11550
11551 for (int ThisCaptureLevel =
11552 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11553 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11554 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11555 // 1.2.2 OpenMP Language Terminology
11556 // Structured block - An executable statement with a single entry at the
11557 // top and a single exit at the bottom.
11558 // The point of exit cannot be a branch out of the structured block.
11559 // longjmp() and throw() must not violate the entry/exit criteria.
11560 CS->getCapturedDecl()->setNothrow();
11561 }
11562
11563 OMPLoopDirective::HelperExprs B;
11564 // In presence of clause 'collapse' with number of loops, it will
11565 // define the nested loops number.
11566 unsigned NestedLoopCount = checkOpenMPLoop(
11567 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11568 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11569 VarsWithImplicitDSA, B);
11570
11571 if (NestedLoopCount == 0)
11572 return StmtError();
11573
11574 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11575, __PRETTY_FUNCTION__))
11575 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11575, __PRETTY_FUNCTION__))
;
11576
11577 if (!CurContext->isDependentContext()) {
11578 // Finalize the clauses that need pre-built expressions for CodeGen.
11579 for (OMPClause *C : Clauses) {
11580 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11581 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11582 B.NumIterations, *this, CurScope,
11583 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11584 return StmtError();
11585 }
11586 }
11587
11588 if (checkSimdlenSafelenSpecified(*this, Clauses))
11589 return StmtError();
11590
11591 setFunctionHasBranchProtectedScope();
11592
11593 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11594
11595 return OMPTeamsDistributeParallelForSimdDirective::Create(
11596 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11597}
11598
11599StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11600 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11601 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11602 if (!AStmt)
11603 return StmtError();
11604
11605 auto *CS = cast<CapturedStmt>(AStmt);
11606 // 1.2.2 OpenMP Language Terminology
11607 // Structured block - An executable statement with a single entry at the
11608 // top and a single exit at the bottom.
11609 // The point of exit cannot be a branch out of the structured block.
11610 // longjmp() and throw() must not violate the entry/exit criteria.
11611 CS->getCapturedDecl()->setNothrow();
11612
11613 for (int ThisCaptureLevel =
11614 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11615 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11616 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11617 // 1.2.2 OpenMP Language Terminology
11618 // Structured block - An executable statement with a single entry at the
11619 // top and a single exit at the bottom.
11620 // The point of exit cannot be a branch out of the structured block.
11621 // longjmp() and throw() must not violate the entry/exit criteria.
11622 CS->getCapturedDecl()->setNothrow();
11623 }
11624
11625 OMPLoopDirective::HelperExprs B;
11626 // In presence of clause 'collapse' with number of loops, it will
11627 // define the nested loops number.
11628 unsigned NestedLoopCount = checkOpenMPLoop(
11629 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11630 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11631 VarsWithImplicitDSA, B);
11632
11633 if (NestedLoopCount == 0)
11634 return StmtError();
11635
11636 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11637, __PRETTY_FUNCTION__))
11637 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11637, __PRETTY_FUNCTION__))
;
11638
11639 setFunctionHasBranchProtectedScope();
11640
11641 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11642
11643 return OMPTeamsDistributeParallelForDirective::Create(
11644 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11645 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11646}
11647
11648StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11649 Stmt *AStmt,
11650 SourceLocation StartLoc,
11651 SourceLocation EndLoc) {
11652 if (!AStmt)
11653 return StmtError();
11654
11655 auto *CS = cast<CapturedStmt>(AStmt);
11656 // 1.2.2 OpenMP Language Terminology
11657 // Structured block - An executable statement with a single entry at the
11658 // top and a single exit at the bottom.
11659 // The point of exit cannot be a branch out of the structured block.
11660 // longjmp() and throw() must not violate the entry/exit criteria.
11661 CS->getCapturedDecl()->setNothrow();
11662
11663 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11664 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11665 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11666 // 1.2.2 OpenMP Language Terminology
11667 // Structured block - An executable statement with a single entry at the
11668 // top and a single exit at the bottom.
11669 // The point of exit cannot be a branch out of the structured block.
11670 // longjmp() and throw() must not violate the entry/exit criteria.
11671 CS->getCapturedDecl()->setNothrow();
11672 }
11673 setFunctionHasBranchProtectedScope();
11674
11675 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11676 AStmt);
11677}
11678
11679StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11680 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11681 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11682 if (!AStmt)
11683 return StmtError();
11684
11685 auto *CS = cast<CapturedStmt>(AStmt);
11686 // 1.2.2 OpenMP Language Terminology
11687 // Structured block - An executable statement with a single entry at the
11688 // top and a single exit at the bottom.
11689 // The point of exit cannot be a branch out of the structured block.
11690 // longjmp() and throw() must not violate the entry/exit criteria.
11691 CS->getCapturedDecl()->setNothrow();
11692 for (int ThisCaptureLevel =
11693 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11694 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11695 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11696 // 1.2.2 OpenMP Language Terminology
11697 // Structured block - An executable statement with a single entry at the
11698 // top and a single exit at the bottom.
11699 // The point of exit cannot be a branch out of the structured block.
11700 // longjmp() and throw() must not violate the entry/exit criteria.
11701 CS->getCapturedDecl()->setNothrow();
11702 }
11703
11704 OMPLoopDirective::HelperExprs B;
11705 // In presence of clause 'collapse' with number of loops, it will
11706 // define the nested loops number.
11707 unsigned NestedLoopCount = checkOpenMPLoop(
11708 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11709 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11710 VarsWithImplicitDSA, B);
11711 if (NestedLoopCount == 0)
11712 return StmtError();
11713
11714 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11715, __PRETTY_FUNCTION__))
11715 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11715, __PRETTY_FUNCTION__))
;
11716
11717 setFunctionHasBranchProtectedScope();
11718 return OMPTargetTeamsDistributeDirective::Create(
11719 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11720}
11721
11722StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11723 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11724 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11725 if (!AStmt)
11726 return StmtError();
11727
11728 auto *CS = cast<CapturedStmt>(AStmt);
11729 // 1.2.2 OpenMP Language Terminology
11730 // Structured block - An executable statement with a single entry at the
11731 // top and a single exit at the bottom.
11732 // The point of exit cannot be a branch out of the structured block.
11733 // longjmp() and throw() must not violate the entry/exit criteria.
11734 CS->getCapturedDecl()->setNothrow();
11735 for (int ThisCaptureLevel =
11736 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11737 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11738 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11739 // 1.2.2 OpenMP Language Terminology
11740 // Structured block - An executable statement with a single entry at the
11741 // top and a single exit at the bottom.
11742 // The point of exit cannot be a branch out of the structured block.
11743 // longjmp() and throw() must not violate the entry/exit criteria.
11744 CS->getCapturedDecl()->setNothrow();
11745 }
11746
11747 OMPLoopDirective::HelperExprs B;
11748 // In presence of clause 'collapse' with number of loops, it will
11749 // define the nested loops number.
11750 unsigned NestedLoopCount = checkOpenMPLoop(
11751 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11752 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11753 VarsWithImplicitDSA, B);
11754 if (NestedLoopCount == 0)
11755 return StmtError();
11756
11757 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11758, __PRETTY_FUNCTION__))
11758 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11758, __PRETTY_FUNCTION__))
;
11759
11760 if (!CurContext->isDependentContext()) {
11761 // Finalize the clauses that need pre-built expressions for CodeGen.
11762 for (OMPClause *C : Clauses) {
11763 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11764 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11765 B.NumIterations, *this, CurScope,
11766 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11767 return StmtError();
11768 }
11769 }
11770
11771 setFunctionHasBranchProtectedScope();
11772 return OMPTargetTeamsDistributeParallelForDirective::Create(
11773 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11774 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11775}
11776
11777StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11778 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11779 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11780 if (!AStmt)
11781 return StmtError();
11782
11783 auto *CS = cast<CapturedStmt>(AStmt);
11784 // 1.2.2 OpenMP Language Terminology
11785 // Structured block - An executable statement with a single entry at the
11786 // top and a single exit at the bottom.
11787 // The point of exit cannot be a branch out of the structured block.
11788 // longjmp() and throw() must not violate the entry/exit criteria.
11789 CS->getCapturedDecl()->setNothrow();
11790 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11791 OMPD_target_teams_distribute_parallel_for_simd);
11792 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11793 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11794 // 1.2.2 OpenMP Language Terminology
11795 // Structured block - An executable statement with a single entry at the
11796 // top and a single exit at the bottom.
11797 // The point of exit cannot be a branch out of the structured block.
11798 // longjmp() and throw() must not violate the entry/exit criteria.
11799 CS->getCapturedDecl()->setNothrow();
11800 }
11801
11802 OMPLoopDirective::HelperExprs B;
11803 // In presence of clause 'collapse' with number of loops, it will
11804 // define the nested loops number.
11805 unsigned NestedLoopCount =
11806 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11807 getCollapseNumberExpr(Clauses),
11808 nullptr /*ordered not a clause on distribute*/, CS, *this,
11809 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11810 if (NestedLoopCount == 0)
11811 return StmtError();
11812
11813 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11815, __PRETTY_FUNCTION__))
11814 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11815, __PRETTY_FUNCTION__))
11815 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11815, __PRETTY_FUNCTION__))
;
11816
11817 if (!CurContext->isDependentContext()) {
11818 // Finalize the clauses that need pre-built expressions for CodeGen.
11819 for (OMPClause *C : Clauses) {
11820 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11821 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11822 B.NumIterations, *this, CurScope,
11823 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11824 return StmtError();
11825 }
11826 }
11827
11828 if (checkSimdlenSafelenSpecified(*this, Clauses))
11829 return StmtError();
11830
11831 setFunctionHasBranchProtectedScope();
11832 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11833 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11834}
11835
11836StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11837 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11838 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11839 if (!AStmt)
11840 return StmtError();
11841
11842 auto *CS = cast<CapturedStmt>(AStmt);
11843 // 1.2.2 OpenMP Language Terminology
11844 // Structured block - An executable statement with a single entry at the
11845 // top and a single exit at the bottom.
11846 // The point of exit cannot be a branch out of the structured block.
11847 // longjmp() and throw() must not violate the entry/exit criteria.
11848 CS->getCapturedDecl()->setNothrow();
11849 for (int ThisCaptureLevel =
11850 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11851 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11852 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11853 // 1.2.2 OpenMP Language Terminology
11854 // Structured block - An executable statement with a single entry at the
11855 // top and a single exit at the bottom.
11856 // The point of exit cannot be a branch out of the structured block.
11857 // longjmp() and throw() must not violate the entry/exit criteria.
11858 CS->getCapturedDecl()->setNothrow();
11859 }
11860
11861 OMPLoopDirective::HelperExprs B;
11862 // In presence of clause 'collapse' with number of loops, it will
11863 // define the nested loops number.
11864 unsigned NestedLoopCount = checkOpenMPLoop(
11865 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11866 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11867 VarsWithImplicitDSA, B);
11868 if (NestedLoopCount == 0)
11869 return StmtError();
11870
11871 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11872, __PRETTY_FUNCTION__))
11872 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 11872, __PRETTY_FUNCTION__))
;
11873
11874 if (!CurContext->isDependentContext()) {
11875 // Finalize the clauses that need pre-built expressions for CodeGen.
11876 for (OMPClause *C : Clauses) {
11877 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11878 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11879 B.NumIterations, *this, CurScope,
11880 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11881 return StmtError();
11882 }
11883 }
11884
11885 if (checkSimdlenSafelenSpecified(*this, Clauses))
11886 return StmtError();
11887
11888 setFunctionHasBranchProtectedScope();
11889 return OMPTargetTeamsDistributeSimdDirective::Create(
11890 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11891}
11892
11893OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11894 SourceLocation StartLoc,
11895 SourceLocation LParenLoc,
11896 SourceLocation EndLoc) {
11897 OMPClause *Res = nullptr;
11898 switch (Kind) {
11899 case OMPC_final:
11900 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11901 break;
11902 case OMPC_num_threads:
11903 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11904 break;
11905 case OMPC_safelen:
11906 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11907 break;
11908 case OMPC_simdlen:
11909 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11910 break;
11911 case OMPC_allocator:
11912 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11913 break;
11914 case OMPC_collapse:
11915 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11916 break;
11917 case OMPC_ordered:
11918 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11919 break;
11920 case OMPC_num_teams:
11921 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11922 break;
11923 case OMPC_thread_limit:
11924 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11925 break;
11926 case OMPC_priority:
11927 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11928 break;
11929 case OMPC_grainsize:
11930 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11931 break;
11932 case OMPC_num_tasks:
11933 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11934 break;
11935 case OMPC_hint:
11936 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11937 break;
11938 case OMPC_depobj:
11939 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11940 break;
11941 case OMPC_detach:
11942 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11943 break;
11944 case OMPC_device:
11945 case OMPC_if:
11946 case OMPC_default:
11947 case OMPC_proc_bind:
11948 case OMPC_schedule:
11949 case OMPC_private:
11950 case OMPC_firstprivate:
11951 case OMPC_lastprivate:
11952 case OMPC_shared:
11953 case OMPC_reduction:
11954 case OMPC_task_reduction:
11955 case OMPC_in_reduction:
11956 case OMPC_linear:
11957 case OMPC_aligned:
11958 case OMPC_copyin:
11959 case OMPC_copyprivate:
11960 case OMPC_nowait:
11961 case OMPC_untied:
11962 case OMPC_mergeable:
11963 case OMPC_threadprivate:
11964 case OMPC_allocate:
11965 case OMPC_flush:
11966 case OMPC_read:
11967 case OMPC_write:
11968 case OMPC_update:
11969 case OMPC_capture:
11970 case OMPC_seq_cst:
11971 case OMPC_acq_rel:
11972 case OMPC_acquire:
11973 case OMPC_release:
11974 case OMPC_relaxed:
11975 case OMPC_depend:
11976 case OMPC_threads:
11977 case OMPC_simd:
11978 case OMPC_map:
11979 case OMPC_nogroup:
11980 case OMPC_dist_schedule:
11981 case OMPC_defaultmap:
11982 case OMPC_unknown:
11983 case OMPC_uniform:
11984 case OMPC_to:
11985 case OMPC_from:
11986 case OMPC_use_device_ptr:
11987 case OMPC_use_device_addr:
11988 case OMPC_is_device_ptr:
11989 case OMPC_unified_address:
11990 case OMPC_unified_shared_memory:
11991 case OMPC_reverse_offload:
11992 case OMPC_dynamic_allocators:
11993 case OMPC_atomic_default_mem_order:
11994 case OMPC_device_type:
11995 case OMPC_match:
11996 case OMPC_nontemporal:
11997 case OMPC_order:
11998 case OMPC_destroy:
11999 case OMPC_inclusive:
12000 case OMPC_exclusive:
12001 case OMPC_uses_allocators:
12002 case OMPC_affinity:
12003 default:
12004 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12004)
;
12005 }
12006 return Res;
12007}
12008
12009// An OpenMP directive such as 'target parallel' has two captured regions:
12010// for the 'target' and 'parallel' respectively. This function returns
12011// the region in which to capture expressions associated with a clause.
12012// A return value of OMPD_unknown signifies that the expression should not
12013// be captured.
12014static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
12015 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
12016 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
12017 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12018 switch (CKind) {
12019 case OMPC_if:
12020 switch (DKind) {
12021 case OMPD_target_parallel_for_simd:
12022 if (OpenMPVersion >= 50 &&
12023 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12024 CaptureRegion = OMPD_parallel;
12025 break;
12026 }
12027 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12028 case OMPD_target_parallel:
12029 case OMPD_target_parallel_for:
12030 // If this clause applies to the nested 'parallel' region, capture within
12031 // the 'target' region, otherwise do not capture.
12032 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12033 CaptureRegion = OMPD_target;
12034 break;
12035 case OMPD_target_teams_distribute_parallel_for_simd:
12036 if (OpenMPVersion >= 50 &&
12037 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12038 CaptureRegion = OMPD_parallel;
12039 break;
12040 }
12041 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12042 case OMPD_target_teams_distribute_parallel_for:
12043 // If this clause applies to the nested 'parallel' region, capture within
12044 // the 'teams' region, otherwise do not capture.
12045 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12046 CaptureRegion = OMPD_teams;
12047 break;
12048 case OMPD_teams_distribute_parallel_for_simd:
12049 if (OpenMPVersion >= 50 &&
12050 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12051 CaptureRegion = OMPD_parallel;
12052 break;
12053 }
12054 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12055 case OMPD_teams_distribute_parallel_for:
12056 CaptureRegion = OMPD_teams;
12057 break;
12058 case OMPD_target_update:
12059 case OMPD_target_enter_data:
12060 case OMPD_target_exit_data:
12061 CaptureRegion = OMPD_task;
12062 break;
12063 case OMPD_parallel_master_taskloop:
12064 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
12065 CaptureRegion = OMPD_parallel;
12066 break;
12067 case OMPD_parallel_master_taskloop_simd:
12068 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
12069 NameModifier == OMPD_taskloop) {
12070 CaptureRegion = OMPD_parallel;
12071 break;
12072 }
12073 if (OpenMPVersion <= 45)
12074 break;
12075 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12076 CaptureRegion = OMPD_taskloop;
12077 break;
12078 case OMPD_parallel_for_simd:
12079 if (OpenMPVersion <= 45)
12080 break;
12081 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12082 CaptureRegion = OMPD_parallel;
12083 break;
12084 case OMPD_taskloop_simd:
12085 case OMPD_master_taskloop_simd:
12086 if (OpenMPVersion <= 45)
12087 break;
12088 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12089 CaptureRegion = OMPD_taskloop;
12090 break;
12091 case OMPD_distribute_parallel_for_simd:
12092 if (OpenMPVersion <= 45)
12093 break;
12094 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12095 CaptureRegion = OMPD_parallel;
12096 break;
12097 case OMPD_target_simd:
12098 if (OpenMPVersion >= 50 &&
12099 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12100 CaptureRegion = OMPD_target;
12101 break;
12102 case OMPD_teams_distribute_simd:
12103 case OMPD_target_teams_distribute_simd:
12104 if (OpenMPVersion >= 50 &&
12105 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12106 CaptureRegion = OMPD_teams;
12107 break;
12108 case OMPD_cancel:
12109 case OMPD_parallel:
12110 case OMPD_parallel_master:
12111 case OMPD_parallel_sections:
12112 case OMPD_parallel_for:
12113 case OMPD_target:
12114 case OMPD_target_teams:
12115 case OMPD_target_teams_distribute:
12116 case OMPD_distribute_parallel_for:
12117 case OMPD_task:
12118 case OMPD_taskloop:
12119 case OMPD_master_taskloop:
12120 case OMPD_target_data:
12121 case OMPD_simd:
12122 case OMPD_for_simd:
12123 case OMPD_distribute_simd:
12124 // Do not capture if-clause expressions.
12125 break;
12126 case OMPD_threadprivate:
12127 case OMPD_allocate:
12128 case OMPD_taskyield:
12129 case OMPD_barrier:
12130 case OMPD_taskwait:
12131 case OMPD_cancellation_point:
12132 case OMPD_flush:
12133 case OMPD_depobj:
12134 case OMPD_scan:
12135 case OMPD_declare_reduction:
12136 case OMPD_declare_mapper:
12137 case OMPD_declare_simd:
12138 case OMPD_declare_variant:
12139 case OMPD_begin_declare_variant:
12140 case OMPD_end_declare_variant:
12141 case OMPD_declare_target:
12142 case OMPD_end_declare_target:
12143 case OMPD_teams:
12144 case OMPD_for:
12145 case OMPD_sections:
12146 case OMPD_section:
12147 case OMPD_single:
12148 case OMPD_master:
12149 case OMPD_critical:
12150 case OMPD_taskgroup:
12151 case OMPD_distribute:
12152 case OMPD_ordered:
12153 case OMPD_atomic:
12154 case OMPD_teams_distribute:
12155 case OMPD_requires:
12156 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12156)
;
12157 case OMPD_unknown:
12158 default:
12159 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12159)
;
12160 }
12161 break;
12162 case OMPC_num_threads:
12163 switch (DKind) {
12164 case OMPD_target_parallel:
12165 case OMPD_target_parallel_for:
12166 case OMPD_target_parallel_for_simd:
12167 CaptureRegion = OMPD_target;
12168 break;
12169 case OMPD_teams_distribute_parallel_for:
12170 case OMPD_teams_distribute_parallel_for_simd:
12171 case OMPD_target_teams_distribute_parallel_for:
12172 case OMPD_target_teams_distribute_parallel_for_simd:
12173 CaptureRegion = OMPD_teams;
12174 break;
12175 case OMPD_parallel:
12176 case OMPD_parallel_master:
12177 case OMPD_parallel_sections:
12178 case OMPD_parallel_for:
12179 case OMPD_parallel_for_simd:
12180 case OMPD_distribute_parallel_for:
12181 case OMPD_distribute_parallel_for_simd:
12182 case OMPD_parallel_master_taskloop:
12183 case OMPD_parallel_master_taskloop_simd:
12184 // Do not capture num_threads-clause expressions.
12185 break;
12186 case OMPD_target_data:
12187 case OMPD_target_enter_data:
12188 case OMPD_target_exit_data:
12189 case OMPD_target_update:
12190 case OMPD_target:
12191 case OMPD_target_simd:
12192 case OMPD_target_teams:
12193 case OMPD_target_teams_distribute:
12194 case OMPD_target_teams_distribute_simd:
12195 case OMPD_cancel:
12196 case OMPD_task:
12197 case OMPD_taskloop:
12198 case OMPD_taskloop_simd:
12199 case OMPD_master_taskloop:
12200 case OMPD_master_taskloop_simd:
12201 case OMPD_threadprivate:
12202 case OMPD_allocate:
12203 case OMPD_taskyield:
12204 case OMPD_barrier:
12205 case OMPD_taskwait:
12206 case OMPD_cancellation_point:
12207 case OMPD_flush:
12208 case OMPD_depobj:
12209 case OMPD_scan:
12210 case OMPD_declare_reduction:
12211 case OMPD_declare_mapper:
12212 case OMPD_declare_simd:
12213 case OMPD_declare_variant:
12214 case OMPD_begin_declare_variant:
12215 case OMPD_end_declare_variant:
12216 case OMPD_declare_target:
12217 case OMPD_end_declare_target:
12218 case OMPD_teams:
12219 case OMPD_simd:
12220 case OMPD_for:
12221 case OMPD_for_simd:
12222 case OMPD_sections:
12223 case OMPD_section:
12224 case OMPD_single:
12225 case OMPD_master:
12226 case OMPD_critical:
12227 case OMPD_taskgroup:
12228 case OMPD_distribute:
12229 case OMPD_ordered:
12230 case OMPD_atomic:
12231 case OMPD_distribute_simd:
12232 case OMPD_teams_distribute:
12233 case OMPD_teams_distribute_simd:
12234 case OMPD_requires:
12235 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12235)
;
12236 case OMPD_unknown:
12237 default:
12238 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12238)
;
12239 }
12240 break;
12241 case OMPC_num_teams:
12242 switch (DKind) {
12243 case OMPD_target_teams:
12244 case OMPD_target_teams_distribute:
12245 case OMPD_target_teams_distribute_simd:
12246 case OMPD_target_teams_distribute_parallel_for:
12247 case OMPD_target_teams_distribute_parallel_for_simd:
12248 CaptureRegion = OMPD_target;
12249 break;
12250 case OMPD_teams_distribute_parallel_for:
12251 case OMPD_teams_distribute_parallel_for_simd:
12252 case OMPD_teams:
12253 case OMPD_teams_distribute:
12254 case OMPD_teams_distribute_simd:
12255 // Do not capture num_teams-clause expressions.
12256 break;
12257 case OMPD_distribute_parallel_for:
12258 case OMPD_distribute_parallel_for_simd:
12259 case OMPD_task:
12260 case OMPD_taskloop:
12261 case OMPD_taskloop_simd:
12262 case OMPD_master_taskloop:
12263 case OMPD_master_taskloop_simd:
12264 case OMPD_parallel_master_taskloop:
12265 case OMPD_parallel_master_taskloop_simd:
12266 case OMPD_target_data:
12267 case OMPD_target_enter_data:
12268 case OMPD_target_exit_data:
12269 case OMPD_target_update:
12270 case OMPD_cancel:
12271 case OMPD_parallel:
12272 case OMPD_parallel_master:
12273 case OMPD_parallel_sections:
12274 case OMPD_parallel_for:
12275 case OMPD_parallel_for_simd:
12276 case OMPD_target:
12277 case OMPD_target_simd:
12278 case OMPD_target_parallel:
12279 case OMPD_target_parallel_for:
12280 case OMPD_target_parallel_for_simd:
12281 case OMPD_threadprivate:
12282 case OMPD_allocate:
12283 case OMPD_taskyield:
12284 case OMPD_barrier:
12285 case OMPD_taskwait:
12286 case OMPD_cancellation_point:
12287 case OMPD_flush:
12288 case OMPD_depobj:
12289 case OMPD_scan:
12290 case OMPD_declare_reduction:
12291 case OMPD_declare_mapper:
12292 case OMPD_declare_simd:
12293 case OMPD_declare_variant:
12294 case OMPD_begin_declare_variant:
12295 case OMPD_end_declare_variant:
12296 case OMPD_declare_target:
12297 case OMPD_end_declare_target:
12298 case OMPD_simd:
12299 case OMPD_for:
12300 case OMPD_for_simd:
12301 case OMPD_sections:
12302 case OMPD_section:
12303 case OMPD_single:
12304 case OMPD_master:
12305 case OMPD_critical:
12306 case OMPD_taskgroup:
12307 case OMPD_distribute:
12308 case OMPD_ordered:
12309 case OMPD_atomic:
12310 case OMPD_distribute_simd:
12311 case OMPD_requires:
12312 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12312)
;
12313 case OMPD_unknown:
12314 default:
12315 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12315)
;
12316 }
12317 break;
12318 case OMPC_thread_limit:
12319 switch (DKind) {
12320 case OMPD_target_teams:
12321 case OMPD_target_teams_distribute:
12322 case OMPD_target_teams_distribute_simd:
12323 case OMPD_target_teams_distribute_parallel_for:
12324 case OMPD_target_teams_distribute_parallel_for_simd:
12325 CaptureRegion = OMPD_target;
12326 break;
12327 case OMPD_teams_distribute_parallel_for:
12328 case OMPD_teams_distribute_parallel_for_simd:
12329 case OMPD_teams:
12330 case OMPD_teams_distribute:
12331 case OMPD_teams_distribute_simd:
12332 // Do not capture thread_limit-clause expressions.
12333 break;
12334 case OMPD_distribute_parallel_for:
12335 case OMPD_distribute_parallel_for_simd:
12336 case OMPD_task:
12337 case OMPD_taskloop:
12338 case OMPD_taskloop_simd:
12339 case OMPD_master_taskloop:
12340 case OMPD_master_taskloop_simd:
12341 case OMPD_parallel_master_taskloop:
12342 case OMPD_parallel_master_taskloop_simd:
12343 case OMPD_target_data:
12344 case OMPD_target_enter_data:
12345 case OMPD_target_exit_data:
12346 case OMPD_target_update:
12347 case OMPD_cancel:
12348 case OMPD_parallel:
12349 case OMPD_parallel_master:
12350 case OMPD_parallel_sections:
12351 case OMPD_parallel_for:
12352 case OMPD_parallel_for_simd:
12353 case OMPD_target:
12354 case OMPD_target_simd:
12355 case OMPD_target_parallel:
12356 case OMPD_target_parallel_for:
12357 case OMPD_target_parallel_for_simd:
12358 case OMPD_threadprivate:
12359 case OMPD_allocate:
12360 case OMPD_taskyield:
12361 case OMPD_barrier:
12362 case OMPD_taskwait:
12363 case OMPD_cancellation_point:
12364 case OMPD_flush:
12365 case OMPD_depobj:
12366 case OMPD_scan:
12367 case OMPD_declare_reduction:
12368 case OMPD_declare_mapper:
12369 case OMPD_declare_simd:
12370 case OMPD_declare_variant:
12371 case OMPD_begin_declare_variant:
12372 case OMPD_end_declare_variant:
12373 case OMPD_declare_target:
12374 case OMPD_end_declare_target:
12375 case OMPD_simd:
12376 case OMPD_for:
12377 case OMPD_for_simd:
12378 case OMPD_sections:
12379 case OMPD_section:
12380 case OMPD_single:
12381 case OMPD_master:
12382 case OMPD_critical:
12383 case OMPD_taskgroup:
12384 case OMPD_distribute:
12385 case OMPD_ordered:
12386 case OMPD_atomic:
12387 case OMPD_distribute_simd:
12388 case OMPD_requires:
12389 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12389)
;
12390 case OMPD_unknown:
12391 default:
12392 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12392)
;
12393 }
12394 break;
12395 case OMPC_schedule:
12396 switch (DKind) {
12397 case OMPD_parallel_for:
12398 case OMPD_parallel_for_simd:
12399 case OMPD_distribute_parallel_for:
12400 case OMPD_distribute_parallel_for_simd:
12401 case OMPD_teams_distribute_parallel_for:
12402 case OMPD_teams_distribute_parallel_for_simd:
12403 case OMPD_target_parallel_for:
12404 case OMPD_target_parallel_for_simd:
12405 case OMPD_target_teams_distribute_parallel_for:
12406 case OMPD_target_teams_distribute_parallel_for_simd:
12407 CaptureRegion = OMPD_parallel;
12408 break;
12409 case OMPD_for:
12410 case OMPD_for_simd:
12411 // Do not capture schedule-clause expressions.
12412 break;
12413 case OMPD_task:
12414 case OMPD_taskloop:
12415 case OMPD_taskloop_simd:
12416 case OMPD_master_taskloop:
12417 case OMPD_master_taskloop_simd:
12418 case OMPD_parallel_master_taskloop:
12419 case OMPD_parallel_master_taskloop_simd:
12420 case OMPD_target_data:
12421 case OMPD_target_enter_data:
12422 case OMPD_target_exit_data:
12423 case OMPD_target_update:
12424 case OMPD_teams:
12425 case OMPD_teams_distribute:
12426 case OMPD_teams_distribute_simd:
12427 case OMPD_target_teams_distribute:
12428 case OMPD_target_teams_distribute_simd:
12429 case OMPD_target:
12430 case OMPD_target_simd:
12431 case OMPD_target_parallel:
12432 case OMPD_cancel:
12433 case OMPD_parallel:
12434 case OMPD_parallel_master:
12435 case OMPD_parallel_sections:
12436 case OMPD_threadprivate:
12437 case OMPD_allocate:
12438 case OMPD_taskyield:
12439 case OMPD_barrier:
12440 case OMPD_taskwait:
12441 case OMPD_cancellation_point:
12442 case OMPD_flush:
12443 case OMPD_depobj:
12444 case OMPD_scan:
12445 case OMPD_declare_reduction:
12446 case OMPD_declare_mapper:
12447 case OMPD_declare_simd:
12448 case OMPD_declare_variant:
12449 case OMPD_begin_declare_variant:
12450 case OMPD_end_declare_variant:
12451 case OMPD_declare_target:
12452 case OMPD_end_declare_target:
12453 case OMPD_simd:
12454 case OMPD_sections:
12455 case OMPD_section:
12456 case OMPD_single:
12457 case OMPD_master:
12458 case OMPD_critical:
12459 case OMPD_taskgroup:
12460 case OMPD_distribute:
12461 case OMPD_ordered:
12462 case OMPD_atomic:
12463 case OMPD_distribute_simd:
12464 case OMPD_target_teams:
12465 case OMPD_requires:
12466 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12466)
;
12467 case OMPD_unknown:
12468 default:
12469 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12469)
;
12470 }
12471 break;
12472 case OMPC_dist_schedule:
12473 switch (DKind) {
12474 case OMPD_teams_distribute_parallel_for:
12475 case OMPD_teams_distribute_parallel_for_simd:
12476 case OMPD_teams_distribute:
12477 case OMPD_teams_distribute_simd:
12478 case OMPD_target_teams_distribute_parallel_for:
12479 case OMPD_target_teams_distribute_parallel_for_simd:
12480 case OMPD_target_teams_distribute:
12481 case OMPD_target_teams_distribute_simd:
12482 CaptureRegion = OMPD_teams;
12483 break;
12484 case OMPD_distribute_parallel_for:
12485 case OMPD_distribute_parallel_for_simd:
12486 case OMPD_distribute:
12487 case OMPD_distribute_simd:
12488 // Do not capture dist_schedule-clause expressions.
12489 break;
12490 case OMPD_parallel_for:
12491 case OMPD_parallel_for_simd:
12492 case OMPD_target_parallel_for_simd:
12493 case OMPD_target_parallel_for:
12494 case OMPD_task:
12495 case OMPD_taskloop:
12496 case OMPD_taskloop_simd:
12497 case OMPD_master_taskloop:
12498 case OMPD_master_taskloop_simd:
12499 case OMPD_parallel_master_taskloop:
12500 case OMPD_parallel_master_taskloop_simd:
12501 case OMPD_target_data:
12502 case OMPD_target_enter_data:
12503 case OMPD_target_exit_data:
12504 case OMPD_target_update:
12505 case OMPD_teams:
12506 case OMPD_target:
12507 case OMPD_target_simd:
12508 case OMPD_target_parallel:
12509 case OMPD_cancel:
12510 case OMPD_parallel:
12511 case OMPD_parallel_master:
12512 case OMPD_parallel_sections:
12513 case OMPD_threadprivate:
12514 case OMPD_allocate:
12515 case OMPD_taskyield:
12516 case OMPD_barrier:
12517 case OMPD_taskwait:
12518 case OMPD_cancellation_point:
12519 case OMPD_flush:
12520 case OMPD_depobj:
12521 case OMPD_scan:
12522 case OMPD_declare_reduction:
12523 case OMPD_declare_mapper:
12524 case OMPD_declare_simd:
12525 case OMPD_declare_variant:
12526 case OMPD_begin_declare_variant:
12527 case OMPD_end_declare_variant:
12528 case OMPD_declare_target:
12529 case OMPD_end_declare_target:
12530 case OMPD_simd:
12531 case OMPD_for:
12532 case OMPD_for_simd:
12533 case OMPD_sections:
12534 case OMPD_section:
12535 case OMPD_single:
12536 case OMPD_master:
12537 case OMPD_critical:
12538 case OMPD_taskgroup:
12539 case OMPD_ordered:
12540 case OMPD_atomic:
12541 case OMPD_target_teams:
12542 case OMPD_requires:
12543 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12543)
;
12544 case OMPD_unknown:
12545 default:
12546 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12546)
;
12547 }
12548 break;
12549 case OMPC_device:
12550 switch (DKind) {
12551 case OMPD_target_update:
12552 case OMPD_target_enter_data:
12553 case OMPD_target_exit_data:
12554 case OMPD_target:
12555 case OMPD_target_simd:
12556 case OMPD_target_teams:
12557 case OMPD_target_parallel:
12558 case OMPD_target_teams_distribute:
12559 case OMPD_target_teams_distribute_simd:
12560 case OMPD_target_parallel_for:
12561 case OMPD_target_parallel_for_simd:
12562 case OMPD_target_teams_distribute_parallel_for:
12563 case OMPD_target_teams_distribute_parallel_for_simd:
12564 CaptureRegion = OMPD_task;
12565 break;
12566 case OMPD_target_data:
12567 // Do not capture device-clause expressions.
12568 break;
12569 case OMPD_teams_distribute_parallel_for:
12570 case OMPD_teams_distribute_parallel_for_simd:
12571 case OMPD_teams:
12572 case OMPD_teams_distribute:
12573 case OMPD_teams_distribute_simd:
12574 case OMPD_distribute_parallel_for:
12575 case OMPD_distribute_parallel_for_simd:
12576 case OMPD_task:
12577 case OMPD_taskloop:
12578 case OMPD_taskloop_simd:
12579 case OMPD_master_taskloop:
12580 case OMPD_master_taskloop_simd:
12581 case OMPD_parallel_master_taskloop:
12582 case OMPD_parallel_master_taskloop_simd:
12583 case OMPD_cancel:
12584 case OMPD_parallel:
12585 case OMPD_parallel_master:
12586 case OMPD_parallel_sections:
12587 case OMPD_parallel_for:
12588 case OMPD_parallel_for_simd:
12589 case OMPD_threadprivate:
12590 case OMPD_allocate:
12591 case OMPD_taskyield:
12592 case OMPD_barrier:
12593 case OMPD_taskwait:
12594 case OMPD_cancellation_point:
12595 case OMPD_flush:
12596 case OMPD_depobj:
12597 case OMPD_scan:
12598 case OMPD_declare_reduction:
12599 case OMPD_declare_mapper:
12600 case OMPD_declare_simd:
12601 case OMPD_declare_variant:
12602 case OMPD_begin_declare_variant:
12603 case OMPD_end_declare_variant:
12604 case OMPD_declare_target:
12605 case OMPD_end_declare_target:
12606 case OMPD_simd:
12607 case OMPD_for:
12608 case OMPD_for_simd:
12609 case OMPD_sections:
12610 case OMPD_section:
12611 case OMPD_single:
12612 case OMPD_master:
12613 case OMPD_critical:
12614 case OMPD_taskgroup:
12615 case OMPD_distribute:
12616 case OMPD_ordered:
12617 case OMPD_atomic:
12618 case OMPD_distribute_simd:
12619 case OMPD_requires:
12620 llvm_unreachable("Unexpected OpenMP directive with device-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with device-clause"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12620)
;
12621 case OMPD_unknown:
12622 default:
12623 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12623)
;
12624 }
12625 break;
12626 case OMPC_grainsize:
12627 case OMPC_num_tasks:
12628 case OMPC_final:
12629 case OMPC_priority:
12630 switch (DKind) {
12631 case OMPD_task:
12632 case OMPD_taskloop:
12633 case OMPD_taskloop_simd:
12634 case OMPD_master_taskloop:
12635 case OMPD_master_taskloop_simd:
12636 break;
12637 case OMPD_parallel_master_taskloop:
12638 case OMPD_parallel_master_taskloop_simd:
12639 CaptureRegion = OMPD_parallel;
12640 break;
12641 case OMPD_target_update:
12642 case OMPD_target_enter_data:
12643 case OMPD_target_exit_data:
12644 case OMPD_target:
12645 case OMPD_target_simd:
12646 case OMPD_target_teams:
12647 case OMPD_target_parallel:
12648 case OMPD_target_teams_distribute:
12649 case OMPD_target_teams_distribute_simd:
12650 case OMPD_target_parallel_for:
12651 case OMPD_target_parallel_for_simd:
12652 case OMPD_target_teams_distribute_parallel_for:
12653 case OMPD_target_teams_distribute_parallel_for_simd:
12654 case OMPD_target_data:
12655 case OMPD_teams_distribute_parallel_for:
12656 case OMPD_teams_distribute_parallel_for_simd:
12657 case OMPD_teams:
12658 case OMPD_teams_distribute:
12659 case OMPD_teams_distribute_simd:
12660 case OMPD_distribute_parallel_for:
12661 case OMPD_distribute_parallel_for_simd:
12662 case OMPD_cancel:
12663 case OMPD_parallel:
12664 case OMPD_parallel_master:
12665 case OMPD_parallel_sections:
12666 case OMPD_parallel_for:
12667 case OMPD_parallel_for_simd:
12668 case OMPD_threadprivate:
12669 case OMPD_allocate:
12670 case OMPD_taskyield:
12671 case OMPD_barrier:
12672 case OMPD_taskwait:
12673 case OMPD_cancellation_point:
12674 case OMPD_flush:
12675 case OMPD_depobj:
12676 case OMPD_scan:
12677 case OMPD_declare_reduction:
12678 case OMPD_declare_mapper:
12679 case OMPD_declare_simd:
12680 case OMPD_declare_variant:
12681 case OMPD_begin_declare_variant:
12682 case OMPD_end_declare_variant:
12683 case OMPD_declare_target:
12684 case OMPD_end_declare_target:
12685 case OMPD_simd:
12686 case OMPD_for:
12687 case OMPD_for_simd:
12688 case OMPD_sections:
12689 case OMPD_section:
12690 case OMPD_single:
12691 case OMPD_master:
12692 case OMPD_critical:
12693 case OMPD_taskgroup:
12694 case OMPD_distribute:
12695 case OMPD_ordered:
12696 case OMPD_atomic:
12697 case OMPD_distribute_simd:
12698 case OMPD_requires:
12699 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12699)
;
12700 case OMPD_unknown:
12701 default:
12702 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12702)
;
12703 }
12704 break;
12705 case OMPC_firstprivate:
12706 case OMPC_lastprivate:
12707 case OMPC_reduction:
12708 case OMPC_task_reduction:
12709 case OMPC_in_reduction:
12710 case OMPC_linear:
12711 case OMPC_default:
12712 case OMPC_proc_bind:
12713 case OMPC_safelen:
12714 case OMPC_simdlen:
12715 case OMPC_allocator:
12716 case OMPC_collapse:
12717 case OMPC_private:
12718 case OMPC_shared:
12719 case OMPC_aligned:
12720 case OMPC_copyin:
12721 case OMPC_copyprivate:
12722 case OMPC_ordered:
12723 case OMPC_nowait:
12724 case OMPC_untied:
12725 case OMPC_mergeable:
12726 case OMPC_threadprivate:
12727 case OMPC_allocate:
12728 case OMPC_flush:
12729 case OMPC_depobj:
12730 case OMPC_read:
12731 case OMPC_write:
12732 case OMPC_update:
12733 case OMPC_capture:
12734 case OMPC_seq_cst:
12735 case OMPC_acq_rel:
12736 case OMPC_acquire:
12737 case OMPC_release:
12738 case OMPC_relaxed:
12739 case OMPC_depend:
12740 case OMPC_threads:
12741 case OMPC_simd:
12742 case OMPC_map:
12743 case OMPC_nogroup:
12744 case OMPC_hint:
12745 case OMPC_defaultmap:
12746 case OMPC_unknown:
12747 case OMPC_uniform:
12748 case OMPC_to:
12749 case OMPC_from:
12750 case OMPC_use_device_ptr:
12751 case OMPC_use_device_addr:
12752 case OMPC_is_device_ptr:
12753 case OMPC_unified_address:
12754 case OMPC_unified_shared_memory:
12755 case OMPC_reverse_offload:
12756 case OMPC_dynamic_allocators:
12757 case OMPC_atomic_default_mem_order:
12758 case OMPC_device_type:
12759 case OMPC_match:
12760 case OMPC_nontemporal:
12761 case OMPC_order:
12762 case OMPC_destroy:
12763 case OMPC_detach:
12764 case OMPC_inclusive:
12765 case OMPC_exclusive:
12766 case OMPC_uses_allocators:
12767 case OMPC_affinity:
12768 default:
12769 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12769)
;
12770 }
12771 return CaptureRegion;
12772}
12773
12774OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12775 Expr *Condition, SourceLocation StartLoc,
12776 SourceLocation LParenLoc,
12777 SourceLocation NameModifierLoc,
12778 SourceLocation ColonLoc,
12779 SourceLocation EndLoc) {
12780 Expr *ValExpr = Condition;
12781 Stmt *HelperValStmt = nullptr;
12782 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12783 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12784 !Condition->isInstantiationDependent() &&
12785 !Condition->containsUnexpandedParameterPack()) {
12786 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12787 if (Val.isInvalid())
12788 return nullptr;
12789
12790 ValExpr = Val.get();
12791
12792 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12793 CaptureRegion = getOpenMPCaptureRegionForClause(
12794 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12795 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12796 ValExpr = MakeFullExpr(ValExpr).get();
12797 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12798 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12799 HelperValStmt = buildPreInits(Context, Captures);
12800 }
12801 }
12802
12803 return new (Context)
12804 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12805 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12806}
12807
12808OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12809 SourceLocation StartLoc,
12810 SourceLocation LParenLoc,
12811 SourceLocation EndLoc) {
12812 Expr *ValExpr = Condition;
12813 Stmt *HelperValStmt = nullptr;
12814 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12815 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12816 !Condition->isInstantiationDependent() &&
12817 !Condition->containsUnexpandedParameterPack()) {
12818 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12819 if (Val.isInvalid())
12820 return nullptr;
12821
12822 ValExpr = MakeFullExpr(Val.get()).get();
12823
12824 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12825 CaptureRegion =
12826 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12827 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12828 ValExpr = MakeFullExpr(ValExpr).get();
12829 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12830 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12831 HelperValStmt = buildPreInits(Context, Captures);
12832 }
12833 }
12834
12835 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12836 StartLoc, LParenLoc, EndLoc);
12837}
12838
12839ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12840 Expr *Op) {
12841 if (!Op)
12842 return ExprError();
12843
12844 class IntConvertDiagnoser : public ICEConvertDiagnoser {
12845 public:
12846 IntConvertDiagnoser()
12847 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12848 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12849 QualType T) override {
12850 return S.Diag(Loc, diag::err_omp_not_integral) << T;
12851 }
12852 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12853 QualType T) override {
12854 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12855 }
12856 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12857 QualType T,
12858 QualType ConvTy) override {
12859 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12860 }
12861 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12862 QualType ConvTy) override {
12863 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12864 << ConvTy->isEnumeralType() << ConvTy;
12865 }
12866 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12867 QualType T) override {
12868 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12869 }
12870 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12871 QualType ConvTy) override {
12872 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12873 << ConvTy->isEnumeralType() << ConvTy;
12874 }
12875 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12876 QualType) override {
12877 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 12877)
;
12878 }
12879 } ConvertDiagnoser;
12880 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12881}
12882
12883static bool
12884isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12885 bool StrictlyPositive, bool BuildCapture = false,
12886 OpenMPDirectiveKind DKind = OMPD_unknown,
12887 OpenMPDirectiveKind *CaptureRegion = nullptr,
12888 Stmt **HelperValStmt = nullptr) {
12889 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12890 !ValExpr->isInstantiationDependent()) {
12891 SourceLocation Loc = ValExpr->getExprLoc();
12892 ExprResult Value =
12893 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12894 if (Value.isInvalid())
12895 return false;
12896
12897 ValExpr = Value.get();
12898 // The expression must evaluate to a non-negative integer value.
12899 if (Optional<llvm::APSInt> Result =
12900 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
12901 if (Result->isSigned() &&
12902 !((!StrictlyPositive && Result->isNonNegative()) ||
12903 (StrictlyPositive && Result->isStrictlyPositive()))) {
12904 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12905 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12906 << ValExpr->getSourceRange();
12907 return false;
12908 }
12909 }
12910 if (!BuildCapture)
12911 return true;
12912 *CaptureRegion =
12913 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12914 if (*CaptureRegion != OMPD_unknown &&
12915 !SemaRef.CurContext->isDependentContext()) {
12916 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12917 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12918 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12919 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12920 }
12921 }
12922 return true;
12923}
12924
12925OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12926 SourceLocation StartLoc,
12927 SourceLocation LParenLoc,
12928 SourceLocation EndLoc) {
12929 Expr *ValExpr = NumThreads;
12930 Stmt *HelperValStmt = nullptr;
12931
12932 // OpenMP [2.5, Restrictions]
12933 // The num_threads expression must evaluate to a positive integer value.
12934 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12935 /*StrictlyPositive=*/true))
12936 return nullptr;
12937
12938 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12939 OpenMPDirectiveKind CaptureRegion =
12940 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12941 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12942 ValExpr = MakeFullExpr(ValExpr).get();
12943 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12944 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12945 HelperValStmt = buildPreInits(Context, Captures);
12946 }
12947
12948 return new (Context) OMPNumThreadsClause(
12949 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12950}
12951
12952ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12953 OpenMPClauseKind CKind,
12954 bool StrictlyPositive) {
12955 if (!E)
12956 return ExprError();
12957 if (E->isValueDependent() || E->isTypeDependent() ||
12958 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12959 return E;
12960 llvm::APSInt Result;
12961 ExprResult ICE =
12962 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
12963 if (ICE.isInvalid())
12964 return ExprError();
12965 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12966 (!StrictlyPositive && !Result.isNonNegative())) {
12967 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12968 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12969 << E->getSourceRange();
12970 return ExprError();
12971 }
12972 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12973 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12974 << E->getSourceRange();
12975 return ExprError();
12976 }
12977 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
12978 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
12979 else if (CKind == OMPC_ordered)
12980 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
12981 return ICE;
12982}
12983
12984OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12985 SourceLocation LParenLoc,
12986 SourceLocation EndLoc) {
12987 // OpenMP [2.8.1, simd construct, Description]
12988 // The parameter of the safelen clause must be a constant
12989 // positive integer expression.
12990 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12991 if (Safelen.isInvalid())
12992 return nullptr;
12993 return new (Context)
12994 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
12995}
12996
12997OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
12998 SourceLocation LParenLoc,
12999 SourceLocation EndLoc) {
13000 // OpenMP [2.8.1, simd construct, Description]
13001 // The parameter of the simdlen clause must be a constant
13002 // positive integer expression.
13003 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
13004 if (Simdlen.isInvalid())
13005 return nullptr;
13006 return new (Context)
13007 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
13008}
13009
13010/// Tries to find omp_allocator_handle_t type.
13011static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
13012 DSAStackTy *Stack) {
13013 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
13014 if (!OMPAllocatorHandleT.isNull())
13015 return true;
13016 // Build the predefined allocator expressions.
13017 bool ErrorFound = false;
13018 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
13019 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
13020 StringRef Allocator =
13021 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
13022 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
13023 auto *VD = dyn_cast_or_null<ValueDecl>(
13024 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
13025 if (!VD) {
13026 ErrorFound = true;
13027 break;
13028 }
13029 QualType AllocatorType =
13030 VD->getType().getNonLValueExprType(S.getASTContext());
13031 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
13032 if (!Res.isUsable()) {
13033 ErrorFound = true;
13034 break;
13035 }
13036 if (OMPAllocatorHandleT.isNull())
13037 OMPAllocatorHandleT = AllocatorType;
13038 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
13039 ErrorFound = true;
13040 break;
13041 }
13042 Stack->setAllocator(AllocatorKind, Res.get());
13043 }
13044 if (ErrorFound) {
13045 S.Diag(Loc, diag::err_omp_implied_type_not_found)
13046 << "omp_allocator_handle_t";
13047 return false;
13048 }
13049 OMPAllocatorHandleT.addConst();
13050 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
13051 return true;
13052}
13053
13054OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
13055 SourceLocation LParenLoc,
13056 SourceLocation EndLoc) {
13057 // OpenMP [2.11.3, allocate Directive, Description]
13058 // allocator is an expression of omp_allocator_handle_t type.
13059 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13060 return nullptr;
13061
13062 ExprResult Allocator = DefaultLvalueConversion(A);
13063 if (Allocator.isInvalid())
13064 return nullptr;
13065 Allocator = PerformImplicitConversion(Allocator.get(),
13066 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
13067 Sema::AA_Initializing,
13068 /*AllowExplicit=*/true);
13069 if (Allocator.isInvalid())
13070 return nullptr;
13071 return new (Context)
13072 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
13073}
13074
13075OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
13076 SourceLocation StartLoc,
13077 SourceLocation LParenLoc,
13078 SourceLocation EndLoc) {
13079 // OpenMP [2.7.1, loop construct, Description]
13080 // OpenMP [2.8.1, simd construct, Description]
13081 // OpenMP [2.9.6, distribute construct, Description]
13082 // The parameter of the collapse clause must be a constant
13083 // positive integer expression.
13084 ExprResult NumForLoopsResult =
13085 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
13086 if (NumForLoopsResult.isInvalid())
13087 return nullptr;
13088 return new (Context)
13089 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
13090}
13091
13092OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
13093 SourceLocation EndLoc,
13094 SourceLocation LParenLoc,
13095 Expr *NumForLoops) {
13096 // OpenMP [2.7.1, loop construct, Description]
13097 // OpenMP [2.8.1, simd construct, Description]
13098 // OpenMP [2.9.6, distribute construct, Description]
13099 // The parameter of the ordered clause must be a constant
13100 // positive integer expression if any.
13101 if (NumForLoops && LParenLoc.isValid()) {
13102 ExprResult NumForLoopsResult =
13103 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
13104 if (NumForLoopsResult.isInvalid())
13105 return nullptr;
13106 NumForLoops = NumForLoopsResult.get();
13107 } else {
13108 NumForLoops = nullptr;
13109 }
13110 auto *Clause = OMPOrderedClause::Create(
13111 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
13112 StartLoc, LParenLoc, EndLoc);
13113 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
13114 return Clause;
13115}
13116
13117OMPClause *Sema::ActOnOpenMPSimpleClause(
13118 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
13119 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13120 OMPClause *Res = nullptr;
13121 switch (Kind) {
13122 case OMPC_default:
13123 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
13124 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13125 break;
13126 case OMPC_proc_bind:
13127 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
13128 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13129 break;
13130 case OMPC_atomic_default_mem_order:
13131 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
13132 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
13133 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13134 break;
13135 case OMPC_order:
13136 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
13137 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13138 break;
13139 case OMPC_update:
13140 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
13141 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13142 break;
13143 case OMPC_if:
13144 case OMPC_final:
13145 case OMPC_num_threads:
13146 case OMPC_safelen:
13147 case OMPC_simdlen:
13148 case OMPC_allocator:
13149 case OMPC_collapse:
13150 case OMPC_schedule:
13151 case OMPC_private:
13152 case OMPC_firstprivate:
13153 case OMPC_lastprivate:
13154 case OMPC_shared:
13155 case OMPC_reduction:
13156 case OMPC_task_reduction:
13157 case OMPC_in_reduction:
13158 case OMPC_linear:
13159 case OMPC_aligned:
13160 case OMPC_copyin:
13161 case OMPC_copyprivate:
13162 case OMPC_ordered:
13163 case OMPC_nowait:
13164 case OMPC_untied:
13165 case OMPC_mergeable:
13166 case OMPC_threadprivate:
13167 case OMPC_allocate:
13168 case OMPC_flush:
13169 case OMPC_depobj:
13170 case OMPC_read:
13171 case OMPC_write:
13172 case OMPC_capture:
13173 case OMPC_seq_cst:
13174 case OMPC_acq_rel:
13175 case OMPC_acquire:
13176 case OMPC_release:
13177 case OMPC_relaxed:
13178 case OMPC_depend:
13179 case OMPC_device:
13180 case OMPC_threads:
13181 case OMPC_simd:
13182 case OMPC_map:
13183 case OMPC_num_teams:
13184 case OMPC_thread_limit:
13185 case OMPC_priority:
13186 case OMPC_grainsize:
13187 case OMPC_nogroup:
13188 case OMPC_num_tasks:
13189 case OMPC_hint:
13190 case OMPC_dist_schedule:
13191 case OMPC_defaultmap:
13192 case OMPC_unknown:
13193 case OMPC_uniform:
13194 case OMPC_to:
13195 case OMPC_from:
13196 case OMPC_use_device_ptr:
13197 case OMPC_use_device_addr:
13198 case OMPC_is_device_ptr:
13199 case OMPC_unified_address:
13200 case OMPC_unified_shared_memory:
13201 case OMPC_reverse_offload:
13202 case OMPC_dynamic_allocators:
13203 case OMPC_device_type:
13204 case OMPC_match:
13205 case OMPC_nontemporal:
13206 case OMPC_destroy:
13207 case OMPC_detach:
13208 case OMPC_inclusive:
13209 case OMPC_exclusive:
13210 case OMPC_uses_allocators:
13211 case OMPC_affinity:
13212 default:
13213 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13213)
;
13214 }
13215 return Res;
13216}
13217
13218static std::string
13219getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
13220 ArrayRef<unsigned> Exclude = llvm::None) {
13221 SmallString<256> Buffer;
13222 llvm::raw_svector_ostream Out(Buffer);
13223 unsigned Skipped = Exclude.size();
13224 auto S = Exclude.begin(), E = Exclude.end();
13225 for (unsigned I = First; I < Last; ++I) {
13226 if (std::find(S, E, I) != E) {
13227 --Skipped;
13228 continue;
13229 }
13230 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
13231 if (I + Skipped + 2 == Last)
13232 Out << " or ";
13233 else if (I + Skipped + 1 != Last)
13234 Out << ", ";
13235 }
13236 return std::string(Out.str());
13237}
13238
13239OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
13240 SourceLocation KindKwLoc,
13241 SourceLocation StartLoc,
13242 SourceLocation LParenLoc,
13243 SourceLocation EndLoc) {
13244 if (Kind == OMP_DEFAULT_unknown) {
13245 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13246 << getListOfPossibleValues(OMPC_default, /*First=*/0,
13247 /*Last=*/unsigned(OMP_DEFAULT_unknown))
13248 << getOpenMPClauseName(OMPC_default);
13249 return nullptr;
13250 }
13251
13252 switch (Kind) {
13253 case OMP_DEFAULT_none:
13254 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
13255 break;
13256 case OMP_DEFAULT_shared:
13257 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
13258 break;
13259 case OMP_DEFAULT_firstprivate:
13260 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
13261 break;
13262 default:
13263 llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13263)
;
13264 }
13265
13266 return new (Context)
13267 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13268}
13269
13270OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13271 SourceLocation KindKwLoc,
13272 SourceLocation StartLoc,
13273 SourceLocation LParenLoc,
13274 SourceLocation EndLoc) {
13275 if (Kind == OMP_PROC_BIND_unknown) {
13276 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13277 << getListOfPossibleValues(OMPC_proc_bind,
13278 /*First=*/unsigned(OMP_PROC_BIND_master),
13279 /*Last=*/5)
13280 << getOpenMPClauseName(OMPC_proc_bind);
13281 return nullptr;
13282 }
13283 return new (Context)
13284 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13285}
13286
13287OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13288 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13289 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13290 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13291 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13292 << getListOfPossibleValues(
13293 OMPC_atomic_default_mem_order, /*First=*/0,
13294 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13295 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13296 return nullptr;
13297 }
13298 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13299 LParenLoc, EndLoc);
13300}
13301
13302OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13303 SourceLocation KindKwLoc,
13304 SourceLocation StartLoc,
13305 SourceLocation LParenLoc,
13306 SourceLocation EndLoc) {
13307 if (Kind == OMPC_ORDER_unknown) {
13308 static_assert(OMPC_ORDER_unknown > 0,
13309 "OMPC_ORDER_unknown not greater than 0");
13310 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13311 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13312 /*Last=*/OMPC_ORDER_unknown)
13313 << getOpenMPClauseName(OMPC_order);
13314 return nullptr;
13315 }
13316 return new (Context)
13317 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13318}
13319
13320OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13321 SourceLocation KindKwLoc,
13322 SourceLocation StartLoc,
13323 SourceLocation LParenLoc,
13324 SourceLocation EndLoc) {
13325 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13326 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13327 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13328 OMPC_DEPEND_depobj};
13329 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13330 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13331 /*Last=*/OMPC_DEPEND_unknown, Except)
13332 << getOpenMPClauseName(OMPC_update);
13333 return nullptr;
13334 }
13335 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13336 EndLoc);
13337}
13338
13339OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13340 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13341 SourceLocation StartLoc, SourceLocation LParenLoc,
13342 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13343 SourceLocation EndLoc) {
13344 OMPClause *Res = nullptr;
13345 switch (Kind) {
13346 case OMPC_schedule:
13347 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13348 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13349, __PRETTY_FUNCTION__))
13349 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13349, __PRETTY_FUNCTION__))
;
13350 Res = ActOnOpenMPScheduleClause(
13351 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13352 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13353 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13354 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13355 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13356 break;
13357 case OMPC_if:
13358 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13358, __PRETTY_FUNCTION__))
;
13359 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13360 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13361 DelimLoc, EndLoc);
13362 break;
13363 case OMPC_dist_schedule:
13364 Res = ActOnOpenMPDistScheduleClause(
13365 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13366 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13367 break;
13368 case OMPC_defaultmap:
13369 enum { Modifier, DefaultmapKind };
13370 Res = ActOnOpenMPDefaultmapClause(
13371 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13372 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13373 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13374 EndLoc);
13375 break;
13376 case OMPC_device:
13377 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13377, __PRETTY_FUNCTION__))
;
13378 Res = ActOnOpenMPDeviceClause(
13379 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13380 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13381 break;
13382 case OMPC_final:
13383 case OMPC_num_threads:
13384 case OMPC_safelen:
13385 case OMPC_simdlen:
13386 case OMPC_allocator:
13387 case OMPC_collapse:
13388 case OMPC_default:
13389 case OMPC_proc_bind:
13390 case OMPC_private:
13391 case OMPC_firstprivate:
13392 case OMPC_lastprivate:
13393 case OMPC_shared:
13394 case OMPC_reduction:
13395 case OMPC_task_reduction:
13396 case OMPC_in_reduction:
13397 case OMPC_linear:
13398 case OMPC_aligned:
13399 case OMPC_copyin:
13400 case OMPC_copyprivate:
13401 case OMPC_ordered:
13402 case OMPC_nowait:
13403 case OMPC_untied:
13404 case OMPC_mergeable:
13405 case OMPC_threadprivate:
13406 case OMPC_allocate:
13407 case OMPC_flush:
13408 case OMPC_depobj:
13409 case OMPC_read:
13410 case OMPC_write:
13411 case OMPC_update:
13412 case OMPC_capture:
13413 case OMPC_seq_cst:
13414 case OMPC_acq_rel:
13415 case OMPC_acquire:
13416 case OMPC_release:
13417 case OMPC_relaxed:
13418 case OMPC_depend:
13419 case OMPC_threads:
13420 case OMPC_simd:
13421 case OMPC_map:
13422 case OMPC_num_teams:
13423 case OMPC_thread_limit:
13424 case OMPC_priority:
13425 case OMPC_grainsize:
13426 case OMPC_nogroup:
13427 case OMPC_num_tasks:
13428 case OMPC_hint:
13429 case OMPC_unknown:
13430 case OMPC_uniform:
13431 case OMPC_to:
13432 case OMPC_from:
13433 case OMPC_use_device_ptr:
13434 case OMPC_use_device_addr:
13435 case OMPC_is_device_ptr:
13436 case OMPC_unified_address:
13437 case OMPC_unified_shared_memory:
13438 case OMPC_reverse_offload:
13439 case OMPC_dynamic_allocators:
13440 case OMPC_atomic_default_mem_order:
13441 case OMPC_device_type:
13442 case OMPC_match:
13443 case OMPC_nontemporal:
13444 case OMPC_order:
13445 case OMPC_destroy:
13446 case OMPC_detach:
13447 case OMPC_inclusive:
13448 case OMPC_exclusive:
13449 case OMPC_uses_allocators:
13450 case OMPC_affinity:
13451 default:
13452 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13452)
;
13453 }
13454 return Res;
13455}
13456
13457static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13458 OpenMPScheduleClauseModifier M2,
13459 SourceLocation M1Loc, SourceLocation M2Loc) {
13460 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13461 SmallVector<unsigned, 2> Excluded;
13462 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13463 Excluded.push_back(M2);
13464 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13465 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13466 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13467 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13468 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13469 << getListOfPossibleValues(OMPC_schedule,
13470 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13471 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13472 Excluded)
13473 << getOpenMPClauseName(OMPC_schedule);
13474 return true;
13475 }
13476 return false;
13477}
13478
13479OMPClause *Sema::ActOnOpenMPScheduleClause(
13480 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13481 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13482 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13483 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13484 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13485 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13486 return nullptr;
13487 // OpenMP, 2.7.1, Loop Construct, Restrictions
13488 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13489 // but not both.
13490 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13491 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13492 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13493 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13494 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13495 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13496 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13497 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13498 return nullptr;
13499 }
13500 if (Kind == OMPC_SCHEDULE_unknown) {
13501 std::string Values;
13502 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13503 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13504 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13505 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13506 Exclude);
13507 } else {
13508 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13509 /*Last=*/OMPC_SCHEDULE_unknown);
13510 }
13511 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13512 << Values << getOpenMPClauseName(OMPC_schedule);
13513 return nullptr;
13514 }
13515 // OpenMP, 2.7.1, Loop Construct, Restrictions
13516 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13517 // schedule(guided).
13518 // OpenMP 5.0 does not have this restriction.
13519 if (LangOpts.OpenMP < 50 &&
13520 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13521 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13522 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13523 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13524 diag::err_omp_schedule_nonmonotonic_static);
13525 return nullptr;
13526 }
13527 Expr *ValExpr = ChunkSize;
13528 Stmt *HelperValStmt = nullptr;
13529 if (ChunkSize) {
13530 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13531 !ChunkSize->isInstantiationDependent() &&
13532 !ChunkSize->containsUnexpandedParameterPack()) {
13533 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13534 ExprResult Val =
13535 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13536 if (Val.isInvalid())
13537 return nullptr;
13538
13539 ValExpr = Val.get();
13540
13541 // OpenMP [2.7.1, Restrictions]
13542 // chunk_size must be a loop invariant integer expression with a positive
13543 // value.
13544 if (Optional<llvm::APSInt> Result =
13545 ValExpr->getIntegerConstantExpr(Context)) {
13546 if (Result->isSigned() && !Result->isStrictlyPositive()) {
13547 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13548 << "schedule" << 1 << ChunkSize->getSourceRange();
13549 return nullptr;
13550 }
13551 } else if (getOpenMPCaptureRegionForClause(
13552 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
13553 LangOpts.OpenMP) != OMPD_unknown &&
13554 !CurContext->isDependentContext()) {
13555 ValExpr = MakeFullExpr(ValExpr).get();
13556 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13557 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13558 HelperValStmt = buildPreInits(Context, Captures);
13559 }
13560 }
13561 }
13562
13563 return new (Context)
13564 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13565 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13566}
13567
13568OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13569 SourceLocation StartLoc,
13570 SourceLocation EndLoc) {
13571 OMPClause *Res = nullptr;
13572 switch (Kind) {
13573 case OMPC_ordered:
13574 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13575 break;
13576 case OMPC_nowait:
13577 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13578 break;
13579 case OMPC_untied:
13580 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13581 break;
13582 case OMPC_mergeable:
13583 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13584 break;
13585 case OMPC_read:
13586 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13587 break;
13588 case OMPC_write:
13589 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13590 break;
13591 case OMPC_update:
13592 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13593 break;
13594 case OMPC_capture:
13595 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13596 break;
13597 case OMPC_seq_cst:
13598 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13599 break;
13600 case OMPC_acq_rel:
13601 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13602 break;
13603 case OMPC_acquire:
13604 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13605 break;
13606 case OMPC_release:
13607 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13608 break;
13609 case OMPC_relaxed:
13610 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13611 break;
13612 case OMPC_threads:
13613 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13614 break;
13615 case OMPC_simd:
13616 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13617 break;
13618 case OMPC_nogroup:
13619 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13620 break;
13621 case OMPC_unified_address:
13622 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13623 break;
13624 case OMPC_unified_shared_memory:
13625 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13626 break;
13627 case OMPC_reverse_offload:
13628 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13629 break;
13630 case OMPC_dynamic_allocators:
13631 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13632 break;
13633 case OMPC_destroy:
13634 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13635 break;
13636 case OMPC_if:
13637 case OMPC_final:
13638 case OMPC_num_threads:
13639 case OMPC_safelen:
13640 case OMPC_simdlen:
13641 case OMPC_allocator:
13642 case OMPC_collapse:
13643 case OMPC_schedule:
13644 case OMPC_private:
13645 case OMPC_firstprivate:
13646 case OMPC_lastprivate:
13647 case OMPC_shared:
13648 case OMPC_reduction:
13649 case OMPC_task_reduction:
13650 case OMPC_in_reduction:
13651 case OMPC_linear:
13652 case OMPC_aligned:
13653 case OMPC_copyin:
13654 case OMPC_copyprivate:
13655 case OMPC_default:
13656 case OMPC_proc_bind:
13657 case OMPC_threadprivate:
13658 case OMPC_allocate:
13659 case OMPC_flush:
13660 case OMPC_depobj:
13661 case OMPC_depend:
13662 case OMPC_device:
13663 case OMPC_map:
13664 case OMPC_num_teams:
13665 case OMPC_thread_limit:
13666 case OMPC_priority:
13667 case OMPC_grainsize:
13668 case OMPC_num_tasks:
13669 case OMPC_hint:
13670 case OMPC_dist_schedule:
13671 case OMPC_defaultmap:
13672 case OMPC_unknown:
13673 case OMPC_uniform:
13674 case OMPC_to:
13675 case OMPC_from:
13676 case OMPC_use_device_ptr:
13677 case OMPC_use_device_addr:
13678 case OMPC_is_device_ptr:
13679 case OMPC_atomic_default_mem_order:
13680 case OMPC_device_type:
13681 case OMPC_match:
13682 case OMPC_nontemporal:
13683 case OMPC_order:
13684 case OMPC_detach:
13685 case OMPC_inclusive:
13686 case OMPC_exclusive:
13687 case OMPC_uses_allocators:
13688 case OMPC_affinity:
13689 default:
13690 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13690)
;
13691 }
13692 return Res;
13693}
13694
13695OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13696 SourceLocation EndLoc) {
13697 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
13698 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13699}
13700
13701OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13702 SourceLocation EndLoc) {
13703 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13704}
13705
13706OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13707 SourceLocation EndLoc) {
13708 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13709}
13710
13711OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13712 SourceLocation EndLoc) {
13713 return new (Context) OMPReadClause(StartLoc, EndLoc);
13714}
13715
13716OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13717 SourceLocation EndLoc) {
13718 return new (Context) OMPWriteClause(StartLoc, EndLoc);
13719}
13720
13721OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13722 SourceLocation EndLoc) {
13723 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13724}
13725
13726OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13727 SourceLocation EndLoc) {
13728 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13729}
13730
13731OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13732 SourceLocation EndLoc) {
13733 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13734}
13735
13736OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13737 SourceLocation EndLoc) {
13738 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13739}
13740
13741OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13742 SourceLocation EndLoc) {
13743 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13744}
13745
13746OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13747 SourceLocation EndLoc) {
13748 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13749}
13750
13751OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13752 SourceLocation EndLoc) {
13753 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13754}
13755
13756OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13757 SourceLocation EndLoc) {
13758 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13759}
13760
13761OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13762 SourceLocation EndLoc) {
13763 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13764}
13765
13766OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13767 SourceLocation EndLoc) {
13768 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13769}
13770
13771OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13772 SourceLocation EndLoc) {
13773 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13774}
13775
13776OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13777 SourceLocation EndLoc) {
13778 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13779}
13780
13781OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13782 SourceLocation EndLoc) {
13783 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13784}
13785
13786OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13787 SourceLocation EndLoc) {
13788 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13789}
13790
13791OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13792 SourceLocation EndLoc) {
13793 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13794}
13795
13796OMPClause *Sema::ActOnOpenMPVarListClause(
13797 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13798 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13799 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13800 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13801 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13802 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13803 SourceLocation ExtraModifierLoc,
13804 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
13805 ArrayRef<SourceLocation> MotionModifiersLoc) {
13806 SourceLocation StartLoc = Locs.StartLoc;
13807 SourceLocation LParenLoc = Locs.LParenLoc;
13808 SourceLocation EndLoc = Locs.EndLoc;
13809 OMPClause *Res = nullptr;
13810 switch (Kind) {
13811 case OMPC_private:
13812 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13813 break;
13814 case OMPC_firstprivate:
13815 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13816 break;
13817 case OMPC_lastprivate:
13818 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13819, __PRETTY_FUNCTION__))
13819 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13819, __PRETTY_FUNCTION__))
;
13820 Res = ActOnOpenMPLastprivateClause(
13821 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13822 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13823 break;
13824 case OMPC_shared:
13825 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13826 break;
13827 case OMPC_reduction:
13828 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13829, __PRETTY_FUNCTION__))
13829 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13829, __PRETTY_FUNCTION__))
;
13830 Res = ActOnOpenMPReductionClause(
13831 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13832 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13833 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13834 break;
13835 case OMPC_task_reduction:
13836 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13837 EndLoc, ReductionOrMapperIdScopeSpec,
13838 ReductionOrMapperId);
13839 break;
13840 case OMPC_in_reduction:
13841 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13842 EndLoc, ReductionOrMapperIdScopeSpec,
13843 ReductionOrMapperId);
13844 break;
13845 case OMPC_linear:
13846 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13847, __PRETTY_FUNCTION__))
13847 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13847, __PRETTY_FUNCTION__))
;
13848 Res = ActOnOpenMPLinearClause(
13849 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13850 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13851 ColonLoc, EndLoc);
13852 break;
13853 case OMPC_aligned:
13854 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13855 LParenLoc, ColonLoc, EndLoc);
13856 break;
13857 case OMPC_copyin:
13858 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13859 break;
13860 case OMPC_copyprivate:
13861 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13862 break;
13863 case OMPC_flush:
13864 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13865 break;
13866 case OMPC_depend:
13867 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13868, __PRETTY_FUNCTION__))
13868 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13868, __PRETTY_FUNCTION__))
;
13869 Res = ActOnOpenMPDependClause(
13870 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13871 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13872 break;
13873 case OMPC_map:
13874 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13875, __PRETTY_FUNCTION__))
13875 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13875, __PRETTY_FUNCTION__))
;
13876 Res = ActOnOpenMPMapClause(
13877 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13878 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13879 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13880 break;
13881 case OMPC_to:
13882 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
13883 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
13884 ColonLoc, VarList, Locs);
13885 break;
13886 case OMPC_from:
13887 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
13888 ReductionOrMapperIdScopeSpec,
13889 ReductionOrMapperId, ColonLoc, VarList, Locs);
13890 break;
13891 case OMPC_use_device_ptr:
13892 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13893 break;
13894 case OMPC_use_device_addr:
13895 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13896 break;
13897 case OMPC_is_device_ptr:
13898 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13899 break;
13900 case OMPC_allocate:
13901 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13902 LParenLoc, ColonLoc, EndLoc);
13903 break;
13904 case OMPC_nontemporal:
13905 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13906 break;
13907 case OMPC_inclusive:
13908 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13909 break;
13910 case OMPC_exclusive:
13911 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13912 break;
13913 case OMPC_affinity:
13914 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13915 DepModOrTailExpr, VarList);
13916 break;
13917 case OMPC_if:
13918 case OMPC_depobj:
13919 case OMPC_final:
13920 case OMPC_num_threads:
13921 case OMPC_safelen:
13922 case OMPC_simdlen:
13923 case OMPC_allocator:
13924 case OMPC_collapse:
13925 case OMPC_default:
13926 case OMPC_proc_bind:
13927 case OMPC_schedule:
13928 case OMPC_ordered:
13929 case OMPC_nowait:
13930 case OMPC_untied:
13931 case OMPC_mergeable:
13932 case OMPC_threadprivate:
13933 case OMPC_read:
13934 case OMPC_write:
13935 case OMPC_update:
13936 case OMPC_capture:
13937 case OMPC_seq_cst:
13938 case OMPC_acq_rel:
13939 case OMPC_acquire:
13940 case OMPC_release:
13941 case OMPC_relaxed:
13942 case OMPC_device:
13943 case OMPC_threads:
13944 case OMPC_simd:
13945 case OMPC_num_teams:
13946 case OMPC_thread_limit:
13947 case OMPC_priority:
13948 case OMPC_grainsize:
13949 case OMPC_nogroup:
13950 case OMPC_num_tasks:
13951 case OMPC_hint:
13952 case OMPC_dist_schedule:
13953 case OMPC_defaultmap:
13954 case OMPC_unknown:
13955 case OMPC_uniform:
13956 case OMPC_unified_address:
13957 case OMPC_unified_shared_memory:
13958 case OMPC_reverse_offload:
13959 case OMPC_dynamic_allocators:
13960 case OMPC_atomic_default_mem_order:
13961 case OMPC_device_type:
13962 case OMPC_match:
13963 case OMPC_order:
13964 case OMPC_destroy:
13965 case OMPC_detach:
13966 case OMPC_uses_allocators:
13967 default:
13968 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13968)
;
13969 }
13970 return Res;
13971}
13972
13973ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13974 ExprObjectKind OK, SourceLocation Loc) {
13975 ExprResult Res = BuildDeclRefExpr(
13976 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13977 if (!Res.isUsable())
13978 return ExprError();
13979 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13980 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13981 if (!Res.isUsable())
13982 return ExprError();
13983 }
13984 if (VK != VK_LValue && Res.get()->isGLValue()) {
13985 Res = DefaultLvalueConversion(Res.get());
13986 if (!Res.isUsable())
13987 return ExprError();
13988 }
13989 return Res;
13990}
13991
13992OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13993 SourceLocation StartLoc,
13994 SourceLocation LParenLoc,
13995 SourceLocation EndLoc) {
13996 SmallVector<Expr *, 8> Vars;
13997 SmallVector<Expr *, 8> PrivateCopies;
13998 for (Expr *RefExpr : VarList) {
13999 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 13999, __PRETTY_FUNCTION__))
;
14000 SourceLocation ELoc;
14001 SourceRange ERange;
14002 Expr *SimpleRefExpr = RefExpr;
14003 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14004 if (Res.second) {
14005 // It will be analyzed later.
14006 Vars.push_back(RefExpr);
14007 PrivateCopies.push_back(nullptr);
14008 }
14009 ValueDecl *D = Res.first;
14010 if (!D)
14011 continue;
14012
14013 QualType Type = D->getType();
14014 auto *VD = dyn_cast<VarDecl>(D);
14015
14016 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14017 // A variable that appears in a private clause must not have an incomplete
14018 // type or a reference type.
14019 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
14020 continue;
14021 Type = Type.getNonReferenceType();
14022
14023 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14024 // A variable that is privatized must not have a const-qualified type
14025 // unless it is of class type with a mutable member. This restriction does
14026 // not apply to the firstprivate clause.
14027 //
14028 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
14029 // A variable that appears in a private clause must not have a
14030 // const-qualified type unless it is of class type with a mutable member.
14031 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
14032 continue;
14033
14034 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14035 // in a Construct]
14036 // Variables with the predetermined data-sharing attributes may not be
14037 // listed in data-sharing attributes clauses, except for the cases
14038 // listed below. For these exceptions only, listing a predetermined
14039 // variable in a data-sharing attribute clause is allowed and overrides
14040 // the variable's predetermined data-sharing attributes.
14041 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14042 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
14043 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14044 << getOpenMPClauseName(OMPC_private);
14045 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14046 continue;
14047 }
14048
14049 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14050 // Variably modified types are not supported for tasks.
14051 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14052 isOpenMPTaskingDirective(CurrDir)) {
14053 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14054 << getOpenMPClauseName(OMPC_private) << Type
14055 << getOpenMPDirectiveName(CurrDir);
14056 bool IsDecl =
14057 !VD ||
14058 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14059 Diag(D->getLocation(),
14060 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14061 << D;
14062 continue;
14063 }
14064
14065 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14066 // A list item cannot appear in both a map clause and a data-sharing
14067 // attribute clause on the same construct
14068 //
14069 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14070 // A list item cannot appear in both a map clause and a data-sharing
14071 // attribute clause on the same construct unless the construct is a
14072 // combined construct.
14073 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
14074 CurrDir == OMPD_target) {
14075 OpenMPClauseKind ConflictKind;
14076 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
14077 VD, /*CurrentRegionOnly=*/true,
14078 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
14079 OpenMPClauseKind WhereFoundClauseKind) -> bool {
14080 ConflictKind = WhereFoundClauseKind;
14081 return true;
14082 })) {
14083 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14084 << getOpenMPClauseName(OMPC_private)
14085 << getOpenMPClauseName(ConflictKind)
14086 << getOpenMPDirectiveName(CurrDir);
14087 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14088 continue;
14089 }
14090 }
14091
14092 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
14093 // A variable of class type (or array thereof) that appears in a private
14094 // clause requires an accessible, unambiguous default constructor for the
14095 // class type.
14096 // Generate helper private variable and initialize it with the default
14097 // value. The address of the original variable is replaced by the address of
14098 // the new private variable in CodeGen. This new variable is not added to
14099 // IdResolver, so the code in the OpenMP region uses original variable for
14100 // proper diagnostics.
14101 Type = Type.getUnqualifiedType();
14102 VarDecl *VDPrivate =
14103 buildVarDecl(*this, ELoc, Type, D->getName(),
14104 D->hasAttrs() ? &D->getAttrs() : nullptr,
14105 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14106 ActOnUninitializedDecl(VDPrivate);
14107 if (VDPrivate->isInvalidDecl())
14108 continue;
14109 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14110 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
14111
14112 DeclRefExpr *Ref = nullptr;
14113 if (!VD && !CurContext->isDependentContext())
14114 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14115 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
14116 Vars.push_back((VD || CurContext->isDependentContext())
14117 ? RefExpr->IgnoreParens()
14118 : Ref);
14119 PrivateCopies.push_back(VDPrivateRefExpr);
14120 }
14121
14122 if (Vars.empty())
14123 return nullptr;
14124
14125 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
14126 PrivateCopies);
14127}
14128
14129namespace {
14130class DiagsUninitializedSeveretyRAII {
14131private:
14132 DiagnosticsEngine &Diags;
14133 SourceLocation SavedLoc;
14134 bool IsIgnored = false;
14135
14136public:
14137 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
14138 bool IsIgnored)
14139 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
14140 if (!IsIgnored) {
14141 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
14142 /*Map*/ diag::Severity::Ignored, Loc);
14143 }
14144 }
14145 ~DiagsUninitializedSeveretyRAII() {
14146 if (!IsIgnored)
14147 Diags.popMappings(SavedLoc);
14148 }
14149};
14150}
14151
14152OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
14153 SourceLocation StartLoc,
14154 SourceLocation LParenLoc,
14155 SourceLocation EndLoc) {
14156 SmallVector<Expr *, 8> Vars;
14157 SmallVector<Expr *, 8> PrivateCopies;
14158 SmallVector<Expr *, 8> Inits;
14159 SmallVector<Decl *, 4> ExprCaptures;
14160 bool IsImplicitClause =
14161 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
14162 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
14163
14164 for (Expr *RefExpr : VarList) {
14165 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 14165, __PRETTY_FUNCTION__))
;
14166 SourceLocation ELoc;
14167 SourceRange ERange;
14168 Expr *SimpleRefExpr = RefExpr;
14169 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14170 if (Res.second) {
14171 // It will be analyzed later.
14172 Vars.push_back(RefExpr);
14173 PrivateCopies.push_back(nullptr);
14174 Inits.push_back(nullptr);
14175 }
14176 ValueDecl *D = Res.first;
14177 if (!D)
14178 continue;
14179
14180 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
14181 QualType Type = D->getType();
14182 auto *VD = dyn_cast<VarDecl>(D);
14183
14184 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14185 // A variable that appears in a private clause must not have an incomplete
14186 // type or a reference type.
14187 if (RequireCompleteType(ELoc, Type,
14188 diag::err_omp_firstprivate_incomplete_type))
14189 continue;
14190 Type = Type.getNonReferenceType();
14191
14192 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
14193 // A variable of class type (or array thereof) that appears in a private
14194 // clause requires an accessible, unambiguous copy constructor for the
14195 // class type.
14196 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14197
14198 // If an implicit firstprivate variable found it was checked already.
14199 DSAStackTy::DSAVarData TopDVar;
14200 if (!IsImplicitClause) {
14201 DSAStackTy::DSAVarData DVar =
14202 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14203 TopDVar = DVar;
14204 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14205 bool IsConstant = ElemType.isConstant(Context);
14206 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
14207 // A list item that specifies a given variable may not appear in more
14208 // than one clause on the same directive, except that a variable may be
14209 // specified in both firstprivate and lastprivate clauses.
14210 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14211 // A list item may appear in a firstprivate or lastprivate clause but not
14212 // both.
14213 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
14214 (isOpenMPDistributeDirective(CurrDir) ||
14215 DVar.CKind != OMPC_lastprivate) &&
14216 DVar.RefExpr) {
14217 Diag(ELoc, diag::err_omp_wrong_dsa)
14218 << getOpenMPClauseName(DVar.CKind)
14219 << getOpenMPClauseName(OMPC_firstprivate);
14220 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14221 continue;
14222 }
14223
14224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14225 // in a Construct]
14226 // Variables with the predetermined data-sharing attributes may not be
14227 // listed in data-sharing attributes clauses, except for the cases
14228 // listed below. For these exceptions only, listing a predetermined
14229 // variable in a data-sharing attribute clause is allowed and overrides
14230 // the variable's predetermined data-sharing attributes.
14231 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14232 // in a Construct, C/C++, p.2]
14233 // Variables with const-qualified type having no mutable member may be
14234 // listed in a firstprivate clause, even if they are static data members.
14235 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
14236 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
14237 Diag(ELoc, diag::err_omp_wrong_dsa)
14238 << getOpenMPClauseName(DVar.CKind)
14239 << getOpenMPClauseName(OMPC_firstprivate);
14240 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14241 continue;
14242 }
14243
14244 // OpenMP [2.9.3.4, Restrictions, p.2]
14245 // A list item that is private within a parallel region must not appear
14246 // in a firstprivate clause on a worksharing construct if any of the
14247 // worksharing regions arising from the worksharing construct ever bind
14248 // to any of the parallel regions arising from the parallel construct.
14249 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14250 // A list item that is private within a teams region must not appear in a
14251 // firstprivate clause on a distribute construct if any of the distribute
14252 // regions arising from the distribute construct ever bind to any of the
14253 // teams regions arising from the teams construct.
14254 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14255 // A list item that appears in a reduction clause of a teams construct
14256 // must not appear in a firstprivate clause on a distribute construct if
14257 // any of the distribute regions arising from the distribute construct
14258 // ever bind to any of the teams regions arising from the teams construct.
14259 if ((isOpenMPWorksharingDirective(CurrDir) ||
14260 isOpenMPDistributeDirective(CurrDir)) &&
14261 !isOpenMPParallelDirective(CurrDir) &&
14262 !isOpenMPTeamsDirective(CurrDir)) {
14263 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14264 if (DVar.CKind != OMPC_shared &&
14265 (isOpenMPParallelDirective(DVar.DKind) ||
14266 isOpenMPTeamsDirective(DVar.DKind) ||
14267 DVar.DKind == OMPD_unknown)) {
14268 Diag(ELoc, diag::err_omp_required_access)
14269 << getOpenMPClauseName(OMPC_firstprivate)
14270 << getOpenMPClauseName(OMPC_shared);
14271 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14272 continue;
14273 }
14274 }
14275 // OpenMP [2.9.3.4, Restrictions, p.3]
14276 // A list item that appears in a reduction clause of a parallel construct
14277 // must not appear in a firstprivate clause on a worksharing or task
14278 // construct if any of the worksharing or task regions arising from the
14279 // worksharing or task construct ever bind to any of the parallel regions
14280 // arising from the parallel construct.
14281 // OpenMP [2.9.3.4, Restrictions, p.4]
14282 // A list item that appears in a reduction clause in worksharing
14283 // construct must not appear in a firstprivate clause in a task construct
14284 // encountered during execution of any of the worksharing regions arising
14285 // from the worksharing construct.
14286 if (isOpenMPTaskingDirective(CurrDir)) {
14287 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
14288 D,
14289 [](OpenMPClauseKind C, bool AppliedToPointee) {
14290 return C == OMPC_reduction && !AppliedToPointee;
14291 },
14292 [](OpenMPDirectiveKind K) {
14293 return isOpenMPParallelDirective(K) ||
14294 isOpenMPWorksharingDirective(K) ||
14295 isOpenMPTeamsDirective(K);
14296 },
14297 /*FromParent=*/true);
14298 if (DVar.CKind == OMPC_reduction &&
14299 (isOpenMPParallelDirective(DVar.DKind) ||
14300 isOpenMPWorksharingDirective(DVar.DKind) ||
14301 isOpenMPTeamsDirective(DVar.DKind))) {
14302 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14303 << getOpenMPDirectiveName(DVar.DKind);
14304 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14305 continue;
14306 }
14307 }
14308
14309 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14310 // A list item cannot appear in both a map clause and a data-sharing
14311 // attribute clause on the same construct
14312 //
14313 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14314 // A list item cannot appear in both a map clause and a data-sharing
14315 // attribute clause on the same construct unless the construct is a
14316 // combined construct.
14317 if ((LangOpts.OpenMP <= 45 &&
14318 isOpenMPTargetExecutionDirective(CurrDir)) ||
14319 CurrDir == OMPD_target) {
14320 OpenMPClauseKind ConflictKind;
14321 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
14322 VD, /*CurrentRegionOnly=*/true,
14323 [&ConflictKind](
14324 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14325 OpenMPClauseKind WhereFoundClauseKind) {
14326 ConflictKind = WhereFoundClauseKind;
14327 return true;
14328 })) {
14329 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14330 << getOpenMPClauseName(OMPC_firstprivate)
14331 << getOpenMPClauseName(ConflictKind)
14332 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14333 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14334 continue;
14335 }
14336 }
14337 }
14338
14339 // Variably modified types are not supported for tasks.
14340 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14341 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
14342 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14343 << getOpenMPClauseName(OMPC_firstprivate) << Type
14344 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14345 bool IsDecl =
14346 !VD ||
14347 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14348 Diag(D->getLocation(),
14349 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14350 << D;
14351 continue;
14352 }
14353
14354 Type = Type.getUnqualifiedType();
14355 VarDecl *VDPrivate =
14356 buildVarDecl(*this, ELoc, Type, D->getName(),
14357 D->hasAttrs() ? &D->getAttrs() : nullptr,
14358 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14359 // Generate helper private variable and initialize it with the value of the
14360 // original variable. The address of the original variable is replaced by
14361 // the address of the new private variable in the CodeGen. This new variable
14362 // is not added to IdResolver, so the code in the OpenMP region uses
14363 // original variable for proper diagnostics and variable capturing.
14364 Expr *VDInitRefExpr = nullptr;
14365 // For arrays generate initializer for single element and replace it by the
14366 // original array element in CodeGen.
14367 if (Type->isArrayType()) {
14368 VarDecl *VDInit =
14369 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14370 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14371 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14372 ElemType = ElemType.getUnqualifiedType();
14373 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14374 ".firstprivate.temp");
14375 InitializedEntity Entity =
14376 InitializedEntity::InitializeVariable(VDInitTemp);
14377 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14378
14379 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14380 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14381 if (Result.isInvalid())
14382 VDPrivate->setInvalidDecl();
14383 else
14384 VDPrivate->setInit(Result.getAs<Expr>());
14385 // Remove temp variable declaration.
14386 Context.Deallocate(VDInitTemp);
14387 } else {
14388 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14389 ".firstprivate.temp");
14390 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14391 RefExpr->getExprLoc());
14392 AddInitializerToDecl(VDPrivate,
14393 DefaultLvalueConversion(VDInitRefExpr).get(),
14394 /*DirectInit=*/false);
14395 }
14396 if (VDPrivate->isInvalidDecl()) {
14397 if (IsImplicitClause) {
14398 Diag(RefExpr->getExprLoc(),
14399 diag::note_omp_task_predetermined_firstprivate_here);
14400 }
14401 continue;
14402 }
14403 CurContext->addDecl(VDPrivate);
14404 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14405 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14406 RefExpr->getExprLoc());
14407 DeclRefExpr *Ref = nullptr;
14408 if (!VD && !CurContext->isDependentContext()) {
14409 if (TopDVar.CKind == OMPC_lastprivate) {
14410 Ref = TopDVar.PrivateCopy;
14411 } else {
14412 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14413 if (!isOpenMPCapturedDecl(D))
14414 ExprCaptures.push_back(Ref->getDecl());
14415 }
14416 }
14417 if (!IsImplicitClause)
14418 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14419 Vars.push_back((VD || CurContext->isDependentContext())
14420 ? RefExpr->IgnoreParens()
14421 : Ref);
14422 PrivateCopies.push_back(VDPrivateRefExpr);
14423 Inits.push_back(VDInitRefExpr);
14424 }
14425
14426 if (Vars.empty())
14427 return nullptr;
14428
14429 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14430 Vars, PrivateCopies, Inits,
14431 buildPreInits(Context, ExprCaptures));
14432}
14433
14434OMPClause *Sema::ActOnOpenMPLastprivateClause(
14435 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14436 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14437 SourceLocation LParenLoc, SourceLocation EndLoc) {
14438 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14439 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 14439, __PRETTY_FUNCTION__))
;
14440 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14441 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14442 /*Last=*/OMPC_LASTPRIVATE_unknown)
14443 << getOpenMPClauseName(OMPC_lastprivate);
14444 return nullptr;
14445 }
14446
14447 SmallVector<Expr *, 8> Vars;
14448 SmallVector<Expr *, 8> SrcExprs;
14449 SmallVector<Expr *, 8> DstExprs;
14450 SmallVector<Expr *, 8> AssignmentOps;
14451 SmallVector<Decl *, 4> ExprCaptures;
14452 SmallVector<Expr *, 4> ExprPostUpdates;
14453 for (Expr *RefExpr : VarList) {
14454 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 14454, __PRETTY_FUNCTION__))
;
14455 SourceLocation ELoc;
14456 SourceRange ERange;
14457 Expr *SimpleRefExpr = RefExpr;
14458 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14459 if (Res.second) {
14460 // It will be analyzed later.
14461 Vars.push_back(RefExpr);
14462 SrcExprs.push_back(nullptr);
14463 DstExprs.push_back(nullptr);
14464 AssignmentOps.push_back(nullptr);
14465 }
14466 ValueDecl *D = Res.first;
14467 if (!D)
14468 continue;
14469
14470 QualType Type = D->getType();
14471 auto *VD = dyn_cast<VarDecl>(D);
14472
14473 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14474 // A variable that appears in a lastprivate clause must not have an
14475 // incomplete type or a reference type.
14476 if (RequireCompleteType(ELoc, Type,
14477 diag::err_omp_lastprivate_incomplete_type))
14478 continue;
14479 Type = Type.getNonReferenceType();
14480
14481 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14482 // A variable that is privatized must not have a const-qualified type
14483 // unless it is of class type with a mutable member. This restriction does
14484 // not apply to the firstprivate clause.
14485 //
14486 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14487 // A variable that appears in a lastprivate clause must not have a
14488 // const-qualified type unless it is of class type with a mutable member.
14489 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14490 continue;
14491
14492 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14493 // A list item that appears in a lastprivate clause with the conditional
14494 // modifier must be a scalar variable.
14495 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14496 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14497 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14498 VarDecl::DeclarationOnly;
14499 Diag(D->getLocation(),
14500 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14501 << D;
14502 continue;
14503 }
14504
14505 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14506 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14507 // in a Construct]
14508 // Variables with the predetermined data-sharing attributes may not be
14509 // listed in data-sharing attributes clauses, except for the cases
14510 // listed below.
14511 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14512 // A list item may appear in a firstprivate or lastprivate clause but not
14513 // both.
14514 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14515 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14516 (isOpenMPDistributeDirective(CurrDir) ||
14517 DVar.CKind != OMPC_firstprivate) &&
14518 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14519 Diag(ELoc, diag::err_omp_wrong_dsa)
14520 << getOpenMPClauseName(DVar.CKind)
14521 << getOpenMPClauseName(OMPC_lastprivate);
14522 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14523 continue;
14524 }
14525
14526 // OpenMP [2.14.3.5, Restrictions, p.2]
14527 // A list item that is private within a parallel region, or that appears in
14528 // the reduction clause of a parallel construct, must not appear in a
14529 // lastprivate clause on a worksharing construct if any of the corresponding
14530 // worksharing regions ever binds to any of the corresponding parallel
14531 // regions.
14532 DSAStackTy::DSAVarData TopDVar = DVar;
14533 if (isOpenMPWorksharingDirective(CurrDir) &&
14534 !isOpenMPParallelDirective(CurrDir) &&
14535 !isOpenMPTeamsDirective(CurrDir)) {
14536 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14537 if (DVar.CKind != OMPC_shared) {
14538 Diag(ELoc, diag::err_omp_required_access)
14539 << getOpenMPClauseName(OMPC_lastprivate)
14540 << getOpenMPClauseName(OMPC_shared);
14541 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14542 continue;
14543 }
14544 }
14545
14546 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14547 // A variable of class type (or array thereof) that appears in a
14548 // lastprivate clause requires an accessible, unambiguous default
14549 // constructor for the class type, unless the list item is also specified
14550 // in a firstprivate clause.
14551 // A variable of class type (or array thereof) that appears in a
14552 // lastprivate clause requires an accessible, unambiguous copy assignment
14553 // operator for the class type.
14554 Type = Context.getBaseElementType(Type).getNonReferenceType();
14555 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14556 Type.getUnqualifiedType(), ".lastprivate.src",
14557 D->hasAttrs() ? &D->getAttrs() : nullptr);
14558 DeclRefExpr *PseudoSrcExpr =
14559 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14560 VarDecl *DstVD =
14561 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14562 D->hasAttrs() ? &D->getAttrs() : nullptr);
14563 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14564 // For arrays generate assignment operation for single element and replace
14565 // it by the original array element in CodeGen.
14566 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14567 PseudoDstExpr, PseudoSrcExpr);
14568 if (AssignmentOp.isInvalid())
14569 continue;
14570 AssignmentOp =
14571 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14572 if (AssignmentOp.isInvalid())
14573 continue;
14574
14575 DeclRefExpr *Ref = nullptr;
14576 if (!VD && !CurContext->isDependentContext()) {
14577 if (TopDVar.CKind == OMPC_firstprivate) {
14578 Ref = TopDVar.PrivateCopy;
14579 } else {
14580 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14581 if (!isOpenMPCapturedDecl(D))
14582 ExprCaptures.push_back(Ref->getDecl());
14583 }
14584 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
14585 (!isOpenMPCapturedDecl(D) &&
14586 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14587 ExprResult RefRes = DefaultLvalueConversion(Ref);
14588 if (!RefRes.isUsable())
14589 continue;
14590 ExprResult PostUpdateRes =
14591 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14592 RefRes.get());
14593 if (!PostUpdateRes.isUsable())
14594 continue;
14595 ExprPostUpdates.push_back(
14596 IgnoredValueConversions(PostUpdateRes.get()).get());
14597 }
14598 }
14599 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14600 Vars.push_back((VD || CurContext->isDependentContext())
14601 ? RefExpr->IgnoreParens()
14602 : Ref);
14603 SrcExprs.push_back(PseudoSrcExpr);
14604 DstExprs.push_back(PseudoDstExpr);
14605 AssignmentOps.push_back(AssignmentOp.get());
14606 }
14607
14608 if (Vars.empty())
14609 return nullptr;
14610
14611 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14612 Vars, SrcExprs, DstExprs, AssignmentOps,
14613 LPKind, LPKindLoc, ColonLoc,
14614 buildPreInits(Context, ExprCaptures),
14615 buildPostUpdate(*this, ExprPostUpdates));
14616}
14617
14618OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14619 SourceLocation StartLoc,
14620 SourceLocation LParenLoc,
14621 SourceLocation EndLoc) {
14622 SmallVector<Expr *, 8> Vars;
14623 for (Expr *RefExpr : VarList) {
14624 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 14624, __PRETTY_FUNCTION__))
;
14625 SourceLocation ELoc;
14626 SourceRange ERange;
14627 Expr *SimpleRefExpr = RefExpr;
14628 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14629 if (Res.second) {
14630 // It will be analyzed later.
14631 Vars.push_back(RefExpr);
14632 }
14633 ValueDecl *D = Res.first;
14634 if (!D)
14635 continue;
14636
14637 auto *VD = dyn_cast<VarDecl>(D);
14638 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14639 // in a Construct]
14640 // Variables with the predetermined data-sharing attributes may not be
14641 // listed in data-sharing attributes clauses, except for the cases
14642 // listed below. For these exceptions only, listing a predetermined
14643 // variable in a data-sharing attribute clause is allowed and overrides
14644 // the variable's predetermined data-sharing attributes.
14645 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14646 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14647 DVar.RefExpr) {
14648 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14649 << getOpenMPClauseName(OMPC_shared);
14650 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14651 continue;
14652 }
14653
14654 DeclRefExpr *Ref = nullptr;
14655 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14656 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14657 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14658 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14659 ? RefExpr->IgnoreParens()
14660 : Ref);
14661 }
14662
14663 if (Vars.empty())
14664 return nullptr;
14665
14666 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14667}
14668
14669namespace {
14670class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14671 DSAStackTy *Stack;
14672
14673public:
14674 bool VisitDeclRefExpr(DeclRefExpr *E) {
14675 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14676 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14677 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14678 return false;
14679 if (DVar.CKind != OMPC_unknown)
14680 return true;
14681 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14682 VD,
14683 [](OpenMPClauseKind C, bool AppliedToPointee) {
14684 return isOpenMPPrivate(C) && !AppliedToPointee;
14685 },
14686 [](OpenMPDirectiveKind) { return true; },
14687 /*FromParent=*/true);
14688 return DVarPrivate.CKind != OMPC_unknown;
14689 }
14690 return false;
14691 }
14692 bool VisitStmt(Stmt *S) {
14693 for (Stmt *Child : S->children()) {
14694 if (Child && Visit(Child))
14695 return true;
14696 }
14697 return false;
14698 }
14699 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14700};
14701} // namespace
14702
14703namespace {
14704// Transform MemberExpression for specified FieldDecl of current class to
14705// DeclRefExpr to specified OMPCapturedExprDecl.
14706class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14707 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14708 ValueDecl *Field = nullptr;
14709 DeclRefExpr *CapturedExpr = nullptr;
14710
14711public:
14712 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14713 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14714
14715 ExprResult TransformMemberExpr(MemberExpr *E) {
14716 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14717 E->getMemberDecl() == Field) {
14718 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14719 return CapturedExpr;
14720 }
14721 return BaseTransform::TransformMemberExpr(E);
14722 }
14723 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14724};
14725} // namespace
14726
14727template <typename T, typename U>
14728static T filterLookupForUDReductionAndMapper(
14729 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14730 for (U &Set : Lookups) {
14731 for (auto *D : Set) {
14732 if (T Res = Gen(cast<ValueDecl>(D)))
14733 return Res;
14734 }
14735 }
14736 return T();
14737}
14738
14739static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14740 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 14740, __PRETTY_FUNCTION__))
;
14741
14742 for (auto RD : D->redecls()) {
14743 // Don't bother with extra checks if we already know this one isn't visible.
14744 if (RD == D)
14745 continue;
14746
14747 auto ND = cast<NamedDecl>(RD);
14748 if (LookupResult::isVisible(SemaRef, ND))
14749 return ND;
14750 }
14751
14752 return nullptr;
14753}
14754
14755static void
14756argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14757 SourceLocation Loc, QualType Ty,
14758 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14759 // Find all of the associated namespaces and classes based on the
14760 // arguments we have.
14761 Sema::AssociatedNamespaceSet AssociatedNamespaces;
14762 Sema::AssociatedClassSet AssociatedClasses;
14763 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14764 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14765 AssociatedClasses);
14766
14767 // C++ [basic.lookup.argdep]p3:
14768 // Let X be the lookup set produced by unqualified lookup (3.4.1)
14769 // and let Y be the lookup set produced by argument dependent
14770 // lookup (defined as follows). If X contains [...] then Y is
14771 // empty. Otherwise Y is the set of declarations found in the
14772 // namespaces associated with the argument types as described
14773 // below. The set of declarations found by the lookup of the name
14774 // is the union of X and Y.
14775 //
14776 // Here, we compute Y and add its members to the overloaded
14777 // candidate set.
14778 for (auto *NS : AssociatedNamespaces) {
14779 // When considering an associated namespace, the lookup is the
14780 // same as the lookup performed when the associated namespace is
14781 // used as a qualifier (3.4.3.2) except that:
14782 //
14783 // -- Any using-directives in the associated namespace are
14784 // ignored.
14785 //
14786 // -- Any namespace-scope friend functions declared in
14787 // associated classes are visible within their respective
14788 // namespaces even if they are not visible during an ordinary
14789 // lookup (11.4).
14790 DeclContext::lookup_result R = NS->lookup(Id.getName());
14791 for (auto *D : R) {
14792 auto *Underlying = D;
14793 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14794 Underlying = USD->getTargetDecl();
14795
14796 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14797 !isa<OMPDeclareMapperDecl>(Underlying))
14798 continue;
14799
14800 if (!SemaRef.isVisible(D)) {
14801 D = findAcceptableDecl(SemaRef, D);
14802 if (!D)
14803 continue;
14804 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14805 Underlying = USD->getTargetDecl();
14806 }
14807 Lookups.emplace_back();
14808 Lookups.back().addDecl(Underlying);
14809 }
14810 }
14811}
14812
14813static ExprResult
14814buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14815 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14816 const DeclarationNameInfo &ReductionId, QualType Ty,
14817 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14818 if (ReductionIdScopeSpec.isInvalid())
14819 return ExprError();
14820 SmallVector<UnresolvedSet<8>, 4> Lookups;
14821 if (S) {
14822 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14823 Lookup.suppressDiagnostics();
14824 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14825 NamedDecl *D = Lookup.getRepresentativeDecl();
14826 do {
14827 S = S->getParent();
14828 } while (S && !S->isDeclScope(D));
14829 if (S)
14830 S = S->getParent();
14831 Lookups.emplace_back();
14832 Lookups.back().append(Lookup.begin(), Lookup.end());
14833 Lookup.clear();
14834 }
14835 } else if (auto *ULE =
14836 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14837 Lookups.push_back(UnresolvedSet<8>());
14838 Decl *PrevD = nullptr;
14839 for (NamedDecl *D : ULE->decls()) {
14840 if (D == PrevD)
14841 Lookups.push_back(UnresolvedSet<8>());
14842 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14843 Lookups.back().addDecl(DRD);
14844 PrevD = D;
14845 }
14846 }
14847 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14848 Ty->isInstantiationDependentType() ||
14849 Ty->containsUnexpandedParameterPack() ||
14850 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14851 return !D->isInvalidDecl() &&
14852 (D->getType()->isDependentType() ||
14853 D->getType()->isInstantiationDependentType() ||
14854 D->getType()->containsUnexpandedParameterPack());
14855 })) {
14856 UnresolvedSet<8> ResSet;
14857 for (const UnresolvedSet<8> &Set : Lookups) {
14858 if (Set.empty())
14859 continue;
14860 ResSet.append(Set.begin(), Set.end());
14861 // The last item marks the end of all declarations at the specified scope.
14862 ResSet.addDecl(Set[Set.size() - 1]);
14863 }
14864 return UnresolvedLookupExpr::Create(
14865 SemaRef.Context, /*NamingClass=*/nullptr,
14866 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14867 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14868 }
14869 // Lookup inside the classes.
14870 // C++ [over.match.oper]p3:
14871 // For a unary operator @ with an operand of a type whose
14872 // cv-unqualified version is T1, and for a binary operator @ with
14873 // a left operand of a type whose cv-unqualified version is T1 and
14874 // a right operand of a type whose cv-unqualified version is T2,
14875 // three sets of candidate functions, designated member
14876 // candidates, non-member candidates and built-in candidates, are
14877 // constructed as follows:
14878 // -- If T1 is a complete class type or a class currently being
14879 // defined, the set of member candidates is the result of the
14880 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14881 // the set of member candidates is empty.
14882 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14883 Lookup.suppressDiagnostics();
14884 if (const auto *TyRec = Ty->getAs<RecordType>()) {
14885 // Complete the type if it can be completed.
14886 // If the type is neither complete nor being defined, bail out now.
14887 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14888 TyRec->getDecl()->getDefinition()) {
14889 Lookup.clear();
14890 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14891 if (Lookup.empty()) {
14892 Lookups.emplace_back();
14893 Lookups.back().append(Lookup.begin(), Lookup.end());
14894 }
14895 }
14896 }
14897 // Perform ADL.
14898 if (SemaRef.getLangOpts().CPlusPlus)
14899 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14900 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14901 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14902 if (!D->isInvalidDecl() &&
14903 SemaRef.Context.hasSameType(D->getType(), Ty))
14904 return D;
14905 return nullptr;
14906 }))
14907 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14908 VK_LValue, Loc);
14909 if (SemaRef.getLangOpts().CPlusPlus) {
14910 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14911 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14912 if (!D->isInvalidDecl() &&
14913 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14914 !Ty.isMoreQualifiedThan(D->getType()))
14915 return D;
14916 return nullptr;
14917 })) {
14918 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14919 /*DetectVirtual=*/false);
14920 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14921 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14922 VD->getType().getUnqualifiedType()))) {
14923 if (SemaRef.CheckBaseClassAccess(
14924 Loc, VD->getType(), Ty, Paths.front(),
14925 /*DiagID=*/0) != Sema::AR_inaccessible) {
14926 SemaRef.BuildBasePathArray(Paths, BasePath);
14927 return SemaRef.BuildDeclRefExpr(
14928 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14929 }
14930 }
14931 }
14932 }
14933 }
14934 if (ReductionIdScopeSpec.isSet()) {
14935 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14936 << Ty << Range;
14937 return ExprError();
14938 }
14939 return ExprEmpty();
14940}
14941
14942namespace {
14943/// Data for the reduction-based clauses.
14944struct ReductionData {
14945 /// List of original reduction items.
14946 SmallVector<Expr *, 8> Vars;
14947 /// List of private copies of the reduction items.
14948 SmallVector<Expr *, 8> Privates;
14949 /// LHS expressions for the reduction_op expressions.
14950 SmallVector<Expr *, 8> LHSs;
14951 /// RHS expressions for the reduction_op expressions.
14952 SmallVector<Expr *, 8> RHSs;
14953 /// Reduction operation expression.
14954 SmallVector<Expr *, 8> ReductionOps;
14955 /// inscan copy operation expressions.
14956 SmallVector<Expr *, 8> InscanCopyOps;
14957 /// inscan copy temp array expressions for prefix sums.
14958 SmallVector<Expr *, 8> InscanCopyArrayTemps;
14959 /// inscan copy temp array element expressions for prefix sums.
14960 SmallVector<Expr *, 8> InscanCopyArrayElems;
14961 /// Taskgroup descriptors for the corresponding reduction items in
14962 /// in_reduction clauses.
14963 SmallVector<Expr *, 8> TaskgroupDescriptors;
14964 /// List of captures for clause.
14965 SmallVector<Decl *, 4> ExprCaptures;
14966 /// List of postupdate expressions.
14967 SmallVector<Expr *, 4> ExprPostUpdates;
14968 /// Reduction modifier.
14969 unsigned RedModifier = 0;
14970 ReductionData() = delete;
14971 /// Reserves required memory for the reduction data.
14972 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14973 Vars.reserve(Size);
14974 Privates.reserve(Size);
14975 LHSs.reserve(Size);
14976 RHSs.reserve(Size);
14977 ReductionOps.reserve(Size);
14978 if (RedModifier == OMPC_REDUCTION_inscan) {
14979 InscanCopyOps.reserve(Size);
14980 InscanCopyArrayTemps.reserve(Size);
14981 InscanCopyArrayElems.reserve(Size);
14982 }
14983 TaskgroupDescriptors.reserve(Size);
14984 ExprCaptures.reserve(Size);
14985 ExprPostUpdates.reserve(Size);
14986 }
14987 /// Stores reduction item and reduction operation only (required for dependent
14988 /// reduction item).
14989 void push(Expr *Item, Expr *ReductionOp) {
14990 Vars.emplace_back(Item);
14991 Privates.emplace_back(nullptr);
14992 LHSs.emplace_back(nullptr);
14993 RHSs.emplace_back(nullptr);
14994 ReductionOps.emplace_back(ReductionOp);
14995 TaskgroupDescriptors.emplace_back(nullptr);
14996 if (RedModifier == OMPC_REDUCTION_inscan) {
14997 InscanCopyOps.push_back(nullptr);
14998 InscanCopyArrayTemps.push_back(nullptr);
14999 InscanCopyArrayElems.push_back(nullptr);
15000 }
15001 }
15002 /// Stores reduction data.
15003 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
15004 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
15005 Expr *CopyArrayElem) {
15006 Vars.emplace_back(Item);
15007 Privates.emplace_back(Private);
15008 LHSs.emplace_back(LHS);
15009 RHSs.emplace_back(RHS);
15010 ReductionOps.emplace_back(ReductionOp);
15011 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
15012 if (RedModifier == OMPC_REDUCTION_inscan) {
15013 InscanCopyOps.push_back(CopyOp);
15014 InscanCopyArrayTemps.push_back(CopyArrayTemp);
15015 InscanCopyArrayElems.push_back(CopyArrayElem);
15016 } else {
15017 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 15019, __PRETTY_FUNCTION__))
15018 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 15019, __PRETTY_FUNCTION__))
15019 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 15019, __PRETTY_FUNCTION__))
;
15020 }
15021 }
15022};
15023} // namespace
15024
15025static bool checkOMPArraySectionConstantForReduction(
15026 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
15027 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
15028 const Expr *Length = OASE->getLength();
15029 if (Length == nullptr) {
15030 // For array sections of the form [1:] or [:], we would need to analyze
15031 // the lower bound...
15032 if (OASE->getColonLocFirst().isValid())
15033 return false;
15034
15035 // This is an array subscript which has implicit length 1!
15036 SingleElement = true;
15037 ArraySizes.push_back(llvm::APSInt::get(1));
15038 } else {
15039 Expr::EvalResult Result;
15040 if (!Length->EvaluateAsInt(Result, Context))
15041 return false;
15042
15043 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15044 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
15045 ArraySizes.push_back(ConstantLengthValue);
15046 }
15047
15048 // Get the base of this array section and walk up from there.
15049 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
15050
15051 // We require length = 1 for all array sections except the right-most to
15052 // guarantee that the memory region is contiguous and has no holes in it.
15053 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
15054 Length = TempOASE->getLength();
15055 if (Length == nullptr) {
15056 // For array sections of the form [1:] or [:], we would need to analyze
15057 // the lower bound...
15058 if (OASE->getColonLocFirst().isValid())
15059 return false;
15060
15061 // This is an array subscript which has implicit length 1!
15062 ArraySizes.push_back(llvm::APSInt::get(1));
15063 } else {
15064 Expr::EvalResult Result;
15065 if (!Length->EvaluateAsInt(Result, Context))
15066 return false;
15067
15068 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15069 if (ConstantLengthValue.getSExtValue() != 1)
15070 return false;
15071
15072 ArraySizes.push_back(ConstantLengthValue);
15073 }
15074 Base = TempOASE->getBase()->IgnoreParenImpCasts();
15075 }
15076
15077 // If we have a single element, we don't need to add the implicit lengths.
15078 if (!SingleElement) {
15079 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
15080 // Has implicit length 1!
15081 ArraySizes.push_back(llvm::APSInt::get(1));
15082 Base = TempASE->getBase()->IgnoreParenImpCasts();
15083 }
15084 }
15085
15086 // This array section can be privatized as a single value or as a constant
15087 // sized array.
15088 return true;
15089}
15090
15091static bool actOnOMPReductionKindClause(
15092 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
15093 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15094 SourceLocation ColonLoc, SourceLocation EndLoc,
15095 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15096 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
15097 DeclarationName DN = ReductionId.getName();
15098 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
15099 BinaryOperatorKind BOK = BO_Comma;
15100
15101 ASTContext &Context = S.Context;
15102 // OpenMP [2.14.3.6, reduction clause]
15103 // C
15104 // reduction-identifier is either an identifier or one of the following
15105 // operators: +, -, *, &, |, ^, && and ||
15106 // C++
15107 // reduction-identifier is either an id-expression or one of the following
15108 // operators: +, -, *, &, |, ^, && and ||
15109 switch (OOK) {
15110 case OO_Plus:
15111 case OO_Minus:
15112 BOK = BO_Add;
15113 break;
15114 case OO_Star:
15115 BOK = BO_Mul;
15116 break;
15117 case OO_Amp:
15118 BOK = BO_And;
15119 break;
15120 case OO_Pipe:
15121 BOK = BO_Or;
15122 break;
15123 case OO_Caret:
15124 BOK = BO_Xor;
15125 break;
15126 case OO_AmpAmp:
15127 BOK = BO_LAnd;
15128 break;
15129 case OO_PipePipe:
15130 BOK = BO_LOr;
15131 break;
15132 case OO_New:
15133 case OO_Delete:
15134 case OO_Array_New:
15135 case OO_Array_Delete:
15136 case OO_Slash:
15137 case OO_Percent:
15138 case OO_Tilde:
15139 case OO_Exclaim:
15140 case OO_Equal:
15141 case OO_Less:
15142 case OO_Greater:
15143 case OO_LessEqual:
15144 case OO_GreaterEqual:
15145 case OO_PlusEqual:
15146 case OO_MinusEqual:
15147 case OO_StarEqual:
15148 case OO_SlashEqual:
15149 case OO_PercentEqual:
15150 case OO_CaretEqual:
15151 case OO_AmpEqual:
15152 case OO_PipeEqual:
15153 case OO_LessLess:
15154 case OO_GreaterGreater:
15155 case OO_LessLessEqual:
15156 case OO_GreaterGreaterEqual:
15157 case OO_EqualEqual:
15158 case OO_ExclaimEqual:
15159 case OO_Spaceship:
15160 case OO_PlusPlus:
15161 case OO_MinusMinus:
15162 case OO_Comma:
15163 case OO_ArrowStar:
15164 case OO_Arrow:
15165 case OO_Call:
15166 case OO_Subscript:
15167 case OO_Conditional:
15168 case OO_Coawait:
15169 case NUM_OVERLOADED_OPERATORS:
15170 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 15170)
;
15171 case OO_None:
15172 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
15173 if (II->isStr("max"))
15174 BOK = BO_GT;
15175 else if (II->isStr("min"))
15176 BOK = BO_LT;
15177 }
15178 break;
15179 }
15180 SourceRange ReductionIdRange;
15181 if (ReductionIdScopeSpec.isValid())
15182 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
15183 else
15184 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
15185 ReductionIdRange.setEnd(ReductionId.getEndLoc());
15186
15187 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
15188 bool FirstIter = true;
15189 for (Expr *RefExpr : VarList) {
15190 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 15190, __PRETTY_FUNCTION__))
;
15191 // OpenMP [2.1, C/C++]
15192 // A list item is a variable or array section, subject to the restrictions
15193 // specified in Section 2.4 on page 42 and in each of the sections
15194 // describing clauses and directives for which a list appears.
15195 // OpenMP [2.14.3.3, Restrictions, p.1]
15196 // A variable that is part of another variable (as an array or
15197 // structure element) cannot appear in a private clause.
15198 if (!FirstIter && IR != ER)
15199 ++IR;
15200 FirstIter = false;
15201 SourceLocation ELoc;
15202 SourceRange ERange;
15203 Expr *SimpleRefExpr = RefExpr;
15204 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
15205 /*AllowArraySection=*/true);
15206 if (Res.second) {
15207 // Try to find 'declare reduction' corresponding construct before using
15208 // builtin/overloaded operators.
15209 QualType Type = Context.DependentTy;
15210 CXXCastPath BasePath;
15211 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15212 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15213 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15214 Expr *ReductionOp = nullptr;
15215 if (S.CurContext->isDependentContext() &&
15216 (DeclareReductionRef.isUnset() ||
15217 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
15218 ReductionOp = DeclareReductionRef.get();
15219 // It will be analyzed later.
15220 RD.push(RefExpr, ReductionOp);
15221 }
15222 ValueDecl *D = Res.first;
15223 if (!D)
15224 continue;
15225
15226 Expr *TaskgroupDescriptor = nullptr;
15227 QualType Type;
15228 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
15229 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
15230 if (ASE) {
15231 Type = ASE->getType().getNonReferenceType();
15232 } else if (OASE) {
15233 QualType BaseType =
15234 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15235 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15236 Type = ATy->getElementType();
15237 else
15238 Type = BaseType->getPointeeType();
15239 Type = Type.getNonReferenceType();
15240 } else {
15241 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
15242 }
15243 auto *VD = dyn_cast<VarDecl>(D);
15244
15245 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15246 // A variable that appears in a private clause must not have an incomplete
15247 // type or a reference type.
15248 if (S.RequireCompleteType(ELoc, D->getType(),
15249 diag::err_omp_reduction_incomplete_type))
15250 continue;
15251 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15252 // A list item that appears in a reduction clause must not be
15253 // const-qualified.
15254 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
15255 /*AcceptIfMutable*/ false, ASE || OASE))
15256 continue;
15257
15258 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
15259 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
15260 // If a list-item is a reference type then it must bind to the same object
15261 // for all threads of the team.
15262 if (!ASE && !OASE) {
15263 if (VD) {
15264 VarDecl *VDDef = VD->getDefinition();
15265 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15266 DSARefChecker Check(Stack);
15267 if (Check.Visit(VDDef->getInit())) {
15268 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15269 << getOpenMPClauseName(ClauseKind) << ERange;
15270 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15271 continue;
15272 }
15273 }
15274 }
15275
15276 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15277 // in a Construct]
15278 // Variables with the predetermined data-sharing attributes may not be
15279 // listed in data-sharing attributes clauses, except for the cases
15280 // listed below. For these exceptions only, listing a predetermined
15281 // variable in a data-sharing attribute clause is allowed and overrides
15282 // the variable's predetermined data-sharing attributes.
15283 // OpenMP [2.14.3.6, Restrictions, p.3]
15284 // Any number of reduction clauses can be specified on the directive,
15285 // but a list item can appear only once in the reduction clauses for that
15286 // directive.
15287 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15288 if (DVar.CKind == OMPC_reduction) {
15289 S.Diag(ELoc, diag::err_omp_once_referenced)
15290 << getOpenMPClauseName(ClauseKind);
15291 if (DVar.RefExpr)
15292 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15293 continue;
15294 }
15295 if (DVar.CKind != OMPC_unknown) {
15296 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15297 << getOpenMPClauseName(DVar.CKind)
15298 << getOpenMPClauseName(OMPC_reduction);
15299 reportOriginalDsa(S, Stack, D, DVar);
15300 continue;
15301 }
15302
15303 // OpenMP [2.14.3.6, Restrictions, p.1]
15304 // A list item that appears in a reduction clause of a worksharing
15305 // construct must be shared in the parallel regions to which any of the
15306 // worksharing regions arising from the worksharing construct bind.
15307 if (isOpenMPWorksharingDirective(CurrDir) &&
15308 !isOpenMPParallelDirective(CurrDir) &&
15309 !isOpenMPTeamsDirective(CurrDir)) {
15310 DVar = Stack->getImplicitDSA(D, true);
15311 if (DVar.CKind != OMPC_shared) {
15312 S.Diag(ELoc, diag::err_omp_required_access)
15313 << getOpenMPClauseName(OMPC_reduction)
15314 << getOpenMPClauseName(OMPC_shared);
15315 reportOriginalDsa(S, Stack, D, DVar);
15316 continue;
15317 }
15318 }
15319 } else {
15320 // Threadprivates cannot be shared between threads, so dignose if the base
15321 // is a threadprivate variable.
15322 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15323 if (DVar.CKind == OMPC_threadprivate) {
15324 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15325 << getOpenMPClauseName(DVar.CKind)
15326 << getOpenMPClauseName(OMPC_reduction);
15327 reportOriginalDsa(S, Stack, D, DVar);
15328 continue;
15329 }
15330 }
15331
15332 // Try to find 'declare reduction' corresponding construct before using
15333 // builtin/overloaded operators.
15334 CXXCastPath BasePath;
15335 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15336 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15337 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15338 if (DeclareReductionRef.isInvalid())
15339 continue;
15340 if (S.CurContext->isDependentContext() &&
15341 (DeclareReductionRef.isUnset() ||
15342 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15343 RD.push(RefExpr, DeclareReductionRef.get());
15344 continue;
15345 }
15346 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15347 // Not allowed reduction identifier is found.
15348 S.Diag(ReductionId.getBeginLoc(),
15349 diag::err_omp_unknown_reduction_identifier)
15350 << Type << ReductionIdRange;
15351 continue;
15352 }
15353
15354 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15355 // The type of a list item that appears in a reduction clause must be valid
15356 // for the reduction-identifier. For a max or min reduction in C, the type
15357 // of the list item must be an allowed arithmetic data type: char, int,
15358 // float, double, or _Bool, possibly modified with long, short, signed, or
15359 // unsigned. For a max or min reduction in C++, the type of the list item
15360 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15361 // double, or bool, possibly modified with long, short, signed, or unsigned.
15362 if (DeclareReductionRef.isUnset()) {
15363 if ((BOK == BO_GT || BOK == BO_LT) &&
15364 !(Type->isScalarType() ||
15365 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15366 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15367 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15368 if (!ASE && !OASE) {
15369 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15370 VarDecl::DeclarationOnly;
15371 S.Diag(D->getLocation(),
15372 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15373 << D;
15374 }
15375 continue;
15376 }
15377 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15378 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15379 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15380 << getOpenMPClauseName(ClauseKind);
15381 if (!ASE && !OASE) {
15382 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15383 VarDecl::DeclarationOnly;
15384 S.Diag(D->getLocation(),
15385 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15386 << D;
15387 }
15388 continue;
15389 }
15390 }
15391
15392 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15393 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15394 D->hasAttrs() ? &D->getAttrs() : nullptr);
15395 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15396 D->hasAttrs() ? &D->getAttrs() : nullptr);
15397 QualType PrivateTy = Type;
15398
15399 // Try if we can determine constant lengths for all array sections and avoid
15400 // the VLA.
15401 bool ConstantLengthOASE = false;
15402 if (OASE) {
15403 bool SingleElement;
15404 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15405 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15406 Context, OASE, SingleElement, ArraySizes);
15407
15408 // If we don't have a single element, we must emit a constant array type.
15409 if (ConstantLengthOASE && !SingleElement) {
15410 for (llvm::APSInt &Size : ArraySizes)
15411 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15412 ArrayType::Normal,
15413 /*IndexTypeQuals=*/0);
15414 }
15415 }
15416
15417 if ((OASE && !ConstantLengthOASE) ||
15418 (!OASE && !ASE &&
15419 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15420 if (!Context.getTargetInfo().isVLASupported()) {
15421 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15422 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15423 S.Diag(ELoc, diag::note_vla_unsupported);
15424 continue;
15425 } else {
15426 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15427 S.targetDiag(ELoc, diag::note_vla_unsupported);
15428 }
15429 }
15430 // For arrays/array sections only:
15431 // Create pseudo array type for private copy. The size for this array will
15432 // be generated during codegen.
15433 // For array subscripts or single variables Private Ty is the same as Type
15434 // (type of the variable or single array element).
15435 PrivateTy = Context.getVariableArrayType(
15436 Type,
15437 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15438 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15439 } else if (!ASE && !OASE &&
15440 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15441 PrivateTy = D->getType().getNonReferenceType();
15442 }
15443 // Private copy.
15444 VarDecl *PrivateVD =
15445 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15446 D->hasAttrs() ? &D->getAttrs() : nullptr,
15447 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15448 // Add initializer for private variable.
15449 Expr *Init = nullptr;
15450 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15451 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15452 if (DeclareReductionRef.isUsable()) {
15453 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15454 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15455 if (DRD->getInitializer()) {
15456 S.ActOnUninitializedDecl(PrivateVD);
15457 Init = DRDRef;
15458 RHSVD->setInit(DRDRef);
15459 RHSVD->setInitStyle(VarDecl::CallInit);
15460 }
15461 } else {
15462 switch (BOK) {
15463 case BO_Add:
15464 case BO_Xor:
15465 case BO_Or:
15466 case BO_LOr:
15467 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15468 if (Type->isScalarType() || Type->isAnyComplexType())
15469 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15470 break;
15471 case BO_Mul:
15472 case BO_LAnd:
15473 if (Type->isScalarType() || Type->isAnyComplexType()) {
15474 // '*' and '&&' reduction ops - initializer is '1'.
15475 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15476 }
15477 break;
15478 case BO_And: {
15479 // '&' reduction op - initializer is '~0'.
15480 QualType OrigType = Type;
15481 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15482 Type = ComplexTy->getElementType();
15483 if (Type->isRealFloatingType()) {
15484 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15485 Context.getFloatTypeSemantics(Type),
15486 Context.getTypeSize(Type));
15487 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15488 Type, ELoc);
15489 } else if (Type->isScalarType()) {
15490 uint64_t Size = Context.getTypeSize(Type);
15491 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15492 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15493 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15494 }
15495 if (Init && OrigType->isAnyComplexType()) {
15496 // Init = 0xFFFF + 0xFFFFi;
15497 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15498 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15499 }
15500 Type = OrigType;
15501 break;
15502 }
15503 case BO_LT:
15504 case BO_GT: {
15505 // 'min' reduction op - initializer is 'Largest representable number in
15506 // the reduction list item type'.
15507 // 'max' reduction op - initializer is 'Least representable number in
15508 // the reduction list item type'.
15509 if (Type->isIntegerType() || Type->isPointerType()) {
15510 bool IsSigned = Type->hasSignedIntegerRepresentation();
15511 uint64_t Size = Context.getTypeSize(Type);
15512 QualType IntTy =
15513 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15514 llvm::APInt InitValue =
15515 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15516 : llvm::APInt::getMinValue(Size)
15517 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15518 : llvm::APInt::getMaxValue(Size);
15519 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15520 if (Type->isPointerType()) {
15521 // Cast to pointer type.
15522 ExprResult CastExpr = S.BuildCStyleCastExpr(
15523 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15524 if (CastExpr.isInvalid())
15525 continue;
15526 Init = CastExpr.get();
15527 }
15528 } else if (Type->isRealFloatingType()) {
15529 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15530 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15531 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15532 Type, ELoc);
15533 }
15534 break;
15535 }
15536 case BO_PtrMemD:
15537 case BO_PtrMemI:
15538 case BO_MulAssign:
15539 case BO_Div:
15540 case BO_Rem:
15541 case BO_Sub:
15542 case BO_Shl:
15543 case BO_Shr:
15544 case BO_LE:
15545 case BO_GE:
15546 case BO_EQ:
15547 case BO_NE:
15548 case BO_Cmp:
15549 case BO_AndAssign:
15550 case BO_XorAssign:
15551 case BO_OrAssign:
15552 case BO_Assign:
15553 case BO_AddAssign:
15554 case BO_SubAssign:
15555 case BO_DivAssign:
15556 case BO_RemAssign:
15557 case BO_ShlAssign:
15558 case BO_ShrAssign:
15559 case BO_Comma:
15560 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 15560)
;
15561 }
15562 }
15563 if (Init && DeclareReductionRef.isUnset()) {
15564 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15565 // Store initializer for single element in private copy. Will be used
15566 // during codegen.
15567 PrivateVD->setInit(RHSVD->getInit());
15568 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15569 } else if (!Init) {
15570 S.ActOnUninitializedDecl(RHSVD);
15571 // Store initializer for single element in private copy. Will be used
15572 // during codegen.
15573 PrivateVD->setInit(RHSVD->getInit());
15574 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15575 }
15576 if (RHSVD->isInvalidDecl())
15577 continue;
15578 if (!RHSVD->hasInit() &&
15579 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15580 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15581 << Type << ReductionIdRange;
15582 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15583 VarDecl::DeclarationOnly;
15584 S.Diag(D->getLocation(),
15585 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15586 << D;
15587 continue;
15588 }
15589 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15590 ExprResult ReductionOp;
15591 if (DeclareReductionRef.isUsable()) {
15592 QualType RedTy = DeclareReductionRef.get()->getType();
15593 QualType PtrRedTy = Context.getPointerType(RedTy);
15594 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15595 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15596 if (!BasePath.empty()) {
15597 LHS = S.DefaultLvalueConversion(LHS.get());
15598 RHS = S.DefaultLvalueConversion(RHS.get());
15599 LHS = ImplicitCastExpr::Create(
15600 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
15601 LHS.get()->getValueKind(), FPOptionsOverride());
15602 RHS = ImplicitCastExpr::Create(
15603 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
15604 RHS.get()->getValueKind(), FPOptionsOverride());
15605 }
15606 FunctionProtoType::ExtProtoInfo EPI;
15607 QualType Params[] = {PtrRedTy, PtrRedTy};
15608 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15609 auto *OVE = new (Context) OpaqueValueExpr(
15610 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15611 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15612 Expr *Args[] = {LHS.get(), RHS.get()};
15613 ReductionOp =
15614 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
15615 S.CurFPFeatureOverrides());
15616 } else {
15617 ReductionOp = S.BuildBinOp(
15618 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15619 if (ReductionOp.isUsable()) {
15620 if (BOK != BO_LT && BOK != BO_GT) {
15621 ReductionOp =
15622 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15623 BO_Assign, LHSDRE, ReductionOp.get());
15624 } else {
15625 auto *ConditionalOp = new (Context)
15626 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15627 Type, VK_LValue, OK_Ordinary);
15628 ReductionOp =
15629 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15630 BO_Assign, LHSDRE, ConditionalOp);
15631 }
15632 if (ReductionOp.isUsable())
15633 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15634 /*DiscardedValue*/ false);
15635 }
15636 if (!ReductionOp.isUsable())
15637 continue;
15638 }
15639
15640 // Add copy operations for inscan reductions.
15641 // LHS = RHS;
15642 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15643 if (ClauseKind == OMPC_reduction &&
15644 RD.RedModifier == OMPC_REDUCTION_inscan) {
15645 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15646 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15647 RHS.get());
15648 if (!CopyOpRes.isUsable())
15649 continue;
15650 CopyOpRes =
15651 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15652 if (!CopyOpRes.isUsable())
15653 continue;
15654 // For simd directive and simd-based directives in simd mode no need to
15655 // construct temp array, need just a single temp element.
15656 if (Stack->getCurrentDirective() == OMPD_simd ||
15657 (S.getLangOpts().OpenMPSimd &&
15658 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15659 VarDecl *TempArrayVD =
15660 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15661 D->hasAttrs() ? &D->getAttrs() : nullptr);
15662 // Add a constructor to the temp decl.
15663 S.ActOnUninitializedDecl(TempArrayVD);
15664 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15665 } else {
15666 // Build temp array for prefix sum.
15667 auto *Dim = new (S.Context)
15668 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15669 QualType ArrayTy =
15670 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15671 /*IndexTypeQuals=*/0, {ELoc, ELoc});
15672 VarDecl *TempArrayVD =
15673 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15674 D->hasAttrs() ? &D->getAttrs() : nullptr);
15675 // Add a constructor to the temp decl.
15676 S.ActOnUninitializedDecl(TempArrayVD);
15677 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15678 TempArrayElem =
15679 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15680 auto *Idx = new (S.Context)
15681 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15682 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15683 ELoc, Idx, ELoc);
15684 }
15685 }
15686
15687 // OpenMP [2.15.4.6, Restrictions, p.2]
15688 // A list item that appears in an in_reduction clause of a task construct
15689 // must appear in a task_reduction clause of a construct associated with a
15690 // taskgroup region that includes the participating task in its taskgroup
15691 // set. The construct associated with the innermost region that meets this
15692 // condition must specify the same reduction-identifier as the in_reduction
15693 // clause.
15694 if (ClauseKind == OMPC_in_reduction) {
15695 SourceRange ParentSR;
15696 BinaryOperatorKind ParentBOK;
15697 const Expr *ParentReductionOp = nullptr;
15698 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15699 DSAStackTy::DSAVarData ParentBOKDSA =
15700 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15701 ParentBOKTD);
15702 DSAStackTy::DSAVarData ParentReductionOpDSA =
15703 Stack->getTopMostTaskgroupReductionData(
15704 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15705 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15706 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15707 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15708 (DeclareReductionRef.isUsable() && IsParentBOK) ||
15709 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15710 bool EmitError = true;
15711 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15712 llvm::FoldingSetNodeID RedId, ParentRedId;
15713 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15714 DeclareReductionRef.get()->Profile(RedId, Context,
15715 /*Canonical=*/true);
15716 EmitError = RedId != ParentRedId;
15717 }
15718 if (EmitError) {
15719 S.Diag(ReductionId.getBeginLoc(),
15720 diag::err_omp_reduction_identifier_mismatch)
15721 << ReductionIdRange << RefExpr->getSourceRange();
15722 S.Diag(ParentSR.getBegin(),
15723 diag::note_omp_previous_reduction_identifier)
15724 << ParentSR
15725 << (IsParentBOK ? ParentBOKDSA.RefExpr
15726 : ParentReductionOpDSA.RefExpr)
15727 ->getSourceRange();
15728 continue;
15729 }
15730 }
15731 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15732 }
15733
15734 DeclRefExpr *Ref = nullptr;
15735 Expr *VarsExpr = RefExpr->IgnoreParens();
15736 if (!VD && !S.CurContext->isDependentContext()) {
15737 if (ASE || OASE) {
15738 TransformExprToCaptures RebuildToCapture(S, D);
15739 VarsExpr =
15740 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15741 Ref = RebuildToCapture.getCapturedExpr();
15742 } else {
15743 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15744 }
15745 if (!S.isOpenMPCapturedDecl(D)) {
15746 RD.ExprCaptures.emplace_back(Ref->getDecl());
15747 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15748 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15749 if (!RefRes.isUsable())
15750 continue;
15751 ExprResult PostUpdateRes =
15752 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15753 RefRes.get());
15754 if (!PostUpdateRes.isUsable())
15755 continue;
15756 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15757 Stack->getCurrentDirective() == OMPD_taskgroup) {
15758 S.Diag(RefExpr->getExprLoc(),
15759 diag::err_omp_reduction_non_addressable_expression)
15760 << RefExpr->getSourceRange();
15761 continue;
15762 }
15763 RD.ExprPostUpdates.emplace_back(
15764 S.IgnoredValueConversions(PostUpdateRes.get()).get());
15765 }
15766 }
15767 }
15768 // All reduction items are still marked as reduction (to do not increase
15769 // code base size).
15770 unsigned Modifier = RD.RedModifier;
15771 // Consider task_reductions as reductions with task modifier. Required for
15772 // correct analysis of in_reduction clauses.
15773 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15774 Modifier = OMPC_REDUCTION_task;
15775 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
15776 ASE || OASE);
15777 if (Modifier == OMPC_REDUCTION_task &&
15778 (CurrDir == OMPD_taskgroup ||
15779 ((isOpenMPParallelDirective(CurrDir) ||
15780 isOpenMPWorksharingDirective(CurrDir)) &&
15781 !isOpenMPSimdDirective(CurrDir)))) {
15782 if (DeclareReductionRef.isUsable())
15783 Stack->addTaskgroupReductionData(D, ReductionIdRange,
15784 DeclareReductionRef.get());
15785 else
15786 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15787 }
15788 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15789 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15790 TempArrayElem.get());
15791 }
15792 return RD.Vars.empty();
15793}
15794
15795OMPClause *Sema::ActOnOpenMPReductionClause(
15796 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15797 SourceLocation StartLoc, SourceLocation LParenLoc,
15798 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15799 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15800 ArrayRef<Expr *> UnresolvedReductions) {
15801 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15802 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15803 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15804 /*Last=*/OMPC_REDUCTION_unknown)
15805 << getOpenMPClauseName(OMPC_reduction);
15806 return nullptr;
15807 }
15808 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15809 // A reduction clause with the inscan reduction-modifier may only appear on a
15810 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15811 // construct, a parallel worksharing-loop construct or a parallel
15812 // worksharing-loop SIMD construct.
15813 if (Modifier == OMPC_REDUCTION_inscan &&
15814 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
15815 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
15816 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
15817 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
15818 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
15819 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15820 return nullptr;
15821 }
15822
15823 ReductionData RD(VarList.size(), Modifier);
15824 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
15825 StartLoc, LParenLoc, ColonLoc, EndLoc,
15826 ReductionIdScopeSpec, ReductionId,
15827 UnresolvedReductions, RD))
15828 return nullptr;
15829
15830 return OMPReductionClause::Create(
15831 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15832 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15833 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15834 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15835 buildPreInits(Context, RD.ExprCaptures),
15836 buildPostUpdate(*this, RD.ExprPostUpdates));
15837}
15838
15839OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15840 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15841 SourceLocation ColonLoc, SourceLocation EndLoc,
15842 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15843 ArrayRef<Expr *> UnresolvedReductions) {
15844 ReductionData RD(VarList.size());
15845 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
15846 StartLoc, LParenLoc, ColonLoc, EndLoc,
15847 ReductionIdScopeSpec, ReductionId,
15848 UnresolvedReductions, RD))
15849 return nullptr;
15850
15851 return OMPTaskReductionClause::Create(
15852 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15853 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15854 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15855 buildPreInits(Context, RD.ExprCaptures),
15856 buildPostUpdate(*this, RD.ExprPostUpdates));
15857}
15858
15859OMPClause *Sema::ActOnOpenMPInReductionClause(
15860 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15861 SourceLocation ColonLoc, SourceLocation EndLoc,
15862 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15863 ArrayRef<Expr *> UnresolvedReductions) {
15864 ReductionData RD(VarList.size());
15865 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
15866 StartLoc, LParenLoc, ColonLoc, EndLoc,
15867 ReductionIdScopeSpec, ReductionId,
15868 UnresolvedReductions, RD))
15869 return nullptr;
15870
15871 return OMPInReductionClause::Create(
15872 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15873 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15874 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15875 buildPreInits(Context, RD.ExprCaptures),
15876 buildPostUpdate(*this, RD.ExprPostUpdates));
15877}
15878
15879bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15880 SourceLocation LinLoc) {
15881 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15882 LinKind == OMPC_LINEAR_unknown) {
15883 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15884 return true;
15885 }
15886 return false;
15887}
15888
15889bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15890 OpenMPLinearClauseKind LinKind, QualType Type,
15891 bool IsDeclareSimd) {
15892 const auto *VD = dyn_cast_or_null<VarDecl>(D);
15893 // A variable must not have an incomplete type or a reference type.
15894 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15895 return true;
15896 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15897 !Type->isReferenceType()) {
15898 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15899 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15900 return true;
15901 }
15902 Type = Type.getNonReferenceType();
15903
15904 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15905 // A variable that is privatized must not have a const-qualified type
15906 // unless it is of class type with a mutable member. This restriction does
15907 // not apply to the firstprivate clause, nor to the linear clause on
15908 // declarative directives (like declare simd).
15909 if (!IsDeclareSimd &&
15910 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15911 return true;
15912
15913 // A list item must be of integral or pointer type.
15914 Type = Type.getUnqualifiedType().getCanonicalType();
15915 const auto *Ty = Type.getTypePtrOrNull();
15916 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15917 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15918 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15919 if (D) {
15920 bool IsDecl =
15921 !VD ||
15922 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15923 Diag(D->getLocation(),
15924 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15925 << D;
15926 }
15927 return true;
15928 }
15929 return false;
15930}
15931
15932OMPClause *Sema::ActOnOpenMPLinearClause(
15933 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15934 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15935 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15936 SmallVector<Expr *, 8> Vars;
15937 SmallVector<Expr *, 8> Privates;
15938 SmallVector<Expr *, 8> Inits;
15939 SmallVector<Decl *, 4> ExprCaptures;
15940 SmallVector<Expr *, 4> ExprPostUpdates;
15941 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15942 LinKind = OMPC_LINEAR_val;
15943 for (Expr *RefExpr : VarList) {
15944 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 15944, __PRETTY_FUNCTION__))
;
15945 SourceLocation ELoc;
15946 SourceRange ERange;
15947 Expr *SimpleRefExpr = RefExpr;
15948 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15949 if (Res.second) {
15950 // It will be analyzed later.
15951 Vars.push_back(RefExpr);
15952 Privates.push_back(nullptr);
15953 Inits.push_back(nullptr);
15954 }
15955 ValueDecl *D = Res.first;
15956 if (!D)
15957 continue;
15958
15959 QualType Type = D->getType();
15960 auto *VD = dyn_cast<VarDecl>(D);
15961
15962 // OpenMP [2.14.3.7, linear clause]
15963 // A list-item cannot appear in more than one linear clause.
15964 // A list-item that appears in a linear clause cannot appear in any
15965 // other data-sharing attribute clause.
15966 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15967 if (DVar.RefExpr) {
15968 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15969 << getOpenMPClauseName(OMPC_linear);
15970 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15971 continue;
15972 }
15973
15974 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15975 continue;
15976 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15977
15978 // Build private copy of original var.
15979 VarDecl *Private =
15980 buildVarDecl(*this, ELoc, Type, D->getName(),
15981 D->hasAttrs() ? &D->getAttrs() : nullptr,
15982 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15983 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15984 // Build var to save initial value.
15985 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15986 Expr *InitExpr;
15987 DeclRefExpr *Ref = nullptr;
15988 if (!VD && !CurContext->isDependentContext()) {
15989 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15990 if (!isOpenMPCapturedDecl(D)) {
15991 ExprCaptures.push_back(Ref->getDecl());
15992 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15993 ExprResult RefRes = DefaultLvalueConversion(Ref);
15994 if (!RefRes.isUsable())
15995 continue;
15996 ExprResult PostUpdateRes =
15997 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
15998 SimpleRefExpr, RefRes.get());
15999 if (!PostUpdateRes.isUsable())
16000 continue;
16001 ExprPostUpdates.push_back(
16002 IgnoredValueConversions(PostUpdateRes.get()).get());
16003 }
16004 }
16005 }
16006 if (LinKind == OMPC_LINEAR_uval)
16007 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
16008 else
16009 InitExpr = VD ? SimpleRefExpr : Ref;
16010 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
16011 /*DirectInit=*/false);
16012 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
16013
16014 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
16015 Vars.push_back((VD || CurContext->isDependentContext())
16016 ? RefExpr->IgnoreParens()
16017 : Ref);
16018 Privates.push_back(PrivateRef);
16019 Inits.push_back(InitRef);
16020 }
16021
16022 if (Vars.empty())
16023 return nullptr;
16024
16025 Expr *StepExpr = Step;
16026 Expr *CalcStepExpr = nullptr;
16027 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
16028 !Step->isInstantiationDependent() &&
16029 !Step->containsUnexpandedParameterPack()) {
16030 SourceLocation StepLoc = Step->getBeginLoc();
16031 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
16032 if (Val.isInvalid())
16033 return nullptr;
16034 StepExpr = Val.get();
16035
16036 // Build var to save the step value.
16037 VarDecl *SaveVar =
16038 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
16039 ExprResult SaveRef =
16040 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
16041 ExprResult CalcStep =
16042 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
16043 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
16044
16045 // Warn about zero linear step (it would be probably better specified as
16046 // making corresponding variables 'const').
16047 if (Optional<llvm::APSInt> Result =
16048 StepExpr->getIntegerConstantExpr(Context)) {
16049 if (!Result->isNegative() && !Result->isStrictlyPositive())
16050 Diag(StepLoc, diag::warn_omp_linear_step_zero)
16051 << Vars[0] << (Vars.size() > 1);
16052 } else if (CalcStep.isUsable()) {
16053 // Calculate the step beforehand instead of doing this on each iteration.
16054 // (This is not used if the number of iterations may be kfold-ed).
16055 CalcStepExpr = CalcStep.get();
16056 }
16057 }
16058
16059 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
16060 ColonLoc, EndLoc, Vars, Privates, Inits,
16061 StepExpr, CalcStepExpr,
16062 buildPreInits(Context, ExprCaptures),
16063 buildPostUpdate(*this, ExprPostUpdates));
16064}
16065
16066static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
16067 Expr *NumIterations, Sema &SemaRef,
16068 Scope *S, DSAStackTy *Stack) {
16069 // Walk the vars and build update/final expressions for the CodeGen.
16070 SmallVector<Expr *, 8> Updates;
16071 SmallVector<Expr *, 8> Finals;
16072 SmallVector<Expr *, 8> UsedExprs;
16073 Expr *Step = Clause.getStep();
16074 Expr *CalcStep = Clause.getCalcStep();
16075 // OpenMP [2.14.3.7, linear clause]
16076 // If linear-step is not specified it is assumed to be 1.
16077 if (!Step)
16078 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
16079 else if (CalcStep)
16080 Step = cast<BinaryOperator>(CalcStep)->getLHS();
16081 bool HasErrors = false;
16082 auto CurInit = Clause.inits().begin();
16083 auto CurPrivate = Clause.privates().begin();
16084 OpenMPLinearClauseKind LinKind = Clause.getModifier();
16085 for (Expr *RefExpr : Clause.varlists()) {
16086 SourceLocation ELoc;
16087 SourceRange ERange;
16088 Expr *SimpleRefExpr = RefExpr;
16089 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
16090 ValueDecl *D = Res.first;
16091 if (Res.second || !D) {
16092 Updates.push_back(nullptr);
16093 Finals.push_back(nullptr);
16094 HasErrors = true;
16095 continue;
16096 }
16097 auto &&Info = Stack->isLoopControlVariable(D);
16098 // OpenMP [2.15.11, distribute simd Construct]
16099 // A list item may not appear in a linear clause, unless it is the loop
16100 // iteration variable.
16101 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
16102 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
16103 SemaRef.Diag(ELoc,
16104 diag::err_omp_linear_distribute_var_non_loop_iteration);
16105 Updates.push_back(nullptr);
16106 Finals.push_back(nullptr);
16107 HasErrors = true;
16108 continue;
16109 }
16110 Expr *InitExpr = *CurInit;
16111
16112 // Build privatized reference to the current linear var.
16113 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
16114 Expr *CapturedRef;
16115 if (LinKind == OMPC_LINEAR_uval)
16116 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
16117 else
16118 CapturedRef =
16119 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
16120 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
16121 /*RefersToCapture=*/true);
16122
16123 // Build update: Var = InitExpr + IV * Step
16124 ExprResult Update;
16125 if (!Info.first)
16126 Update = buildCounterUpdate(
16127 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
16128 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
16129 else
16130 Update = *CurPrivate;
16131 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
16132 /*DiscardedValue*/ false);
16133
16134 // Build final: Var = InitExpr + NumIterations * Step
16135 ExprResult Final;
16136 if (!Info.first)
16137 Final =
16138 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
16139 InitExpr, NumIterations, Step, /*Subtract=*/false,
16140 /*IsNonRectangularLB=*/false);
16141 else
16142 Final = *CurPrivate;
16143 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
16144 /*DiscardedValue*/ false);
16145
16146 if (!Update.isUsable() || !Final.isUsable()) {
16147 Updates.push_back(nullptr);
16148 Finals.push_back(nullptr);
16149 UsedExprs.push_back(nullptr);
16150 HasErrors = true;
16151 } else {
16152 Updates.push_back(Update.get());
16153 Finals.push_back(Final.get());
16154 if (!Info.first)
16155 UsedExprs.push_back(SimpleRefExpr);
16156 }
16157 ++CurInit;
16158 ++CurPrivate;
16159 }
16160 if (Expr *S = Clause.getStep())
16161 UsedExprs.push_back(S);
16162 // Fill the remaining part with the nullptr.
16163 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
16164 Clause.setUpdates(Updates);
16165 Clause.setFinals(Finals);
16166 Clause.setUsedExprs(UsedExprs);
16167 return HasErrors;
16168}
16169
16170OMPClause *Sema::ActOnOpenMPAlignedClause(
16171 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
16172 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16173 SmallVector<Expr *, 8> Vars;
16174 for (Expr *RefExpr : VarList) {
16175 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16175, __PRETTY_FUNCTION__))
;
16176 SourceLocation ELoc;
16177 SourceRange ERange;
16178 Expr *SimpleRefExpr = RefExpr;
16179 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16180 if (Res.second) {
16181 // It will be analyzed later.
16182 Vars.push_back(RefExpr);
16183 }
16184 ValueDecl *D = Res.first;
16185 if (!D)
16186 continue;
16187
16188 QualType QType = D->getType();
16189 auto *VD = dyn_cast<VarDecl>(D);
16190
16191 // OpenMP [2.8.1, simd construct, Restrictions]
16192 // The type of list items appearing in the aligned clause must be
16193 // array, pointer, reference to array, or reference to pointer.
16194 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16195 const Type *Ty = QType.getTypePtrOrNull();
16196 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
16197 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
16198 << QType << getLangOpts().CPlusPlus << ERange;
16199 bool IsDecl =
16200 !VD ||
16201 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16202 Diag(D->getLocation(),
16203 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16204 << D;
16205 continue;
16206 }
16207
16208 // OpenMP [2.8.1, simd construct, Restrictions]
16209 // A list-item cannot appear in more than one aligned clause.
16210 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
16211 Diag(ELoc, diag::err_omp_used_in_clause_twice)
16212 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
16213 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
16214 << getOpenMPClauseName(OMPC_aligned);
16215 continue;
16216 }
16217
16218 DeclRefExpr *Ref = nullptr;
16219 if (!VD && isOpenMPCapturedDecl(D))
16220 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16221 Vars.push_back(DefaultFunctionArrayConversion(
16222 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
16223 .get());
16224 }
16225
16226 // OpenMP [2.8.1, simd construct, Description]
16227 // The parameter of the aligned clause, alignment, must be a constant
16228 // positive integer expression.
16229 // If no optional parameter is specified, implementation-defined default
16230 // alignments for SIMD instructions on the target platforms are assumed.
16231 if (Alignment != nullptr) {
16232 ExprResult AlignResult =
16233 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
16234 if (AlignResult.isInvalid())
16235 return nullptr;
16236 Alignment = AlignResult.get();
16237 }
16238 if (Vars.empty())
16239 return nullptr;
16240
16241 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
16242 EndLoc, Vars, Alignment);
16243}
16244
16245OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
16246 SourceLocation StartLoc,
16247 SourceLocation LParenLoc,
16248 SourceLocation EndLoc) {
16249 SmallVector<Expr *, 8> Vars;
16250 SmallVector<Expr *, 8> SrcExprs;
16251 SmallVector<Expr *, 8> DstExprs;
16252 SmallVector<Expr *, 8> AssignmentOps;
16253 for (Expr *RefExpr : VarList) {
16254 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16254, __PRETTY_FUNCTION__))
;
16255 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16256 // It will be analyzed later.
16257 Vars.push_back(RefExpr);
16258 SrcExprs.push_back(nullptr);
16259 DstExprs.push_back(nullptr);
16260 AssignmentOps.push_back(nullptr);
16261 continue;
16262 }
16263
16264 SourceLocation ELoc = RefExpr->getExprLoc();
16265 // OpenMP [2.1, C/C++]
16266 // A list item is a variable name.
16267 // OpenMP [2.14.4.1, Restrictions, p.1]
16268 // A list item that appears in a copyin clause must be threadprivate.
16269 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
16270 if (!DE || !isa<VarDecl>(DE->getDecl())) {
16271 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
16272 << 0 << RefExpr->getSourceRange();
16273 continue;
16274 }
16275
16276 Decl *D = DE->getDecl();
16277 auto *VD = cast<VarDecl>(D);
16278
16279 QualType Type = VD->getType();
16280 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16281 // It will be analyzed later.
16282 Vars.push_back(DE);
16283 SrcExprs.push_back(nullptr);
16284 DstExprs.push_back(nullptr);
16285 AssignmentOps.push_back(nullptr);
16286 continue;
16287 }
16288
16289 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16290 // A list item that appears in a copyin clause must be threadprivate.
16291 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16292 Diag(ELoc, diag::err_omp_required_access)
16293 << getOpenMPClauseName(OMPC_copyin)
16294 << getOpenMPDirectiveName(OMPD_threadprivate);
16295 continue;
16296 }
16297
16298 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16299 // A variable of class type (or array thereof) that appears in a
16300 // copyin clause requires an accessible, unambiguous copy assignment
16301 // operator for the class type.
16302 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16303 VarDecl *SrcVD =
16304 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16305 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16306 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16307 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16308 VarDecl *DstVD =
16309 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16310 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16311 DeclRefExpr *PseudoDstExpr =
16312 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16313 // For arrays generate assignment operation for single element and replace
16314 // it by the original array element in CodeGen.
16315 ExprResult AssignmentOp =
16316 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16317 PseudoSrcExpr);
16318 if (AssignmentOp.isInvalid())
16319 continue;
16320 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16321 /*DiscardedValue*/ false);
16322 if (AssignmentOp.isInvalid())
16323 continue;
16324
16325 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
16326 Vars.push_back(DE);
16327 SrcExprs.push_back(PseudoSrcExpr);
16328 DstExprs.push_back(PseudoDstExpr);
16329 AssignmentOps.push_back(AssignmentOp.get());
16330 }
16331
16332 if (Vars.empty())
16333 return nullptr;
16334
16335 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16336 SrcExprs, DstExprs, AssignmentOps);
16337}
16338
16339OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16340 SourceLocation StartLoc,
16341 SourceLocation LParenLoc,
16342 SourceLocation EndLoc) {
16343 SmallVector<Expr *, 8> Vars;
16344 SmallVector<Expr *, 8> SrcExprs;
16345 SmallVector<Expr *, 8> DstExprs;
16346 SmallVector<Expr *, 8> AssignmentOps;
16347 for (Expr *RefExpr : VarList) {
16348 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16348, __PRETTY_FUNCTION__))
;
16349 SourceLocation ELoc;
16350 SourceRange ERange;
16351 Expr *SimpleRefExpr = RefExpr;
16352 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16353 if (Res.second) {
16354 // It will be analyzed later.
16355 Vars.push_back(RefExpr);
16356 SrcExprs.push_back(nullptr);
16357 DstExprs.push_back(nullptr);
16358 AssignmentOps.push_back(nullptr);
16359 }
16360 ValueDecl *D = Res.first;
16361 if (!D)
16362 continue;
16363
16364 QualType Type = D->getType();
16365 auto *VD = dyn_cast<VarDecl>(D);
16366
16367 // OpenMP [2.14.4.2, Restrictions, p.2]
16368 // A list item that appears in a copyprivate clause may not appear in a
16369 // private or firstprivate clause on the single construct.
16370 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16371 DSAStackTy::DSAVarData DVar =
16372 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16373 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16374 DVar.RefExpr) {
16375 Diag(ELoc, diag::err_omp_wrong_dsa)
16376 << getOpenMPClauseName(DVar.CKind)
16377 << getOpenMPClauseName(OMPC_copyprivate);
16378 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16379 continue;
16380 }
16381
16382 // OpenMP [2.11.4.2, Restrictions, p.1]
16383 // All list items that appear in a copyprivate clause must be either
16384 // threadprivate or private in the enclosing context.
16385 if (DVar.CKind == OMPC_unknown) {
16386 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
16387 if (DVar.CKind == OMPC_shared) {
16388 Diag(ELoc, diag::err_omp_required_access)
16389 << getOpenMPClauseName(OMPC_copyprivate)
16390 << "threadprivate or private in the enclosing context";
16391 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16392 continue;
16393 }
16394 }
16395 }
16396
16397 // Variably modified types are not supported.
16398 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16399 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16400 << getOpenMPClauseName(OMPC_copyprivate) << Type
16401 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
16402 bool IsDecl =
16403 !VD ||
16404 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16405 Diag(D->getLocation(),
16406 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16407 << D;
16408 continue;
16409 }
16410
16411 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16412 // A variable of class type (or array thereof) that appears in a
16413 // copyin clause requires an accessible, unambiguous copy assignment
16414 // operator for the class type.
16415 Type = Context.getBaseElementType(Type.getNonReferenceType())
16416 .getUnqualifiedType();
16417 VarDecl *SrcVD =
16418 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16419 D->hasAttrs() ? &D->getAttrs() : nullptr);
16420 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16421 VarDecl *DstVD =
16422 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16423 D->hasAttrs() ? &D->getAttrs() : nullptr);
16424 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16425 ExprResult AssignmentOp = BuildBinOp(
16426 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16427 if (AssignmentOp.isInvalid())
16428 continue;
16429 AssignmentOp =
16430 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16431 if (AssignmentOp.isInvalid())
16432 continue;
16433
16434 // No need to mark vars as copyprivate, they are already threadprivate or
16435 // implicitly private.
16436 assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0
) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16436, __PRETTY_FUNCTION__))
;
16437 Vars.push_back(
16438 VD ? RefExpr->IgnoreParens()
16439 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16440 SrcExprs.push_back(PseudoSrcExpr);
16441 DstExprs.push_back(PseudoDstExpr);
16442 AssignmentOps.push_back(AssignmentOp.get());
16443 }
16444
16445 if (Vars.empty())
16446 return nullptr;
16447
16448 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16449 Vars, SrcExprs, DstExprs, AssignmentOps);
16450}
16451
16452OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16453 SourceLocation StartLoc,
16454 SourceLocation LParenLoc,
16455 SourceLocation EndLoc) {
16456 if (VarList.empty())
16457 return nullptr;
16458
16459 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16460}
16461
16462/// Tries to find omp_depend_t. type.
16463static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16464 bool Diagnose = true) {
16465 QualType OMPDependT = Stack->getOMPDependT();
16466 if (!OMPDependT.isNull())
16467 return true;
16468 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16469 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16470 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16471 if (Diagnose)
16472 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16473 return false;
16474 }
16475 Stack->setOMPDependT(PT.get());
16476 return true;
16477}
16478
16479OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16480 SourceLocation LParenLoc,
16481 SourceLocation EndLoc) {
16482 if (!Depobj)
16483 return nullptr;
16484
16485 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
16486
16487 // OpenMP 5.0, 2.17.10.1 depobj Construct
16488 // depobj is an lvalue expression of type omp_depend_t.
16489 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16490 !Depobj->isInstantiationDependent() &&
16491 !Depobj->containsUnexpandedParameterPack() &&
16492 (OMPDependTFound &&
16493 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
16494 /*CompareUnqualified=*/true))) {
16495 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16496 << 0 << Depobj->getType() << Depobj->getSourceRange();
16497 }
16498
16499 if (!Depobj->isLValue()) {
16500 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16501 << 1 << Depobj->getSourceRange();
16502 }
16503
16504 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16505}
16506
16507OMPClause *
16508Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16509 SourceLocation DepLoc, SourceLocation ColonLoc,
16510 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16511 SourceLocation LParenLoc, SourceLocation EndLoc) {
16512 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
16513 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16514 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16515 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16516 return nullptr;
16517 }
16518 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
16519 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16520 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16521 DepKind == OMPC_DEPEND_sink ||
16522 ((LangOpts.OpenMP < 50 ||
16523 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16524 DepKind == OMPC_DEPEND_depobj))) {
16525 SmallVector<unsigned, 3> Except;
16526 Except.push_back(OMPC_DEPEND_source);
16527 Except.push_back(OMPC_DEPEND_sink);
16528 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
16529 Except.push_back(OMPC_DEPEND_depobj);
16530 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16531 ? "depend modifier(iterator) or "
16532 : "";
16533 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16534 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16535 /*Last=*/OMPC_DEPEND_unknown,
16536 Except)
16537 << getOpenMPClauseName(OMPC_depend);
16538 return nullptr;
16539 }
16540 if (DepModifier &&
16541 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16542 Diag(DepModifier->getExprLoc(),
16543 diag::err_omp_depend_sink_source_with_modifier);
16544 return nullptr;
16545 }
16546 if (DepModifier &&
16547 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16548 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16549
16550 SmallVector<Expr *, 8> Vars;
16551 DSAStackTy::OperatorOffsetTy OpsOffs;
16552 llvm::APSInt DepCounter(/*BitWidth=*/32);
16553 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16554 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16555 if (const Expr *OrderedCountExpr =
16556 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
16557 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16558 TotalDepCount.setIsUnsigned(/*Val=*/true);
16559 }
16560 }
16561 for (Expr *RefExpr : VarList) {
16562 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16562, __PRETTY_FUNCTION__))
;
16563 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16564 // It will be analyzed later.
16565 Vars.push_back(RefExpr);
16566 continue;
16567 }
16568
16569 SourceLocation ELoc = RefExpr->getExprLoc();
16570 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16571 if (DepKind == OMPC_DEPEND_sink) {
16572 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16573 DepCounter >= TotalDepCount) {
16574 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16575 continue;
16576 }
16577 ++DepCounter;
16578 // OpenMP [2.13.9, Summary]
16579 // depend(dependence-type : vec), where dependence-type is:
16580 // 'sink' and where vec is the iteration vector, which has the form:
16581 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16582 // where n is the value specified by the ordered clause in the loop
16583 // directive, xi denotes the loop iteration variable of the i-th nested
16584 // loop associated with the loop directive, and di is a constant
16585 // non-negative integer.
16586 if (CurContext->isDependentContext()) {
16587 // It will be analyzed later.
16588 Vars.push_back(RefExpr);
16589 continue;
16590 }
16591 SimpleExpr = SimpleExpr->IgnoreImplicit();
16592 OverloadedOperatorKind OOK = OO_None;
16593 SourceLocation OOLoc;
16594 Expr *LHS = SimpleExpr;
16595 Expr *RHS = nullptr;
16596 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16597 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16598 OOLoc = BO->getOperatorLoc();
16599 LHS = BO->getLHS()->IgnoreParenImpCasts();
16600 RHS = BO->getRHS()->IgnoreParenImpCasts();
16601 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16602 OOK = OCE->getOperator();
16603 OOLoc = OCE->getOperatorLoc();
16604 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16605 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16606 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16607 OOK = MCE->getMethodDecl()
16608 ->getNameInfo()
16609 .getName()
16610 .getCXXOverloadedOperator();
16611 OOLoc = MCE->getCallee()->getExprLoc();
16612 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16613 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16614 }
16615 SourceLocation ELoc;
16616 SourceRange ERange;
16617 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16618 if (Res.second) {
16619 // It will be analyzed later.
16620 Vars.push_back(RefExpr);
16621 }
16622 ValueDecl *D = Res.first;
16623 if (!D)
16624 continue;
16625
16626 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16627 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16628 continue;
16629 }
16630 if (RHS) {
16631 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16632 RHS, OMPC_depend, /*StrictlyPositive=*/false);
16633 if (RHSRes.isInvalid())
16634 continue;
16635 }
16636 if (!CurContext->isDependentContext() &&
16637 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16638 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
16639 const ValueDecl *VD =
16640 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
16641 if (VD)
16642 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16643 << 1 << VD;
16644 else
16645 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16646 continue;
16647 }
16648 OpsOffs.emplace_back(RHS, OOK);
16649 } else {
16650 bool OMPDependTFound = LangOpts.OpenMP >= 50;
16651 if (OMPDependTFound)
16652 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
16653 DepKind == OMPC_DEPEND_depobj);
16654 if (DepKind == OMPC_DEPEND_depobj) {
16655 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16656 // List items used in depend clauses with the depobj dependence type
16657 // must be expressions of the omp_depend_t type.
16658 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16659 !RefExpr->isInstantiationDependent() &&
16660 !RefExpr->containsUnexpandedParameterPack() &&
16661 (OMPDependTFound &&
16662 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
16663 RefExpr->getType()))) {
16664 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16665 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16666 continue;
16667 }
16668 if (!RefExpr->isLValue()) {
16669 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16670 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16671 continue;
16672 }
16673 } else {
16674 // OpenMP 5.0 [2.17.11, Restrictions]
16675 // List items used in depend clauses cannot be zero-length array
16676 // sections.
16677 QualType ExprTy = RefExpr->getType().getNonReferenceType();
16678 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16679 if (OASE) {
16680 QualType BaseType =
16681 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16682 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16683 ExprTy = ATy->getElementType();
16684 else
16685 ExprTy = BaseType->getPointeeType();
16686 ExprTy = ExprTy.getNonReferenceType();
16687 const Expr *Length = OASE->getLength();
16688 Expr::EvalResult Result;
16689 if (Length && !Length->isValueDependent() &&
16690 Length->EvaluateAsInt(Result, Context) &&
16691 Result.Val.getInt().isNullValue()) {
16692 Diag(ELoc,
16693 diag::err_omp_depend_zero_length_array_section_not_allowed)
16694 << SimpleExpr->getSourceRange();
16695 continue;
16696 }
16697 }
16698
16699 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16700 // List items used in depend clauses with the in, out, inout or
16701 // mutexinoutset dependence types cannot be expressions of the
16702 // omp_depend_t type.
16703 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16704 !RefExpr->isInstantiationDependent() &&
16705 !RefExpr->containsUnexpandedParameterPack() &&
16706 (OMPDependTFound &&
16707 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16708 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16709 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16710 << RefExpr->getSourceRange();
16711 continue;
16712 }
16713
16714 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16715 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16716 (ASE && !ASE->getBase()->isTypeDependent() &&
16717 !ASE->getBase()
16718 ->getType()
16719 .getNonReferenceType()
16720 ->isPointerType() &&
16721 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16722 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16723 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16724 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16725 continue;
16726 }
16727
16728 ExprResult Res;
16729 {
16730 Sema::TentativeAnalysisScope Trap(*this);
16731 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16732 RefExpr->IgnoreParenImpCasts());
16733 }
16734 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16735 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16736 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16737 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16738 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16739 continue;
16740 }
16741 }
16742 }
16743 Vars.push_back(RefExpr->IgnoreParenImpCasts());
16744 }
16745
16746 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16747 TotalDepCount > VarList.size() &&
16748 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16749 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
16750 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16751 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
16752 }
16753 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16754 Vars.empty())
16755 return nullptr;
16756
16757 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16758 DepModifier, DepKind, DepLoc, ColonLoc,
16759 Vars, TotalDepCount.getZExtValue());
16760 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16761 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
16762 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
16763 return C;
16764}
16765
16766OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16767 Expr *Device, SourceLocation StartLoc,
16768 SourceLocation LParenLoc,
16769 SourceLocation ModifierLoc,
16770 SourceLocation EndLoc) {
16771 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16772, __PRETTY_FUNCTION__))
16772 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16772, __PRETTY_FUNCTION__))
;
16773
16774 bool ErrorFound = false;
16775 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16776 std::string Values =
16777 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16778 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16779 << Values << getOpenMPClauseName(OMPC_device);
16780 ErrorFound = true;
16781 }
16782
16783 Expr *ValExpr = Device;
16784 Stmt *HelperValStmt = nullptr;
16785
16786 // OpenMP [2.9.1, Restrictions]
16787 // The device expression must evaluate to a non-negative integer value.
16788 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16789 /*StrictlyPositive=*/false) ||
16790 ErrorFound;
16791 if (ErrorFound)
16792 return nullptr;
16793
16794 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16795 OpenMPDirectiveKind CaptureRegion =
16796 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16797 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16798 ValExpr = MakeFullExpr(ValExpr).get();
16799 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16800 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16801 HelperValStmt = buildPreInits(Context, Captures);
16802 }
16803
16804 return new (Context)
16805 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16806 LParenLoc, ModifierLoc, EndLoc);
16807}
16808
16809static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16810 DSAStackTy *Stack, QualType QTy,
16811 bool FullCheck = true) {
16812 NamedDecl *ND;
16813 if (QTy->isIncompleteType(&ND)) {
16814 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16815 return false;
16816 }
16817 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16818 !QTy.isTriviallyCopyableType(SemaRef.Context))
16819 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16820 return true;
16821}
16822
16823/// Return true if it can be proven that the provided array expression
16824/// (array section or array subscript) does NOT specify the whole size of the
16825/// array whose base type is \a BaseQTy.
16826static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16827 const Expr *E,
16828 QualType BaseQTy) {
16829 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16830
16831 // If this is an array subscript, it refers to the whole size if the size of
16832 // the dimension is constant and equals 1. Also, an array section assumes the
16833 // format of an array subscript if no colon is used.
16834 if (isa<ArraySubscriptExpr>(E) ||
16835 (OASE && OASE->getColonLocFirst().isInvalid())) {
16836 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16837 return ATy->getSize().getSExtValue() != 1;
16838 // Size can't be evaluated statically.
16839 return false;
16840 }
16841
16842 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16842, __PRETTY_FUNCTION__))
;
16843 const Expr *LowerBound = OASE->getLowerBound();
16844 const Expr *Length = OASE->getLength();
16845
16846 // If there is a lower bound that does not evaluates to zero, we are not
16847 // covering the whole dimension.
16848 if (LowerBound) {
16849 Expr::EvalResult Result;
16850 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16851 return false; // Can't get the integer value as a constant.
16852
16853 llvm::APSInt ConstLowerBound = Result.Val.getInt();
16854 if (ConstLowerBound.getSExtValue())
16855 return true;
16856 }
16857
16858 // If we don't have a length we covering the whole dimension.
16859 if (!Length)
16860 return false;
16861
16862 // If the base is a pointer, we don't have a way to get the size of the
16863 // pointee.
16864 if (BaseQTy->isPointerType())
16865 return false;
16866
16867 // We can only check if the length is the same as the size of the dimension
16868 // if we have a constant array.
16869 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16870 if (!CATy)
16871 return false;
16872
16873 Expr::EvalResult Result;
16874 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16875 return false; // Can't get the integer value as a constant.
16876
16877 llvm::APSInt ConstLength = Result.Val.getInt();
16878 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16879}
16880
16881// Return true if it can be proven that the provided array expression (array
16882// section or array subscript) does NOT specify a single element of the array
16883// whose base type is \a BaseQTy.
16884static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16885 const Expr *E,
16886 QualType BaseQTy) {
16887 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16888
16889 // An array subscript always refer to a single element. Also, an array section
16890 // assumes the format of an array subscript if no colon is used.
16891 if (isa<ArraySubscriptExpr>(E) ||
16892 (OASE && OASE->getColonLocFirst().isInvalid()))
16893 return false;
16894
16895 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16895, __PRETTY_FUNCTION__))
;
16896 const Expr *Length = OASE->getLength();
16897
16898 // If we don't have a length we have to check if the array has unitary size
16899 // for this dimension. Also, we should always expect a length if the base type
16900 // is pointer.
16901 if (!Length) {
16902 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16903 return ATy->getSize().getSExtValue() != 1;
16904 // We cannot assume anything.
16905 return false;
16906 }
16907
16908 // Check if the length evaluates to 1.
16909 Expr::EvalResult Result;
16910 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16911 return false; // Can't get the integer value as a constant.
16912
16913 llvm::APSInt ConstLength = Result.Val.getInt();
16914 return ConstLength.getSExtValue() != 1;
16915}
16916
16917// The base of elements of list in a map clause have to be either:
16918// - a reference to variable or field.
16919// - a member expression.
16920// - an array expression.
16921//
16922// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16923// reference to 'r'.
16924//
16925// If we have:
16926//
16927// struct SS {
16928// Bla S;
16929// foo() {
16930// #pragma omp target map (S.Arr[:12]);
16931// }
16932// }
16933//
16934// We want to retrieve the member expression 'this->S';
16935
16936// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16937// If a list item is an array section, it must specify contiguous storage.
16938//
16939// For this restriction it is sufficient that we make sure only references
16940// to variables or fields and array expressions, and that no array sections
16941// exist except in the rightmost expression (unless they cover the whole
16942// dimension of the array). E.g. these would be invalid:
16943//
16944// r.ArrS[3:5].Arr[6:7]
16945//
16946// r.ArrS[3:5].x
16947//
16948// but these would be valid:
16949// r.ArrS[3].Arr[6:7]
16950//
16951// r.ArrS[3].x
16952namespace {
16953class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16954 Sema &SemaRef;
16955 OpenMPClauseKind CKind = OMPC_unknown;
16956 OpenMPDirectiveKind DKind = OMPD_unknown;
16957 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16958 bool IsNonContiguous = false;
16959 bool NoDiagnose = false;
16960 const Expr *RelevantExpr = nullptr;
16961 bool AllowUnitySizeArraySection = true;
16962 bool AllowWholeSizeArraySection = true;
16963 bool AllowAnotherPtr = true;
16964 SourceLocation ELoc;
16965 SourceRange ERange;
16966
16967 void emitErrorMsg() {
16968 // If nothing else worked, this is not a valid map clause expression.
16969 if (SemaRef.getLangOpts().OpenMP < 50) {
16970 SemaRef.Diag(ELoc,
16971 diag::err_omp_expected_named_var_member_or_array_expression)
16972 << ERange;
16973 } else {
16974 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16975 << getOpenMPClauseName(CKind) << ERange;
16976 }
16977 }
16978
16979public:
16980 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16981 if (!isa<VarDecl>(DRE->getDecl())) {
16982 emitErrorMsg();
16983 return false;
16984 }
16985 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16985, __PRETTY_FUNCTION__))
;
16986 RelevantExpr = DRE;
16987 // Record the component.
16988 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
16989 return true;
16990 }
16991
16992 bool VisitMemberExpr(MemberExpr *ME) {
16993 Expr *E = ME;
16994 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
16995
16996 if (isa<CXXThisExpr>(BaseE)) {
16997 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 16997, __PRETTY_FUNCTION__))
;
16998 // We found a base expression: this->Val.
16999 RelevantExpr = ME;
17000 } else {
17001 E = BaseE;
17002 }
17003
17004 if (!isa<FieldDecl>(ME->getMemberDecl())) {
17005 if (!NoDiagnose) {
17006 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
17007 << ME->getSourceRange();
17008 return false;
17009 }
17010 if (RelevantExpr)
17011 return false;
17012 return Visit(E);
17013 }
17014
17015 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
17016
17017 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
17018 // A bit-field cannot appear in a map clause.
17019 //
17020 if (FD->isBitField()) {
17021 if (!NoDiagnose) {
17022 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
17023 << ME->getSourceRange() << getOpenMPClauseName(CKind);
17024 return false;
17025 }
17026 if (RelevantExpr)
17027 return false;
17028 return Visit(E);
17029 }
17030
17031 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17032 // If the type of a list item is a reference to a type T then the type
17033 // will be considered to be T for all purposes of this clause.
17034 QualType CurType = BaseE->getType().getNonReferenceType();
17035
17036 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
17037 // A list item cannot be a variable that is a member of a structure with
17038 // a union type.
17039 //
17040 if (CurType->isUnionType()) {
17041 if (!NoDiagnose) {
17042 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
17043 << ME->getSourceRange();
17044 return false;
17045 }
17046 return RelevantExpr || Visit(E);
17047 }
17048
17049 // If we got a member expression, we should not expect any array section
17050 // before that:
17051 //
17052 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
17053 // If a list item is an element of a structure, only the rightmost symbol
17054 // of the variable reference can be an array section.
17055 //
17056 AllowUnitySizeArraySection = false;
17057 AllowWholeSizeArraySection = false;
17058
17059 // Record the component.
17060 Components.emplace_back(ME, FD, IsNonContiguous);
17061 return RelevantExpr || Visit(E);
17062 }
17063
17064 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
17065 Expr *E = AE->getBase()->IgnoreParenImpCasts();
17066
17067 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
17068 if (!NoDiagnose) {
17069 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17070 << 0 << AE->getSourceRange();
17071 return false;
17072 }
17073 return RelevantExpr || Visit(E);
17074 }
17075
17076 // If we got an array subscript that express the whole dimension we
17077 // can have any array expressions before. If it only expressing part of
17078 // the dimension, we can only have unitary-size array expressions.
17079 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
17080 E->getType()))
17081 AllowWholeSizeArraySection = false;
17082
17083 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
17084 Expr::EvalResult Result;
17085 if (!AE->getIdx()->isValueDependent() &&
17086 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
17087 !Result.Val.getInt().isNullValue()) {
17088 SemaRef.Diag(AE->getIdx()->getExprLoc(),
17089 diag::err_omp_invalid_map_this_expr);
17090 SemaRef.Diag(AE->getIdx()->getExprLoc(),
17091 diag::note_omp_invalid_subscript_on_this_ptr_map);
17092 }
17093 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17093, __PRETTY_FUNCTION__))
;
17094 RelevantExpr = TE;
17095 }
17096
17097 // Record the component - we don't have any declaration associated.
17098 Components.emplace_back(AE, nullptr, IsNonContiguous);
17099
17100 return RelevantExpr || Visit(E);
17101 }
17102
17103 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
17104 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17104, __PRETTY_FUNCTION__))
;
17105 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17106 QualType CurType =
17107 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17108
17109 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17110 // If the type of a list item is a reference to a type T then the type
17111 // will be considered to be T for all purposes of this clause.
17112 if (CurType->isReferenceType())
17113 CurType = CurType->getPointeeType();
17114
17115 bool IsPointer = CurType->isAnyPointerType();
17116
17117 if (!IsPointer && !CurType->isArrayType()) {
17118 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17119 << 0 << OASE->getSourceRange();
17120 return false;
17121 }
17122
17123 bool NotWhole =
17124 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
17125 bool NotUnity =
17126 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
17127
17128 if (AllowWholeSizeArraySection) {
17129 // Any array section is currently allowed. Allowing a whole size array
17130 // section implies allowing a unity array section as well.
17131 //
17132 // If this array section refers to the whole dimension we can still
17133 // accept other array sections before this one, except if the base is a
17134 // pointer. Otherwise, only unitary sections are accepted.
17135 if (NotWhole || IsPointer)
17136 AllowWholeSizeArraySection = false;
17137 } else if (DKind == OMPD_target_update &&
17138 SemaRef.getLangOpts().OpenMP >= 50) {
17139 if (IsPointer && !AllowAnotherPtr)
17140 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
17141 << /*array of unknown bound */ 1;
17142 else
17143 IsNonContiguous = true;
17144 } else if (AllowUnitySizeArraySection && NotUnity) {
17145 // A unity or whole array section is not allowed and that is not
17146 // compatible with the properties of the current array section.
17147 SemaRef.Diag(
17148 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
17149 << OASE->getSourceRange();
17150 return false;
17151 }
17152
17153 if (IsPointer)
17154 AllowAnotherPtr = false;
17155
17156 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
17157 Expr::EvalResult ResultR;
17158 Expr::EvalResult ResultL;
17159 if (!OASE->getLength()->isValueDependent() &&
17160 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
17161 !ResultR.Val.getInt().isOneValue()) {
17162 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17163 diag::err_omp_invalid_map_this_expr);
17164 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17165 diag::note_omp_invalid_length_on_this_ptr_mapping);
17166 }
17167 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
17168 OASE->getLowerBound()->EvaluateAsInt(ResultL,
17169 SemaRef.getASTContext()) &&
17170 !ResultL.Val.getInt().isNullValue()) {
17171 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17172 diag::err_omp_invalid_map_this_expr);
17173 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17174 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
17175 }
17176 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17176, __PRETTY_FUNCTION__))
;
17177 RelevantExpr = TE;
17178 }
17179
17180 // Record the component - we don't have any declaration associated.
17181 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
17182 return RelevantExpr || Visit(E);
17183 }
17184 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
17185 Expr *Base = E->getBase();
17186
17187 // Record the component - we don't have any declaration associated.
17188 Components.emplace_back(E, nullptr, IsNonContiguous);
17189
17190 return Visit(Base->IgnoreParenImpCasts());
17191 }
17192
17193 bool VisitUnaryOperator(UnaryOperator *UO) {
17194 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
17195 UO->getOpcode() != UO_Deref) {
17196 emitErrorMsg();
17197 return false;
17198 }
17199 if (!RelevantExpr) {
17200 // Record the component if haven't found base decl.
17201 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
17202 }
17203 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
17204 }
17205 bool VisitBinaryOperator(BinaryOperator *BO) {
17206 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
17207 emitErrorMsg();
17208 return false;
17209 }
17210
17211 // Pointer arithmetic is the only thing we expect to happen here so after we
17212 // make sure the binary operator is a pointer type, the we only thing need
17213 // to to is to visit the subtree that has the same type as root (so that we
17214 // know the other subtree is just an offset)
17215 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
17216 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
17217 Components.emplace_back(BO, nullptr, false);
17218 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17220, __PRETTY_FUNCTION__))
17219 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17220, __PRETTY_FUNCTION__))
17220 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17220, __PRETTY_FUNCTION__))
;
17221 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
17222 return RelevantExpr || Visit(LE);
17223 return RelevantExpr || Visit(RE);
17224 }
17225 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
17226 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17226, __PRETTY_FUNCTION__))
;
17227 RelevantExpr = CTE;
17228 Components.emplace_back(CTE, nullptr, IsNonContiguous);
17229 return true;
17230 }
17231 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
17232 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17232, __PRETTY_FUNCTION__))
;
17233 Components.emplace_back(COCE, nullptr, IsNonContiguous);
17234 return true;
17235 }
17236 bool VisitStmt(Stmt *) {
17237 emitErrorMsg();
17238 return false;
17239 }
17240 const Expr *getFoundBase() const {
17241 return RelevantExpr;
17242 }
17243 explicit MapBaseChecker(
17244 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
17245 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
17246 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
17247 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
17248 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
17249};
17250} // namespace
17251
17252/// Return the expression of the base of the mappable expression or null if it
17253/// cannot be determined and do all the necessary checks to see if the expression
17254/// is valid as a standalone mappable expression. In the process, record all the
17255/// components of the expression.
17256static const Expr *checkMapClauseExpressionBase(
17257 Sema &SemaRef, Expr *E,
17258 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
17259 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
17260 SourceLocation ELoc = E->getExprLoc();
17261 SourceRange ERange = E->getSourceRange();
17262 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
17263 ERange);
17264 if (Checker.Visit(E->IgnoreParens())) {
17265 // Check if the highest dimension array section has length specified
17266 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
17267 (CKind == OMPC_to || CKind == OMPC_from)) {
17268 auto CI = CurComponents.rbegin();
17269 auto CE = CurComponents.rend();
17270 for (; CI != CE; ++CI) {
17271 const auto *OASE =
17272 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
17273 if (!OASE)
17274 continue;
17275 if (OASE && OASE->getLength())
17276 break;
17277 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
17278 << ERange;
17279 }
17280 }
17281 return Checker.getFoundBase();
17282 }
17283 return nullptr;
17284}
17285
17286// Return true if expression E associated with value VD has conflicts with other
17287// map information.
17288static bool checkMapConflicts(
17289 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
17290 bool CurrentRegionOnly,
17291 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
17292 OpenMPClauseKind CKind) {
17293 assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail
("VD && E", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17293, __PRETTY_FUNCTION__))
;
17294 SourceLocation ELoc = E->getExprLoc();
17295 SourceRange ERange = E->getSourceRange();
17296
17297 // In order to easily check the conflicts we need to match each component of
17298 // the expression under test with the components of the expressions that are
17299 // already in the stack.
17300
17301 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17301, __PRETTY_FUNCTION__))
;
17302 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17303, __PRETTY_FUNCTION__))
17303 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17303, __PRETTY_FUNCTION__))
;
17304
17305 // Variables to help detecting enclosing problems in data environment nests.
17306 bool IsEnclosedByDataEnvironmentExpr = false;
17307 const Expr *EnclosingExpr = nullptr;
17308
17309 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17310 VD, CurrentRegionOnly,
17311 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17312 ERange, CKind, &EnclosingExpr,
17313 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17314 StackComponents,
17315 OpenMPClauseKind) {
17316 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17317, __PRETTY_FUNCTION__))
17317 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17317, __PRETTY_FUNCTION__))
;
17318 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17319, __PRETTY_FUNCTION__))
17319 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17319, __PRETTY_FUNCTION__))
;
17320 (void)VD;
17321
17322 // The whole expression in the stack.
17323 const Expr *RE = StackComponents.front().getAssociatedExpression();
17324
17325 // Expressions must start from the same base. Here we detect at which
17326 // point both expressions diverge from each other and see if we can
17327 // detect if the memory referred to both expressions is contiguous and
17328 // do not overlap.
17329 auto CI = CurComponents.rbegin();
17330 auto CE = CurComponents.rend();
17331 auto SI = StackComponents.rbegin();
17332 auto SE = StackComponents.rend();
17333 for (; CI != CE && SI != SE; ++CI, ++SI) {
17334
17335 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17336 // At most one list item can be an array item derived from a given
17337 // variable in map clauses of the same construct.
17338 if (CurrentRegionOnly &&
17339 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17340 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17341 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17342 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17343 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17344 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17345 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17346 diag::err_omp_multiple_array_items_in_map_clause)
17347 << CI->getAssociatedExpression()->getSourceRange();
17348 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17349 diag::note_used_here)
17350 << SI->getAssociatedExpression()->getSourceRange();
17351 return true;
17352 }
17353
17354 // Do both expressions have the same kind?
17355 if (CI->getAssociatedExpression()->getStmtClass() !=
17356 SI->getAssociatedExpression()->getStmtClass())
17357 break;
17358
17359 // Are we dealing with different variables/fields?
17360 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17361 break;
17362 }
17363 // Check if the extra components of the expressions in the enclosing
17364 // data environment are redundant for the current base declaration.
17365 // If they are, the maps completely overlap, which is legal.
17366 for (; SI != SE; ++SI) {
17367 QualType Type;
17368 if (const auto *ASE =
17369 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17370 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17371 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17372 SI->getAssociatedExpression())) {
17373 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17374 Type =
17375 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17376 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17377 SI->getAssociatedExpression())) {
17378 Type = OASE->getBase()->getType()->getPointeeType();
17379 }
17380 if (Type.isNull() || Type->isAnyPointerType() ||
17381 checkArrayExpressionDoesNotReferToWholeSize(
17382 SemaRef, SI->getAssociatedExpression(), Type))
17383 break;
17384 }
17385
17386 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17387 // List items of map clauses in the same construct must not share
17388 // original storage.
17389 //
17390 // If the expressions are exactly the same or one is a subset of the
17391 // other, it means they are sharing storage.
17392 if (CI == CE && SI == SE) {
17393 if (CurrentRegionOnly) {
17394 if (CKind == OMPC_map) {
17395 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17396 } else {
17397 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17397, __PRETTY_FUNCTION__))
;
17398 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17399 << ERange;
17400 }
17401 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17402 << RE->getSourceRange();
17403 return true;
17404 }
17405 // If we find the same expression in the enclosing data environment,
17406 // that is legal.
17407 IsEnclosedByDataEnvironmentExpr = true;
17408 return false;
17409 }
17410
17411 QualType DerivedType =
17412 std::prev(CI)->getAssociatedDeclaration()->getType();
17413 SourceLocation DerivedLoc =
17414 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17415
17416 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17417 // If the type of a list item is a reference to a type T then the type
17418 // will be considered to be T for all purposes of this clause.
17419 DerivedType = DerivedType.getNonReferenceType();
17420
17421 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17422 // A variable for which the type is pointer and an array section
17423 // derived from that variable must not appear as list items of map
17424 // clauses of the same construct.
17425 //
17426 // Also, cover one of the cases in:
17427 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17428 // If any part of the original storage of a list item has corresponding
17429 // storage in the device data environment, all of the original storage
17430 // must have corresponding storage in the device data environment.
17431 //
17432 if (DerivedType->isAnyPointerType()) {
17433 if (CI == CE || SI == SE) {
17434 SemaRef.Diag(
17435 DerivedLoc,
17436 diag::err_omp_pointer_mapped_along_with_derived_section)
17437 << DerivedLoc;
17438 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17439 << RE->getSourceRange();
17440 return true;
17441 }
17442 if (CI->getAssociatedExpression()->getStmtClass() !=
17443 SI->getAssociatedExpression()->getStmtClass() ||
17444 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17445 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17446 assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0)
: __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17446, __PRETTY_FUNCTION__))
;
17447 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17448 << DerivedLoc;
17449 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17450 << RE->getSourceRange();
17451 return true;
17452 }
17453 }
17454
17455 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17456 // List items of map clauses in the same construct must not share
17457 // original storage.
17458 //
17459 // An expression is a subset of the other.
17460 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17461 if (CKind == OMPC_map) {
17462 if (CI != CE || SI != SE) {
17463 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17464 // a pointer.
17465 auto Begin =
17466 CI != CE ? CurComponents.begin() : StackComponents.begin();
17467 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17468 auto It = Begin;
17469 while (It != End && !It->getAssociatedDeclaration())
17470 std::advance(It, 1);
17471 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17472, __PRETTY_FUNCTION__))
17472 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17472, __PRETTY_FUNCTION__))
;
17473 if (It != Begin && It->getAssociatedDeclaration()
17474 ->getType()
17475 .getCanonicalType()
17476 ->isAnyPointerType()) {
17477 IsEnclosedByDataEnvironmentExpr = false;
17478 EnclosingExpr = nullptr;
17479 return false;
17480 }
17481 }
17482 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17483 } else {
17484 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17484, __PRETTY_FUNCTION__))
;
17485 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17486 << ERange;
17487 }
17488 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17489 << RE->getSourceRange();
17490 return true;
17491 }
17492
17493 // The current expression uses the same base as other expression in the
17494 // data environment but does not contain it completely.
17495 if (!CurrentRegionOnly && SI != SE)
17496 EnclosingExpr = RE;
17497
17498 // The current expression is a subset of the expression in the data
17499 // environment.
17500 IsEnclosedByDataEnvironmentExpr |=
17501 (!CurrentRegionOnly && CI != CE && SI == SE);
17502
17503 return false;
17504 });
17505
17506 if (CurrentRegionOnly)
17507 return FoundError;
17508
17509 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17510 // If any part of the original storage of a list item has corresponding
17511 // storage in the device data environment, all of the original storage must
17512 // have corresponding storage in the device data environment.
17513 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17514 // If a list item is an element of a structure, and a different element of
17515 // the structure has a corresponding list item in the device data environment
17516 // prior to a task encountering the construct associated with the map clause,
17517 // then the list item must also have a corresponding list item in the device
17518 // data environment prior to the task encountering the construct.
17519 //
17520 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17521 SemaRef.Diag(ELoc,
17522 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17523 << ERange;
17524 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17525 << EnclosingExpr->getSourceRange();
17526 return true;
17527 }
17528
17529 return FoundError;
17530}
17531
17532// Look up the user-defined mapper given the mapper name and mapped type, and
17533// build a reference to it.
17534static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17535 CXXScopeSpec &MapperIdScopeSpec,
17536 const DeclarationNameInfo &MapperId,
17537 QualType Type,
17538 Expr *UnresolvedMapper) {
17539 if (MapperIdScopeSpec.isInvalid())
17540 return ExprError();
17541 // Get the actual type for the array type.
17542 if (Type->isArrayType()) {
17543 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17543, __PRETTY_FUNCTION__))
;
17544 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17545 }
17546 // Find all user-defined mappers with the given MapperId.
17547 SmallVector<UnresolvedSet<8>, 4> Lookups;
17548 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17549 Lookup.suppressDiagnostics();
17550 if (S) {
17551 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17552 NamedDecl *D = Lookup.getRepresentativeDecl();
17553 while (S && !S->isDeclScope(D))
17554 S = S->getParent();
17555 if (S)
17556 S = S->getParent();
17557 Lookups.emplace_back();
17558 Lookups.back().append(Lookup.begin(), Lookup.end());
17559 Lookup.clear();
17560 }
17561 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17562 // Extract the user-defined mappers with the given MapperId.
17563 Lookups.push_back(UnresolvedSet<8>());
17564 for (NamedDecl *D : ULE->decls()) {
17565 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17566 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17566, __PRETTY_FUNCTION__))
;
17567 Lookups.back().addDecl(DMD);
17568 }
17569 }
17570 // Defer the lookup for dependent types. The results will be passed through
17571 // UnresolvedMapper on instantiation.
17572 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17573 Type->isInstantiationDependentType() ||
17574 Type->containsUnexpandedParameterPack() ||
17575 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17576 return !D->isInvalidDecl() &&
17577 (D->getType()->isDependentType() ||
17578 D->getType()->isInstantiationDependentType() ||
17579 D->getType()->containsUnexpandedParameterPack());
17580 })) {
17581 UnresolvedSet<8> URS;
17582 for (const UnresolvedSet<8> &Set : Lookups) {
17583 if (Set.empty())
17584 continue;
17585 URS.append(Set.begin(), Set.end());
17586 }
17587 return UnresolvedLookupExpr::Create(
17588 SemaRef.Context, /*NamingClass=*/nullptr,
17589 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17590 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17591 }
17592 SourceLocation Loc = MapperId.getLoc();
17593 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17594 // The type must be of struct, union or class type in C and C++
17595 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17596 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17597 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17598 return ExprError();
17599 }
17600 // Perform argument dependent lookup.
17601 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17602 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17603 // Return the first user-defined mapper with the desired type.
17604 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17605 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17606 if (!D->isInvalidDecl() &&
17607 SemaRef.Context.hasSameType(D->getType(), Type))
17608 return D;
17609 return nullptr;
17610 }))
17611 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17612 // Find the first user-defined mapper with a type derived from the desired
17613 // type.
17614 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17615 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17616 if (!D->isInvalidDecl() &&
17617 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17618 !Type.isMoreQualifiedThan(D->getType()))
17619 return D;
17620 return nullptr;
17621 })) {
17622 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17623 /*DetectVirtual=*/false);
17624 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17625 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17626 VD->getType().getUnqualifiedType()))) {
17627 if (SemaRef.CheckBaseClassAccess(
17628 Loc, VD->getType(), Type, Paths.front(),
17629 /*DiagID=*/0) != Sema::AR_inaccessible) {
17630 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17631 }
17632 }
17633 }
17634 }
17635 // Report error if a mapper is specified, but cannot be found.
17636 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17637 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17638 << Type << MapperId.getName();
17639 return ExprError();
17640 }
17641 return ExprEmpty();
17642}
17643
17644namespace {
17645// Utility struct that gathers all the related lists associated with a mappable
17646// expression.
17647struct MappableVarListInfo {
17648 // The list of expressions.
17649 ArrayRef<Expr *> VarList;
17650 // The list of processed expressions.
17651 SmallVector<Expr *, 16> ProcessedVarList;
17652 // The mappble components for each expression.
17653 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17654 // The base declaration of the variable.
17655 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17656 // The reference to the user-defined mapper associated with every expression.
17657 SmallVector<Expr *, 16> UDMapperList;
17658
17659 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17660 // We have a list of components and base declarations for each entry in the
17661 // variable list.
17662 VarComponents.reserve(VarList.size());
17663 VarBaseDeclarations.reserve(VarList.size());
17664 }
17665};
17666}
17667
17668// Check the validity of the provided variable list for the provided clause kind
17669// \a CKind. In the check process the valid expressions, mappable expression
17670// components, variables, and user-defined mappers are extracted and used to
17671// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17672// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17673// and \a MapperId are expected to be valid if the clause kind is 'map'.
17674static void checkMappableExpressionList(
17675 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17676 MappableVarListInfo &MVLI, SourceLocation StartLoc,
17677 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17678 ArrayRef<Expr *> UnresolvedMappers,
17679 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17680 bool IsMapTypeImplicit = false) {
17681 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17682 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17683, __PRETTY_FUNCTION__))
17683 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17683, __PRETTY_FUNCTION__))
;
17684
17685 // If the identifier of user-defined mapper is not specified, it is "default".
17686 // We do not change the actual name in this clause to distinguish whether a
17687 // mapper is specified explicitly, i.e., it is not explicitly specified when
17688 // MapperId.getName() is empty.
17689 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17690 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17691 MapperId.setName(DeclNames.getIdentifier(
17692 &SemaRef.getASTContext().Idents.get("default")));
17693 MapperId.setLoc(StartLoc);
17694 }
17695
17696 // Iterators to find the current unresolved mapper expression.
17697 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17698 bool UpdateUMIt = false;
17699 Expr *UnresolvedMapper = nullptr;
17700
17701 // Keep track of the mappable components and base declarations in this clause.
17702 // Each entry in the list is going to have a list of components associated. We
17703 // record each set of the components so that we can build the clause later on.
17704 // In the end we should have the same amount of declarations and component
17705 // lists.
17706
17707 for (Expr *RE : MVLI.VarList) {
17708 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17708, __PRETTY_FUNCTION__))
;
17709 SourceLocation ELoc = RE->getExprLoc();
17710
17711 // Find the current unresolved mapper expression.
17712 if (UpdateUMIt && UMIt != UMEnd) {
17713 UMIt++;
17714 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17716, __PRETTY_FUNCTION__))
17715 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17716, __PRETTY_FUNCTION__))
17716 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17716, __PRETTY_FUNCTION__))
;
17717 }
17718 UpdateUMIt = true;
17719 if (UMIt != UMEnd)
17720 UnresolvedMapper = *UMIt;
17721
17722 const Expr *VE = RE->IgnoreParenLValueCasts();
17723
17724 if (VE->isValueDependent() || VE->isTypeDependent() ||
17725 VE->isInstantiationDependent() ||
17726 VE->containsUnexpandedParameterPack()) {
17727 // Try to find the associated user-defined mapper.
17728 ExprResult ER = buildUserDefinedMapperRef(
17729 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17730 VE->getType().getCanonicalType(), UnresolvedMapper);
17731 if (ER.isInvalid())
17732 continue;
17733 MVLI.UDMapperList.push_back(ER.get());
17734 // We can only analyze this information once the missing information is
17735 // resolved.
17736 MVLI.ProcessedVarList.push_back(RE);
17737 continue;
17738 }
17739
17740 Expr *SimpleExpr = RE->IgnoreParenCasts();
17741
17742 if (!RE->isLValue()) {
17743 if (SemaRef.getLangOpts().OpenMP < 50) {
17744 SemaRef.Diag(
17745 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17746 << RE->getSourceRange();
17747 } else {
17748 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17749 << getOpenMPClauseName(CKind) << RE->getSourceRange();
17750 }
17751 continue;
17752 }
17753
17754 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17755 ValueDecl *CurDeclaration = nullptr;
17756
17757 // Obtain the array or member expression bases if required. Also, fill the
17758 // components array with all the components identified in the process.
17759 const Expr *BE = checkMapClauseExpressionBase(
17760 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
17761 /*NoDiagnose=*/false);
17762 if (!BE)
17763 continue;
17764
17765 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17766, __PRETTY_FUNCTION__))
17766 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17766, __PRETTY_FUNCTION__))
;
17767
17768 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17769 // Add store "this" pointer to class in DSAStackTy for future checking
17770 DSAS->addMappedClassesQualTypes(TE->getType());
17771 // Try to find the associated user-defined mapper.
17772 ExprResult ER = buildUserDefinedMapperRef(
17773 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17774 VE->getType().getCanonicalType(), UnresolvedMapper);
17775 if (ER.isInvalid())
17776 continue;
17777 MVLI.UDMapperList.push_back(ER.get());
17778 // Skip restriction checking for variable or field declarations
17779 MVLI.ProcessedVarList.push_back(RE);
17780 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17781 MVLI.VarComponents.back().append(CurComponents.begin(),
17782 CurComponents.end());
17783 MVLI.VarBaseDeclarations.push_back(nullptr);
17784 continue;
17785 }
17786
17787 // For the following checks, we rely on the base declaration which is
17788 // expected to be associated with the last component. The declaration is
17789 // expected to be a variable or a field (if 'this' is being mapped).
17790 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17791 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17791, __PRETTY_FUNCTION__))
;
17792 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17794, __PRETTY_FUNCTION__))
17793 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17794, __PRETTY_FUNCTION__))
17794 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17794, __PRETTY_FUNCTION__))
;
17795
17796 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17797 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17798
17799 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17799, __PRETTY_FUNCTION__))
;
17800 (void)FD;
17801
17802 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17803 // threadprivate variables cannot appear in a map clause.
17804 // OpenMP 4.5 [2.10.5, target update Construct]
17805 // threadprivate variables cannot appear in a from clause.
17806 if (VD && DSAS->isThreadPrivate(VD)) {
17807 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17808 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17809 << getOpenMPClauseName(CKind);
17810 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17811 continue;
17812 }
17813
17814 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17815 // A list item cannot appear in both a map clause and a data-sharing
17816 // attribute clause on the same construct.
17817
17818 // Check conflicts with other map clause expressions. We check the conflicts
17819 // with the current construct separately from the enclosing data
17820 // environment, because the restrictions are different. We only have to
17821 // check conflicts across regions for the map clauses.
17822 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17823 /*CurrentRegionOnly=*/true, CurComponents, CKind))
17824 break;
17825 if (CKind == OMPC_map &&
17826 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
17827 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17828 /*CurrentRegionOnly=*/false, CurComponents, CKind))
17829 break;
17830
17831 // OpenMP 4.5 [2.10.5, target update Construct]
17832 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17833 // If the type of a list item is a reference to a type T then the type will
17834 // be considered to be T for all purposes of this clause.
17835 auto I = llvm::find_if(
17836 CurComponents,
17837 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17838 return MC.getAssociatedDeclaration();
17839 });
17840 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17840, __PRETTY_FUNCTION__))
;
17841 QualType Type;
17842 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17843 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17844 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17845 if (ASE) {
17846 Type = ASE->getType().getNonReferenceType();
17847 } else if (OASE) {
17848 QualType BaseType =
17849 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17850 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17851 Type = ATy->getElementType();
17852 else
17853 Type = BaseType->getPointeeType();
17854 Type = Type.getNonReferenceType();
17855 } else if (OAShE) {
17856 Type = OAShE->getBase()->getType()->getPointeeType();
17857 } else {
17858 Type = VE->getType();
17859 }
17860
17861 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17862 // A list item in a to or from clause must have a mappable type.
17863 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17864 // A list item must have a mappable type.
17865 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17866 DSAS, Type))
17867 continue;
17868
17869 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17870
17871 if (CKind == OMPC_map) {
17872 // target enter data
17873 // OpenMP [2.10.2, Restrictions, p. 99]
17874 // A map-type must be specified in all map clauses and must be either
17875 // to or alloc.
17876 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17877 if (DKind == OMPD_target_enter_data &&
17878 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17879 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17880 << (IsMapTypeImplicit ? 1 : 0)
17881 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17882 << getOpenMPDirectiveName(DKind);
17883 continue;
17884 }
17885
17886 // target exit_data
17887 // OpenMP [2.10.3, Restrictions, p. 102]
17888 // A map-type must be specified in all map clauses and must be either
17889 // from, release, or delete.
17890 if (DKind == OMPD_target_exit_data &&
17891 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17892 MapType == OMPC_MAP_delete)) {
17893 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17894 << (IsMapTypeImplicit ? 1 : 0)
17895 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17896 << getOpenMPDirectiveName(DKind);
17897 continue;
17898 }
17899
17900 // target, target data
17901 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17902 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17903 // A map-type in a map clause must be to, from, tofrom or alloc
17904 if ((DKind == OMPD_target_data ||
17905 isOpenMPTargetExecutionDirective(DKind)) &&
17906 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17907 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17908 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17909 << (IsMapTypeImplicit ? 1 : 0)
17910 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17911 << getOpenMPDirectiveName(DKind);
17912 continue;
17913 }
17914
17915 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17916 // A list item cannot appear in both a map clause and a data-sharing
17917 // attribute clause on the same construct
17918 //
17919 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17920 // A list item cannot appear in both a map clause and a data-sharing
17921 // attribute clause on the same construct unless the construct is a
17922 // combined construct.
17923 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17924 isOpenMPTargetExecutionDirective(DKind)) ||
17925 DKind == OMPD_target)) {
17926 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17927 if (isOpenMPPrivate(DVar.CKind)) {
17928 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17929 << getOpenMPClauseName(DVar.CKind)
17930 << getOpenMPClauseName(OMPC_map)
17931 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17932 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17933 continue;
17934 }
17935 }
17936 }
17937
17938 // Try to find the associated user-defined mapper.
17939 ExprResult ER = buildUserDefinedMapperRef(
17940 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17941 Type.getCanonicalType(), UnresolvedMapper);
17942 if (ER.isInvalid())
17943 continue;
17944 MVLI.UDMapperList.push_back(ER.get());
17945
17946 // Save the current expression.
17947 MVLI.ProcessedVarList.push_back(RE);
17948
17949 // Store the components in the stack so that they can be used to check
17950 // against other clauses later on.
17951 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17952 /*WhereFoundClauseKind=*/OMPC_map);
17953
17954 // Save the components and declaration to create the clause. For purposes of
17955 // the clause creation, any component list that has has base 'this' uses
17956 // null as base declaration.
17957 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17958 MVLI.VarComponents.back().append(CurComponents.begin(),
17959 CurComponents.end());
17960 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17961 : CurDeclaration);
17962 }
17963}
17964
17965OMPClause *Sema::ActOnOpenMPMapClause(
17966 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17967 ArrayRef<SourceLocation> MapTypeModifiersLoc,
17968 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17969 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17970 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17971 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17972 OpenMPMapModifierKind Modifiers[] = {
17973 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
17974 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
17975 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17976
17977 // Process map-type-modifiers, flag errors for duplicate modifiers.
17978 unsigned Count = 0;
17979 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17980 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17981 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17982 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17983 continue;
17984 }
17985 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17986, __PRETTY_FUNCTION__))
17986 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 17986, __PRETTY_FUNCTION__))
;
17987 Modifiers[Count] = MapTypeModifiers[I];
17988 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17989 ++Count;
17990 }
17991
17992 MappableVarListInfo MVLI(VarList);
17993 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
17994 MapperIdScopeSpec, MapperId, UnresolvedMappers,
17995 MapType, IsMapTypeImplicit);
17996
17997 // We need to produce a map clause even if we don't have variables so that
17998 // other diagnostics related with non-existing map clauses are accurate.
17999 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
18000 MVLI.VarBaseDeclarations, MVLI.VarComponents,
18001 MVLI.UDMapperList, Modifiers, ModifiersLoc,
18002 MapperIdScopeSpec.getWithLocInContext(Context),
18003 MapperId, MapType, IsMapTypeImplicit, MapLoc);
18004}
18005
18006QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
18007 TypeResult ParsedType) {
18008 assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail
("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18008, __PRETTY_FUNCTION__))
;
18009
18010 QualType ReductionType = GetTypeFromParser(ParsedType.get());
18011 if (ReductionType.isNull())
18012 return QualType();
18013
18014 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
18015 // A type name in a declare reduction directive cannot be a function type, an
18016 // array type, a reference type, or a type qualified with const, volatile or
18017 // restrict.
18018 if (ReductionType.hasQualifiers()) {
18019 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
18020 return QualType();
18021 }
18022
18023 if (ReductionType->isFunctionType()) {
18024 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
18025 return QualType();
18026 }
18027 if (ReductionType->isReferenceType()) {
18028 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
18029 return QualType();
18030 }
18031 if (ReductionType->isArrayType()) {
18032 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
18033 return QualType();
18034 }
18035 return ReductionType;
18036}
18037
18038Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
18039 Scope *S, DeclContext *DC, DeclarationName Name,
18040 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
18041 AccessSpecifier AS, Decl *PrevDeclInScope) {
18042 SmallVector<Decl *, 8> Decls;
18043 Decls.reserve(ReductionTypes.size());
18044
18045 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
18046 forRedeclarationInCurContext());
18047 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
18048 // A reduction-identifier may not be re-declared in the current scope for the
18049 // same type or for a type that is compatible according to the base language
18050 // rules.
18051 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18052 OMPDeclareReductionDecl *PrevDRD = nullptr;
18053 bool InCompoundScope = true;
18054 if (S != nullptr) {
18055 // Find previous declaration with the same name not referenced in other
18056 // declarations.
18057 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18058 InCompoundScope =
18059 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18060 LookupName(Lookup, S);
18061 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18062 /*AllowInlineNamespace=*/false);
18063 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
18064 LookupResult::Filter Filter = Lookup.makeFilter();
18065 while (Filter.hasNext()) {
18066 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
18067 if (InCompoundScope) {
18068 auto I = UsedAsPrevious.find(PrevDecl);
18069 if (I == UsedAsPrevious.end())
18070 UsedAsPrevious[PrevDecl] = false;
18071 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
18072 UsedAsPrevious[D] = true;
18073 }
18074 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18075 PrevDecl->getLocation();
18076 }
18077 Filter.done();
18078 if (InCompoundScope) {
18079 for (const auto &PrevData : UsedAsPrevious) {
18080 if (!PrevData.second) {
18081 PrevDRD = PrevData.first;
18082 break;
18083 }
18084 }
18085 }
18086 } else if (PrevDeclInScope != nullptr) {
18087 auto *PrevDRDInScope = PrevDRD =
18088 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
18089 do {
18090 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
18091 PrevDRDInScope->getLocation();
18092 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
18093 } while (PrevDRDInScope != nullptr);
18094 }
18095 for (const auto &TyData : ReductionTypes) {
18096 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
18097 bool Invalid = false;
18098 if (I != PreviousRedeclTypes.end()) {
18099 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
18100 << TyData.first;
18101 Diag(I->second, diag::note_previous_definition);
18102 Invalid = true;
18103 }
18104 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
18105 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
18106 Name, TyData.first, PrevDRD);
18107 DC->addDecl(DRD);
18108 DRD->setAccess(AS);
18109 Decls.push_back(DRD);
18110 if (Invalid)
18111 DRD->setInvalidDecl();
18112 else
18113 PrevDRD = DRD;
18114 }
18115
18116 return DeclGroupPtrTy::make(
18117 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
18118}
18119
18120void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
18121 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18122
18123 // Enter new function scope.
18124 PushFunctionScope();
18125 setFunctionHasBranchProtectedScope();
18126 getCurFunction()->setHasOMPDeclareReductionCombiner();
18127
18128 if (S != nullptr)
18129 PushDeclContext(S, DRD);
18130 else
18131 CurContext = DRD;
18132
18133 PushExpressionEvaluationContext(
18134 ExpressionEvaluationContext::PotentiallyEvaluated);
18135
18136 QualType ReductionType = DRD->getType();
18137 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
18138 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
18139 // uses semantics of argument handles by value, but it should be passed by
18140 // reference. C lang does not support references, so pass all parameters as
18141 // pointers.
18142 // Create 'T omp_in;' variable.
18143 VarDecl *OmpInParm =
18144 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
18145 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
18146 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
18147 // uses semantics of argument handles by value, but it should be passed by
18148 // reference. C lang does not support references, so pass all parameters as
18149 // pointers.
18150 // Create 'T omp_out;' variable.
18151 VarDecl *OmpOutParm =
18152 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
18153 if (S != nullptr) {
18154 PushOnScopeChains(OmpInParm, S);
18155 PushOnScopeChains(OmpOutParm, S);
18156 } else {
18157 DRD->addDecl(OmpInParm);
18158 DRD->addDecl(OmpOutParm);
18159 }
18160 Expr *InE =
18161 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
18162 Expr *OutE =
18163 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
18164 DRD->setCombinerData(InE, OutE);
18165}
18166
18167void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
18168 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18169 DiscardCleanupsInEvaluationContext();
18170 PopExpressionEvaluationContext();
18171
18172 PopDeclContext();
18173 PopFunctionScopeInfo();
18174
18175 if (Combiner != nullptr)
18176 DRD->setCombiner(Combiner);
18177 else
18178 DRD->setInvalidDecl();
18179}
18180
18181VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
18182 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18183
18184 // Enter new function scope.
18185 PushFunctionScope();
18186 setFunctionHasBranchProtectedScope();
18187
18188 if (S != nullptr)
18189 PushDeclContext(S, DRD);
18190 else
18191 CurContext = DRD;
18192
18193 PushExpressionEvaluationContext(
18194 ExpressionEvaluationContext::PotentiallyEvaluated);
18195
18196 QualType ReductionType = DRD->getType();
18197 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
18198 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
18199 // uses semantics of argument handles by value, but it should be passed by
18200 // reference. C lang does not support references, so pass all parameters as
18201 // pointers.
18202 // Create 'T omp_priv;' variable.
18203 VarDecl *OmpPrivParm =
18204 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
18205 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
18206 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
18207 // uses semantics of argument handles by value, but it should be passed by
18208 // reference. C lang does not support references, so pass all parameters as
18209 // pointers.
18210 // Create 'T omp_orig;' variable.
18211 VarDecl *OmpOrigParm =
18212 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
18213 if (S != nullptr) {
18214 PushOnScopeChains(OmpPrivParm, S);
18215 PushOnScopeChains(OmpOrigParm, S);
18216 } else {
18217 DRD->addDecl(OmpPrivParm);
18218 DRD->addDecl(OmpOrigParm);
18219 }
18220 Expr *OrigE =
18221 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
18222 Expr *PrivE =
18223 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
18224 DRD->setInitializerData(OrigE, PrivE);
18225 return OmpPrivParm;
18226}
18227
18228void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
18229 VarDecl *OmpPrivParm) {
18230 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18231 DiscardCleanupsInEvaluationContext();
18232 PopExpressionEvaluationContext();
18233
18234 PopDeclContext();
18235 PopFunctionScopeInfo();
18236
18237 if (Initializer != nullptr) {
18238 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
18239 } else if (OmpPrivParm->hasInit()) {
18240 DRD->setInitializer(OmpPrivParm->getInit(),
18241 OmpPrivParm->isDirectInit()
18242 ? OMPDeclareReductionDecl::DirectInit
18243 : OMPDeclareReductionDecl::CopyInit);
18244 } else {
18245 DRD->setInvalidDecl();
18246 }
18247}
18248
18249Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
18250 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
18251 for (Decl *D : DeclReductions.get()) {
18252 if (IsValid) {
18253 if (S)
18254 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
18255 /*AddToContext=*/false);
18256 } else {
18257 D->setInvalidDecl();
18258 }
18259 }
18260 return DeclReductions;
18261}
18262
18263TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
18264 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
18265 QualType T = TInfo->getType();
18266 if (D.isInvalidType())
18267 return true;
18268
18269 if (getLangOpts().CPlusPlus) {
18270 // Check that there are no default arguments (C++ only).
18271 CheckExtraCXXDefaultArguments(D);
18272 }
18273
18274 return CreateParsedType(T, TInfo);
18275}
18276
18277QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
18278 TypeResult ParsedType) {
18279 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18279, __PRETTY_FUNCTION__))
;
18280
18281 QualType MapperType = GetTypeFromParser(ParsedType.get());
18282 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18282, __PRETTY_FUNCTION__))
;
18283
18284 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18285 // The type must be of struct, union or class type in C and C++
18286 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
18287 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
18288 return QualType();
18289 }
18290 return MapperType;
18291}
18292
18293Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
18294 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
18295 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
18296 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
18297 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
18298 forRedeclarationInCurContext());
18299 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18300 // A mapper-identifier may not be redeclared in the current scope for the
18301 // same type or for a type that is compatible according to the base language
18302 // rules.
18303 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18304 OMPDeclareMapperDecl *PrevDMD = nullptr;
18305 bool InCompoundScope = true;
18306 if (S != nullptr) {
18307 // Find previous declaration with the same name not referenced in other
18308 // declarations.
18309 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18310 InCompoundScope =
18311 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18312 LookupName(Lookup, S);
18313 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18314 /*AllowInlineNamespace=*/false);
18315 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18316 LookupResult::Filter Filter = Lookup.makeFilter();
18317 while (Filter.hasNext()) {
18318 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18319 if (InCompoundScope) {
18320 auto I = UsedAsPrevious.find(PrevDecl);
18321 if (I == UsedAsPrevious.end())
18322 UsedAsPrevious[PrevDecl] = false;
18323 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18324 UsedAsPrevious[D] = true;
18325 }
18326 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18327 PrevDecl->getLocation();
18328 }
18329 Filter.done();
18330 if (InCompoundScope) {
18331 for (const auto &PrevData : UsedAsPrevious) {
18332 if (!PrevData.second) {
18333 PrevDMD = PrevData.first;
18334 break;
18335 }
18336 }
18337 }
18338 } else if (PrevDeclInScope) {
18339 auto *PrevDMDInScope = PrevDMD =
18340 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18341 do {
18342 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18343 PrevDMDInScope->getLocation();
18344 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18345 } while (PrevDMDInScope != nullptr);
18346 }
18347 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18348 bool Invalid = false;
18349 if (I != PreviousRedeclTypes.end()) {
18350 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18351 << MapperType << Name;
18352 Diag(I->second, diag::note_previous_definition);
18353 Invalid = true;
18354 }
18355 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18356 MapperType, VN, Clauses, PrevDMD);
18357 if (S)
18358 PushOnScopeChains(DMD, S);
18359 else
18360 DC->addDecl(DMD);
18361 DMD->setAccess(AS);
18362 if (Invalid)
18363 DMD->setInvalidDecl();
18364
18365 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
18366 VD->setDeclContext(DMD);
18367 VD->setLexicalDeclContext(DMD);
18368 DMD->addDecl(VD);
18369 DMD->setMapperVarRef(MapperVarRef);
18370
18371 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
18372}
18373
18374ExprResult
18375Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
18376 SourceLocation StartLoc,
18377 DeclarationName VN) {
18378 TypeSourceInfo *TInfo =
18379 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
18380 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
18381 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
18382 MapperType, TInfo, SC_None);
18383 if (S)
18384 PushOnScopeChains(VD, S, /*AddToContext=*/false);
18385 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18386 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
18387 return E;
18388}
18389
18390bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
18391 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18391, __PRETTY_FUNCTION__))
;
18392 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
18393 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
18394 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
18395 return true;
18396}
18397
18398const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
18399 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18399, __PRETTY_FUNCTION__))
;
18400 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
18401}
18402
18403OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18404 SourceLocation StartLoc,
18405 SourceLocation LParenLoc,
18406 SourceLocation EndLoc) {
18407 Expr *ValExpr = NumTeams;
18408 Stmt *HelperValStmt = nullptr;
18409
18410 // OpenMP [teams Constrcut, Restrictions]
18411 // The num_teams expression must evaluate to a positive integer value.
18412 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18413 /*StrictlyPositive=*/true))
18414 return nullptr;
18415
18416 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18417 OpenMPDirectiveKind CaptureRegion =
18418 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18419 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18420 ValExpr = MakeFullExpr(ValExpr).get();
18421 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18422 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18423 HelperValStmt = buildPreInits(Context, Captures);
18424 }
18425
18426 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18427 StartLoc, LParenLoc, EndLoc);
18428}
18429
18430OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18431 SourceLocation StartLoc,
18432 SourceLocation LParenLoc,
18433 SourceLocation EndLoc) {
18434 Expr *ValExpr = ThreadLimit;
18435 Stmt *HelperValStmt = nullptr;
18436
18437 // OpenMP [teams Constrcut, Restrictions]
18438 // The thread_limit expression must evaluate to a positive integer value.
18439 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18440 /*StrictlyPositive=*/true))
18441 return nullptr;
18442
18443 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18444 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18445 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18446 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18447 ValExpr = MakeFullExpr(ValExpr).get();
18448 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18449 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18450 HelperValStmt = buildPreInits(Context, Captures);
18451 }
18452
18453 return new (Context) OMPThreadLimitClause(
18454 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18455}
18456
18457OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18458 SourceLocation StartLoc,
18459 SourceLocation LParenLoc,
18460 SourceLocation EndLoc) {
18461 Expr *ValExpr = Priority;
18462 Stmt *HelperValStmt = nullptr;
18463 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18464
18465 // OpenMP [2.9.1, task Constrcut]
18466 // The priority-value is a non-negative numerical scalar expression.
18467 if (!isNonNegativeIntegerValue(
18468 ValExpr, *this, OMPC_priority,
18469 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18470 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18471 return nullptr;
18472
18473 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18474 StartLoc, LParenLoc, EndLoc);
18475}
18476
18477OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18478 SourceLocation StartLoc,
18479 SourceLocation LParenLoc,
18480 SourceLocation EndLoc) {
18481 Expr *ValExpr = Grainsize;
18482 Stmt *HelperValStmt = nullptr;
18483 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18484
18485 // OpenMP [2.9.2, taskloop Constrcut]
18486 // The parameter of the grainsize clause must be a positive integer
18487 // expression.
18488 if (!isNonNegativeIntegerValue(
18489 ValExpr, *this, OMPC_grainsize,
18490 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18491 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18492 return nullptr;
18493
18494 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18495 StartLoc, LParenLoc, EndLoc);
18496}
18497
18498OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18499 SourceLocation StartLoc,
18500 SourceLocation LParenLoc,
18501 SourceLocation EndLoc) {
18502 Expr *ValExpr = NumTasks;
18503 Stmt *HelperValStmt = nullptr;
18504 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18505
18506 // OpenMP [2.9.2, taskloop Constrcut]
18507 // The parameter of the num_tasks clause must be a positive integer
18508 // expression.
18509 if (!isNonNegativeIntegerValue(
18510 ValExpr, *this, OMPC_num_tasks,
18511 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18512 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18513 return nullptr;
18514
18515 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18516 StartLoc, LParenLoc, EndLoc);
18517}
18518
18519OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18520 SourceLocation LParenLoc,
18521 SourceLocation EndLoc) {
18522 // OpenMP [2.13.2, critical construct, Description]
18523 // ... where hint-expression is an integer constant expression that evaluates
18524 // to a valid lock hint.
18525 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18526 if (HintExpr.isInvalid())
18527 return nullptr;
18528 return new (Context)
18529 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18530}
18531
18532/// Tries to find omp_event_handle_t type.
18533static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18534 DSAStackTy *Stack) {
18535 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18536 if (!OMPEventHandleT.isNull())
18537 return true;
18538 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18539 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18540 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18541 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18542 return false;
18543 }
18544 Stack->setOMPEventHandleT(PT.get());
18545 return true;
18546}
18547
18548OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18549 SourceLocation LParenLoc,
18550 SourceLocation EndLoc) {
18551 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18552 !Evt->isInstantiationDependent() &&
18553 !Evt->containsUnexpandedParameterPack()) {
18554 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
18555 return nullptr;
18556 // OpenMP 5.0, 2.10.1 task Construct.
18557 // event-handle is a variable of the omp_event_handle_t type.
18558 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18559 if (!Ref) {
18560 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18561 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18562 return nullptr;
18563 }
18564 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18565 if (!VD) {
18566 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18567 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18568 return nullptr;
18569 }
18570 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
18571 VD->getType()) ||
18572 VD->getType().isConstant(Context)) {
18573 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18574 << "omp_event_handle_t" << 1 << VD->getType()
18575 << Evt->getSourceRange();
18576 return nullptr;
18577 }
18578 // OpenMP 5.0, 2.10.1 task Construct
18579 // [detach clause]... The event-handle will be considered as if it was
18580 // specified on a firstprivate clause.
18581 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
18582 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18583 DVar.RefExpr) {
18584 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18585 << getOpenMPClauseName(DVar.CKind)
18586 << getOpenMPClauseName(OMPC_firstprivate);
18587 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
18588 return nullptr;
18589 }
18590 }
18591
18592 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18593}
18594
18595OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18596 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18597 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18598 SourceLocation EndLoc) {
18599 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18600 std::string Values;
18601 Values += "'";
18602 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18603 Values += "'";
18604 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18605 << Values << getOpenMPClauseName(OMPC_dist_schedule);
18606 return nullptr;
18607 }
18608 Expr *ValExpr = ChunkSize;
18609 Stmt *HelperValStmt = nullptr;
18610 if (ChunkSize) {
18611 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18612 !ChunkSize->isInstantiationDependent() &&
18613 !ChunkSize->containsUnexpandedParameterPack()) {
18614 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18615 ExprResult Val =
18616 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18617 if (Val.isInvalid())
18618 return nullptr;
18619
18620 ValExpr = Val.get();
18621
18622 // OpenMP [2.7.1, Restrictions]
18623 // chunk_size must be a loop invariant integer expression with a positive
18624 // value.
18625 if (Optional<llvm::APSInt> Result =
18626 ValExpr->getIntegerConstantExpr(Context)) {
18627 if (Result->isSigned() && !Result->isStrictlyPositive()) {
18628 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18629 << "dist_schedule" << ChunkSize->getSourceRange();
18630 return nullptr;
18631 }
18632 } else if (getOpenMPCaptureRegionForClause(
18633 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
18634 LangOpts.OpenMP) != OMPD_unknown &&
18635 !CurContext->isDependentContext()) {
18636 ValExpr = MakeFullExpr(ValExpr).get();
18637 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18638 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18639 HelperValStmt = buildPreInits(Context, Captures);
18640 }
18641 }
18642 }
18643
18644 return new (Context)
18645 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18646 Kind, ValExpr, HelperValStmt);
18647}
18648
18649OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18650 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18651 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18652 SourceLocation KindLoc, SourceLocation EndLoc) {
18653 if (getLangOpts().OpenMP < 50) {
18654 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18655 Kind != OMPC_DEFAULTMAP_scalar) {
18656 std::string Value;
18657 SourceLocation Loc;
18658 Value += "'";
18659 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18660 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18661 OMPC_DEFAULTMAP_MODIFIER_tofrom);
18662 Loc = MLoc;
18663 } else {
18664 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18665 OMPC_DEFAULTMAP_scalar);
18666 Loc = KindLoc;
18667 }
18668 Value += "'";
18669 Diag(Loc, diag::err_omp_unexpected_clause_value)
18670 << Value << getOpenMPClauseName(OMPC_defaultmap);
18671 return nullptr;
18672 }
18673 } else {
18674 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18675 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18676 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18677 if (!isDefaultmapKind || !isDefaultmapModifier) {
18678 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
18679 if (LangOpts.OpenMP == 50) {
18680 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18681 "'firstprivate', 'none', 'default'";
18682 if (!isDefaultmapKind && isDefaultmapModifier) {
18683 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18684 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18685 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18686 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18687 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18688 } else {
18689 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18690 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18691 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18692 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18693 }
18694 } else {
18695 StringRef ModifierValue =
18696 "'alloc', 'from', 'to', 'tofrom', "
18697 "'firstprivate', 'none', 'default', 'present'";
18698 if (!isDefaultmapKind && isDefaultmapModifier) {
18699 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18700 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18701 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18702 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18703 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18704 } else {
18705 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18706 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18707 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18708 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18709 }
18710 }
18711 return nullptr;
18712 }
18713
18714 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18715 // At most one defaultmap clause for each category can appear on the
18716 // directive.
18717 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
18718 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18719 return nullptr;
18720 }
18721 }
18722 if (Kind == OMPC_DEFAULTMAP_unknown) {
18723 // Variable category is not specified - mark all categories.
18724 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18725 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18726 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18727 } else {
18728 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
18729 }
18730
18731 return new (Context)
18732 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18733}
18734
18735bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18736 DeclContext *CurLexicalContext = getCurLexicalContext();
18737 if (!CurLexicalContext->isFileContext() &&
18738 !CurLexicalContext->isExternCContext() &&
18739 !CurLexicalContext->isExternCXXContext() &&
18740 !isa<CXXRecordDecl>(CurLexicalContext) &&
18741 !isa<ClassTemplateDecl>(CurLexicalContext) &&
18742 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18743 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18744 Diag(Loc, diag::err_omp_region_not_file_context);
18745 return false;
18746 }
18747 DeclareTargetNesting.push_back(Loc);
18748 return true;
18749}
18750
18751void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18752 assert(!DeclareTargetNesting.empty() &&((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18753, __PRETTY_FUNCTION__))
18753 "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-13~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18753, __PRETTY_FUNCTION__))
;
18754 DeclareTargetNesting.pop_back();
18755}
18756
18757NamedDecl *
18758Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18759 const DeclarationNameInfo &Id,
18760 NamedDeclSetType &SameDirectiveDecls) {
18761 LookupResult Lookup(*this, Id, LookupOrdinaryName);
18762 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18763
18764 if (Lookup.isAmbiguous())
18765 return nullptr;
18766 Lookup.suppressDiagnostics();
18767
18768 if (!Lookup.isSingleResult()) {
18769 VarOrFuncDeclFilterCCC CCC(*this);
18770 if (TypoCorrection Corrected =
18771 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18772 CTK_ErrorRecovery)) {
18773 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18774 << Id.getName());
18775 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18776 return nullptr;
18777 }
18778
18779 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18780 return nullptr;
18781 }
18782
18783 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18784 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18785 !isa<FunctionTemplateDecl>(ND)) {
18786 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18787 return nullptr;
18788 }
18789 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18790 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18791 return ND;
18792}
18793
18794void Sema::ActOnOpenMPDeclareTargetName(
18795 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18796 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18797 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18799, __PRETTY_FUNCTION__))
18798 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18799, __PRETTY_FUNCTION__))
18799 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18799, __PRETTY_FUNCTION__))
;
18800
18801 // Diagnose marking after use as it may lead to incorrect diagnosis and
18802 // codegen.
18803 if (LangOpts.OpenMP >= 50 &&
18804 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18805 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18806
18807 auto *VD = cast<ValueDecl>(ND);
18808 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18809 OMPDeclareTargetDeclAttr::getDeviceType(VD);
18810 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
18811 if (DevTy.hasValue() && *DevTy != DT &&
18812 (DeclareTargetNesting.empty() ||
18813 *AttrLoc != DeclareTargetNesting.back())) {
18814 Diag(Loc, diag::err_omp_device_type_mismatch)
18815 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18816 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18817 return;
18818 }
18819 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18820 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18821 if (!Res || (!DeclareTargetNesting.empty() &&
18822 *AttrLoc == DeclareTargetNesting.back())) {
18823 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18824 Context, MT, DT, DeclareTargetNesting.size() + 1,
18825 SourceRange(Loc, Loc));
18826 ND->addAttr(A);
18827 if (ASTMutationListener *ML = Context.getASTMutationListener())
18828 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18829 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18830 } else if (*Res != MT) {
18831 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18832 }
18833}
18834
18835static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18836 Sema &SemaRef, Decl *D) {
18837 if (!D || !isa<VarDecl>(D))
18838 return;
18839 auto *VD = cast<VarDecl>(D);
18840 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18841 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18842 if (SemaRef.LangOpts.OpenMP >= 50 &&
18843 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18844 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18845 VD->hasGlobalStorage()) {
18846 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18847 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18848 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18849 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18850 // If a lambda declaration and definition appears between a
18851 // declare target directive and the matching end declare target
18852 // directive, all variables that are captured by the lambda
18853 // expression must also appear in a to clause.
18854 SemaRef.Diag(VD->getLocation(),
18855 diag::err_omp_lambda_capture_in_declare_target_not_to);
18856 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18857 << VD << 0 << SR;
18858 return;
18859 }
18860 }
18861 if (MapTy.hasValue())
18862 return;
18863 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18864 SemaRef.Diag(SL, diag::note_used_here) << SR;
18865}
18866
18867static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18868 Sema &SemaRef, DSAStackTy *Stack,
18869 ValueDecl *VD) {
18870 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18871 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18872 /*FullCheck=*/false);
18873}
18874
18875void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18876 SourceLocation IdLoc) {
18877 if (!D || D->isInvalidDecl())
18878 return;
18879 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18880 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18881 if (auto *VD = dyn_cast<VarDecl>(D)) {
18882 // Only global variables can be marked as declare target.
18883 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18884 !VD->isStaticDataMember())
18885 return;
18886 // 2.10.6: threadprivate variable cannot appear in a declare target
18887 // directive.
18888 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
18889 Diag(SL, diag::err_omp_threadprivate_in_target);
18890 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
18891 return;
18892 }
18893 }
18894 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18895 D = FTD->getTemplatedDecl();
18896 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18897 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18898 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18899 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18900 Diag(IdLoc, diag::err_omp_function_in_link_clause);
18901 Diag(FD->getLocation(), diag::note_defined_here) << FD;
18902 return;
18903 }
18904 }
18905 if (auto *VD = dyn_cast<ValueDecl>(D)) {
18906 // Problem if any with var declared with incomplete type will be reported
18907 // as normal, so no need to check it here.
18908 if ((E || !VD->getType()->isIncompleteType()) &&
18909 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
18910 return;
18911 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18912 // Checking declaration inside declare target region.
18913 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18914 isa<FunctionTemplateDecl>(D)) {
18915 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18916 Context, OMPDeclareTargetDeclAttr::MT_To,
18917 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
18918 SourceRange(DeclareTargetNesting.back(),
18919 DeclareTargetNesting.back()));
18920 D->addAttr(A);
18921 if (ASTMutationListener *ML = Context.getASTMutationListener())
18922 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18923 }
18924 return;
18925 }
18926 }
18927 if (!E)
18928 return;
18929 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18930}
18931
18932OMPClause *Sema::ActOnOpenMPToClause(
18933 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18934 ArrayRef<SourceLocation> MotionModifiersLoc,
18935 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18936 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18937 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18938 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18939 OMPC_MOTION_MODIFIER_unknown};
18940 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18941
18942 // Process motion-modifiers, flag errors for duplicate modifiers.
18943 unsigned Count = 0;
18944 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18945 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18946 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18947 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18948 continue;
18949 }
18950 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18951, __PRETTY_FUNCTION__))
18951 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18951, __PRETTY_FUNCTION__))
;
18952 Modifiers[Count] = MotionModifiers[I];
18953 ModifiersLoc[Count] = MotionModifiersLoc[I];
18954 ++Count;
18955 }
18956
18957 MappableVarListInfo MVLI(VarList);
18958 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
18959 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18960 if (MVLI.ProcessedVarList.empty())
18961 return nullptr;
18962
18963 return OMPToClause::Create(
18964 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18965 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18966 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18967}
18968
18969OMPClause *Sema::ActOnOpenMPFromClause(
18970 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18971 ArrayRef<SourceLocation> MotionModifiersLoc,
18972 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18973 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18974 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18975 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18976 OMPC_MOTION_MODIFIER_unknown};
18977 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18978
18979 // Process motion-modifiers, flag errors for duplicate modifiers.
18980 unsigned Count = 0;
18981 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18982 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18983 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18984 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18985 continue;
18986 }
18987 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18988, __PRETTY_FUNCTION__))
18988 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 18988, __PRETTY_FUNCTION__))
;
18989 Modifiers[Count] = MotionModifiers[I];
18990 ModifiersLoc[Count] = MotionModifiersLoc[I];
18991 ++Count;
18992 }
18993
18994 MappableVarListInfo MVLI(VarList);
18995 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
18996 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18997 if (MVLI.ProcessedVarList.empty())
18998 return nullptr;
18999
19000 return OMPFromClause::Create(
19001 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
19002 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
19003 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
19004}
19005
19006OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
19007 const OMPVarListLocTy &Locs) {
19008 MappableVarListInfo MVLI(VarList);
19009 SmallVector<Expr *, 8> PrivateCopies;
19010 SmallVector<Expr *, 8> Inits;
19011
19012 for (Expr *RefExpr : VarList) {
19013 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19013, __PRETTY_FUNCTION__))
;
19014 SourceLocation ELoc;
19015 SourceRange ERange;
19016 Expr *SimpleRefExpr = RefExpr;
19017 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19018 if (Res.second) {
19019 // It will be analyzed later.
19020 MVLI.ProcessedVarList.push_back(RefExpr);
19021 PrivateCopies.push_back(nullptr);
19022 Inits.push_back(nullptr);
19023 }
19024 ValueDecl *D = Res.first;
19025 if (!D)
19026 continue;
19027
19028 QualType Type = D->getType();
19029 Type = Type.getNonReferenceType().getUnqualifiedType();
19030
19031 auto *VD = dyn_cast<VarDecl>(D);
19032
19033 // Item should be a pointer or reference to pointer.
19034 if (!Type->isPointerType()) {
19035 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
19036 << 0 << RefExpr->getSourceRange();
19037 continue;
19038 }
19039
19040 // Build the private variable and the expression that refers to it.
19041 auto VDPrivate =
19042 buildVarDecl(*this, ELoc, Type, D->getName(),
19043 D->hasAttrs() ? &D->getAttrs() : nullptr,
19044 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19045 if (VDPrivate->isInvalidDecl())
19046 continue;
19047
19048 CurContext->addDecl(VDPrivate);
19049 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
19050 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
19051
19052 // Add temporary variable to initialize the private copy of the pointer.
19053 VarDecl *VDInit =
19054 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
19055 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
19056 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
19057 AddInitializerToDecl(VDPrivate,
19058 DefaultLvalueConversion(VDInitRefExpr).get(),
19059 /*DirectInit=*/false);
19060
19061 // If required, build a capture to implement the privatization initialized
19062 // with the current list item value.
19063 DeclRefExpr *Ref = nullptr;
19064 if (!VD)
19065 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19066 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19067 PrivateCopies.push_back(VDPrivateRefExpr);
19068 Inits.push_back(VDInitRefExpr);
19069
19070 // We need to add a data sharing attribute for this variable to make sure it
19071 // is correctly captured. A variable that shows up in a use_device_ptr has
19072 // similar properties of a first private variable.
19073 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19074
19075 // Create a mappable component for the list item. List items in this clause
19076 // only need a component.
19077 MVLI.VarBaseDeclarations.push_back(D);
19078 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19079 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
19080 /*IsNonContiguous=*/false);
19081 }
19082
19083 if (MVLI.ProcessedVarList.empty())
19084 return nullptr;
19085
19086 return OMPUseDevicePtrClause::Create(
19087 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
19088 MVLI.VarBaseDeclarations, MVLI.VarComponents);
19089}
19090
19091OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
19092 const OMPVarListLocTy &Locs) {
19093 MappableVarListInfo MVLI(VarList);
19094
19095 for (Expr *RefExpr : VarList) {
19096 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19096, __PRETTY_FUNCTION__))
;
19097 SourceLocation ELoc;
19098 SourceRange ERange;
19099 Expr *SimpleRefExpr = RefExpr;
19100 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19101 /*AllowArraySection=*/true);
19102 if (Res.second) {
19103 // It will be analyzed later.
19104 MVLI.ProcessedVarList.push_back(RefExpr);
19105 }
19106 ValueDecl *D = Res.first;
19107 if (!D)
19108 continue;
19109 auto *VD = dyn_cast<VarDecl>(D);
19110
19111 // If required, build a capture to implement the privatization initialized
19112 // with the current list item value.
19113 DeclRefExpr *Ref = nullptr;
19114 if (!VD)
19115 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19116 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19117
19118 // We need to add a data sharing attribute for this variable to make sure it
19119 // is correctly captured. A variable that shows up in a use_device_addr has
19120 // similar properties of a first private variable.
19121 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19122
19123 // Create a mappable component for the list item. List items in this clause
19124 // only need a component.
19125 MVLI.VarBaseDeclarations.push_back(D);
19126 MVLI.VarComponents.emplace_back();
19127 Expr *Component = SimpleRefExpr;
19128 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
19129 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
19130 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
19131 MVLI.VarComponents.back().emplace_back(Component, D,
19132 /*IsNonContiguous=*/false);
19133 }
19134
19135 if (MVLI.ProcessedVarList.empty())
19136 return nullptr;
19137
19138 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19139 MVLI.VarBaseDeclarations,
19140 MVLI.VarComponents);
19141}
19142
19143OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
19144 const OMPVarListLocTy &Locs) {
19145 MappableVarListInfo MVLI(VarList);
19146 for (Expr *RefExpr : VarList) {
19147 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19147, __PRETTY_FUNCTION__))
;
19148 SourceLocation ELoc;
19149 SourceRange ERange;
19150 Expr *SimpleRefExpr = RefExpr;
19151 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19152 if (Res.second) {
19153 // It will be analyzed later.
19154 MVLI.ProcessedVarList.push_back(RefExpr);
19155 }
19156 ValueDecl *D = Res.first;
19157 if (!D)
19158 continue;
19159
19160 QualType Type = D->getType();
19161 // item should be a pointer or array or reference to pointer or array
19162 if (!Type.getNonReferenceType()->isPointerType() &&
19163 !Type.getNonReferenceType()->isArrayType()) {
19164 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
19165 << 0 << RefExpr->getSourceRange();
19166 continue;
19167 }
19168
19169 // Check if the declaration in the clause does not show up in any data
19170 // sharing attribute.
19171 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
19172 if (isOpenMPPrivate(DVar.CKind)) {
19173 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19174 << getOpenMPClauseName(DVar.CKind)
19175 << getOpenMPClauseName(OMPC_is_device_ptr)
19176 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
19177 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
19178 continue;
19179 }
19180
19181 const Expr *ConflictExpr;
19182 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
19183 D, /*CurrentRegionOnly=*/true,
19184 [&ConflictExpr](
19185 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
19186 OpenMPClauseKind) -> bool {
19187 ConflictExpr = R.front().getAssociatedExpression();
19188 return true;
19189 })) {
19190 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
19191 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
19192 << ConflictExpr->getSourceRange();
19193 continue;
19194 }
19195
19196 // Store the components in the stack so that they can be used to check
19197 // against other clauses later on.
19198 OMPClauseMappableExprCommon::MappableComponent MC(
19199 SimpleRefExpr, D, /*IsNonContiguous=*/false);
19200 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
19201 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
19202
19203 // Record the expression we've just processed.
19204 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
19205
19206 // Create a mappable component for the list item. List items in this clause
19207 // only need a component. We use a null declaration to signal fields in
19208 // 'this'.
19209 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19211, __PRETTY_FUNCTION__))
19210 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19211, __PRETTY_FUNCTION__))
19211 "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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19211, __PRETTY_FUNCTION__))
;
19212 MVLI.VarBaseDeclarations.push_back(
19213 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
19214 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19215 MVLI.VarComponents.back().push_back(MC);
19216 }
19217
19218 if (MVLI.ProcessedVarList.empty())
19219 return nullptr;
19220
19221 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19222 MVLI.VarBaseDeclarations,
19223 MVLI.VarComponents);
19224}
19225
19226OMPClause *Sema::ActOnOpenMPAllocateClause(
19227 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19228 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
19229 if (Allocator) {
19230 // OpenMP [2.11.4 allocate Clause, Description]
19231 // allocator is an expression of omp_allocator_handle_t type.
19232 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19233 return nullptr;
19234
19235 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
19236 if (AllocatorRes.isInvalid())
19237 return nullptr;
19238 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
19239 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
19240 Sema::AA_Initializing,
19241 /*AllowExplicit=*/true);
19242 if (AllocatorRes.isInvalid())
19243 return nullptr;
19244 Allocator = AllocatorRes.get();
19245 } else {
19246 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
19247 // allocate clauses that appear on a target construct or on constructs in a
19248 // target region must specify an allocator expression unless a requires
19249 // directive with the dynamic_allocators clause is present in the same
19250 // compilation unit.
19251 if (LangOpts.OpenMPIsDevice &&
19252 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
19253 targetDiag(StartLoc, diag::err_expected_allocator_expression);
19254 }
19255 // Analyze and build list of variables.
19256 SmallVector<Expr *, 8> Vars;
19257 for (Expr *RefExpr : VarList) {
19258 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19258, __PRETTY_FUNCTION__))
;
19259 SourceLocation ELoc;
19260 SourceRange ERange;
19261 Expr *SimpleRefExpr = RefExpr;
19262 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19263 if (Res.second) {
19264 // It will be analyzed later.
19265 Vars.push_back(RefExpr);
19266 }
19267 ValueDecl *D = Res.first;
19268 if (!D)
19269 continue;
19270
19271 auto *VD = dyn_cast<VarDecl>(D);
19272 DeclRefExpr *Ref = nullptr;
19273 if (!VD && !CurContext->isDependentContext())
19274 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19275 Vars.push_back((VD || CurContext->isDependentContext())
19276 ? RefExpr->IgnoreParens()
19277 : Ref);
19278 }
19279
19280 if (Vars.empty())
19281 return nullptr;
19282
19283 if (Allocator)
19284 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
19285 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
19286 ColonLoc, EndLoc, Vars);
19287}
19288
19289OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
19290 SourceLocation StartLoc,
19291 SourceLocation LParenLoc,
19292 SourceLocation EndLoc) {
19293 SmallVector<Expr *, 8> Vars;
19294 for (Expr *RefExpr : VarList) {
19295 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19295, __PRETTY_FUNCTION__))
;
19296 SourceLocation ELoc;
19297 SourceRange ERange;
19298 Expr *SimpleRefExpr = RefExpr;
19299 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19300 if (Res.second)
19301 // It will be analyzed later.
19302 Vars.push_back(RefExpr);
19303 ValueDecl *D = Res.first;
19304 if (!D)
19305 continue;
19306
19307 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
19308 // A list-item cannot appear in more than one nontemporal clause.
19309 if (const Expr *PrevRef =
19310 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
19311 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19312 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
19313 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19314 << getOpenMPClauseName(OMPC_nontemporal);
19315 continue;
19316 }
19317
19318 Vars.push_back(RefExpr);
19319 }
19320
19321 if (Vars.empty())
19322 return nullptr;
19323
19324 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19325 Vars);
19326}
19327
19328OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
19329 SourceLocation StartLoc,
19330 SourceLocation LParenLoc,
19331 SourceLocation EndLoc) {
19332 SmallVector<Expr *, 8> Vars;
19333 for (Expr *RefExpr : VarList) {
19334 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19334, __PRETTY_FUNCTION__))
;
19335 SourceLocation ELoc;
19336 SourceRange ERange;
19337 Expr *SimpleRefExpr = RefExpr;
19338 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19339 /*AllowArraySection=*/true);
19340 if (Res.second)
19341 // It will be analyzed later.
19342 Vars.push_back(RefExpr);
19343 ValueDecl *D = Res.first;
19344 if (!D)
19345 continue;
19346
19347 const DSAStackTy::DSAVarData DVar =
19348 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19349 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19350 // A list item that appears in the inclusive or exclusive clause must appear
19351 // in a reduction clause with the inscan modifier on the enclosing
19352 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19353 if (DVar.CKind != OMPC_reduction ||
19354 DVar.Modifier != OMPC_REDUCTION_inscan)
19355 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19356 << RefExpr->getSourceRange();
19357
19358 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
19359 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19360 Vars.push_back(RefExpr);
19361 }
19362
19363 if (Vars.empty())
19364 return nullptr;
19365
19366 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19367}
19368
19369OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19370 SourceLocation StartLoc,
19371 SourceLocation LParenLoc,
19372 SourceLocation EndLoc) {
19373 SmallVector<Expr *, 8> Vars;
19374 for (Expr *RefExpr : VarList) {
19375 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19375, __PRETTY_FUNCTION__))
;
19376 SourceLocation ELoc;
19377 SourceRange ERange;
19378 Expr *SimpleRefExpr = RefExpr;
19379 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19380 /*AllowArraySection=*/true);
19381 if (Res.second)
19382 // It will be analyzed later.
19383 Vars.push_back(RefExpr);
19384 ValueDecl *D = Res.first;
19385 if (!D)
19386 continue;
19387
19388 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
19389 DSAStackTy::DSAVarData DVar;
19390 if (ParentDirective != OMPD_unknown)
19391 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19392 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19393 // A list item that appears in the inclusive or exclusive clause must appear
19394 // in a reduction clause with the inscan modifier on the enclosing
19395 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19396 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19397 DVar.Modifier != OMPC_REDUCTION_inscan) {
19398 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19399 << RefExpr->getSourceRange();
19400 } else {
19401 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19402 }
19403 Vars.push_back(RefExpr);
19404 }
19405
19406 if (Vars.empty())
19407 return nullptr;
19408
19409 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19410}
19411
19412/// Tries to find omp_alloctrait_t type.
19413static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19414 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19415 if (!OMPAlloctraitT.isNull())
19416 return true;
19417 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19418 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19419 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19420 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19421 return false;
19422 }
19423 Stack->setOMPAlloctraitT(PT.get());
19424 return true;
19425}
19426
19427OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19428 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19429 ArrayRef<UsesAllocatorsData> Data) {
19430 // OpenMP [2.12.5, target Construct]
19431 // allocator is an identifier of omp_allocator_handle_t type.
19432 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19433 return nullptr;
19434 // OpenMP [2.12.5, target Construct]
19435 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19436 if (llvm::any_of(
19437 Data,
19438 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19439 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19440 return nullptr;
19441 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19442 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19443 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19444 StringRef Allocator =
19445 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19446 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19447 PredefinedAllocators.insert(LookupSingleName(
19448 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19449 }
19450
19451 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19452 for (const UsesAllocatorsData &D : Data) {
19453 Expr *AllocatorExpr = nullptr;
19454 // Check allocator expression.
19455 if (D.Allocator->isTypeDependent()) {
19456 AllocatorExpr = D.Allocator;
19457 } else {
19458 // Traits were specified - need to assign new allocator to the specified
19459 // allocator, so it must be an lvalue.
19460 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19461 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19462 bool IsPredefinedAllocator = false;
19463 if (DRE)
19464 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19465 if (!DRE ||
19466 !(Context.hasSameUnqualifiedType(
19467 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
19468 Context.typesAreCompatible(AllocatorExpr->getType(),
19469 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
19470 /*CompareUnqualified=*/true)) ||
19471 (!IsPredefinedAllocator &&
19472 (AllocatorExpr->getType().isConstant(Context) ||
19473 !AllocatorExpr->isLValue()))) {
19474 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19475 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19476 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19477 continue;
19478 }
19479 // OpenMP [2.12.5, target Construct]
19480 // Predefined allocators appearing in a uses_allocators clause cannot have
19481 // traits specified.
19482 if (IsPredefinedAllocator && D.AllocatorTraits) {
19483 Diag(D.AllocatorTraits->getExprLoc(),
19484 diag::err_omp_predefined_allocator_with_traits)
19485 << D.AllocatorTraits->getSourceRange();
19486 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19487 << cast<NamedDecl>(DRE->getDecl())->getName()
19488 << D.Allocator->getSourceRange();
19489 continue;
19490 }
19491 // OpenMP [2.12.5, target Construct]
19492 // Non-predefined allocators appearing in a uses_allocators clause must
19493 // have traits specified.
19494 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19495 Diag(D.Allocator->getExprLoc(),
19496 diag::err_omp_nonpredefined_allocator_without_traits);
19497 continue;
19498 }
19499 // No allocator traits - just convert it to rvalue.
19500 if (!D.AllocatorTraits)
19501 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19502 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19503 DRE->getDecl(),
19504 IsPredefinedAllocator
19505 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19506 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19507 }
19508 Expr *AllocatorTraitsExpr = nullptr;
19509 if (D.AllocatorTraits) {
19510 if (D.AllocatorTraits->isTypeDependent()) {
19511 AllocatorTraitsExpr = D.AllocatorTraits;
19512 } else {
19513 // OpenMP [2.12.5, target Construct]
19514 // Arrays that contain allocator traits that appear in a uses_allocators
19515 // clause must be constant arrays, have constant values and be defined
19516 // in the same scope as the construct in which the clause appears.
19517 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19518 // Check that traits expr is a constant array.
19519 QualType TraitTy;
19520 if (const ArrayType *Ty =
19521 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19522 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19523 TraitTy = ConstArrayTy->getElementType();
19524 if (TraitTy.isNull() ||
19525 !(Context.hasSameUnqualifiedType(TraitTy,
19526 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
19527 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
19528 /*CompareUnqualified=*/true))) {
19529 Diag(D.AllocatorTraits->getExprLoc(),
19530 diag::err_omp_expected_array_alloctraits)
19531 << AllocatorTraitsExpr->getType();
19532 continue;
19533 }
19534 // Do not map by default allocator traits if it is a standalone
19535 // variable.
19536 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19537 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19538 DRE->getDecl(),
19539 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19540 }
19541 }
19542 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19543 NewD.Allocator = AllocatorExpr;
19544 NewD.AllocatorTraits = AllocatorTraitsExpr;
19545 NewD.LParenLoc = D.LParenLoc;
19546 NewD.RParenLoc = D.RParenLoc;
19547 }
19548 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19549 NewData);
19550}
19551
19552OMPClause *Sema::ActOnOpenMPAffinityClause(
19553 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19554 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19555 SmallVector<Expr *, 8> Vars;
19556 for (Expr *RefExpr : Locators) {
19557 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~++20210216111115+df22133a8a40/clang/lib/Sema/SemaOpenMP.cpp"
, 19557, __PRETTY_FUNCTION__))
;
19558 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19559 // It will be analyzed later.
19560 Vars.push_back(RefExpr);
19561 continue;
19562 }
19563
19564 SourceLocation ELoc = RefExpr->getExprLoc();
19565 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19566
19567 if (!SimpleExpr->isLValue()) {
19568 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19569 << 1 << 0 << RefExpr->getSourceRange();
19570 continue;
19571 }
19572
19573 ExprResult Res;
19574 {
19575 Sema::TentativeAnalysisScope Trap(*this);
19576 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19577 }
19578 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19579 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19580 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19581 << 1 << 0 << RefExpr->getSourceRange();
19582 continue;
19583 }
19584 Vars.push_back(SimpleExpr);
19585 }
19586
19587 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19588 EndLoc, Modifier, Vars);
19589}