Bug Summary

File:clang/lib/Sema/SemaOpenMP.cpp
Warning:line 18500, column 28
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 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/lib/Sema -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/clang/lib/Sema -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/clang/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/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-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c++ /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/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")(static_cast<void> (0));
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")(static_cast<void> (0));
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.")(static_cast<void> (0));
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 &&(static_cast<void> (0))
372 "cannot change stack while ignoring elements")(static_cast<void> (0));
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 &&(static_cast<void> (0))
382 "cannot change stack while ignoring elements")(static_cast<void> (0));
383 assert(!Stack.back().first.empty() &&(static_cast<void> (0))
384 "Data-sharing attributes stack is empty!")(static_cast<void> (0));
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()) &&(static_cast<void> (0))
417 "Expected loop-based directive.")(static_cast<void> (0));
418 getTopOfStack().LoopStart = true;
419 }
420 /// Start capturing of the variables in the loop context.
421 void loopStart() {
422 assert(isOpenMPLoopDirective(getCurrentDirective()) &&(static_cast<void> (0))
423 "Expected loop-based directive.")(static_cast<void> (0));
424 getTopOfStack().LoopStart = false;
425 }
426 /// true, if variables are captured, false otherwise.
427 bool isLoopStarted() const {
428 assert(isOpenMPLoopDirective(getCurrentDirective()) &&(static_cast<void> (0))
429 "Expected loop-based directive.")(static_cast<void> (0));
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 &&(static_cast<void> (0))
444 "cannot change stack while ignoring elements")(static_cast<void> (0));
445 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
446 assert(!isa<CapturingScopeInfo>(CurFnScope))(static_cast<void> (0));
447 CurrentNonCapturingFunctionScope = CurFnScope;
448 }
449 /// Pop region stack for non-capturing function.
450 void popFunction(const FunctionScopeInfo *OldFSI) {
451 assert(!IgnoredStackElements &&(static_cast<void> (0))
452 "cannot change stack while ignoring elements")(static_cast<void> (0));
453 if (!Stack.empty() && Stack.back().second == OldFSI) {
454 assert(Stack.back().first.empty())(static_cast<void> (0));
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 ||(static_cast<void> (0))
549 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(static_cast<void> (0))
550 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(static_cast<void> (0))
551 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(static_cast<void> (0))
552 "taskgroup reference expression requested for non taskgroup or "(static_cast<void> (0))
553 "parallel/worksharing directive.")(static_cast<void> (0));
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.")(static_cast<void> (0));
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")__builtin_unreachable();
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())(static_cast<void> (0));
997 return getStackSize() - 1;
998 }
999 void addDoacrossDependClause(OMPDependClause *C,
1000 const OperatorOffsetTy &OpsOffs) {
1001 SharingMapTy *Parent = getSecondOnStackOrNull();
1002 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))(static_cast<void> (0));
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((static_cast<void> (0))
1031 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&(static_cast<void> (0))
1032 "Expected declare target link global.")(static_cast<void> (0));
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()) &&(static_cast<void> (0))
1045 "Expected target executable directive.")(static_cast<void> (0));
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)(static_cast<void> (0));
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")(static_cast<void> (0));
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")(static_cast<void> (0));
1280 StackElem.AlignedMap[D] = NewDE;
1281 return nullptr;
1282 }
1283 assert(It->second && "Unexpected nullptr expr in the aligned map")(static_cast<void> (0));
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")(static_cast<void> (0));
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")(static_cast<void> (0));
1295 StackElem.NontemporalMap[D] = NewDE;
1296 return nullptr;
1297 }
1298 assert(It->second && "Unexpected nullptr expr in the aligned map")(static_cast<void> (0));
1299 return It->second;
1300}
1301
1302void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1303 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast<void> (0));
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")(static_cast<void> (0));
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")(static_cast<void> (0));
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")(static_cast<void> (0));
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")(static_cast<void> (0));
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) ||(static_cast<void> (0))
1369 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||(static_cast<void> (0))
1370 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||(static_cast<void> (0))
1371 (isLoopControlVariable(D).first && A == OMPC_private))(static_cast<void> (0));
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")(static_cast<void> (0));
1430 assert((static_cast<void> (0))
1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&(static_cast<void> (0))
1432 "Additional reduction info may be specified only for reduction items.")(static_cast<void> (0));
1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434 assert(ReductionData.ReductionRange.isInvalid() &&(static_cast<void> (0))
1435 (getTopOfStack().Directive == OMPD_taskgroup ||(static_cast<void> (0))
1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(static_cast<void> (0))
1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(static_cast<void> (0))
1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(static_cast<void> (0))
1439 "Additional reduction info may be specified only once for reduction "(static_cast<void> (0))
1440 "items.")(static_cast<void> (0));
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")(static_cast<void> (0));
1456 assert((static_cast<void> (0))
1457 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&(static_cast<void> (0))
1458 "Additional reduction info may be specified only for reduction items.")(static_cast<void> (0));
1459 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1460 assert(ReductionData.ReductionRange.isInvalid() &&(static_cast<void> (0))
1461 (getTopOfStack().Directive == OMPD_taskgroup ||(static_cast<void> (0))
1462 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(static_cast<void> (0))
1463 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(static_cast<void> (0))
1464 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(static_cast<void> (0))
1465 "Additional reduction info may be specified only once for reduction "(static_cast<void> (0))
1466 "items.")(static_cast<void> (0));
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.")(static_cast<void> (0));
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 "(static_cast<void> (0))
1495 "expression for the descriptor is not "(static_cast<void> (0))
1496 "set.")(static_cast<void> (0));
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.")(static_cast<void> (0));
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 "(static_cast<void> (0))
1522 "expression for the descriptor is not "(static_cast<void> (0))
1523 "set.")(static_cast<void> (0));
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 &&(static_cast<void> (0))
1886 "Expected OpenMP device compilation.")(static_cast<void> (0));
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 &&(static_cast<void> (0))
1903 "Expected OpenMP device compilation.")(static_cast<void> (0));
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")__builtin_unreachable();
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 &&(static_cast<void> (0))
1941 "Expected OpenMP host compilation.")(static_cast<void> (0));
1942
1943 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944 if (FD) {
1945 FunctionEmissionStatus FES = getEmissionStatus(FD);
1946 switch (FES) {
1947 case FunctionEmissionStatus::Emitted:
1948 Kind = SemaDiagnosticBuilder::K_Immediate;
1949 break;
1950 case FunctionEmissionStatus::Unknown:
1951 Kind = SemaDiagnosticBuilder::K_Deferred;
1952 break;
1953 case FunctionEmissionStatus::TemplateDiscarded:
1954 case FunctionEmissionStatus::OMPDiscarded:
1955 case FunctionEmissionStatus::CUDADiscarded:
1956 Kind = SemaDiagnosticBuilder::K_Nop;
1957 break;
1958 }
1959 }
1960
1961 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1962}
1963
1964static OpenMPDefaultmapClauseKind
1965getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1966 if (LO.OpenMP <= 45) {
1967 if (VD->getType().getNonReferenceType()->isScalarType())
1968 return OMPC_DEFAULTMAP_scalar;
1969 return OMPC_DEFAULTMAP_aggregate;
1970 }
1971 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1972 return OMPC_DEFAULTMAP_pointer;
1973 if (VD->getType().getNonReferenceType()->isScalarType())
1974 return OMPC_DEFAULTMAP_scalar;
1975 return OMPC_DEFAULTMAP_aggregate;
1976}
1977
1978bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1979 unsigned OpenMPCaptureLevel) const {
1980 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast<void> (0));
1981
1982 ASTContext &Ctx = getASTContext();
1983 bool IsByRef = true;
1984
1985 // Find the directive that is associated with the provided scope.
1986 D = cast<ValueDecl>(D->getCanonicalDecl());
1987 QualType Ty = D->getType();
1988
1989 bool IsVariableUsedInMapClause = false;
1990 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1991 // This table summarizes how a given variable should be passed to the device
1992 // given its type and the clauses where it appears. This table is based on
1993 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1994 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1995 //
1996 // =========================================================================
1997 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1998 // | |(tofrom:scalar)| | pvt | | | |
1999 // =========================================================================
2000 // | scl | | | | - | | bycopy|
2001 // | scl | | - | x | - | - | bycopy|
2002 // | scl | | x | - | - | - | null |
2003 // | scl | x | | | - | | byref |
2004 // | scl | x | - | x | - | - | bycopy|
2005 // | scl | x | x | - | - | - | null |
2006 // | scl | | - | - | - | x | byref |
2007 // | scl | x | - | - | - | x | byref |
2008 //
2009 // | agg | n.a. | | | - | | byref |
2010 // | agg | n.a. | - | x | - | - | byref |
2011 // | agg | n.a. | x | - | - | - | null |
2012 // | agg | n.a. | - | - | - | x | byref |
2013 // | agg | n.a. | - | - | - | x[] | byref |
2014 //
2015 // | ptr | n.a. | | | - | | bycopy|
2016 // | ptr | n.a. | - | x | - | - | bycopy|
2017 // | ptr | n.a. | x | - | - | - | null |
2018 // | ptr | n.a. | - | - | - | x | byref |
2019 // | ptr | n.a. | - | - | - | x[] | bycopy|
2020 // | ptr | n.a. | - | - | x | | bycopy|
2021 // | ptr | n.a. | - | - | x | x | bycopy|
2022 // | ptr | n.a. | - | - | x | x[] | bycopy|
2023 // =========================================================================
2024 // Legend:
2025 // scl - scalar
2026 // ptr - pointer
2027 // agg - aggregate
2028 // x - applies
2029 // - - invalid in this combination
2030 // [] - mapped with an array section
2031 // byref - should be mapped by reference
2032 // byval - should be mapped by value
2033 // null - initialize a local variable to null on the device
2034 //
2035 // Observations:
2036 // - All scalar declarations that show up in a map clause have to be passed
2037 // by reference, because they may have been mapped in the enclosing data
2038 // environment.
2039 // - If the scalar value does not fit the size of uintptr, it has to be
2040 // passed by reference, regardless the result in the table above.
2041 // - For pointers mapped by value that have either an implicit map or an
2042 // array section, the runtime library may pass the NULL value to the
2043 // device instead of the value passed to it by the compiler.
2044
2045 if (Ty->isReferenceType())
2046 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2047
2048 // Locate map clauses and see if the variable being captured is referred to
2049 // in any of those clauses. Here we only care about variables, not fields,
2050 // because fields are part of aggregates.
2051 bool IsVariableAssociatedWithSection = false;
2052
2053 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2054 D, Level,
2055 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2056 OMPClauseMappableExprCommon::MappableExprComponentListRef
2057 MapExprComponents,
2058 OpenMPClauseKind WhereFoundClauseKind) {
2059 // Only the map clause information influences how a variable is
2060 // captured. E.g. is_device_ptr does not require changing the default
2061 // behavior.
2062 if (WhereFoundClauseKind != OMPC_map)
2063 return false;
2064
2065 auto EI = MapExprComponents.rbegin();
2066 auto EE = MapExprComponents.rend();
2067
2068 assert(EI != EE && "Invalid map expression!")(static_cast<void> (0));
2069
2070 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2071 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2072
2073 ++EI;
2074 if (EI == EE)
2075 return false;
2076
2077 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2078 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2079 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2080 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2081 IsVariableAssociatedWithSection = true;
2082 // There is nothing more we need to know about this variable.
2083 return true;
2084 }
2085
2086 // Keep looking for more map info.
2087 return false;
2088 });
2089
2090 if (IsVariableUsedInMapClause) {
2091 // If variable is identified in a map clause it is always captured by
2092 // reference except if it is a pointer that is dereferenced somehow.
2093 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2094 } else {
2095 // By default, all the data that has a scalar type is mapped by copy
2096 // (except for reduction variables).
2097 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2098 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2099 !Ty->isAnyPointerType()) ||
2100 !Ty->isScalarType() ||
2101 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2102 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2103 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2104 D,
2105 [](OpenMPClauseKind K, bool AppliedToPointee) {
2106 return K == OMPC_reduction && !AppliedToPointee;
2107 },
2108 Level);
2109 }
2110 }
2111
2112 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2113 IsByRef =
2114 ((IsVariableUsedInMapClause &&
2115 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2116 OMPD_target) ||
2117 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2118 D,
2119 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2120 return K == OMPC_firstprivate ||
2121 (K == OMPC_reduction && AppliedToPointee);
2122 },
2123 Level, /*NotLastprivate=*/true) ||
2124 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2125 // If the variable is artificial and must be captured by value - try to
2126 // capture by value.
2127 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2128 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2129 // If the variable is implicitly firstprivate and scalar - capture by
2130 // copy
2131 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2132 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2133 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2134 Level) &&
2135 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2136 }
2137
2138 // When passing data by copy, we need to make sure it fits the uintptr size
2139 // and alignment, because the runtime library only deals with uintptr types.
2140 // If it does not fit the uintptr size, we need to pass the data by reference
2141 // instead.
2142 if (!IsByRef &&
2143 (Ctx.getTypeSizeInChars(Ty) >
2144 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2145 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2146 IsByRef = true;
2147 }
2148
2149 return IsByRef;
2150}
2151
2152unsigned Sema::getOpenMPNestingLevel() const {
2153 assert(getLangOpts().OpenMP)(static_cast<void> (0));
2154 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2155}
2156
2157bool Sema::isInOpenMPTargetExecutionDirective() const {
2158 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2159 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2160 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2161 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2162 SourceLocation) -> bool {
2163 return isOpenMPTargetExecutionDirective(K);
2164 },
2165 false);
2166}
2167
2168VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2169 unsigned StopAt) {
2170 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast<void> (0));
2171 D = getCanonicalDecl(D);
2172
2173 auto *VD = dyn_cast<VarDecl>(D);
2174 // Do not capture constexpr variables.
2175 if (VD && VD->isConstexpr())
2176 return nullptr;
2177
2178 // If we want to determine whether the variable should be captured from the
2179 // perspective of the current capturing scope, and we've already left all the
2180 // capturing scopes of the top directive on the stack, check from the
2181 // perspective of its parent directive (if any) instead.
2182 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2183 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2184
2185 // If we are attempting to capture a global variable in a directive with
2186 // 'target' we return true so that this global is also mapped to the device.
2187 //
2188 if (VD && !VD->hasLocalStorage() &&
2189 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2190 if (isInOpenMPTargetExecutionDirective()) {
2191 DSAStackTy::DSAVarData DVarTop =
2192 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2193 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2194 return VD;
2195 // If the declaration is enclosed in a 'declare target' directive,
2196 // then it should not be captured.
2197 //
2198 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2199 return nullptr;
2200 CapturedRegionScopeInfo *CSI = nullptr;
2201 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2202 llvm::reverse(FunctionScopes),
2203 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2204 if (!isa<CapturingScopeInfo>(FSI))
2205 return nullptr;
2206 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2207 if (RSI->CapRegionKind == CR_OpenMP) {
2208 CSI = RSI;
2209 break;
2210 }
2211 }
2212 assert(CSI && "Failed to find CapturedRegionScopeInfo")(static_cast<void> (0));
2213 SmallVector<OpenMPDirectiveKind, 4> Regions;
2214 getOpenMPCaptureRegions(Regions,
2215 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2216 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2217 return VD;
2218 }
2219 if (isInOpenMPDeclareTargetContext()) {
2220 // Try to mark variable as declare target if it is used in capturing
2221 // regions.
2222 if (LangOpts.OpenMP <= 45 &&
2223 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2224 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2225 return nullptr;
2226 }
2227 }
2228
2229 if (CheckScopeInfo) {
2230 bool OpenMPFound = false;
2231 for (unsigned I = StopAt + 1; I > 0; --I) {
2232 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2233 if(!isa<CapturingScopeInfo>(FSI))
2234 return nullptr;
2235 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2236 if (RSI->CapRegionKind == CR_OpenMP) {
2237 OpenMPFound = true;
2238 break;
2239 }
2240 }
2241 if (!OpenMPFound)
2242 return nullptr;
2243 }
2244
2245 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2246 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2247 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2248 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2249 if (Info.first ||
2250 (VD && VD->hasLocalStorage() &&
2251 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2252 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2253 return VD ? VD : Info.second;
2254 DSAStackTy::DSAVarData DVarTop =
2255 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2256 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2257 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2258 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2259 // Threadprivate variables must not be captured.
2260 if (isOpenMPThreadPrivate(DVarTop.CKind))
2261 return nullptr;
2262 // The variable is not private or it is the variable in the directive with
2263 // default(none) clause and not used in any clause.
2264 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2265 D,
2266 [](OpenMPClauseKind C, bool AppliedToPointee) {
2267 return isOpenMPPrivate(C) && !AppliedToPointee;
2268 },
2269 [](OpenMPDirectiveKind) { return true; },
2270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2271 // Global shared must not be captured.
2272 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2273 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2274 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2275 DVarTop.CKind == OMPC_shared))
2276 return nullptr;
2277 if (DVarPrivate.CKind != OMPC_unknown ||
2278 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2279 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2280 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2281 }
2282 return nullptr;
2283}
2284
2285void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2286 unsigned Level) const {
2287 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2288}
2289
2290void Sema::startOpenMPLoop() {
2291 assert(LangOpts.OpenMP && "OpenMP must be enabled.")(static_cast<void> (0));
2292 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2293 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2294}
2295
2296void Sema::startOpenMPCXXRangeFor() {
2297 assert(LangOpts.OpenMP && "OpenMP must be enabled.")(static_cast<void> (0));
2298 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2299 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2300 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2301 }
2302}
2303
2304OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2305 unsigned CapLevel) const {
2306 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast<void> (0));
2307 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2308 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2309 Level)) {
2310 bool IsTriviallyCopyable =
2311 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2312 !D->getType()
2313 .getNonReferenceType()
2314 .getCanonicalType()
2315 ->getAsCXXRecordDecl();
2316 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2317 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2318 getOpenMPCaptureRegions(CaptureRegions, DKind);
2319 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2320 (IsTriviallyCopyable ||
2321 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2322 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2323 D,
2324 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2325 Level, /*NotLastprivate=*/true))
2326 return OMPC_firstprivate;
2327 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2328 if (DVar.CKind != OMPC_shared &&
2329 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2330 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2331 return OMPC_firstprivate;
2332 }
2333 }
2334 }
2335 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2336 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2337 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2338 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2339 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2340 return OMPC_private;
2341 }
2342 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2343 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2344 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2345 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2346 Level) &&
2347 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2348 return OMPC_private;
2349 }
2350 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2351 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2352 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2353 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2354 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2355 Level))
2356 return OMPC_private;
2357 }
2358 // User-defined allocators are private since they must be defined in the
2359 // context of target region.
2360 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2361 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2362 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2363 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2364 return OMPC_private;
2365 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2366 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2367 Level) ||
2368 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2369 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2370 // Consider taskgroup reduction descriptor variable a private
2371 // to avoid possible capture in the region.
2372 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2373 [](OpenMPDirectiveKind K) {
2374 return K == OMPD_taskgroup ||
2375 ((isOpenMPParallelDirective(K) ||
2376 isOpenMPWorksharingDirective(K)) &&
2377 !isOpenMPSimdDirective(K));
2378 },
2379 Level) &&
2380 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2381 ? OMPC_private
2382 : OMPC_unknown;
2383}
2384
2385void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2386 unsigned Level) {
2387 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast<void> (0));
2388 D = getCanonicalDecl(D);
2389 OpenMPClauseKind OMPC = OMPC_unknown;
2390 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2391 const unsigned NewLevel = I - 1;
2392 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2393 D,
2394 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2395 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2396 OMPC = K;
2397 return true;
2398 }
2399 return false;
2400 },
2401 NewLevel))
2402 break;
2403 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2404 D, NewLevel,
2405 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2406 OpenMPClauseKind) { return true; })) {
2407 OMPC = OMPC_map;
2408 break;
2409 }
2410 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2411 NewLevel)) {
2412 OMPC = OMPC_map;
2413 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2414 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2415 OMPC = OMPC_firstprivate;
2416 break;
2417 }
2418 }
2419 if (OMPC != OMPC_unknown)
2420 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2421}
2422
2423bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2424 unsigned CaptureLevel) const {
2425 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast<void> (0));
2426 // Return true if the current level is no longer enclosed in a target region.
2427
2428 SmallVector<OpenMPDirectiveKind, 4> Regions;
2429 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2430 const auto *VD = dyn_cast<VarDecl>(D);
2431 return VD && !VD->hasLocalStorage() &&
2432 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2433 Level) &&
2434 Regions[CaptureLevel] != OMPD_task;
2435}
2436
2437bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2438 unsigned CaptureLevel) const {
2439 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast<void> (0));
2440 // Return true if the current level is no longer enclosed in a target region.
2441
2442 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2443 if (!VD->hasLocalStorage()) {
2444 if (isInOpenMPTargetExecutionDirective())
2445 return true;
2446 DSAStackTy::DSAVarData TopDVar =
2447 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2448 unsigned NumLevels =
2449 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2450 if (Level == 0)
2451 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2452 do {
2453 --Level;
2454 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2455 if (DVar.CKind != OMPC_shared)
2456 return true;
2457 } while (Level > 0);
2458 }
2459 }
2460 return true;
2461}
2462
2463void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2464
2465void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2466 OMPTraitInfo &TI) {
2467 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2468}
2469
2470void Sema::ActOnOpenMPEndDeclareVariant() {
2471 assert(isInOpenMPDeclareVariantScope() &&(static_cast<void> (0))
2472 "Not in OpenMP declare variant scope!")(static_cast<void> (0));
2473
2474 OMPDeclareVariantScopes.pop_back();
2475}
2476
2477void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2478 const FunctionDecl *Callee,
2479 SourceLocation Loc) {
2480 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.")(static_cast<void> (0));
2481 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2482 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2483 // Ignore host functions during device analyzis.
2484 if (LangOpts.OpenMPIsDevice &&
2485 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2486 return;
2487 // Ignore nohost functions during host analyzis.
2488 if (!LangOpts.OpenMPIsDevice && DevTy &&
2489 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2490 return;
2491 const FunctionDecl *FD = Callee->getMostRecentDecl();
2492 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2493 if (LangOpts.OpenMPIsDevice && DevTy &&
2494 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2495 // Diagnose host function called during device codegen.
2496 StringRef HostDevTy =
2497 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2498 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2499 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2500 diag::note_omp_marked_device_type_here)
2501 << HostDevTy;
2502 return;
2503 }
2504 if (!LangOpts.OpenMPIsDevice && DevTy &&
2505 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2506 // Diagnose nohost function called during host codegen.
2507 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2508 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2509 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2510 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2511 diag::note_omp_marked_device_type_here)
2512 << NoHostDevTy;
2513 }
2514}
2515
2516void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2517 const DeclarationNameInfo &DirName,
2518 Scope *CurScope, SourceLocation Loc) {
2519 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2520 PushExpressionEvaluationContext(
2521 ExpressionEvaluationContext::PotentiallyEvaluated);
2522}
2523
2524void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2525 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2526}
2527
2528void Sema::EndOpenMPClause() {
2529 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2530 CleanupVarDeclMarking();
2531}
2532
2533static std::pair<ValueDecl *, bool>
2534getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2535 SourceRange &ERange, bool AllowArraySection = false);
2536
2537/// Check consistency of the reduction clauses.
2538static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2539 ArrayRef<OMPClause *> Clauses) {
2540 bool InscanFound = false;
2541 SourceLocation InscanLoc;
2542 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2543 // A reduction clause without the inscan reduction-modifier may not appear on
2544 // a construct on which a reduction clause with the inscan reduction-modifier
2545 // appears.
2546 for (OMPClause *C : Clauses) {
2547 if (C->getClauseKind() != OMPC_reduction)
2548 continue;
2549 auto *RC = cast<OMPReductionClause>(C);
2550 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2551 InscanFound = true;
2552 InscanLoc = RC->getModifierLoc();
2553 continue;
2554 }
2555 if (RC->getModifier() == OMPC_REDUCTION_task) {
2556 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2557 // A reduction clause with the task reduction-modifier may only appear on
2558 // a parallel construct, a worksharing construct or a combined or
2559 // composite construct for which any of the aforementioned constructs is a
2560 // constituent construct and simd or loop are not constituent constructs.
2561 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2562 if (!(isOpenMPParallelDirective(CurDir) ||
2563 isOpenMPWorksharingDirective(CurDir)) ||
2564 isOpenMPSimdDirective(CurDir))
2565 S.Diag(RC->getModifierLoc(),
2566 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2567 continue;
2568 }
2569 }
2570 if (InscanFound) {
2571 for (OMPClause *C : Clauses) {
2572 if (C->getClauseKind() != OMPC_reduction)
2573 continue;
2574 auto *RC = cast<OMPReductionClause>(C);
2575 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2576 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2577 ? RC->getBeginLoc()
2578 : RC->getModifierLoc(),
2579 diag::err_omp_inscan_reduction_expected);
2580 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2581 continue;
2582 }
2583 for (Expr *Ref : RC->varlists()) {
2584 assert(Ref && "NULL expr in OpenMP nontemporal clause.")(static_cast<void> (0));
2585 SourceLocation ELoc;
2586 SourceRange ERange;
2587 Expr *SimpleRefExpr = Ref;
2588 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2589 /*AllowArraySection=*/true);
2590 ValueDecl *D = Res.first;
2591 if (!D)
2592 continue;
2593 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2594 S.Diag(Ref->getExprLoc(),
2595 diag::err_omp_reduction_not_inclusive_exclusive)
2596 << Ref->getSourceRange();
2597 }
2598 }
2599 }
2600 }
2601}
2602
2603static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2604 ArrayRef<OMPClause *> Clauses);
2605static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2606 bool WithInit);
2607
2608static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2609 const ValueDecl *D,
2610 const DSAStackTy::DSAVarData &DVar,
2611 bool IsLoopIterVar = false);
2612
2613void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2614 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2615 // A variable of class type (or array thereof) that appears in a lastprivate
2616 // clause requires an accessible, unambiguous default constructor for the
2617 // class type, unless the list item is also specified in a firstprivate
2618 // clause.
2619 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2620 for (OMPClause *C : D->clauses()) {
2621 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2622 SmallVector<Expr *, 8> PrivateCopies;
2623 for (Expr *DE : Clause->varlists()) {
2624 if (DE->isValueDependent() || DE->isTypeDependent()) {
2625 PrivateCopies.push_back(nullptr);
2626 continue;
2627 }
2628 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2629 auto *VD = cast<VarDecl>(DRE->getDecl());
2630 QualType Type = VD->getType().getNonReferenceType();
2631 const DSAStackTy::DSAVarData DVar =
2632 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2633 if (DVar.CKind == OMPC_lastprivate) {
2634 // Generate helper private variable and initialize it with the
2635 // default value. The address of the original variable is replaced
2636 // by the address of the new private variable in CodeGen. This new
2637 // variable is not added to IdResolver, so the code in the OpenMP
2638 // region uses original variable for proper diagnostics.
2639 VarDecl *VDPrivate = buildVarDecl(
2640 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2641 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2642 ActOnUninitializedDecl(VDPrivate);
2643 if (VDPrivate->isInvalidDecl()) {
2644 PrivateCopies.push_back(nullptr);
2645 continue;
2646 }
2647 PrivateCopies.push_back(buildDeclRefExpr(
2648 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2649 } else {
2650 // The variable is also a firstprivate, so initialization sequence
2651 // for private copy is generated already.
2652 PrivateCopies.push_back(nullptr);
2653 }
2654 }
2655 Clause->setPrivateCopies(PrivateCopies);
2656 continue;
2657 }
2658 // Finalize nontemporal clause by handling private copies, if any.
2659 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2660 SmallVector<Expr *, 8> PrivateRefs;
2661 for (Expr *RefExpr : Clause->varlists()) {
2662 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast<void> (0));
2663 SourceLocation ELoc;
2664 SourceRange ERange;
2665 Expr *SimpleRefExpr = RefExpr;
2666 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2667 if (Res.second)
2668 // It will be analyzed later.
2669 PrivateRefs.push_back(RefExpr);
2670 ValueDecl *D = Res.first;
2671 if (!D)
2672 continue;
2673
2674 const DSAStackTy::DSAVarData DVar =
2675 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2676 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2677 : SimpleRefExpr);
2678 }
2679 Clause->setPrivateRefs(PrivateRefs);
2680 continue;
2681 }
2682 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2683 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2684 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2685 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2686 if (!DRE)
2687 continue;
2688 ValueDecl *VD = DRE->getDecl();
2689 if (!VD || !isa<VarDecl>(VD))
2690 continue;
2691 DSAStackTy::DSAVarData DVar =
2692 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2693 // OpenMP [2.12.5, target Construct]
2694 // Memory allocators that appear in a uses_allocators clause cannot
2695 // appear in other data-sharing attribute clauses or data-mapping
2696 // attribute clauses in the same construct.
2697 Expr *MapExpr = nullptr;
2698 if (DVar.RefExpr ||
2699 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2700 VD, /*CurrentRegionOnly=*/true,
2701 [VD, &MapExpr](
2702 OMPClauseMappableExprCommon::MappableExprComponentListRef
2703 MapExprComponents,
2704 OpenMPClauseKind C) {
2705 auto MI = MapExprComponents.rbegin();
2706 auto ME = MapExprComponents.rend();
2707 if (MI != ME &&
2708 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2709 VD->getCanonicalDecl()) {
2710 MapExpr = MI->getAssociatedExpression();
2711 return true;
2712 }
2713 return false;
2714 })) {
2715 Diag(D.Allocator->getExprLoc(),
2716 diag::err_omp_allocator_used_in_clauses)
2717 << D.Allocator->getSourceRange();
2718 if (DVar.RefExpr)
2719 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2720 else
2721 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2722 << MapExpr->getSourceRange();
2723 }
2724 }
2725 continue;
2726 }
2727 }
2728 // Check allocate clauses.
2729 if (!CurContext->isDependentContext())
2730 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2731 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2732 }
2733
2734 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2735 DiscardCleanupsInEvaluationContext();
2736 PopExpressionEvaluationContext();
2737}
2738
2739static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2740 Expr *NumIterations, Sema &SemaRef,
2741 Scope *S, DSAStackTy *Stack);
2742
2743namespace {
2744
2745class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2746private:
2747 Sema &SemaRef;
2748
2749public:
2750 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2751 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2752 NamedDecl *ND = Candidate.getCorrectionDecl();
2753 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2754 return VD->hasGlobalStorage() &&
2755 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2756 SemaRef.getCurScope());
2757 }
2758 return false;
2759 }
2760
2761 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2762 return std::make_unique<VarDeclFilterCCC>(*this);
2763 }
2764
2765};
2766
2767class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2768private:
2769 Sema &SemaRef;
2770
2771public:
2772 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2773 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2774 NamedDecl *ND = Candidate.getCorrectionDecl();
2775 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2776 isa<FunctionDecl>(ND))) {
2777 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2778 SemaRef.getCurScope());
2779 }
2780 return false;
2781 }
2782
2783 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2784 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2785 }
2786};
2787
2788} // namespace
2789
2790ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2791 CXXScopeSpec &ScopeSpec,
2792 const DeclarationNameInfo &Id,
2793 OpenMPDirectiveKind Kind) {
2794 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2795 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2796
2797 if (Lookup.isAmbiguous())
2798 return ExprError();
2799
2800 VarDecl *VD;
2801 if (!Lookup.isSingleResult()) {
2802 VarDeclFilterCCC CCC(*this);
2803 if (TypoCorrection Corrected =
2804 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2805 CTK_ErrorRecovery)) {
2806 diagnoseTypo(Corrected,
2807 PDiag(Lookup.empty()
2808 ? diag::err_undeclared_var_use_suggest
2809 : diag::err_omp_expected_var_arg_suggest)
2810 << Id.getName());
2811 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2812 } else {
2813 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2814 : diag::err_omp_expected_var_arg)
2815 << Id.getName();
2816 return ExprError();
2817 }
2818 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2819 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2820 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2821 return ExprError();
2822 }
2823 Lookup.suppressDiagnostics();
2824
2825 // OpenMP [2.9.2, Syntax, C/C++]
2826 // Variables must be file-scope, namespace-scope, or static block-scope.
2827 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2828 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2829 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2830 bool IsDecl =
2831 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2832 Diag(VD->getLocation(),
2833 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2834 << VD;
2835 return ExprError();
2836 }
2837
2838 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2839 NamedDecl *ND = CanonicalVD;
2840 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2841 // A threadprivate directive for file-scope variables must appear outside
2842 // any definition or declaration.
2843 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2844 !getCurLexicalContext()->isTranslationUnit()) {
2845 Diag(Id.getLoc(), diag::err_omp_var_scope)
2846 << getOpenMPDirectiveName(Kind) << VD;
2847 bool IsDecl =
2848 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2849 Diag(VD->getLocation(),
2850 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2851 << VD;
2852 return ExprError();
2853 }
2854 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2855 // A threadprivate directive for static class member variables must appear
2856 // in the class definition, in the same scope in which the member
2857 // variables are declared.
2858 if (CanonicalVD->isStaticDataMember() &&
2859 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2860 Diag(Id.getLoc(), diag::err_omp_var_scope)
2861 << getOpenMPDirectiveName(Kind) << VD;
2862 bool IsDecl =
2863 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2864 Diag(VD->getLocation(),
2865 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2866 << VD;
2867 return ExprError();
2868 }
2869 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2870 // A threadprivate directive for namespace-scope variables must appear
2871 // outside any definition or declaration other than the namespace
2872 // definition itself.
2873 if (CanonicalVD->getDeclContext()->isNamespace() &&
2874 (!getCurLexicalContext()->isFileContext() ||
2875 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2876 Diag(Id.getLoc(), diag::err_omp_var_scope)
2877 << getOpenMPDirectiveName(Kind) << VD;
2878 bool IsDecl =
2879 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2880 Diag(VD->getLocation(),
2881 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2882 << VD;
2883 return ExprError();
2884 }
2885 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2886 // A threadprivate directive for static block-scope variables must appear
2887 // in the scope of the variable and not in a nested scope.
2888 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2889 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2890 Diag(Id.getLoc(), diag::err_omp_var_scope)
2891 << getOpenMPDirectiveName(Kind) << VD;
2892 bool IsDecl =
2893 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2894 Diag(VD->getLocation(),
2895 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2896 << VD;
2897 return ExprError();
2898 }
2899
2900 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2901 // A threadprivate directive must lexically precede all references to any
2902 // of the variables in its list.
2903 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2904 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2905 Diag(Id.getLoc(), diag::err_omp_var_used)
2906 << getOpenMPDirectiveName(Kind) << VD;
2907 return ExprError();
2908 }
2909
2910 QualType ExprType = VD->getType().getNonReferenceType();
2911 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2912 SourceLocation(), VD,
2913 /*RefersToEnclosingVariableOrCapture=*/false,
2914 Id.getLoc(), ExprType, VK_LValue);
2915}
2916
2917Sema::DeclGroupPtrTy
2918Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2919 ArrayRef<Expr *> VarList) {
2920 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2921 CurContext->addDecl(D);
2922 return DeclGroupPtrTy::make(DeclGroupRef(D));
2923 }
2924 return nullptr;
2925}
2926
2927namespace {
2928class LocalVarRefChecker final
2929 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2930 Sema &SemaRef;
2931
2932public:
2933 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2934 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2935 if (VD->hasLocalStorage()) {
2936 SemaRef.Diag(E->getBeginLoc(),
2937 diag::err_omp_local_var_in_threadprivate_init)
2938 << E->getSourceRange();
2939 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2940 << VD << VD->getSourceRange();
2941 return true;
2942 }
2943 }
2944 return false;
2945 }
2946 bool VisitStmt(const Stmt *S) {
2947 for (const Stmt *Child : S->children()) {
2948 if (Child && Visit(Child))
2949 return true;
2950 }
2951 return false;
2952 }
2953 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2954};
2955} // namespace
2956
2957OMPThreadPrivateDecl *
2958Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2959 SmallVector<Expr *, 8> Vars;
2960 for (Expr *RefExpr : VarList) {
2961 auto *DE = cast<DeclRefExpr>(RefExpr);
2962 auto *VD = cast<VarDecl>(DE->getDecl());
2963 SourceLocation ILoc = DE->getExprLoc();
2964
2965 // Mark variable as used.
2966 VD->setReferenced();
2967 VD->markUsed(Context);
2968
2969 QualType QType = VD->getType();
2970 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2971 // It will be analyzed later.
2972 Vars.push_back(DE);
2973 continue;
2974 }
2975
2976 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2977 // A threadprivate variable must not have an incomplete type.
2978 if (RequireCompleteType(ILoc, VD->getType(),
2979 diag::err_omp_threadprivate_incomplete_type)) {
2980 continue;
2981 }
2982
2983 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2984 // A threadprivate variable must not have a reference type.
2985 if (VD->getType()->isReferenceType()) {
2986 Diag(ILoc, diag::err_omp_ref_type_arg)
2987 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2988 bool IsDecl =
2989 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2990 Diag(VD->getLocation(),
2991 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2992 << VD;
2993 continue;
2994 }
2995
2996 // Check if this is a TLS variable. If TLS is not being supported, produce
2997 // the corresponding diagnostic.
2998 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2999 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3000 getLangOpts().OpenMPUseTLS &&
3001 getASTContext().getTargetInfo().isTLSSupported())) ||
3002 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3003 !VD->isLocalVarDecl())) {
3004 Diag(ILoc, diag::err_omp_var_thread_local)
3005 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3006 bool IsDecl =
3007 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3008 Diag(VD->getLocation(),
3009 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3010 << VD;
3011 continue;
3012 }
3013
3014 // Check if initial value of threadprivate variable reference variable with
3015 // local storage (it is not supported by runtime).
3016 if (const Expr *Init = VD->getAnyInitializer()) {
3017 LocalVarRefChecker Checker(*this);
3018 if (Checker.Visit(Init))
3019 continue;
3020 }
3021
3022 Vars.push_back(RefExpr);
3023 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3024 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3025 Context, SourceRange(Loc, Loc)));
3026 if (ASTMutationListener *ML = Context.getASTMutationListener())
3027 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3028 }
3029 OMPThreadPrivateDecl *D = nullptr;
3030 if (!Vars.empty()) {
3031 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3032 Vars);
3033 D->setAccess(AS_public);
3034 }
3035 return D;
3036}
3037
3038static OMPAllocateDeclAttr::AllocatorTypeTy
3039getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3040 if (!Allocator)
3041 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3042 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3043 Allocator->isInstantiationDependent() ||
3044 Allocator->containsUnexpandedParameterPack())
3045 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3046 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3047 const Expr *AE = Allocator->IgnoreParenImpCasts();
3048 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3049 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3050 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3051 llvm::FoldingSetNodeID AEId, DAEId;
3052 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3053 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3054 if (AEId == DAEId) {
3055 AllocatorKindRes = AllocatorKind;
3056 break;
3057 }
3058 }
3059 return AllocatorKindRes;
3060}
3061
3062static bool checkPreviousOMPAllocateAttribute(
3063 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3064 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3065 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3066 return false;
3067 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3068 Expr *PrevAllocator = A->getAllocator();
3069 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3070 getAllocatorKind(S, Stack, PrevAllocator);
3071 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3072 if (AllocatorsMatch &&
3073 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3074 Allocator && PrevAllocator) {
3075 const Expr *AE = Allocator->IgnoreParenImpCasts();
3076 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3077 llvm::FoldingSetNodeID AEId, PAEId;
3078 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3079 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3080 AllocatorsMatch = AEId == PAEId;
3081 }
3082 if (!AllocatorsMatch) {
3083 SmallString<256> AllocatorBuffer;
3084 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3085 if (Allocator)
3086 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3087 SmallString<256> PrevAllocatorBuffer;
3088 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3089 if (PrevAllocator)
3090 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3091 S.getPrintingPolicy());
3092
3093 SourceLocation AllocatorLoc =
3094 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3095 SourceRange AllocatorRange =
3096 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3097 SourceLocation PrevAllocatorLoc =
3098 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3099 SourceRange PrevAllocatorRange =
3100 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3101 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3102 << (Allocator ? 1 : 0) << AllocatorStream.str()
3103 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3104 << AllocatorRange;
3105 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3106 << PrevAllocatorRange;
3107 return true;
3108 }
3109 return false;
3110}
3111
3112static void
3113applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3114 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3115 Expr *Allocator, SourceRange SR) {
3116 if (VD->hasAttr<OMPAllocateDeclAttr>())
3117 return;
3118 if (Allocator &&
3119 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3120 Allocator->isInstantiationDependent() ||
3121 Allocator->containsUnexpandedParameterPack()))
3122 return;
3123 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3124 Allocator, SR);
3125 VD->addAttr(A);
3126 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3127 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3128}
3129
3130Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3131 SourceLocation Loc, ArrayRef<Expr *> VarList,
3132 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3133 assert(Clauses.size() <= 1 && "Expected at most one clause.")(static_cast<void> (0));
3134 Expr *Allocator = nullptr;
3135 if (Clauses.empty()) {
3136 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3137 // allocate directives that appear in a target region must specify an
3138 // allocator clause unless a requires directive with the dynamic_allocators
3139 // clause is present in the same compilation unit.
3140 if (LangOpts.OpenMPIsDevice &&
3141 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3142 targetDiag(Loc, diag::err_expected_allocator_clause);
3143 } else {
3144 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3145 }
3146 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3147 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3148 SmallVector<Expr *, 8> Vars;
3149 for (Expr *RefExpr : VarList) {
3150 auto *DE = cast<DeclRefExpr>(RefExpr);
3151 auto *VD = cast<VarDecl>(DE->getDecl());
3152
3153 // Check if this is a TLS variable or global register.
3154 if (VD->getTLSKind() != VarDecl::TLS_None ||
3155 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3156 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3157 !VD->isLocalVarDecl()))
3158 continue;
3159
3160 // If the used several times in the allocate directive, the same allocator
3161 // must be used.
3162 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3163 AllocatorKind, Allocator))
3164 continue;
3165
3166 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3167 // If a list item has a static storage type, the allocator expression in the
3168 // allocator clause must be a constant expression that evaluates to one of
3169 // the predefined memory allocator values.
3170 if (Allocator && VD->hasGlobalStorage()) {
3171 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3172 Diag(Allocator->getExprLoc(),
3173 diag::err_omp_expected_predefined_allocator)
3174 << Allocator->getSourceRange();
3175 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3176 VarDecl::DeclarationOnly;
3177 Diag(VD->getLocation(),
3178 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3179 << VD;
3180 continue;
3181 }
3182 }
3183
3184 Vars.push_back(RefExpr);
3185 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3186 DE->getSourceRange());
3187 }
3188 if (Vars.empty())
3189 return nullptr;
3190 if (!Owner)
3191 Owner = getCurLexicalContext();
3192 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3193 D->setAccess(AS_public);
3194 Owner->addDecl(D);
3195 return DeclGroupPtrTy::make(DeclGroupRef(D));
3196}
3197
3198Sema::DeclGroupPtrTy
3199Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3200 ArrayRef<OMPClause *> ClauseList) {
3201 OMPRequiresDecl *D = nullptr;
3202 if (!CurContext->isFileContext()) {
3203 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3204 } else {
3205 D = CheckOMPRequiresDecl(Loc, ClauseList);
3206 if (D) {
3207 CurContext->addDecl(D);
3208 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3209 }
3210 }
3211 return DeclGroupPtrTy::make(DeclGroupRef(D));
3212}
3213
3214void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3215 OpenMPDirectiveKind DKind,
3216 ArrayRef<StringRef> Assumptions,
3217 bool SkippedClauses) {
3218 if (!SkippedClauses && Assumptions.empty())
3219 Diag(Loc, diag::err_omp_no_clause_for_directive)
3220 << llvm::omp::getAllAssumeClauseOptions()
3221 << llvm::omp::getOpenMPDirectiveName(DKind);
3222
3223 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3224 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3225 OMPAssumeScoped.push_back(AA);
3226 return;
3227 }
3228
3229 // Global assumes without assumption clauses are ignored.
3230 if (Assumptions.empty())
3231 return;
3232
3233 assert(DKind == llvm::omp::Directive::OMPD_assumes &&(static_cast<void> (0))
3234 "Unexpected omp assumption directive!")(static_cast<void> (0));
3235 OMPAssumeGlobal.push_back(AA);
3236
3237 // The OMPAssumeGlobal scope above will take care of new declarations but
3238 // we also want to apply the assumption to existing ones, e.g., to
3239 // declarations in included headers. To this end, we traverse all existing
3240 // declaration contexts and annotate function declarations here.
3241 SmallVector<DeclContext *, 8> DeclContexts;
3242 auto *Ctx = CurContext;
3243 while (Ctx->getLexicalParent())
3244 Ctx = Ctx->getLexicalParent();
3245 DeclContexts.push_back(Ctx);
3246 while (!DeclContexts.empty()) {
3247 DeclContext *DC = DeclContexts.pop_back_val();
3248 for (auto *SubDC : DC->decls()) {
3249 if (SubDC->isInvalidDecl())
3250 continue;
3251 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3252 DeclContexts.push_back(CTD->getTemplatedDecl());
3253 for (auto *S : CTD->specializations())
3254 DeclContexts.push_back(S);
3255 continue;
3256 }
3257 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3258 DeclContexts.push_back(DC);
3259 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3260 F->addAttr(AA);
3261 continue;
3262 }
3263 }
3264 }
3265}
3266
3267void Sema::ActOnOpenMPEndAssumesDirective() {
3268 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!")(static_cast<void> (0));
3269 OMPAssumeScoped.pop_back();
3270}
3271
3272OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3273 ArrayRef<OMPClause *> ClauseList) {
3274 /// For target specific clauses, the requires directive cannot be
3275 /// specified after the handling of any of the target regions in the
3276 /// current compilation unit.
3277 ArrayRef<SourceLocation> TargetLocations =
3278 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3279 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3280 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3281 for (const OMPClause *CNew : ClauseList) {
3282 // Check if any of the requires clauses affect target regions.
3283 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3284 isa<OMPUnifiedAddressClause>(CNew) ||
3285 isa<OMPReverseOffloadClause>(CNew) ||
3286 isa<OMPDynamicAllocatorsClause>(CNew)) {
3287 Diag(Loc, diag::err_omp_directive_before_requires)
3288 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3289 for (SourceLocation TargetLoc : TargetLocations) {
3290 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3291 << "target";
3292 }
3293 } else if (!AtomicLoc.isInvalid() &&
3294 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3295 Diag(Loc, diag::err_omp_directive_before_requires)
3296 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3297 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3298 << "atomic";
3299 }
3300 }
3301 }
3302
3303 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3304 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3305 ClauseList);
3306 return nullptr;
3307}
3308
3309static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3310 const ValueDecl *D,
3311 const DSAStackTy::DSAVarData &DVar,
3312 bool IsLoopIterVar) {
3313 if (DVar.RefExpr) {
3314 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3315 << getOpenMPClauseName(DVar.CKind);
3316 return;
3317 }
3318 enum {
3319 PDSA_StaticMemberShared,
3320 PDSA_StaticLocalVarShared,
3321 PDSA_LoopIterVarPrivate,
3322 PDSA_LoopIterVarLinear,
3323 PDSA_LoopIterVarLastprivate,
3324 PDSA_ConstVarShared,
3325 PDSA_GlobalVarShared,
3326 PDSA_TaskVarFirstprivate,
3327 PDSA_LocalVarPrivate,
3328 PDSA_Implicit
3329 } Reason = PDSA_Implicit;
3330 bool ReportHint = false;
3331 auto ReportLoc = D->getLocation();
3332 auto *VD = dyn_cast<VarDecl>(D);
3333 if (IsLoopIterVar) {
3334 if (DVar.CKind == OMPC_private)
3335 Reason = PDSA_LoopIterVarPrivate;
3336 else if (DVar.CKind == OMPC_lastprivate)
3337 Reason = PDSA_LoopIterVarLastprivate;
3338 else
3339 Reason = PDSA_LoopIterVarLinear;
3340 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3341 DVar.CKind == OMPC_firstprivate) {
3342 Reason = PDSA_TaskVarFirstprivate;
3343 ReportLoc = DVar.ImplicitDSALoc;
3344 } else if (VD && VD->isStaticLocal())
3345 Reason = PDSA_StaticLocalVarShared;
3346 else if (VD && VD->isStaticDataMember())
3347 Reason = PDSA_StaticMemberShared;
3348 else if (VD && VD->isFileVarDecl())
3349 Reason = PDSA_GlobalVarShared;
3350 else if (D->getType().isConstant(SemaRef.getASTContext()))
3351 Reason = PDSA_ConstVarShared;
3352 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3353 ReportHint = true;
3354 Reason = PDSA_LocalVarPrivate;
3355 }
3356 if (Reason != PDSA_Implicit) {
3357 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3358 << Reason << ReportHint
3359 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3360 } else if (DVar.ImplicitDSALoc.isValid()) {
3361 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3362 << getOpenMPClauseName(DVar.CKind);
3363 }
3364}
3365
3366static OpenMPMapClauseKind
3367getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3368 bool IsAggregateOrDeclareTarget) {
3369 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3370 switch (M) {
3371 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3372 Kind = OMPC_MAP_alloc;
3373 break;
3374 case OMPC_DEFAULTMAP_MODIFIER_to:
3375 Kind = OMPC_MAP_to;
3376 break;
3377 case OMPC_DEFAULTMAP_MODIFIER_from:
3378 Kind = OMPC_MAP_from;
3379 break;
3380 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3381 Kind = OMPC_MAP_tofrom;
3382 break;
3383 case OMPC_DEFAULTMAP_MODIFIER_present:
3384 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3385 // If implicit-behavior is present, each variable referenced in the
3386 // construct in the category specified by variable-category is treated as if
3387 // it had been listed in a map clause with the map-type of alloc and
3388 // map-type-modifier of present.
3389 Kind = OMPC_MAP_alloc;
3390 break;
3391 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3392 case OMPC_DEFAULTMAP_MODIFIER_last:
3393 llvm_unreachable("Unexpected defaultmap implicit behavior")__builtin_unreachable();
3394 case OMPC_DEFAULTMAP_MODIFIER_none:
3395 case OMPC_DEFAULTMAP_MODIFIER_default:
3396 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3397 // IsAggregateOrDeclareTarget could be true if:
3398 // 1. the implicit behavior for aggregate is tofrom
3399 // 2. it's a declare target link
3400 if (IsAggregateOrDeclareTarget) {
3401 Kind = OMPC_MAP_tofrom;
3402 break;
3403 }
3404 llvm_unreachable("Unexpected defaultmap implicit behavior")__builtin_unreachable();
3405 }
3406 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known")(static_cast<void> (0));
3407 return Kind;
3408}
3409
3410namespace {
3411class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3412 DSAStackTy *Stack;
3413 Sema &SemaRef;
3414 bool ErrorFound = false;
3415 bool TryCaptureCXXThisMembers = false;
3416 CapturedStmt *CS = nullptr;
3417 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3418 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3419 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3420 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3421 ImplicitMapModifier[DefaultmapKindNum];
3422 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3423 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3424
3425 void VisitSubCaptures(OMPExecutableDirective *S) {
3426 // Check implicitly captured variables.
3427 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3428 return;
3429 if (S->getDirectiveKind() == OMPD_atomic ||
3430 S->getDirectiveKind() == OMPD_critical ||
3431 S->getDirectiveKind() == OMPD_section ||
3432 S->getDirectiveKind() == OMPD_master ||
3433 S->getDirectiveKind() == OMPD_masked ||
3434 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3435 Visit(S->getAssociatedStmt());
3436 return;
3437 }
3438 visitSubCaptures(S->getInnermostCapturedStmt());
3439 // Try to capture inner this->member references to generate correct mappings
3440 // and diagnostics.
3441 if (TryCaptureCXXThisMembers ||
3442 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3443 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3444 [](const CapturedStmt::Capture &C) {
3445 return C.capturesThis();
3446 }))) {
3447 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3448 TryCaptureCXXThisMembers = true;
3449 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3450 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3451 }
3452 // In tasks firstprivates are not captured anymore, need to analyze them
3453 // explicitly.
3454 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3455 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3456 for (OMPClause *C : S->clauses())
3457 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3458 for (Expr *Ref : FC->varlists())
3459 Visit(Ref);
3460 }
3461 }
3462 }
3463
3464public:
3465 void VisitDeclRefExpr(DeclRefExpr *E) {
3466 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3467 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3468 E->isInstantiationDependent())
3469 return;
3470 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3471 // Check the datasharing rules for the expressions in the clauses.
3472 if (!CS) {
3473 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3474 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3475 Visit(CED->getInit());
3476 return;
3477 }
3478 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3479 // Do not analyze internal variables and do not enclose them into
3480 // implicit clauses.
3481 return;
3482 VD = VD->getCanonicalDecl();
3483 // Skip internally declared variables.
3484 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3485 !Stack->isImplicitTaskFirstprivate(VD))
3486 return;
3487 // Skip allocators in uses_allocators clauses.
3488 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3489 return;
3490
3491 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3492 // Check if the variable has explicit DSA set and stop analysis if it so.
3493 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3494 return;
3495
3496 // Skip internally declared static variables.
3497 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3498 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3499 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3500 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3501 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3502 !Stack->isImplicitTaskFirstprivate(VD))
3503 return;
3504
3505 SourceLocation ELoc = E->getExprLoc();
3506 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3507 // The default(none) clause requires that each variable that is referenced
3508 // in the construct, and does not have a predetermined data-sharing
3509 // attribute, must have its data-sharing attribute explicitly determined
3510 // by being listed in a data-sharing attribute clause.
3511 if (DVar.CKind == OMPC_unknown &&
3512 (Stack->getDefaultDSA() == DSA_none ||
3513 Stack->getDefaultDSA() == DSA_firstprivate) &&
3514 isImplicitOrExplicitTaskingRegion(DKind) &&
3515 VarsWithInheritedDSA.count(VD) == 0) {
3516 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3517 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3518 DSAStackTy::DSAVarData DVar =
3519 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3520 InheritedDSA = DVar.CKind == OMPC_unknown;
3521 }
3522 if (InheritedDSA)
3523 VarsWithInheritedDSA[VD] = E;
3524 return;
3525 }
3526
3527 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3528 // If implicit-behavior is none, each variable referenced in the
3529 // construct that does not have a predetermined data-sharing attribute
3530 // and does not appear in a to or link clause on a declare target
3531 // directive must be listed in a data-mapping attribute clause, a
3532 // data-haring attribute clause (including a data-sharing attribute
3533 // clause on a combined construct where target. is one of the
3534 // constituent constructs), or an is_device_ptr clause.
3535 OpenMPDefaultmapClauseKind ClauseKind =
3536 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3537 if (SemaRef.getLangOpts().OpenMP >= 50) {
3538 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3539 OMPC_DEFAULTMAP_MODIFIER_none;
3540 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3541 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3542 // Only check for data-mapping attribute and is_device_ptr here
3543 // since we have already make sure that the declaration does not
3544 // have a data-sharing attribute above
3545 if (!Stack->checkMappableExprComponentListsForDecl(
3546 VD, /*CurrentRegionOnly=*/true,
3547 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3548 MapExprComponents,
3549 OpenMPClauseKind) {
3550 auto MI = MapExprComponents.rbegin();
3551 auto ME = MapExprComponents.rend();
3552 return MI != ME && MI->getAssociatedDeclaration() == VD;
3553 })) {
3554 VarsWithInheritedDSA[VD] = E;
3555 return;
3556 }
3557 }
3558 }
3559 if (SemaRef.getLangOpts().OpenMP > 50) {
3560 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3561 OMPC_DEFAULTMAP_MODIFIER_present;
3562 if (IsModifierPresent) {
3563 if (llvm::find(ImplicitMapModifier[ClauseKind],
3564 OMPC_MAP_MODIFIER_present) ==
3565 std::end(ImplicitMapModifier[ClauseKind])) {
3566 ImplicitMapModifier[ClauseKind].push_back(
3567 OMPC_MAP_MODIFIER_present);
3568 }
3569 }
3570 }
3571
3572 if (isOpenMPTargetExecutionDirective(DKind) &&
3573 !Stack->isLoopControlVariable(VD).first) {
3574 if (!Stack->checkMappableExprComponentListsForDecl(
3575 VD, /*CurrentRegionOnly=*/true,
3576 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3577 StackComponents,
3578 OpenMPClauseKind) {
3579 if (SemaRef.LangOpts.OpenMP >= 50)
3580 return !StackComponents.empty();
3581 // Variable is used if it has been marked as an array, array
3582 // section, array shaping or the variable iself.
3583 return StackComponents.size() == 1 ||
3584 std::all_of(
3585 std::next(StackComponents.rbegin()),
3586 StackComponents.rend(),
3587 [](const OMPClauseMappableExprCommon::
3588 MappableComponent &MC) {
3589 return MC.getAssociatedDeclaration() ==
3590 nullptr &&
3591 (isa<OMPArraySectionExpr>(
3592 MC.getAssociatedExpression()) ||
3593 isa<OMPArrayShapingExpr>(
3594 MC.getAssociatedExpression()) ||
3595 isa<ArraySubscriptExpr>(
3596 MC.getAssociatedExpression()));
3597 });
3598 })) {
3599 bool IsFirstprivate = false;
3600 // By default lambdas are captured as firstprivates.
3601 if (const auto *RD =
3602 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3603 IsFirstprivate = RD->isLambda();
3604 IsFirstprivate =
3605 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3606 if (IsFirstprivate) {
3607 ImplicitFirstprivate.emplace_back(E);
3608 } else {
3609 OpenMPDefaultmapClauseModifier M =
3610 Stack->getDefaultmapModifier(ClauseKind);
3611 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3612 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3613 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3614 }
3615 return;
3616 }
3617 }
3618
3619 // OpenMP [2.9.3.6, Restrictions, p.2]
3620 // A list item that appears in a reduction clause of the innermost
3621 // enclosing worksharing or parallel construct may not be accessed in an
3622 // explicit task.
3623 DVar = Stack->hasInnermostDSA(
3624 VD,
3625 [](OpenMPClauseKind C, bool AppliedToPointee) {
3626 return C == OMPC_reduction && !AppliedToPointee;
3627 },
3628 [](OpenMPDirectiveKind K) {
3629 return isOpenMPParallelDirective(K) ||
3630 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3631 },
3632 /*FromParent=*/true);
3633 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3634 ErrorFound = true;
3635 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3636 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3637 return;
3638 }
3639
3640 // Define implicit data-sharing attributes for task.
3641 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3642 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3643 (Stack->getDefaultDSA() == DSA_firstprivate &&
3644 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3645 !Stack->isLoopControlVariable(VD).first) {
3646 ImplicitFirstprivate.push_back(E);
3647 return;
3648 }
3649
3650 // Store implicitly used globals with declare target link for parent
3651 // target.
3652 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3653 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3654 Stack->addToParentTargetRegionLinkGlobals(E);
3655 return;
3656 }
3657 }
3658 }
3659 void VisitMemberExpr(MemberExpr *E) {
3660 if (E->isTypeDependent() || E->isValueDependent() ||
3661 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3662 return;
3663 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3664 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3665 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3666 if (!FD)
3667 return;
3668 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3669 // Check if the variable has explicit DSA set and stop analysis if it
3670 // so.
3671 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3672 return;
3673
3674 if (isOpenMPTargetExecutionDirective(DKind) &&
3675 !Stack->isLoopControlVariable(FD).first &&
3676 !Stack->checkMappableExprComponentListsForDecl(
3677 FD, /*CurrentRegionOnly=*/true,
3678 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3679 StackComponents,
3680 OpenMPClauseKind) {
3681 return isa<CXXThisExpr>(
3682 cast<MemberExpr>(
3683 StackComponents.back().getAssociatedExpression())
3684 ->getBase()
3685 ->IgnoreParens());
3686 })) {
3687 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3688 // A bit-field cannot appear in a map clause.
3689 //
3690 if (FD->isBitField())
3691 return;
3692
3693 // Check to see if the member expression is referencing a class that
3694 // has already been explicitly mapped
3695 if (Stack->isClassPreviouslyMapped(TE->getType()))
3696 return;
3697
3698 OpenMPDefaultmapClauseModifier Modifier =
3699 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3700 OpenMPDefaultmapClauseKind ClauseKind =
3701 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3702 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3703 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3704 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3705 return;
3706 }
3707
3708 SourceLocation ELoc = E->getExprLoc();
3709 // OpenMP [2.9.3.6, Restrictions, p.2]
3710 // A list item that appears in a reduction clause of the innermost
3711 // enclosing worksharing or parallel construct may not be accessed in
3712 // an explicit task.
3713 DVar = Stack->hasInnermostDSA(
3714 FD,
3715 [](OpenMPClauseKind C, bool AppliedToPointee) {
3716 return C == OMPC_reduction && !AppliedToPointee;
3717 },
3718 [](OpenMPDirectiveKind K) {
3719 return isOpenMPParallelDirective(K) ||
3720 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3721 },
3722 /*FromParent=*/true);
3723 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3724 ErrorFound = true;
3725 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3726 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3727 return;
3728 }
3729
3730 // Define implicit data-sharing attributes for task.
3731 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3732 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3733 !Stack->isLoopControlVariable(FD).first) {
3734 // Check if there is a captured expression for the current field in the
3735 // region. Do not mark it as firstprivate unless there is no captured
3736 // expression.
3737 // TODO: try to make it firstprivate.
3738 if (DVar.CKind != OMPC_unknown)
3739 ImplicitFirstprivate.push_back(E);
3740 }
3741 return;
3742 }
3743 if (isOpenMPTargetExecutionDirective(DKind)) {
3744 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3745 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3746 Stack->getCurrentDirective(),
3747 /*NoDiagnose=*/true))
3748 return;
3749 const auto *VD = cast<ValueDecl>(
3750 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3751 if (!Stack->checkMappableExprComponentListsForDecl(
3752 VD, /*CurrentRegionOnly=*/true,
3753 [&CurComponents](
3754 OMPClauseMappableExprCommon::MappableExprComponentListRef
3755 StackComponents,
3756 OpenMPClauseKind) {
3757 auto CCI = CurComponents.rbegin();
3758 auto CCE = CurComponents.rend();
3759 for (const auto &SC : llvm::reverse(StackComponents)) {
3760 // Do both expressions have the same kind?
3761 if (CCI->getAssociatedExpression()->getStmtClass() !=
3762 SC.getAssociatedExpression()->getStmtClass())
3763 if (!((isa<OMPArraySectionExpr>(
3764 SC.getAssociatedExpression()) ||
3765 isa<OMPArrayShapingExpr>(
3766 SC.getAssociatedExpression())) &&
3767 isa<ArraySubscriptExpr>(
3768 CCI->getAssociatedExpression())))
3769 return false;
3770
3771 const Decl *CCD = CCI->getAssociatedDeclaration();
3772 const Decl *SCD = SC.getAssociatedDeclaration();
3773 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3774 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3775 if (SCD != CCD)
3776 return false;
3777 std::advance(CCI, 1);
3778 if (CCI == CCE)
3779 break;
3780 }
3781 return true;
3782 })) {
3783 Visit(E->getBase());
3784 }
3785 } else if (!TryCaptureCXXThisMembers) {
3786 Visit(E->getBase());
3787 }
3788 }
3789 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3790 for (OMPClause *C : S->clauses()) {
3791 // Skip analysis of arguments of implicitly defined firstprivate clause
3792 // for task|target directives.
3793 // Skip analysis of arguments of implicitly defined map clause for target
3794 // directives.
3795 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3796 C->isImplicit() &&
3797 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3798 for (Stmt *CC : C->children()) {
3799 if (CC)
3800 Visit(CC);
3801 }
3802 }
3803 }
3804 // Check implicitly captured variables.
3805 VisitSubCaptures(S);
3806 }
3807
3808 void VisitOMPTileDirective(OMPTileDirective *S) {
3809 // #pragma omp tile does not introduce data sharing.
3810 VisitStmt(S);
3811 }
3812
3813 void VisitOMPUnrollDirective(OMPUnrollDirective *S) {
3814 // #pragma omp unroll does not introduce data sharing.
3815 VisitStmt(S);
3816 }
3817
3818 void VisitStmt(Stmt *S) {
3819 for (Stmt *C : S->children()) {
3820 if (C) {
3821 // Check implicitly captured variables in the task-based directives to
3822 // check if they must be firstprivatized.
3823 Visit(C);
3824 }
3825 }
3826 }
3827
3828 void visitSubCaptures(CapturedStmt *S) {
3829 for (const CapturedStmt::Capture &Cap : S->captures()) {
3830 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3831 continue;
3832 VarDecl *VD = Cap.getCapturedVar();
3833 // Do not try to map the variable if it or its sub-component was mapped
3834 // already.
3835 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3836 Stack->checkMappableExprComponentListsForDecl(
3837 VD, /*CurrentRegionOnly=*/true,
3838 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3839 OpenMPClauseKind) { return true; }))
3840 continue;
3841 DeclRefExpr *DRE = buildDeclRefExpr(
3842 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3843 Cap.getLocation(), /*RefersToCapture=*/true);
3844 Visit(DRE);
3845 }
3846 }
3847 bool isErrorFound() const { return ErrorFound; }
3848 ArrayRef<Expr *> getImplicitFirstprivate() const {
3849 return ImplicitFirstprivate;
3850 }
3851 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3852 OpenMPMapClauseKind MK) const {
3853 return ImplicitMap[DK][MK];
3854 }
3855 ArrayRef<OpenMPMapModifierKind>
3856 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3857 return ImplicitMapModifier[Kind];
3858 }
3859 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3860 return VarsWithInheritedDSA;
3861 }
3862
3863 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3864 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3865 // Process declare target link variables for the target directives.
3866 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3867 for (DeclRefExpr *E : Stack->getLinkGlobals())
3868 Visit(E);
3869 }
3870 }
3871};
3872} // namespace
3873
3874void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3875 switch (DKind) {
3876 case OMPD_parallel:
3877 case OMPD_parallel_for:
3878 case OMPD_parallel_for_simd:
3879 case OMPD_parallel_sections:
3880 case OMPD_parallel_master:
3881 case OMPD_teams:
3882 case OMPD_teams_distribute:
3883 case OMPD_teams_distribute_simd: {
3884 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3885 QualType KmpInt32PtrTy =
3886 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3887 Sema::CapturedParamNameType Params[] = {
3888 std::make_pair(".global_tid.", KmpInt32PtrTy),
3889 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3890 std::make_pair(StringRef(), QualType()) // __context with shared vars
3891 };
3892 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3893 Params);
3894 break;
3895 }
3896 case OMPD_target_teams:
3897 case OMPD_target_parallel:
3898 case OMPD_target_parallel_for:
3899 case OMPD_target_parallel_for_simd:
3900 case OMPD_target_teams_distribute:
3901 case OMPD_target_teams_distribute_simd: {
3902 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3903 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3904 QualType KmpInt32PtrTy =
3905 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3906 QualType Args[] = {VoidPtrTy};
3907 FunctionProtoType::ExtProtoInfo EPI;
3908 EPI.Variadic = true;
3909 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3910 Sema::CapturedParamNameType Params[] = {
3911 std::make_pair(".global_tid.", KmpInt32Ty),
3912 std::make_pair(".part_id.", KmpInt32PtrTy),
3913 std::make_pair(".privates.", VoidPtrTy),
3914 std::make_pair(
3915 ".copy_fn.",
3916 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3917 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3918 std::make_pair(StringRef(), QualType()) // __context with shared vars
3919 };
3920 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3921 Params, /*OpenMPCaptureLevel=*/0);
3922 // Mark this captured region as inlined, because we don't use outlined
3923 // function directly.
3924 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3925 AlwaysInlineAttr::CreateImplicit(
3926 Context, {}, AttributeCommonInfo::AS_Keyword,
3927 AlwaysInlineAttr::Keyword_forceinline));
3928 Sema::CapturedParamNameType ParamsTarget[] = {
3929 std::make_pair(StringRef(), QualType()) // __context with shared vars
3930 };
3931 // Start a captured region for 'target' with no implicit parameters.
3932 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3933 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3934 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3935 std::make_pair(".global_tid.", KmpInt32PtrTy),
3936 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3937 std::make_pair(StringRef(), QualType()) // __context with shared vars
3938 };
3939 // Start a captured region for 'teams' or 'parallel'. Both regions have
3940 // the same implicit parameters.
3941 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3942 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3943 break;
3944 }
3945 case OMPD_target:
3946 case OMPD_target_simd: {
3947 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3948 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3949 QualType KmpInt32PtrTy =
3950 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3951 QualType Args[] = {VoidPtrTy};
3952 FunctionProtoType::ExtProtoInfo EPI;
3953 EPI.Variadic = true;
3954 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3955 Sema::CapturedParamNameType Params[] = {
3956 std::make_pair(".global_tid.", KmpInt32Ty),
3957 std::make_pair(".part_id.", KmpInt32PtrTy),
3958 std::make_pair(".privates.", VoidPtrTy),
3959 std::make_pair(
3960 ".copy_fn.",
3961 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3962 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3963 std::make_pair(StringRef(), QualType()) // __context with shared vars
3964 };
3965 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3966 Params, /*OpenMPCaptureLevel=*/0);
3967 // Mark this captured region as inlined, because we don't use outlined
3968 // function directly.
3969 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3970 AlwaysInlineAttr::CreateImplicit(
3971 Context, {}, AttributeCommonInfo::AS_Keyword,
3972 AlwaysInlineAttr::Keyword_forceinline));
3973 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3974 std::make_pair(StringRef(), QualType()),
3975 /*OpenMPCaptureLevel=*/1);
3976 break;
3977 }
3978 case OMPD_atomic:
3979 case OMPD_critical:
3980 case OMPD_section:
3981 case OMPD_master:
3982 case OMPD_masked:
3983 case OMPD_tile:
3984 case OMPD_unroll:
3985 break;
3986 case OMPD_simd:
3987 case OMPD_for:
3988 case OMPD_for_simd:
3989 case OMPD_sections:
3990 case OMPD_single:
3991 case OMPD_taskgroup:
3992 case OMPD_distribute:
3993 case OMPD_distribute_simd:
3994 case OMPD_ordered:
3995 case OMPD_target_data:
3996 case OMPD_dispatch: {
3997 Sema::CapturedParamNameType Params[] = {
3998 std::make_pair(StringRef(), QualType()) // __context with shared vars
3999 };
4000 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4001 Params);
4002 break;
4003 }
4004 case OMPD_task: {
4005 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4006 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4007 QualType KmpInt32PtrTy =
4008 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4009 QualType Args[] = {VoidPtrTy};
4010 FunctionProtoType::ExtProtoInfo EPI;
4011 EPI.Variadic = true;
4012 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4013 Sema::CapturedParamNameType Params[] = {
4014 std::make_pair(".global_tid.", KmpInt32Ty),
4015 std::make_pair(".part_id.", KmpInt32PtrTy),
4016 std::make_pair(".privates.", VoidPtrTy),
4017 std::make_pair(
4018 ".copy_fn.",
4019 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4020 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4021 std::make_pair(StringRef(), QualType()) // __context with shared vars
4022 };
4023 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4024 Params);
4025 // Mark this captured region as inlined, because we don't use outlined
4026 // function directly.
4027 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4028 AlwaysInlineAttr::CreateImplicit(
4029 Context, {}, AttributeCommonInfo::AS_Keyword,
4030 AlwaysInlineAttr::Keyword_forceinline));
4031 break;
4032 }
4033 case OMPD_taskloop:
4034 case OMPD_taskloop_simd:
4035 case OMPD_master_taskloop:
4036 case OMPD_master_taskloop_simd: {
4037 QualType KmpInt32Ty =
4038 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4039 .withConst();
4040 QualType KmpUInt64Ty =
4041 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4042 .withConst();
4043 QualType KmpInt64Ty =
4044 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4045 .withConst();
4046 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4047 QualType KmpInt32PtrTy =
4048 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4049 QualType Args[] = {VoidPtrTy};
4050 FunctionProtoType::ExtProtoInfo EPI;
4051 EPI.Variadic = true;
4052 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4053 Sema::CapturedParamNameType Params[] = {
4054 std::make_pair(".global_tid.", KmpInt32Ty),
4055 std::make_pair(".part_id.", KmpInt32PtrTy),
4056 std::make_pair(".privates.", VoidPtrTy),
4057 std::make_pair(
4058 ".copy_fn.",
4059 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4060 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4061 std::make_pair(".lb.", KmpUInt64Ty),
4062 std::make_pair(".ub.", KmpUInt64Ty),
4063 std::make_pair(".st.", KmpInt64Ty),
4064 std::make_pair(".liter.", KmpInt32Ty),
4065 std::make_pair(".reductions.", VoidPtrTy),
4066 std::make_pair(StringRef(), QualType()) // __context with shared vars
4067 };
4068 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4069 Params);
4070 // Mark this captured region as inlined, because we don't use outlined
4071 // function directly.
4072 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4073 AlwaysInlineAttr::CreateImplicit(
4074 Context, {}, AttributeCommonInfo::AS_Keyword,
4075 AlwaysInlineAttr::Keyword_forceinline));
4076 break;
4077 }
4078 case OMPD_parallel_master_taskloop:
4079 case OMPD_parallel_master_taskloop_simd: {
4080 QualType KmpInt32Ty =
4081 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4082 .withConst();
4083 QualType KmpUInt64Ty =
4084 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4085 .withConst();
4086 QualType KmpInt64Ty =
4087 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4088 .withConst();
4089 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4090 QualType KmpInt32PtrTy =
4091 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4092 Sema::CapturedParamNameType ParamsParallel[] = {
4093 std::make_pair(".global_tid.", KmpInt32PtrTy),
4094 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4095 std::make_pair(StringRef(), QualType()) // __context with shared vars
4096 };
4097 // Start a captured region for 'parallel'.
4098 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4099 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4100 QualType Args[] = {VoidPtrTy};
4101 FunctionProtoType::ExtProtoInfo EPI;
4102 EPI.Variadic = true;
4103 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4104 Sema::CapturedParamNameType Params[] = {
4105 std::make_pair(".global_tid.", KmpInt32Ty),
4106 std::make_pair(".part_id.", KmpInt32PtrTy),
4107 std::make_pair(".privates.", VoidPtrTy),
4108 std::make_pair(
4109 ".copy_fn.",
4110 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4111 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4112 std::make_pair(".lb.", KmpUInt64Ty),
4113 std::make_pair(".ub.", KmpUInt64Ty),
4114 std::make_pair(".st.", KmpInt64Ty),
4115 std::make_pair(".liter.", KmpInt32Ty),
4116 std::make_pair(".reductions.", VoidPtrTy),
4117 std::make_pair(StringRef(), QualType()) // __context with shared vars
4118 };
4119 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4120 Params, /*OpenMPCaptureLevel=*/1);
4121 // Mark this captured region as inlined, because we don't use outlined
4122 // function directly.
4123 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4124 AlwaysInlineAttr::CreateImplicit(
4125 Context, {}, AttributeCommonInfo::AS_Keyword,
4126 AlwaysInlineAttr::Keyword_forceinline));
4127 break;
4128 }
4129 case OMPD_distribute_parallel_for_simd:
4130 case OMPD_distribute_parallel_for: {
4131 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4132 QualType KmpInt32PtrTy =
4133 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4134 Sema::CapturedParamNameType Params[] = {
4135 std::make_pair(".global_tid.", KmpInt32PtrTy),
4136 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4137 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4138 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4139 std::make_pair(StringRef(), QualType()) // __context with shared vars
4140 };
4141 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4142 Params);
4143 break;
4144 }
4145 case OMPD_target_teams_distribute_parallel_for:
4146 case OMPD_target_teams_distribute_parallel_for_simd: {
4147 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4148 QualType KmpInt32PtrTy =
4149 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4150 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4151
4152 QualType Args[] = {VoidPtrTy};
4153 FunctionProtoType::ExtProtoInfo EPI;
4154 EPI.Variadic = true;
4155 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4156 Sema::CapturedParamNameType Params[] = {
4157 std::make_pair(".global_tid.", KmpInt32Ty),
4158 std::make_pair(".part_id.", KmpInt32PtrTy),
4159 std::make_pair(".privates.", VoidPtrTy),
4160 std::make_pair(
4161 ".copy_fn.",
4162 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4163 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4164 std::make_pair(StringRef(), QualType()) // __context with shared vars
4165 };
4166 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4167 Params, /*OpenMPCaptureLevel=*/0);
4168 // Mark this captured region as inlined, because we don't use outlined
4169 // function directly.
4170 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4171 AlwaysInlineAttr::CreateImplicit(
4172 Context, {}, AttributeCommonInfo::AS_Keyword,
4173 AlwaysInlineAttr::Keyword_forceinline));
4174 Sema::CapturedParamNameType ParamsTarget[] = {
4175 std::make_pair(StringRef(), QualType()) // __context with shared vars
4176 };
4177 // Start a captured region for 'target' with no implicit parameters.
4178 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4179 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4180
4181 Sema::CapturedParamNameType ParamsTeams[] = {
4182 std::make_pair(".global_tid.", KmpInt32PtrTy),
4183 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4184 std::make_pair(StringRef(), QualType()) // __context with shared vars
4185 };
4186 // Start a captured region for 'target' with no implicit parameters.
4187 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4188 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4189
4190 Sema::CapturedParamNameType ParamsParallel[] = {
4191 std::make_pair(".global_tid.", KmpInt32PtrTy),
4192 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4193 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4194 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4195 std::make_pair(StringRef(), QualType()) // __context with shared vars
4196 };
4197 // Start a captured region for 'teams' or 'parallel'. Both regions have
4198 // the same implicit parameters.
4199 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4200 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4201 break;
4202 }
4203
4204 case OMPD_teams_distribute_parallel_for:
4205 case OMPD_teams_distribute_parallel_for_simd: {
4206 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4207 QualType KmpInt32PtrTy =
4208 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4209
4210 Sema::CapturedParamNameType ParamsTeams[] = {
4211 std::make_pair(".global_tid.", KmpInt32PtrTy),
4212 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4213 std::make_pair(StringRef(), QualType()) // __context with shared vars
4214 };
4215 // Start a captured region for 'target' with no implicit parameters.
4216 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4217 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4218
4219 Sema::CapturedParamNameType ParamsParallel[] = {
4220 std::make_pair(".global_tid.", KmpInt32PtrTy),
4221 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4222 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4223 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4224 std::make_pair(StringRef(), QualType()) // __context with shared vars
4225 };
4226 // Start a captured region for 'teams' or 'parallel'. Both regions have
4227 // the same implicit parameters.
4228 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4229 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4230 break;
4231 }
4232 case OMPD_target_update:
4233 case OMPD_target_enter_data:
4234 case OMPD_target_exit_data: {
4235 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4236 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4237 QualType KmpInt32PtrTy =
4238 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4239 QualType Args[] = {VoidPtrTy};
4240 FunctionProtoType::ExtProtoInfo EPI;
4241 EPI.Variadic = true;
4242 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4243 Sema::CapturedParamNameType Params[] = {
4244 std::make_pair(".global_tid.", KmpInt32Ty),
4245 std::make_pair(".part_id.", KmpInt32PtrTy),
4246 std::make_pair(".privates.", VoidPtrTy),
4247 std::make_pair(
4248 ".copy_fn.",
4249 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4250 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4251 std::make_pair(StringRef(), QualType()) // __context with shared vars
4252 };
4253 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4254 Params);
4255 // Mark this captured region as inlined, because we don't use outlined
4256 // function directly.
4257 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4258 AlwaysInlineAttr::CreateImplicit(
4259 Context, {}, AttributeCommonInfo::AS_Keyword,
4260 AlwaysInlineAttr::Keyword_forceinline));
4261 break;
4262 }
4263 case OMPD_threadprivate:
4264 case OMPD_allocate:
4265 case OMPD_taskyield:
4266 case OMPD_barrier:
4267 case OMPD_taskwait:
4268 case OMPD_cancellation_point:
4269 case OMPD_cancel:
4270 case OMPD_flush:
4271 case OMPD_depobj:
4272 case OMPD_scan:
4273 case OMPD_declare_reduction:
4274 case OMPD_declare_mapper:
4275 case OMPD_declare_simd:
4276 case OMPD_declare_target:
4277 case OMPD_end_declare_target:
4278 case OMPD_requires:
4279 case OMPD_declare_variant:
4280 case OMPD_begin_declare_variant:
4281 case OMPD_end_declare_variant:
4282 llvm_unreachable("OpenMP Directive is not allowed")__builtin_unreachable();
4283 case OMPD_unknown:
4284 default:
4285 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
4286 }
4287 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setContext(CurContext);
4288}
4289
4290int Sema::getNumberOfConstructScopes(unsigned Level) const {
4291 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4292}
4293
4294int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4295 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4296 getOpenMPCaptureRegions(CaptureRegions, DKind);
4297 return CaptureRegions.size();
4298}
4299
4300static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4301 Expr *CaptureExpr, bool WithInit,
4302 bool AsExpression) {
4303 assert(CaptureExpr)(static_cast<void> (0));
4304 ASTContext &C = S.getASTContext();
4305 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4306 QualType Ty = Init->getType();
4307 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4308 if (S.getLangOpts().CPlusPlus) {
4309 Ty = C.getLValueReferenceType(Ty);
4310 } else {
4311 Ty = C.getPointerType(Ty);
4312 ExprResult Res =
4313 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4314 if (!Res.isUsable())
4315 return nullptr;
4316 Init = Res.get();
4317 }
4318 WithInit = true;
4319 }
4320 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4321 CaptureExpr->getBeginLoc());
4322 if (!WithInit)
4323 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4324 S.CurContext->addHiddenDecl(CED);
4325 Sema::TentativeAnalysisScope Trap(S);
4326 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4327 return CED;
4328}
4329
4330static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4331 bool WithInit) {
4332 OMPCapturedExprDecl *CD;
4333 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4334 CD = cast<OMPCapturedExprDecl>(VD);
4335 else
4336 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4337 /*AsExpression=*/false);
4338 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4339 CaptureExpr->getExprLoc());
4340}
4341
4342static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4343 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4344 if (!Ref) {
4345 OMPCapturedExprDecl *CD = buildCaptureDecl(
4346 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4347 /*WithInit=*/true, /*AsExpression=*/true);
4348 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4349 CaptureExpr->getExprLoc());
4350 }
4351 ExprResult Res = Ref;
4352 if (!S.getLangOpts().CPlusPlus &&
4353 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4354 Ref->getType()->isPointerType()) {
4355 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4356 if (!Res.isUsable())
4357 return ExprError();
4358 }
4359 return S.DefaultLvalueConversion(Res.get());
4360}
4361
4362namespace {
4363// OpenMP directives parsed in this section are represented as a
4364// CapturedStatement with an associated statement. If a syntax error
4365// is detected during the parsing of the associated statement, the
4366// compiler must abort processing and close the CapturedStatement.
4367//
4368// Combined directives such as 'target parallel' have more than one
4369// nested CapturedStatements. This RAII ensures that we unwind out
4370// of all the nested CapturedStatements when an error is found.
4371class CaptureRegionUnwinderRAII {
4372private:
4373 Sema &S;
4374 bool &ErrorFound;
4375 OpenMPDirectiveKind DKind = OMPD_unknown;
4376
4377public:
4378 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4379 OpenMPDirectiveKind DKind)
4380 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4381 ~CaptureRegionUnwinderRAII() {
4382 if (ErrorFound) {
4383 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4384 while (--ThisCaptureLevel >= 0)
4385 S.ActOnCapturedRegionError();
4386 }
4387 }
4388};
4389} // namespace
4390
4391void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4392 // Capture variables captured by reference in lambdas for target-based
4393 // directives.
4394 if (!CurContext->isDependentContext() &&
4395 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4396 isOpenMPTargetDataManagementDirective(
4397 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4398 QualType Type = V->getType();
4399 if (const auto *RD = Type.getCanonicalType()
4400 .getNonReferenceType()
4401 ->getAsCXXRecordDecl()) {
4402 bool SavedForceCaptureByReferenceInTargetExecutable =
4403 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4404 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4405 /*V=*/true);
4406 if (RD->isLambda()) {
4407 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4408 FieldDecl *ThisCapture;
4409 RD->getCaptureFields(Captures, ThisCapture);
4410 for (const LambdaCapture &LC : RD->captures()) {
4411 if (LC.getCaptureKind() == LCK_ByRef) {
4412 VarDecl *VD = LC.getCapturedVar();
4413 DeclContext *VDC = VD->getDeclContext();
4414 if (!VDC->Encloses(CurContext))
4415 continue;
4416 MarkVariableReferenced(LC.getLocation(), VD);
4417 } else if (LC.getCaptureKind() == LCK_This) {
4418 QualType ThisTy = getCurrentThisType();
4419 if (!ThisTy.isNull() &&
4420 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4421 CheckCXXThisCapture(LC.getLocation());
4422 }
4423 }
4424 }
4425 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4426 SavedForceCaptureByReferenceInTargetExecutable);
4427 }
4428 }
4429}
4430
4431static bool checkOrderedOrderSpecified(Sema &S,
4432 const ArrayRef<OMPClause *> Clauses) {
4433 const OMPOrderedClause *Ordered = nullptr;
4434 const OMPOrderClause *Order = nullptr;
4435
4436 for (const OMPClause *Clause : Clauses) {
4437 if (Clause->getClauseKind() == OMPC_ordered)
4438 Ordered = cast<OMPOrderedClause>(Clause);
4439 else if (Clause->getClauseKind() == OMPC_order) {
4440 Order = cast<OMPOrderClause>(Clause);
4441 if (Order->getKind() != OMPC_ORDER_concurrent)
4442 Order = nullptr;
4443 }
4444 if (Ordered && Order)
4445 break;
4446 }
4447
4448 if (Ordered && Order) {
4449 S.Diag(Order->getKindKwLoc(),
4450 diag::err_omp_simple_clause_incompatible_with_ordered)
4451 << getOpenMPClauseName(OMPC_order)
4452 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4453 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4454 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4455 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4456 return true;
4457 }
4458 return false;
4459}
4460
4461StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4462 ArrayRef<OMPClause *> Clauses) {
4463 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4464 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4465 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4466 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master ||
4467 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_masked)
4468 return S;
4469
4470 bool ErrorFound = false;
4471 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4472 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4473 if (!S.isUsable()) {
4474 ErrorFound = true;
4475 return StmtError();
4476 }
4477
4478 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4479 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4480 OMPOrderedClause *OC = nullptr;
4481 OMPScheduleClause *SC = nullptr;
4482 SmallVector<const OMPLinearClause *, 4> LCs;
4483 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4484 // This is required for proper codegen.
4485 for (OMPClause *Clause : Clauses) {
4486 if (!LangOpts.OpenMPSimd &&
4487 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4488 Clause->getClauseKind() == OMPC_in_reduction) {
4489 // Capture taskgroup task_reduction descriptors inside the tasking regions
4490 // with the corresponding in_reduction items.
4491 auto *IRC = cast<OMPInReductionClause>(Clause);
4492 for (Expr *E : IRC->taskgroup_descriptors())
4493 if (E)
4494 MarkDeclarationsReferencedInExpr(E);
4495 }
4496 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4497 Clause->getClauseKind() == OMPC_copyprivate ||
4498 (getLangOpts().OpenMPUseTLS &&
4499 getASTContext().getTargetInfo().isTLSSupported() &&
4500 Clause->getClauseKind() == OMPC_copyin)) {
4501 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4502 // Mark all variables in private list clauses as used in inner region.
4503 for (Stmt *VarRef : Clause->children()) {
4504 if (auto *E = cast_or_null<Expr>(VarRef)) {
4505 MarkDeclarationsReferencedInExpr(E);
4506 }
4507 }
4508 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4509 } else if (isOpenMPLoopTransformationDirective(
4510 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4511 assert(CaptureRegions.empty() &&(static_cast<void> (0))
4512 "No captured regions in loop transformation directives.")(static_cast<void> (0));
4513 } else if (CaptureRegions.size() > 1 ||
4514 CaptureRegions.back() != OMPD_unknown) {
4515 if (auto *C = OMPClauseWithPreInit::get(Clause))
4516 PICs.push_back(C);
4517 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4518 if (Expr *E = C->getPostUpdateExpr())
4519 MarkDeclarationsReferencedInExpr(E);
4520 }
4521 }
4522 if (Clause->getClauseKind() == OMPC_schedule)
4523 SC = cast<OMPScheduleClause>(Clause);
4524 else if (Clause->getClauseKind() == OMPC_ordered)
4525 OC = cast<OMPOrderedClause>(Clause);
4526 else if (Clause->getClauseKind() == OMPC_linear)
4527 LCs.push_back(cast<OMPLinearClause>(Clause));
4528 }
4529 // Capture allocator expressions if used.
4530 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4531 MarkDeclarationsReferencedInExpr(E);
4532 // OpenMP, 2.7.1 Loop Construct, Restrictions
4533 // The nonmonotonic modifier cannot be specified if an ordered clause is
4534 // specified.
4535 if (SC &&
4536 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4537 SC->getSecondScheduleModifier() ==
4538 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4539 OC) {
4540 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4541 ? SC->getFirstScheduleModifierLoc()
4542 : SC->getSecondScheduleModifierLoc(),
4543 diag::err_omp_simple_clause_incompatible_with_ordered)
4544 << getOpenMPClauseName(OMPC_schedule)
4545 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4546 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4547 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4548 ErrorFound = true;
4549 }
4550 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4551 // If an order(concurrent) clause is present, an ordered clause may not appear
4552 // on the same directive.
4553 if (checkOrderedOrderSpecified(*this, Clauses))
4554 ErrorFound = true;
4555 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4556 for (const OMPLinearClause *C : LCs) {
4557 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4558 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4559 }
4560 ErrorFound = true;
4561 }
4562 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4563 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4564 OC->getNumForLoops()) {
4565 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4566 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4567 ErrorFound = true;
4568 }
4569 if (ErrorFound) {
4570 return StmtError();
4571 }
4572 StmtResult SR = S;
4573 unsigned CompletedRegions = 0;
4574 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4575 // Mark all variables in private list clauses as used in inner region.
4576 // Required for proper codegen of combined directives.
4577 // TODO: add processing for other clauses.
4578 if (ThisCaptureRegion != OMPD_unknown) {
4579 for (const clang::OMPClauseWithPreInit *C : PICs) {
4580 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4581 // Find the particular capture region for the clause if the
4582 // directive is a combined one with multiple capture regions.
4583 // If the directive is not a combined one, the capture region
4584 // associated with the clause is OMPD_unknown and is generated
4585 // only once.
4586 if (CaptureRegion == ThisCaptureRegion ||
4587 CaptureRegion == OMPD_unknown) {
4588 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4589 for (Decl *D : DS->decls())
4590 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4591 }
4592 }
4593 }
4594 }
4595 if (ThisCaptureRegion == OMPD_target) {
4596 // Capture allocator traits in the target region. They are used implicitly
4597 // and, thus, are not captured by default.
4598 for (OMPClause *C : Clauses) {
4599 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4600 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4601 ++I) {
4602 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4603 if (Expr *E = D.AllocatorTraits)
4604 MarkDeclarationsReferencedInExpr(E);
4605 }
4606 continue;
4607 }
4608 }
4609 }
4610 if (ThisCaptureRegion == OMPD_parallel) {
4611 // Capture temp arrays for inscan reductions and locals in aligned
4612 // clauses.
4613 for (OMPClause *C : Clauses) {
4614 if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4615 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4616 continue;
4617 for (Expr *E : RC->copy_array_temps())
4618 MarkDeclarationsReferencedInExpr(E);
4619 }
4620 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4621 for (Expr *E : AC->varlists())
4622 MarkDeclarationsReferencedInExpr(E);
4623 }
4624 }
4625 }
4626 if (++CompletedRegions == CaptureRegions.size())
4627 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4628 SR = ActOnCapturedRegionEnd(SR.get());
4629 }
4630 return SR;
4631}
4632
4633static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4634 OpenMPDirectiveKind CancelRegion,
4635 SourceLocation StartLoc) {
4636 // CancelRegion is only needed for cancel and cancellation_point.
4637 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4638 return false;
4639
4640 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4641 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4642 return false;
4643
4644 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4645 << getOpenMPDirectiveName(CancelRegion);
4646 return true;
4647}
4648
4649static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4650 OpenMPDirectiveKind CurrentRegion,
4651 const DeclarationNameInfo &CurrentName,
4652 OpenMPDirectiveKind CancelRegion,
4653 SourceLocation StartLoc) {
4654 if (Stack->getCurScope()) {
4655 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4656 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4657 bool NestingProhibited = false;
4658 bool CloseNesting = true;
4659 bool OrphanSeen = false;
4660 enum {
4661 NoRecommend,
4662 ShouldBeInParallelRegion,
4663 ShouldBeInOrderedRegion,
4664 ShouldBeInTargetRegion,
4665 ShouldBeInTeamsRegion,
4666 ShouldBeInLoopSimdRegion,
4667 } Recommend = NoRecommend;
4668 if (isOpenMPSimdDirective(ParentRegion) &&
4669 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4670 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4671 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4672 CurrentRegion != OMPD_scan))) {
4673 // OpenMP [2.16, Nesting of Regions]
4674 // OpenMP constructs may not be nested inside a simd region.
4675 // OpenMP [2.8.1,simd Construct, Restrictions]
4676 // An ordered construct with the simd clause is the only OpenMP
4677 // construct that can appear in the simd region.
4678 // Allowing a SIMD construct nested in another SIMD construct is an
4679 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4680 // message.
4681 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4682 // The only OpenMP constructs that can be encountered during execution of
4683 // a simd region are the atomic construct, the loop construct, the simd
4684 // construct and the ordered construct with the simd clause.
4685 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4686 ? diag::err_omp_prohibited_region_simd
4687 : diag::warn_omp_nesting_simd)
4688 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4689 return CurrentRegion != OMPD_simd;
4690 }
4691 if (ParentRegion == OMPD_atomic) {
4692 // OpenMP [2.16, Nesting of Regions]
4693 // OpenMP constructs may not be nested inside an atomic region.
4694 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4695 return true;
4696 }
4697 if (CurrentRegion == OMPD_section) {
4698 // OpenMP [2.7.2, sections Construct, Restrictions]
4699 // Orphaned section directives are prohibited. That is, the section
4700 // directives must appear within the sections construct and must not be
4701 // encountered elsewhere in the sections region.
4702 if (ParentRegion != OMPD_sections &&
4703 ParentRegion != OMPD_parallel_sections) {
4704 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4705 << (ParentRegion != OMPD_unknown)
4706 << getOpenMPDirectiveName(ParentRegion);
4707 return true;
4708 }
4709 return false;
4710 }
4711 // Allow some constructs (except teams and cancellation constructs) to be
4712 // orphaned (they could be used in functions, called from OpenMP regions
4713 // with the required preconditions).
4714 if (ParentRegion == OMPD_unknown &&
4715 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4716 CurrentRegion != OMPD_cancellation_point &&
4717 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4718 return false;
4719 if (CurrentRegion == OMPD_cancellation_point ||
4720 CurrentRegion == OMPD_cancel) {
4721 // OpenMP [2.16, Nesting of Regions]
4722 // A cancellation point construct for which construct-type-clause is
4723 // taskgroup must be nested inside a task construct. A cancellation
4724 // point construct for which construct-type-clause is not taskgroup must
4725 // be closely nested inside an OpenMP construct that matches the type
4726 // specified in construct-type-clause.
4727 // A cancel construct for which construct-type-clause is taskgroup must be
4728 // nested inside a task construct. A cancel construct for which
4729 // construct-type-clause is not taskgroup must be closely nested inside an
4730 // OpenMP construct that matches the type specified in
4731 // construct-type-clause.
4732 NestingProhibited =
4733 !((CancelRegion == OMPD_parallel &&
4734 (ParentRegion == OMPD_parallel ||
4735 ParentRegion == OMPD_target_parallel)) ||
4736 (CancelRegion == OMPD_for &&
4737 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4738 ParentRegion == OMPD_target_parallel_for ||
4739 ParentRegion == OMPD_distribute_parallel_for ||
4740 ParentRegion == OMPD_teams_distribute_parallel_for ||
4741 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4742 (CancelRegion == OMPD_taskgroup &&
4743 (ParentRegion == OMPD_task ||
4744 (SemaRef.getLangOpts().OpenMP >= 50 &&
4745 (ParentRegion == OMPD_taskloop ||
4746 ParentRegion == OMPD_master_taskloop ||
4747 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4748 (CancelRegion == OMPD_sections &&
4749 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4750 ParentRegion == OMPD_parallel_sections)));
4751 OrphanSeen = ParentRegion == OMPD_unknown;
4752 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4753 // OpenMP 5.1 [2.22, Nesting of Regions]
4754 // A masked region may not be closely nested inside a worksharing, loop,
4755 // atomic, task, or taskloop region.
4756 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4757 isOpenMPTaskingDirective(ParentRegion);
4758 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4759 // OpenMP [2.16, Nesting of Regions]
4760 // A critical region may not be nested (closely or otherwise) inside a
4761 // critical region with the same name. Note that this restriction is not
4762 // sufficient to prevent deadlock.
4763 SourceLocation PreviousCriticalLoc;
4764 bool DeadLock = Stack->hasDirective(
4765 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4766 const DeclarationNameInfo &DNI,
4767 SourceLocation Loc) {
4768 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4769 PreviousCriticalLoc = Loc;
4770 return true;
4771 }
4772 return false;
4773 },
4774 false /* skip top directive */);
4775 if (DeadLock) {
4776 SemaRef.Diag(StartLoc,
4777 diag::err_omp_prohibited_region_critical_same_name)
4778 << CurrentName.getName();
4779 if (PreviousCriticalLoc.isValid())
4780 SemaRef.Diag(PreviousCriticalLoc,
4781 diag::note_omp_previous_critical_region);
4782 return true;
4783 }
4784 } else if (CurrentRegion == OMPD_barrier) {
4785 // OpenMP 5.1 [2.22, Nesting of Regions]
4786 // A barrier region may not be closely nested inside a worksharing, loop,
4787 // task, taskloop, critical, ordered, atomic, or masked region.
4788 NestingProhibited =
4789 isOpenMPWorksharingDirective(ParentRegion) ||
4790 isOpenMPTaskingDirective(ParentRegion) ||
4791 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4792 ParentRegion == OMPD_parallel_master ||
4793 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4794 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4795 !isOpenMPParallelDirective(CurrentRegion) &&
4796 !isOpenMPTeamsDirective(CurrentRegion)) {
4797 // OpenMP 5.1 [2.22, Nesting of Regions]
4798 // A loop region that binds to a parallel region or a worksharing region
4799 // may not be closely nested inside a worksharing, loop, task, taskloop,
4800 // critical, ordered, atomic, or masked region.
4801 NestingProhibited =
4802 isOpenMPWorksharingDirective(ParentRegion) ||
4803 isOpenMPTaskingDirective(ParentRegion) ||
4804 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4805 ParentRegion == OMPD_parallel_master ||
4806 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4807 Recommend = ShouldBeInParallelRegion;
4808 } else if (CurrentRegion == OMPD_ordered) {
4809 // OpenMP [2.16, Nesting of Regions]
4810 // An ordered region may not be closely nested inside a critical,
4811 // atomic, or explicit task region.
4812 // An ordered region must be closely nested inside a loop region (or
4813 // parallel loop region) with an ordered clause.
4814 // OpenMP [2.8.1,simd Construct, Restrictions]
4815 // An ordered construct with the simd clause is the only OpenMP construct
4816 // that can appear in the simd region.
4817 NestingProhibited = ParentRegion == OMPD_critical ||
4818 isOpenMPTaskingDirective(ParentRegion) ||
4819 !(isOpenMPSimdDirective(ParentRegion) ||
4820 Stack->isParentOrderedRegion());
4821 Recommend = ShouldBeInOrderedRegion;
4822 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4823 // OpenMP [2.16, Nesting of Regions]
4824 // If specified, a teams construct must be contained within a target
4825 // construct.
4826 NestingProhibited =
4827 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4828 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4829 ParentRegion != OMPD_target);
4830 OrphanSeen = ParentRegion == OMPD_unknown;
4831 Recommend = ShouldBeInTargetRegion;
4832 } else if (CurrentRegion == OMPD_scan) {
4833 // OpenMP [2.16, Nesting of Regions]
4834 // If specified, a teams construct must be contained within a target
4835 // construct.
4836 NestingProhibited =
4837 SemaRef.LangOpts.OpenMP < 50 ||
4838 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4839 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4840 ParentRegion != OMPD_parallel_for_simd);
4841 OrphanSeen = ParentRegion == OMPD_unknown;
4842 Recommend = ShouldBeInLoopSimdRegion;
4843 }
4844 if (!NestingProhibited &&
4845 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4846 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4847 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4848 // OpenMP [2.16, Nesting of Regions]
4849 // distribute, parallel, parallel sections, parallel workshare, and the
4850 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4851 // constructs that can be closely nested in the teams region.
4852 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4853 !isOpenMPDistributeDirective(CurrentRegion);
4854 Recommend = ShouldBeInParallelRegion;
4855 }
4856 if (!NestingProhibited &&
4857 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4858 // OpenMP 4.5 [2.17 Nesting of Regions]
4859 // The region associated with the distribute construct must be strictly
4860 // nested inside a teams region
4861 NestingProhibited =
4862 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4863 Recommend = ShouldBeInTeamsRegion;
4864 }
4865 if (!NestingProhibited &&
4866 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4867 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4868 // OpenMP 4.5 [2.17 Nesting of Regions]
4869 // If a target, target update, target data, target enter data, or
4870 // target exit data construct is encountered during execution of a
4871 // target region, the behavior is unspecified.
4872 NestingProhibited = Stack->hasDirective(
4873 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4874 SourceLocation) {
4875 if (isOpenMPTargetExecutionDirective(K)) {
4876 OffendingRegion = K;
4877 return true;
4878 }
4879 return false;
4880 },
4881 false /* don't skip top directive */);
4882 CloseNesting = false;
4883 }
4884 if (NestingProhibited) {
4885 if (OrphanSeen) {
4886 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4887 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4888 } else {
4889 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4890 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4891 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4892 }
4893 return true;
4894 }
4895 }
4896 return false;
4897}
4898
4899struct Kind2Unsigned {
4900 using argument_type = OpenMPDirectiveKind;
4901 unsigned operator()(argument_type DK) { return unsigned(DK); }
4902};
4903static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4904 ArrayRef<OMPClause *> Clauses,
4905 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4906 bool ErrorFound = false;
4907 unsigned NamedModifiersNumber = 0;
4908 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4909 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4910 SmallVector<SourceLocation, 4> NameModifierLoc;
4911 for (const OMPClause *C : Clauses) {
4912 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4913 // At most one if clause without a directive-name-modifier can appear on
4914 // the directive.
4915 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4916 if (FoundNameModifiers[CurNM]) {
4917 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4918 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4919 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4920 ErrorFound = true;
4921 } else if (CurNM != OMPD_unknown) {
4922 NameModifierLoc.push_back(IC->getNameModifierLoc());
4923 ++NamedModifiersNumber;
4924 }
4925 FoundNameModifiers[CurNM] = IC;
4926 if (CurNM == OMPD_unknown)
4927 continue;
4928 // Check if the specified name modifier is allowed for the current
4929 // directive.
4930 // At most one if clause with the particular directive-name-modifier can
4931 // appear on the directive.
4932 bool MatchFound = false;
4933 for (auto NM : AllowedNameModifiers) {
4934 if (CurNM == NM) {
4935 MatchFound = true;
4936 break;
4937 }
4938 }
4939 if (!MatchFound) {
4940 S.Diag(IC->getNameModifierLoc(),
4941 diag::err_omp_wrong_if_directive_name_modifier)
4942 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4943 ErrorFound = true;
4944 }
4945 }
4946 }
4947 // If any if clause on the directive includes a directive-name-modifier then
4948 // all if clauses on the directive must include a directive-name-modifier.
4949 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4950 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4951 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4952 diag::err_omp_no_more_if_clause);
4953 } else {
4954 std::string Values;
4955 std::string Sep(", ");
4956 unsigned AllowedCnt = 0;
4957 unsigned TotalAllowedNum =
4958 AllowedNameModifiers.size() - NamedModifiersNumber;
4959 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4960 ++Cnt) {
4961 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4962 if (!FoundNameModifiers[NM]) {
4963 Values += "'";
4964 Values += getOpenMPDirectiveName(NM);
4965 Values += "'";
4966 if (AllowedCnt + 2 == TotalAllowedNum)
4967 Values += " or ";
4968 else if (AllowedCnt + 1 != TotalAllowedNum)
4969 Values += Sep;
4970 ++AllowedCnt;
4971 }
4972 }
4973 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4974 diag::err_omp_unnamed_if_clause)
4975 << (TotalAllowedNum > 1) << Values;
4976 }
4977 for (SourceLocation Loc : NameModifierLoc) {
4978 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4979 }
4980 ErrorFound = true;
4981 }
4982 return ErrorFound;
4983}
4984
4985static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4986 SourceLocation &ELoc,
4987 SourceRange &ERange,
4988 bool AllowArraySection) {
4989 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4990 RefExpr->containsUnexpandedParameterPack())
4991 return std::make_pair(nullptr, true);
4992
4993 // OpenMP [3.1, C/C++]
4994 // A list item is a variable name.
4995 // OpenMP [2.9.3.3, Restrictions, p.1]
4996 // A variable that is part of another variable (as an array or
4997 // structure element) cannot appear in a private clause.
4998 RefExpr = RefExpr->IgnoreParens();
4999 enum {
5000 NoArrayExpr = -1,
5001 ArraySubscript = 0,
5002 OMPArraySection = 1
5003 } IsArrayExpr = NoArrayExpr;
5004 if (AllowArraySection) {
5005 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5006 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5007 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5008 Base = TempASE->getBase()->IgnoreParenImpCasts();
5009 RefExpr = Base;
5010 IsArrayExpr = ArraySubscript;
5011 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5012 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5013 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5014 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5015 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5016 Base = TempASE->getBase()->IgnoreParenImpCasts();
5017 RefExpr = Base;
5018 IsArrayExpr = OMPArraySection;
5019 }
5020 }
5021 ELoc = RefExpr->getExprLoc();
5022 ERange = RefExpr->getSourceRange();
5023 RefExpr = RefExpr->IgnoreParenImpCasts();
5024 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5025 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5026 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5027 (S.getCurrentThisType().isNull() || !ME ||
5028 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5029 !isa<FieldDecl>(ME->getMemberDecl()))) {
5030 if (IsArrayExpr != NoArrayExpr) {
5031 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
5032 << ERange;
5033 } else {
5034 S.Diag(ELoc,
5035 AllowArraySection
5036 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5037 : diag::err_omp_expected_var_name_member_expr)
5038 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5039 }
5040 return std::make_pair(nullptr, false);
5041 }
5042 return std::make_pair(
5043 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5044}
5045
5046namespace {
5047/// Checks if the allocator is used in uses_allocators clause to be allowed in
5048/// target regions.
5049class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5050 DSAStackTy *S = nullptr;
5051
5052public:
5053 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5054 return S->isUsesAllocatorsDecl(E->getDecl())
5055 .getValueOr(
5056 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5057 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5058 }
5059 bool VisitStmt(const Stmt *S) {
5060 for (const Stmt *Child : S->children()) {
5061 if (Child && Visit(Child))
5062 return true;
5063 }
5064 return false;
5065 }
5066 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5067};
5068} // namespace
5069
5070static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5071 ArrayRef<OMPClause *> Clauses) {
5072 assert(!S.CurContext->isDependentContext() &&(static_cast<void> (0))
5073 "Expected non-dependent context.")(static_cast<void> (0));
5074 auto AllocateRange =
5075 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5076 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5077 DeclToCopy;
5078 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5079 return isOpenMPPrivate(C->getClauseKind());
5080 });
5081 for (OMPClause *Cl : PrivateRange) {
5082 MutableArrayRef<Expr *>::iterator I, It, Et;
5083 if (Cl->getClauseKind() == OMPC_private) {
5084 auto *PC = cast<OMPPrivateClause>(Cl);
5085 I = PC->private_copies().begin();
5086 It = PC->varlist_begin();
5087 Et = PC->varlist_end();
5088 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5089 auto *PC = cast<OMPFirstprivateClause>(Cl);
5090 I = PC->private_copies().begin();
5091 It = PC->varlist_begin();
5092 Et = PC->varlist_end();
5093 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5094 auto *PC = cast<OMPLastprivateClause>(Cl);
5095 I = PC->private_copies().begin();
5096 It = PC->varlist_begin();
5097 Et = PC->varlist_end();
5098 } else if (Cl->getClauseKind() == OMPC_linear) {
5099 auto *PC = cast<OMPLinearClause>(Cl);
5100 I = PC->privates().begin();
5101 It = PC->varlist_begin();
5102 Et = PC->varlist_end();
5103 } else if (Cl->getClauseKind() == OMPC_reduction) {
5104 auto *PC = cast<OMPReductionClause>(Cl);
5105 I = PC->privates().begin();
5106 It = PC->varlist_begin();
5107 Et = PC->varlist_end();
5108 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5109 auto *PC = cast<OMPTaskReductionClause>(Cl);
5110 I = PC->privates().begin();
5111 It = PC->varlist_begin();
5112 Et = PC->varlist_end();
5113 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5114 auto *PC = cast<OMPInReductionClause>(Cl);
5115 I = PC->privates().begin();
5116 It = PC->varlist_begin();
5117 Et = PC->varlist_end();
5118 } else {
5119 llvm_unreachable("Expected private clause.")__builtin_unreachable();
5120 }
5121 for (Expr *E : llvm::make_range(It, Et)) {
5122 if (!*I) {
5123 ++I;
5124 continue;
5125 }
5126 SourceLocation ELoc;
5127 SourceRange ERange;
5128 Expr *SimpleRefExpr = E;
5129 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5130 /*AllowArraySection=*/true);
5131 DeclToCopy.try_emplace(Res.first,
5132 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5133 ++I;
5134 }
5135 }
5136 for (OMPClause *C : AllocateRange) {
5137 auto *AC = cast<OMPAllocateClause>(C);
5138 if (S.getLangOpts().OpenMP >= 50 &&
5139 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5140 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5141 AC->getAllocator()) {
5142 Expr *Allocator = AC->getAllocator();
5143 // OpenMP, 2.12.5 target Construct
5144 // Memory allocators that do not appear in a uses_allocators clause cannot
5145 // appear as an allocator in an allocate clause or be used in the target
5146 // region unless a requires directive with the dynamic_allocators clause
5147 // is present in the same compilation unit.
5148 AllocatorChecker Checker(Stack);
5149 if (Checker.Visit(Allocator))
5150 S.Diag(Allocator->getExprLoc(),
5151 diag::err_omp_allocator_not_in_uses_allocators)
5152 << Allocator->getSourceRange();
5153 }
5154 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5155 getAllocatorKind(S, Stack, AC->getAllocator());
5156 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5157 // For task, taskloop or target directives, allocation requests to memory
5158 // allocators with the trait access set to thread result in unspecified
5159 // behavior.
5160 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5161 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5162 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5163 S.Diag(AC->getAllocator()->getExprLoc(),
5164 diag::warn_omp_allocate_thread_on_task_target_directive)
5165 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5166 }
5167 for (Expr *E : AC->varlists()) {
5168 SourceLocation ELoc;
5169 SourceRange ERange;
5170 Expr *SimpleRefExpr = E;
5171 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5172 ValueDecl *VD = Res.first;
5173 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5174 if (!isOpenMPPrivate(Data.CKind)) {
5175 S.Diag(E->getExprLoc(),
5176 diag::err_omp_expected_private_copy_for_allocate);
5177 continue;
5178 }
5179 VarDecl *PrivateVD = DeclToCopy[VD];
5180 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5181 AllocatorKind, AC->getAllocator()))
5182 continue;
5183 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5184 E->getSourceRange());
5185 }
5186 }
5187}
5188
5189namespace {
5190/// Rewrite statements and expressions for Sema \p Actions CurContext.
5191///
5192/// Used to wrap already parsed statements/expressions into a new CapturedStmt
5193/// context. DeclRefExpr used inside the new context are changed to refer to the
5194/// captured variable instead.
5195class CaptureVars : public TreeTransform<CaptureVars> {
5196 using BaseTransform = TreeTransform<CaptureVars>;
5197
5198public:
5199 CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5200
5201 bool AlwaysRebuild() { return true; }
5202};
5203} // namespace
5204
5205static VarDecl *precomputeExpr(Sema &Actions,
5206 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5207 StringRef Name) {
5208 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5209 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5210 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5211 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5212 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5213 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5214 BodyStmts.push_back(NewDeclStmt);
5215 return NewVar;
5216}
5217
5218/// Create a closure that computes the number of iterations of a loop.
5219///
5220/// \param Actions The Sema object.
5221/// \param LogicalTy Type for the logical iteration number.
5222/// \param Rel Comparison operator of the loop condition.
5223/// \param StartExpr Value of the loop counter at the first iteration.
5224/// \param StopExpr Expression the loop counter is compared against in the loop
5225/// condition. \param StepExpr Amount of increment after each iteration.
5226///
5227/// \return Closure (CapturedStmt) of the distance calculation.
5228static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5229 BinaryOperator::Opcode Rel,
5230 Expr *StartExpr, Expr *StopExpr,
5231 Expr *StepExpr) {
5232 ASTContext &Ctx = Actions.getASTContext();
5233 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5234
5235 // Captured regions currently don't support return values, we use an
5236 // out-parameter instead. All inputs are implicit captures.
5237 // TODO: Instead of capturing each DeclRefExpr occurring in
5238 // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5239 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5240 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5241 {StringRef(), QualType()}};
5242 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5243
5244 Stmt *Body;
5245 {
5246 Sema::CompoundScopeRAII CompoundScope(Actions);
5247 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5248
5249 // Get the LValue expression for the result.
5250 ImplicitParamDecl *DistParam = CS->getParam(0);
5251 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5252 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5253
5254 SmallVector<Stmt *, 4> BodyStmts;
5255
5256 // Capture all referenced variable references.
5257 // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5258 // CapturedStmt, we could compute them before and capture the result, to be
5259 // used jointly with the LoopVar function.
5260 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5261 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5262 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5263 auto BuildVarRef = [&](VarDecl *VD) {
5264 return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5265 };
5266
5267 IntegerLiteral *Zero = IntegerLiteral::Create(
5268 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5269 Expr *Dist;
5270 if (Rel == BO_NE) {
5271 // When using a != comparison, the increment can be +1 or -1. This can be
5272 // dynamic at runtime, so we need to check for the direction.
5273 Expr *IsNegStep = AssertSuccess(
5274 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5275
5276 // Positive increment.
5277 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5278 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5279 ForwardRange = AssertSuccess(
5280 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5281 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5282 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5283
5284 // Negative increment.
5285 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5286 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5287 BackwardRange = AssertSuccess(
5288 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5289 Expr *NegIncAmount = AssertSuccess(
5290 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5291 Expr *BackwardDist = AssertSuccess(
5292 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5293
5294 // Use the appropriate case.
5295 Dist = AssertSuccess(Actions.ActOnConditionalOp(
5296 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5297 } else {
5298 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&(static_cast<void> (0))
5299 "Expected one of these relational operators")(static_cast<void> (0));
5300
5301 // We can derive the direction from any other comparison operator. It is
5302 // non well-formed OpenMP if Step increments/decrements in the other
5303 // directions. Whether at least the first iteration passes the loop
5304 // condition.
5305 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5306 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5307
5308 // Compute the range between first and last counter value.
5309 Expr *Range;
5310 if (Rel == BO_GE || Rel == BO_GT)
5311 Range = AssertSuccess(Actions.BuildBinOp(
5312 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5313 else
5314 Range = AssertSuccess(Actions.BuildBinOp(
5315 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5316
5317 // Ensure unsigned range space.
5318 Range =
5319 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5320
5321 if (Rel == BO_LE || Rel == BO_GE) {
5322 // Add one to the range if the relational operator is inclusive.
5323 Range = AssertSuccess(Actions.BuildBinOp(
5324 nullptr, {}, BO_Add, Range,
5325 Actions.ActOnIntegerConstant(SourceLocation(), 1).get()));
5326 }
5327
5328 // Divide by the absolute step amount.
5329 Expr *Divisor = BuildVarRef(NewStep);
5330 if (Rel == BO_GE || Rel == BO_GT)
5331 Divisor =
5332 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5333 Dist = AssertSuccess(
5334 Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
5335
5336 // If there is not at least one iteration, the range contains garbage. Fix
5337 // to zero in this case.
5338 Dist = AssertSuccess(
5339 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5340 }
5341
5342 // Assign the result to the out-parameter.
5343 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5344 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5345 BodyStmts.push_back(ResultAssign);
5346
5347 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5348 }
5349
5350 return cast<CapturedStmt>(
5351 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5352}
5353
5354/// Create a closure that computes the loop variable from the logical iteration
5355/// number.
5356///
5357/// \param Actions The Sema object.
5358/// \param LoopVarTy Type for the loop variable used for result value.
5359/// \param LogicalTy Type for the logical iteration number.
5360/// \param StartExpr Value of the loop counter at the first iteration.
5361/// \param Step Amount of increment after each iteration.
5362/// \param Deref Whether the loop variable is a dereference of the loop
5363/// counter variable.
5364///
5365/// \return Closure (CapturedStmt) of the loop value calculation.
5366static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5367 QualType LogicalTy,
5368 DeclRefExpr *StartExpr, Expr *Step,
5369 bool Deref) {
5370 ASTContext &Ctx = Actions.getASTContext();
5371
5372 // Pass the result as an out-parameter. Passing as return value would require
5373 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5374 // invoke a copy constructor.
5375 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5376 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5377 {"Logical", LogicalTy},
5378 {StringRef(), QualType()}};
5379 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5380
5381 // Capture the initial iterator which represents the LoopVar value at the
5382 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5383 // it in every iteration, capture it by value before it is modified.
5384 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5385 bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5386 Sema::TryCapture_ExplicitByVal, {});
5387 (void)Invalid;
5388 assert(!Invalid && "Expecting capture-by-value to work.")(static_cast<void> (0));
5389
5390 Expr *Body;
5391 {
5392 Sema::CompoundScopeRAII CompoundScope(Actions);
5393 auto *CS = cast<CapturedDecl>(Actions.CurContext);
5394
5395 ImplicitParamDecl *TargetParam = CS->getParam(0);
5396 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5397 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5398 ImplicitParamDecl *IndvarParam = CS->getParam(1);
5399 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5400 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5401
5402 // Capture the Start expression.
5403 CaptureVars Recap(Actions);
5404 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5405 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5406
5407 Expr *Skip = AssertSuccess(
5408 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5409 // TODO: Explicitly cast to the iterator's difference_type instead of
5410 // relying on implicit conversion.
5411 Expr *Advanced =
5412 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5413
5414 if (Deref) {
5415 // For range-based for-loops convert the loop counter value to a concrete
5416 // loop variable value by dereferencing the iterator.
5417 Advanced =
5418 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5419 }
5420
5421 // Assign the result to the output parameter.
5422 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5423 BO_Assign, TargetRef, Advanced));
5424 }
5425 return cast<CapturedStmt>(
5426 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5427}
5428
5429StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5430 ASTContext &Ctx = getASTContext();
5431
5432 // Extract the common elements of ForStmt and CXXForRangeStmt:
5433 // Loop variable, repeat condition, increment
5434 Expr *Cond, *Inc;
5435 VarDecl *LIVDecl, *LUVDecl;
5436 if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5437 Stmt *Init = For->getInit();
5438 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5439 // For statement declares loop variable.
5440 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5441 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5442 // For statement reuses variable.
5443 assert(LCAssign->getOpcode() == BO_Assign &&(static_cast<void> (0))
5444 "init part must be a loop variable assignment")(static_cast<void> (0));
5445 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5446 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5447 } else
5448 llvm_unreachable("Cannot determine loop variable")__builtin_unreachable();
5449 LUVDecl = LIVDecl;
5450
5451 Cond = For->getCond();
5452 Inc = For->getInc();
5453 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5454 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5455 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5456 LUVDecl = RangeFor->getLoopVariable();
5457
5458 Cond = RangeFor->getCond();
5459 Inc = RangeFor->getInc();
5460 } else
5461 llvm_unreachable("unhandled kind of loop")__builtin_unreachable();
5462
5463 QualType CounterTy = LIVDecl->getType();
5464 QualType LVTy = LUVDecl->getType();
5465
5466 // Analyze the loop condition.
5467 Expr *LHS, *RHS;
5468 BinaryOperator::Opcode CondRel;
5469 Cond = Cond->IgnoreImplicit();
5470 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5471 LHS = CondBinExpr->getLHS();
5472 RHS = CondBinExpr->getRHS();
5473 CondRel = CondBinExpr->getOpcode();
5474 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5475 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands")(static_cast<void> (0));
5476 LHS = CondCXXOp->getArg(0);
5477 RHS = CondCXXOp->getArg(1);
5478 switch (CondCXXOp->getOperator()) {
5479 case OO_ExclaimEqual:
5480 CondRel = BO_NE;
5481 break;
5482 case OO_Less:
5483 CondRel = BO_LT;
5484 break;
5485 case OO_LessEqual:
5486 CondRel = BO_LE;
5487 break;
5488 case OO_Greater:
5489 CondRel = BO_GT;
5490 break;
5491 case OO_GreaterEqual:
5492 CondRel = BO_GE;
5493 break;
5494 default:
5495 llvm_unreachable("unexpected iterator operator")__builtin_unreachable();
5496 }
5497 } else
5498 llvm_unreachable("unexpected loop condition")__builtin_unreachable();
5499
5500 // Normalize such that the loop counter is on the LHS.
5501 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5502 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5503 std::swap(LHS, RHS);
5504 CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5505 }
5506 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5507
5508 // Decide the bit width for the logical iteration counter. By default use the
5509 // unsigned ptrdiff_t integer size (for iterators and pointers).
5510 // TODO: For iterators, use iterator::difference_type,
5511 // std::iterator_traits<>::difference_type or decltype(it - end).
5512 QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5513 if (CounterTy->isIntegerType()) {
5514 unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5515 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5516 }
5517
5518 // Analyze the loop increment.
5519 Expr *Step;
5520 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5521 int Direction;
5522 switch (IncUn->getOpcode()) {
5523 case UO_PreInc:
5524 case UO_PostInc:
5525 Direction = 1;
5526 break;
5527 case UO_PreDec:
5528 case UO_PostDec:
5529 Direction = -1;
5530 break;
5531 default:
5532 llvm_unreachable("unhandled unary increment operator")__builtin_unreachable();
5533 }
5534 Step = IntegerLiteral::Create(
5535 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5536 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5537 if (IncBin->getOpcode() == BO_AddAssign) {
5538 Step = IncBin->getRHS();
5539 } else if (IncBin->getOpcode() == BO_SubAssign) {
5540 Step =
5541 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5542 } else
5543 llvm_unreachable("unhandled binary increment operator")__builtin_unreachable();
5544 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5545 switch (CondCXXOp->getOperator()) {
5546 case OO_PlusPlus:
5547 Step = IntegerLiteral::Create(
5548 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5549 break;
5550 case OO_MinusMinus:
5551 Step = IntegerLiteral::Create(
5552 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5553 break;
5554 case OO_PlusEqual:
5555 Step = CondCXXOp->getArg(1);
5556 break;
5557 case OO_MinusEqual:
5558 Step = AssertSuccess(
5559 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5560 break;
5561 default:
5562 llvm_unreachable("unhandled overloaded increment operator")__builtin_unreachable();
5563 }
5564 } else
5565 llvm_unreachable("unknown increment expression")__builtin_unreachable();
5566
5567 CapturedStmt *DistanceFunc =
5568 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5569 CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5570 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5571 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5572 {}, nullptr, nullptr, {}, nullptr);
5573 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5574 LoopVarFunc, LVRef);
5575}
5576
5577static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5578 CXXScopeSpec &MapperIdScopeSpec,
5579 const DeclarationNameInfo &MapperId,
5580 QualType Type,
5581 Expr *UnresolvedMapper);
5582
5583/// Perform DFS through the structure/class data members trying to find
5584/// member(s) with user-defined 'default' mapper and generate implicit map
5585/// clauses for such members with the found 'default' mapper.
5586static void
5587processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5588 SmallVectorImpl<OMPClause *> &Clauses) {
5589 // Check for the deault mapper for data members.
5590 if (S.getLangOpts().OpenMP < 50)
5591 return;
5592 SmallVector<OMPClause *, 4> ImplicitMaps;
5593 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5594 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5595 if (!C)
5596 continue;
5597 SmallVector<Expr *, 4> SubExprs;
5598 auto *MI = C->mapperlist_begin();
5599 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5600 ++I, ++MI) {
5601 // Expression is mapped using mapper - skip it.
5602 if (*MI)
5603 continue;
5604 Expr *E = *I;
5605 // Expression is dependent - skip it, build the mapper when it gets
5606 // instantiated.
5607 if (E->isTypeDependent() || E->isValueDependent() ||
5608 E->containsUnexpandedParameterPack())
5609 continue;
5610 // Array section - need to check for the mapping of the array section
5611 // element.
5612 QualType CanonType = E->getType().getCanonicalType();
5613 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5614 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5615 QualType BaseType =
5616 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5617 QualType ElemType;
5618 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5619 ElemType = ATy->getElementType();
5620 else
5621 ElemType = BaseType->getPointeeType();
5622 CanonType = ElemType;
5623 }
5624
5625 // DFS over data members in structures/classes.
5626 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5627 1, {CanonType, nullptr});
5628 llvm::DenseMap<const Type *, Expr *> Visited;
5629 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5630 1, {nullptr, 1});
5631 while (!Types.empty()) {
5632 QualType BaseType;
5633 FieldDecl *CurFD;
5634 std::tie(BaseType, CurFD) = Types.pop_back_val();
5635 while (ParentChain.back().second == 0)
5636 ParentChain.pop_back();
5637 --ParentChain.back().second;
5638 if (BaseType.isNull())
5639 continue;
5640 // Only structs/classes are allowed to have mappers.
5641 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5642 if (!RD)
5643 continue;
5644 auto It = Visited.find(BaseType.getTypePtr());
5645 if (It == Visited.end()) {
5646 // Try to find the associated user-defined mapper.
5647 CXXScopeSpec MapperIdScopeSpec;
5648 DeclarationNameInfo DefaultMapperId;
5649 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5650 &S.Context.Idents.get("default")));
5651 DefaultMapperId.setLoc(E->getExprLoc());
5652 ExprResult ER = buildUserDefinedMapperRef(
5653 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5654 BaseType, /*UnresolvedMapper=*/nullptr);
5655 if (ER.isInvalid())
5656 continue;
5657 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5658 }
5659 // Found default mapper.
5660 if (It->second) {
5661 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5662 VK_LValue, OK_Ordinary, E);
5663 OE->setIsUnique(/*V=*/true);
5664 Expr *BaseExpr = OE;
5665 for (const auto &P : ParentChain) {
5666 if (P.first) {
5667 BaseExpr = S.BuildMemberExpr(
5668 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5669 NestedNameSpecifierLoc(), SourceLocation(), P.first,
5670 DeclAccessPair::make(P.first, P.first->getAccess()),
5671 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5672 P.first->getType(), VK_LValue, OK_Ordinary);
5673 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5674 }
5675 }
5676 if (CurFD)
5677 BaseExpr = S.BuildMemberExpr(
5678 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5679 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5680 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5681 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5682 CurFD->getType(), VK_LValue, OK_Ordinary);
5683 SubExprs.push_back(BaseExpr);
5684 continue;
5685 }
5686 // Check for the "default" mapper for data memebers.
5687 bool FirstIter = true;
5688 for (FieldDecl *FD : RD->fields()) {
5689 if (!FD)
5690 continue;
5691 QualType FieldTy = FD->getType();
5692 if (FieldTy.isNull() ||
5693 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5694 continue;
5695 if (FirstIter) {
5696 FirstIter = false;
5697 ParentChain.emplace_back(CurFD, 1);
5698 } else {
5699 ++ParentChain.back().second;
5700 }
5701 Types.emplace_back(FieldTy, FD);
5702 }
5703 }
5704 }
5705 if (SubExprs.empty())
5706 continue;
5707 CXXScopeSpec MapperIdScopeSpec;
5708 DeclarationNameInfo MapperId;
5709 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5710 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5711 MapperIdScopeSpec, MapperId, C->getMapType(),
5712 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5713 SubExprs, OMPVarListLocTy()))
5714 Clauses.push_back(NewClause);
5715 }
5716}
5717
5718StmtResult Sema::ActOnOpenMPExecutableDirective(
5719 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5720 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5721 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5722 StmtResult Res = StmtError();
5723 // First check CancelRegion which is then used in checkNestingOfRegions.
5724 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5725 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5726 StartLoc))
5727 return StmtError();
5728
5729 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5730 VarsWithInheritedDSAType VarsWithInheritedDSA;
5731 bool ErrorFound = false;
5732 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5733 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5734 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5735 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5736 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
5737
5738 // Check default data sharing attributes for referenced variables.
5739 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5740 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5741 Stmt *S = AStmt;
5742 while (--ThisCaptureLevel >= 0)
5743 S = cast<CapturedStmt>(S)->getCapturedStmt();
5744 DSAChecker.Visit(S);
5745 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5746 !isOpenMPTaskingDirective(Kind)) {
5747 // Visit subcaptures to generate implicit clauses for captured vars.
5748 auto *CS = cast<CapturedStmt>(AStmt);
5749 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5750 getOpenMPCaptureRegions(CaptureRegions, Kind);
5751 // Ignore outer tasking regions for target directives.
5752 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5753 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5754 DSAChecker.visitSubCaptures(CS);
5755 }
5756 if (DSAChecker.isErrorFound())
5757 return StmtError();
5758 // Generate list of implicitly defined firstprivate variables.
5759 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5760
5761 SmallVector<Expr *, 4> ImplicitFirstprivates(
5762 DSAChecker.getImplicitFirstprivate().begin(),
5763 DSAChecker.getImplicitFirstprivate().end());
5764 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5765 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5766 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5767 ImplicitMapModifiers[DefaultmapKindNum];
5768 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5769 ImplicitMapModifiersLoc[DefaultmapKindNum];
5770 // Get the original location of present modifier from Defaultmap clause.
5771 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5772 for (OMPClause *C : Clauses) {
5773 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5774 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5775 PresentModifierLocs[DMC->getDefaultmapKind()] =
5776 DMC->getDefaultmapModifierLoc();
5777 }
5778 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5779 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5780 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5781 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5782 Kind, static_cast<OpenMPMapClauseKind>(I));
5783 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5784 }
5785 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5786 DSAChecker.getImplicitMapModifier(Kind);
5787 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5788 ImplicitModifier.end());
5789 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5790 ImplicitModifier.size(), PresentModifierLocs[VC]);
5791 }
5792 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5793 for (OMPClause *C : Clauses) {
5794 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5795 for (Expr *E : IRC->taskgroup_descriptors())
5796 if (E)
5797 ImplicitFirstprivates.emplace_back(E);
5798 }
5799 // OpenMP 5.0, 2.10.1 task Construct
5800 // [detach clause]... The event-handle will be considered as if it was
5801 // specified on a firstprivate clause.
5802 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5803 ImplicitFirstprivates.push_back(DC->getEventHandler());
5804 }
5805 if (!ImplicitFirstprivates.empty()) {
5806 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5807 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5808 SourceLocation())) {
5809 ClausesWithImplicit.push_back(Implicit);
5810 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5811 ImplicitFirstprivates.size();
5812 } else {
5813 ErrorFound = true;
5814 }
5815 }
5816 // OpenMP 5.0 [2.19.7]
5817 // If a list item appears in a reduction, lastprivate or linear
5818 // clause on a combined target construct then it is treated as
5819 // if it also appears in a map clause with a map-type of tofrom
5820 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
5821 isOpenMPTargetExecutionDirective(Kind)) {
5822 SmallVector<Expr *, 4> ImplicitExprs;
5823 for (OMPClause *C : Clauses) {
5824 if (auto *RC = dyn_cast<OMPReductionClause>(C))
5825 for (Expr *E : RC->varlists())
5826 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
5827 ImplicitExprs.emplace_back(E);
5828 }
5829 if (!ImplicitExprs.empty()) {
5830 ArrayRef<Expr *> Exprs = ImplicitExprs;
5831 CXXScopeSpec MapperIdScopeSpec;
5832 DeclarationNameInfo MapperId;
5833 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5834 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
5835 MapperId, OMPC_MAP_tofrom,
5836 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5837 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
5838 ClausesWithImplicit.emplace_back(Implicit);
5839 }
5840 }
5841 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5842 int ClauseKindCnt = -1;
5843 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5844 ++ClauseKindCnt;
5845 if (ImplicitMap.empty())
5846 continue;
5847 CXXScopeSpec MapperIdScopeSpec;
5848 DeclarationNameInfo MapperId;
5849 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5850 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5851 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5852 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5853 SourceLocation(), SourceLocation(), ImplicitMap,
5854 OMPVarListLocTy())) {
5855 ClausesWithImplicit.emplace_back(Implicit);
5856 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5857 ImplicitMap.size();
5858 } else {
5859 ErrorFound = true;
5860 }
5861 }
5862 }
5863 // Build expressions for implicit maps of data members with 'default'
5864 // mappers.
5865 if (LangOpts.OpenMP >= 50)
5866 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5867 ClausesWithImplicit);
5868 }
5869
5870 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5871 switch (Kind) {
5872 case OMPD_parallel:
5873 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5874 EndLoc);
5875 AllowedNameModifiers.push_back(OMPD_parallel);
5876 break;
5877 case OMPD_simd:
5878 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5879 VarsWithInheritedDSA);
5880 if (LangOpts.OpenMP >= 50)
5881 AllowedNameModifiers.push_back(OMPD_simd);
5882 break;
5883 case OMPD_tile:
5884 Res =
5885 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5886 break;
5887 case OMPD_unroll:
5888 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
5889 EndLoc);
5890 break;
5891 case OMPD_for:
5892 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5893 VarsWithInheritedDSA);
5894 break;
5895 case OMPD_for_simd:
5896 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5897 EndLoc, VarsWithInheritedDSA);
5898 if (LangOpts.OpenMP >= 50)
5899 AllowedNameModifiers.push_back(OMPD_simd);
5900 break;
5901 case OMPD_sections:
5902 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5903 EndLoc);
5904 break;
5905 case OMPD_section:
5906 assert(ClausesWithImplicit.empty() &&(static_cast<void> (0))
5907 "No clauses are allowed for 'omp section' directive")(static_cast<void> (0));
5908 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5909 break;
5910 case OMPD_single:
5911 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5912 EndLoc);
5913 break;
5914 case OMPD_master:
5915 assert(ClausesWithImplicit.empty() &&(static_cast<void> (0))
5916 "No clauses are allowed for 'omp master' directive")(static_cast<void> (0));
5917 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5918 break;
5919 case OMPD_masked:
5920 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
5921 EndLoc);
5922 break;
5923 case OMPD_critical:
5924 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5925 StartLoc, EndLoc);
5926 break;
5927 case OMPD_parallel_for:
5928 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5929 EndLoc, VarsWithInheritedDSA);
5930 AllowedNameModifiers.push_back(OMPD_parallel);
5931 break;
5932 case OMPD_parallel_for_simd:
5933 Res = ActOnOpenMPParallelForSimdDirective(
5934 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5935 AllowedNameModifiers.push_back(OMPD_parallel);
5936 if (LangOpts.OpenMP >= 50)
5937 AllowedNameModifiers.push_back(OMPD_simd);
5938 break;
5939 case OMPD_parallel_master:
5940 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5941 StartLoc, EndLoc);
5942 AllowedNameModifiers.push_back(OMPD_parallel);
5943 break;
5944 case OMPD_parallel_sections:
5945 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5946 StartLoc, EndLoc);
5947 AllowedNameModifiers.push_back(OMPD_parallel);
5948 break;
5949 case OMPD_task:
5950 Res =
5951 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5952 AllowedNameModifiers.push_back(OMPD_task);
5953 break;
5954 case OMPD_taskyield:
5955 assert(ClausesWithImplicit.empty() &&(static_cast<void> (0))
5956 "No clauses are allowed for 'omp taskyield' directive")(static_cast<void> (0));
5957 assert(AStmt == nullptr &&(static_cast<void> (0))
5958 "No associated statement allowed for 'omp taskyield' directive")(static_cast<void> (0));
5959 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5960 break;
5961 case OMPD_barrier:
5962 assert(ClausesWithImplicit.empty() &&(static_cast<void> (0))
5963 "No clauses are allowed for 'omp barrier' directive")(static_cast<void> (0));
5964 assert(AStmt == nullptr &&(static_cast<void> (0))
5965 "No associated statement allowed for 'omp barrier' directive")(static_cast<void> (0));
5966 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5967 break;
5968 case OMPD_taskwait:
5969 assert(ClausesWithImplicit.empty() &&(static_cast<void> (0))
5970 "No clauses are allowed for 'omp taskwait' directive")(static_cast<void> (0));
5971 assert(AStmt == nullptr &&(static_cast<void> (0))
5972 "No associated statement allowed for 'omp taskwait' directive")(static_cast<void> (0));
5973 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5974 break;
5975 case OMPD_taskgroup:
5976 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5977 EndLoc);
5978 break;
5979 case OMPD_flush:
5980 assert(AStmt == nullptr &&(static_cast<void> (0))
5981 "No associated statement allowed for 'omp flush' directive")(static_cast<void> (0));
5982 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5983 break;
5984 case OMPD_depobj:
5985 assert(AStmt == nullptr &&(static_cast<void> (0))
5986 "No associated statement allowed for 'omp depobj' directive")(static_cast<void> (0));
5987 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5988 break;
5989 case OMPD_scan:
5990 assert(AStmt == nullptr &&(static_cast<void> (0))
5991 "No associated statement allowed for 'omp scan' directive")(static_cast<void> (0));
5992 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5993 break;
5994 case OMPD_ordered:
5995 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5996 EndLoc);
5997 break;
5998 case OMPD_atomic:
5999 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6000 EndLoc);
6001 break;
6002 case OMPD_teams:
6003 Res =
6004 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6005 break;
6006 case OMPD_target:
6007 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6008 EndLoc);
6009 AllowedNameModifiers.push_back(OMPD_target);
6010 break;
6011 case OMPD_target_parallel:
6012 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6013 StartLoc, EndLoc);
6014 AllowedNameModifiers.push_back(OMPD_target);
6015 AllowedNameModifiers.push_back(OMPD_parallel);
6016 break;
6017 case OMPD_target_parallel_for:
6018 Res = ActOnOpenMPTargetParallelForDirective(
6019 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6020 AllowedNameModifiers.push_back(OMPD_target);
6021 AllowedNameModifiers.push_back(OMPD_parallel);
6022 break;
6023 case OMPD_cancellation_point:
6024 assert(ClausesWithImplicit.empty() &&(static_cast<void> (0))
6025 "No clauses are allowed for 'omp cancellation point' directive")(static_cast<void> (0));
6026 assert(AStmt == nullptr && "No associated statement allowed for 'omp "(static_cast<void> (0))
6027 "cancellation point' directive")(static_cast<void> (0));
6028 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6029 break;
6030 case OMPD_cancel:
6031 assert(AStmt == nullptr &&(static_cast<void> (0))
6032 "No associated statement allowed for 'omp cancel' directive")(static_cast<void> (0));
6033 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6034 CancelRegion);
6035 AllowedNameModifiers.push_back(OMPD_cancel);
6036 break;
6037 case OMPD_target_data:
6038 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6039 EndLoc);
6040 AllowedNameModifiers.push_back(OMPD_target_data);
6041 break;
6042 case OMPD_target_enter_data:
6043 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6044 EndLoc, AStmt);
6045 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6046 break;
6047 case OMPD_target_exit_data:
6048 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6049 EndLoc, AStmt);
6050 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6051 break;
6052 case OMPD_taskloop:
6053 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6054 EndLoc, VarsWithInheritedDSA);
6055 AllowedNameModifiers.push_back(OMPD_taskloop);
6056 break;
6057 case OMPD_taskloop_simd:
6058 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6059 EndLoc, VarsWithInheritedDSA);
6060 AllowedNameModifiers.push_back(OMPD_taskloop);
6061 if (LangOpts.OpenMP >= 50)
6062 AllowedNameModifiers.push_back(OMPD_simd);
6063 break;
6064 case OMPD_master_taskloop:
6065 Res = ActOnOpenMPMasterTaskLoopDirective(
6066 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6067 AllowedNameModifiers.push_back(OMPD_taskloop);
6068 break;
6069 case OMPD_master_taskloop_simd:
6070 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6071 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6072 AllowedNameModifiers.push_back(OMPD_taskloop);
6073 if (LangOpts.OpenMP >= 50)
6074 AllowedNameModifiers.push_back(OMPD_simd);
6075 break;
6076 case OMPD_parallel_master_taskloop:
6077 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6078 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6079 AllowedNameModifiers.push_back(OMPD_taskloop);
6080 AllowedNameModifiers.push_back(OMPD_parallel);
6081 break;
6082 case OMPD_parallel_master_taskloop_simd:
6083 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6084 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6085 AllowedNameModifiers.push_back(OMPD_taskloop);
6086 AllowedNameModifiers.push_back(OMPD_parallel);
6087 if (LangOpts.OpenMP >= 50)
6088 AllowedNameModifiers.push_back(OMPD_simd);
6089 break;
6090 case OMPD_distribute:
6091 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6092 EndLoc, VarsWithInheritedDSA);
6093 break;
6094 case OMPD_target_update:
6095 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6096 EndLoc, AStmt);
6097 AllowedNameModifiers.push_back(OMPD_target_update);
6098 break;
6099 case OMPD_distribute_parallel_for:
6100 Res = ActOnOpenMPDistributeParallelForDirective(
6101 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6102 AllowedNameModifiers.push_back(OMPD_parallel);
6103 break;
6104 case OMPD_distribute_parallel_for_simd:
6105 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6106 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6107 AllowedNameModifiers.push_back(OMPD_parallel);
6108 if (LangOpts.OpenMP >= 50)
6109 AllowedNameModifiers.push_back(OMPD_simd);
6110 break;
6111 case OMPD_distribute_simd:
6112 Res = ActOnOpenMPDistributeSimdDirective(
6113 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6114 if (LangOpts.OpenMP >= 50)
6115 AllowedNameModifiers.push_back(OMPD_simd);
6116 break;
6117 case OMPD_target_parallel_for_simd:
6118 Res = ActOnOpenMPTargetParallelForSimdDirective(
6119 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6120 AllowedNameModifiers.push_back(OMPD_target);
6121 AllowedNameModifiers.push_back(OMPD_parallel);
6122 if (LangOpts.OpenMP >= 50)
6123 AllowedNameModifiers.push_back(OMPD_simd);
6124 break;
6125 case OMPD_target_simd:
6126 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6127 EndLoc, VarsWithInheritedDSA);
6128 AllowedNameModifiers.push_back(OMPD_target);
6129 if (LangOpts.OpenMP >= 50)
6130 AllowedNameModifiers.push_back(OMPD_simd);
6131 break;
6132 case OMPD_teams_distribute:
6133 Res = ActOnOpenMPTeamsDistributeDirective(
6134 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6135 break;
6136 case OMPD_teams_distribute_simd:
6137 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6138 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6139 if (LangOpts.OpenMP >= 50)
6140 AllowedNameModifiers.push_back(OMPD_simd);
6141 break;
6142 case OMPD_teams_distribute_parallel_for_simd:
6143 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6144 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6145 AllowedNameModifiers.push_back(OMPD_parallel);
6146 if (LangOpts.OpenMP >= 50)
6147 AllowedNameModifiers.push_back(OMPD_simd);
6148 break;
6149 case OMPD_teams_distribute_parallel_for:
6150 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6151 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6152 AllowedNameModifiers.push_back(OMPD_parallel);
6153 break;
6154 case OMPD_target_teams:
6155 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6156 EndLoc);
6157 AllowedNameModifiers.push_back(OMPD_target);
6158 break;
6159 case OMPD_target_teams_distribute:
6160 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6161 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6162 AllowedNameModifiers.push_back(OMPD_target);
6163 break;
6164 case OMPD_target_teams_distribute_parallel_for:
6165 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6166 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6167 AllowedNameModifiers.push_back(OMPD_target);
6168 AllowedNameModifiers.push_back(OMPD_parallel);
6169 break;
6170 case OMPD_target_teams_distribute_parallel_for_simd:
6171 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6172 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6173 AllowedNameModifiers.push_back(OMPD_target);
6174 AllowedNameModifiers.push_back(OMPD_parallel);
6175 if (LangOpts.OpenMP >= 50)
6176 AllowedNameModifiers.push_back(OMPD_simd);
6177 break;
6178 case OMPD_target_teams_distribute_simd:
6179 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6180 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6181 AllowedNameModifiers.push_back(OMPD_target);
6182 if (LangOpts.OpenMP >= 50)
6183 AllowedNameModifiers.push_back(OMPD_simd);
6184 break;
6185 case OMPD_interop:
6186 assert(AStmt == nullptr &&(static_cast<void> (0))
6187 "No associated statement allowed for 'omp interop' directive")(static_cast<void> (0));
6188 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6189 break;
6190 case OMPD_dispatch:
6191 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6192 EndLoc);
6193 break;
6194 case OMPD_declare_target:
6195 case OMPD_end_declare_target:
6196 case OMPD_threadprivate:
6197 case OMPD_allocate:
6198 case OMPD_declare_reduction:
6199 case OMPD_declare_mapper:
6200 case OMPD_declare_simd:
6201 case OMPD_requires:
6202 case OMPD_declare_variant:
6203 case OMPD_begin_declare_variant:
6204 case OMPD_end_declare_variant:
6205 llvm_unreachable("OpenMP Directive is not allowed")__builtin_unreachable();
6206 case OMPD_unknown:
6207 default:
6208 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
6209 }
6210
6211 ErrorFound = Res.isInvalid() || ErrorFound;
6212
6213 // Check variables in the clauses if default(none) or
6214 // default(firstprivate) was specified.
6215 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6216 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6217 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
6218 for (OMPClause *C : Clauses) {
6219 switch (C->getClauseKind()) {
6220 case OMPC_num_threads:
6221 case OMPC_dist_schedule:
6222 // Do not analyse if no parent teams directive.
6223 if (isOpenMPTeamsDirective(Kind))
6224 break;
6225 continue;
6226 case OMPC_if:
6227 if (isOpenMPTeamsDirective(Kind) &&
6228 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6229 break;
6230 if (isOpenMPParallelDirective(Kind) &&
6231 isOpenMPTaskLoopDirective(Kind) &&
6232 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6233 break;
6234 continue;
6235 case OMPC_schedule:
6236 case OMPC_detach:
6237 break;
6238 case OMPC_grainsize:
6239 case OMPC_num_tasks:
6240 case OMPC_final:
6241 case OMPC_priority:
6242 case OMPC_novariants:
6243 case OMPC_nocontext:
6244 // Do not analyze if no parent parallel directive.
6245 if (isOpenMPParallelDirective(Kind))
6246 break;
6247 continue;
6248 case OMPC_ordered:
6249 case OMPC_device:
6250 case OMPC_num_teams:
6251 case OMPC_thread_limit:
6252 case OMPC_hint:
6253 case OMPC_collapse:
6254 case OMPC_safelen:
6255 case OMPC_simdlen:
6256 case OMPC_sizes:
6257 case OMPC_default:
6258 case OMPC_proc_bind:
6259 case OMPC_private:
6260 case OMPC_firstprivate:
6261 case OMPC_lastprivate:
6262 case OMPC_shared:
6263 case OMPC_reduction:
6264 case OMPC_task_reduction:
6265 case OMPC_in_reduction:
6266 case OMPC_linear:
6267 case OMPC_aligned:
6268 case OMPC_copyin:
6269 case OMPC_copyprivate:
6270 case OMPC_nowait:
6271 case OMPC_untied:
6272 case OMPC_mergeable:
6273 case OMPC_allocate:
6274 case OMPC_read:
6275 case OMPC_write:
6276 case OMPC_update:
6277 case OMPC_capture:
6278 case OMPC_seq_cst:
6279 case OMPC_acq_rel:
6280 case OMPC_acquire:
6281 case OMPC_release:
6282 case OMPC_relaxed:
6283 case OMPC_depend:
6284 case OMPC_threads:
6285 case OMPC_simd:
6286 case OMPC_map:
6287 case OMPC_nogroup:
6288 case OMPC_defaultmap:
6289 case OMPC_to:
6290 case OMPC_from:
6291 case OMPC_use_device_ptr:
6292 case OMPC_use_device_addr:
6293 case OMPC_is_device_ptr:
6294 case OMPC_nontemporal:
6295 case OMPC_order:
6296 case OMPC_destroy:
6297 case OMPC_inclusive:
6298 case OMPC_exclusive:
6299 case OMPC_uses_allocators:
6300 case OMPC_affinity:
6301 continue;
6302 case OMPC_allocator:
6303 case OMPC_flush:
6304 case OMPC_depobj:
6305 case OMPC_threadprivate:
6306 case OMPC_uniform:
6307 case OMPC_unknown:
6308 case OMPC_unified_address:
6309 case OMPC_unified_shared_memory:
6310 case OMPC_reverse_offload:
6311 case OMPC_dynamic_allocators:
6312 case OMPC_atomic_default_mem_order:
6313 case OMPC_device_type:
6314 case OMPC_match:
6315 default:
6316 llvm_unreachable("Unexpected clause")__builtin_unreachable();
6317 }
6318 for (Stmt *CC : C->children()) {
6319 if (CC)
6320 DSAChecker.Visit(CC);
6321 }
6322 }
6323 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6324 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6325 }
6326 for (const auto &P : VarsWithInheritedDSA) {
6327 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6328 continue;
6329 ErrorFound = true;
6330 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6331 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6332 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6333 << P.first << P.second->getSourceRange();
6334 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6335 } else if (getLangOpts().OpenMP >= 50) {
6336 Diag(P.second->getExprLoc(),
6337 diag::err_omp_defaultmap_no_attr_for_variable)
6338 << P.first << P.second->getSourceRange();
6339 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
6340 diag::note_omp_defaultmap_attr_none);
6341 }
6342 }
6343
6344 if (!AllowedNameModifiers.empty())
6345 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6346 ErrorFound;
6347
6348 if (ErrorFound)
6349 return StmtError();
6350
6351 if (!CurContext->isDependentContext() &&
6352 isOpenMPTargetExecutionDirective(Kind) &&
6353 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6354 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6355 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6356 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6357 // Register target to DSA Stack.
6358 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
6359 }
6360
6361 return Res;
6362}
6363
6364Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6365 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6366 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6367 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6368 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6369 assert(Aligneds.size() == Alignments.size())(static_cast<void> (0));
6370 assert(Linears.size() == LinModifiers.size())(static_cast<void> (0));
6371 assert(Linears.size() == Steps.size())(static_cast<void> (0));
6372 if (!DG || DG.get().isNull())
6373 return DeclGroupPtrTy();
6374
6375 const int SimdId = 0;
6376 if (!DG.get().isSingleDecl()) {
6377 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6378 << SimdId;
6379 return DG;
6380 }
6381 Decl *ADecl = DG.get().getSingleDecl();
6382 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6383 ADecl = FTD->getTemplatedDecl();
6384
6385 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6386 if (!FD) {
6387 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6388 return DeclGroupPtrTy();
6389 }
6390
6391 // OpenMP [2.8.2, declare simd construct, Description]
6392 // The parameter of the simdlen clause must be a constant positive integer
6393 // expression.
6394 ExprResult SL;
6395 if (Simdlen)
6396 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6397 // OpenMP [2.8.2, declare simd construct, Description]
6398 // The special this pointer can be used as if was one of the arguments to the
6399 // function in any of the linear, aligned, or uniform clauses.
6400 // The uniform clause declares one or more arguments to have an invariant
6401 // value for all concurrent invocations of the function in the execution of a
6402 // single SIMD loop.
6403 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6404 const Expr *UniformedLinearThis = nullptr;
6405 for (const Expr *E : Uniforms) {
6406 E = E->IgnoreParenImpCasts();
6407 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6408 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6409 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6410 FD->getParamDecl(PVD->getFunctionScopeIndex())
6411 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6412 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6413 continue;
6414 }
6415 if (isa<CXXThisExpr>(E)) {
6416 UniformedLinearThis = E;
6417 continue;
6418 }
6419 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6420 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6421 }
6422 // OpenMP [2.8.2, declare simd construct, Description]
6423 // The aligned clause declares that the object to which each list item points
6424 // is aligned to the number of bytes expressed in the optional parameter of
6425 // the aligned clause.
6426 // The special this pointer can be used as if was one of the arguments to the
6427 // function in any of the linear, aligned, or uniform clauses.
6428 // The type of list items appearing in the aligned clause must be array,
6429 // pointer, reference to array, or reference to pointer.
6430 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6431 const Expr *AlignedThis = nullptr;
6432 for (const Expr *E : Aligneds) {
6433 E = E->IgnoreParenImpCasts();
6434 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6435 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6436 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6437 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6438 FD->getParamDecl(PVD->getFunctionScopeIndex())
6439 ->getCanonicalDecl() == CanonPVD) {
6440 // OpenMP [2.8.1, simd construct, Restrictions]
6441 // A list-item cannot appear in more than one aligned clause.
6442 if (AlignedArgs.count(CanonPVD) > 0) {
6443 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6444 << 1 << getOpenMPClauseName(OMPC_aligned)
6445 << E->getSourceRange();
6446 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6447 diag::note_omp_explicit_dsa)
6448 << getOpenMPClauseName(OMPC_aligned);
6449 continue;
6450 }
6451 AlignedArgs[CanonPVD] = E;
6452 QualType QTy = PVD->getType()
6453 .getNonReferenceType()
6454 .getUnqualifiedType()
6455 .getCanonicalType();
6456 const Type *Ty = QTy.getTypePtrOrNull();
6457 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6458 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6459 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6460 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6461 }
6462 continue;
6463 }
6464 }
6465 if (isa<CXXThisExpr>(E)) {
6466 if (AlignedThis) {
6467 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6468 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6469 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6470 << getOpenMPClauseName(OMPC_aligned);
6471 }
6472 AlignedThis = E;
6473 continue;
6474 }
6475 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6476 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6477 }
6478 // The optional parameter of the aligned clause, alignment, must be a constant
6479 // positive integer expression. If no optional parameter is specified,
6480 // implementation-defined default alignments for SIMD instructions on the
6481 // target platforms are assumed.
6482 SmallVector<const Expr *, 4> NewAligns;
6483 for (Expr *E : Alignments) {
6484 ExprResult Align;
6485 if (E)
6486 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6487 NewAligns.push_back(Align.get());
6488 }
6489 // OpenMP [2.8.2, declare simd construct, Description]
6490 // The linear clause declares one or more list items to be private to a SIMD
6491 // lane and to have a linear relationship with respect to the iteration space
6492 // of a loop.
6493 // The special this pointer can be used as if was one of the arguments to the
6494 // function in any of the linear, aligned, or uniform clauses.
6495 // When a linear-step expression is specified in a linear clause it must be
6496 // either a constant integer expression or an integer-typed parameter that is
6497 // specified in a uniform clause on the directive.
6498 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6499 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6500 auto MI = LinModifiers.begin();
6501 for (const Expr *E : Linears) {
6502 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6503 ++MI;
6504 E = E->IgnoreParenImpCasts();
6505 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6506 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6507 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6508 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6509 FD->getParamDecl(PVD->getFunctionScopeIndex())
6510 ->getCanonicalDecl() == CanonPVD) {
6511 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6512 // A list-item cannot appear in more than one linear clause.
6513 if (LinearArgs.count(CanonPVD) > 0) {
6514 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6515 << getOpenMPClauseName(OMPC_linear)
6516 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6517 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6518 diag::note_omp_explicit_dsa)
6519 << getOpenMPClauseName(OMPC_linear);
6520 continue;
6521 }
6522 // Each argument can appear in at most one uniform or linear clause.
6523 if (UniformedArgs.count(CanonPVD) > 0) {
6524 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6525 << getOpenMPClauseName(OMPC_linear)
6526 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6527 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6528 diag::note_omp_explicit_dsa)
6529 << getOpenMPClauseName(OMPC_uniform);
6530 continue;
6531 }
6532 LinearArgs[CanonPVD] = E;
6533 if (E->isValueDependent() || E->isTypeDependent() ||
6534 E->isInstantiationDependent() ||
6535 E->containsUnexpandedParameterPack())
6536 continue;
6537 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6538 PVD->getOriginalType(),
6539 /*IsDeclareSimd=*/true);
6540 continue;
6541 }
6542 }
6543 if (isa<CXXThisExpr>(E)) {
6544 if (UniformedLinearThis) {
6545 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6546 << getOpenMPClauseName(OMPC_linear)
6547 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6548 << E->getSourceRange();
6549 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6550 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6551 : OMPC_linear);
6552 continue;
6553 }
6554 UniformedLinearThis = E;
6555 if (E->isValueDependent() || E->isTypeDependent() ||
6556 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6557 continue;
6558 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6559 E->getType(), /*IsDeclareSimd=*/true);
6560 continue;
6561 }
6562 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6563 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6564 }
6565 Expr *Step = nullptr;
6566 Expr *NewStep = nullptr;
6567 SmallVector<Expr *, 4> NewSteps;
6568 for (Expr *E : Steps) {
6569 // Skip the same step expression, it was checked already.
6570 if (Step == E || !E) {
6571 NewSteps.push_back(E ? NewStep : nullptr);
6572 continue;
6573 }
6574 Step = E;
6575 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6576 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6577 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6578 if (UniformedArgs.count(CanonPVD) == 0) {
6579 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6580 << Step->getSourceRange();
6581 } else if (E->isValueDependent() || E->isTypeDependent() ||
6582 E->isInstantiationDependent() ||
6583 E->containsUnexpandedParameterPack() ||
6584 CanonPVD->getType()->hasIntegerRepresentation()) {
6585 NewSteps.push_back(Step);
6586 } else {
6587 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6588 << Step->getSourceRange();
6589 }
6590 continue;
6591 }
6592 NewStep = Step;
6593 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6594 !Step->isInstantiationDependent() &&
6595 !Step->containsUnexpandedParameterPack()) {
6596 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6597 .get();
6598 if (NewStep)
6599 NewStep =
6600 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6601 }
6602 NewSteps.push_back(NewStep);
6603 }
6604 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6605 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6606 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6607 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6608 const_cast<Expr **>(Linears.data()), Linears.size(),
6609 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6610 NewSteps.data(), NewSteps.size(), SR);
6611 ADecl->addAttr(NewAttr);
6612 return DG;
6613}
6614
6615static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6616 QualType NewType) {
6617 assert(NewType->isFunctionProtoType() &&(static_cast<void> (0))
6618 "Expected function type with prototype.")(static_cast<void> (0));
6619 assert(FD->getType()->isFunctionNoProtoType() &&(static_cast<void> (0))
6620 "Expected function with type with no prototype.")(static_cast<void> (0));
6621 assert(FDWithProto->getType()->isFunctionProtoType() &&(static_cast<void> (0))
6622 "Expected function with prototype.")(static_cast<void> (0));
6623 // Synthesize parameters with the same types.
6624 FD->setType(NewType);
6625 SmallVector<ParmVarDecl *, 16> Params;
6626 for (const ParmVarDecl *P : FDWithProto->parameters()) {
6627 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6628 SourceLocation(), nullptr, P->getType(),
6629 /*TInfo=*/nullptr, SC_None, nullptr);
6630 Param->setScopeInfo(0, Params.size());
6631 Param->setImplicit();
6632 Params.push_back(Param);
6633 }
6634
6635 FD->setParams(Params);
6636}
6637
6638void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6639 if (D->isInvalidDecl())
6640 return;
6641 FunctionDecl *FD = nullptr;
6642 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6643 FD = UTemplDecl->getTemplatedDecl();
6644 else
6645 FD = cast<FunctionDecl>(D);
6646 assert(FD && "Expected a function declaration!")(static_cast<void> (0));
6647
6648 // If we are intantiating templates we do *not* apply scoped assumptions but
6649 // only global ones. We apply scoped assumption to the template definition
6650 // though.
6651 if (!inTemplateInstantiation()) {
6652 for (AssumptionAttr *AA : OMPAssumeScoped)
6653 FD->addAttr(AA);
6654 }
6655 for (AssumptionAttr *AA : OMPAssumeGlobal)
6656 FD->addAttr(AA);
6657}
6658
6659Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6660 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6661
6662void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6663 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6664 SmallVectorImpl<FunctionDecl *> &Bases) {
6665 if (!D.getIdentifier())
6666 return;
6667
6668 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6669
6670 // Template specialization is an extension, check if we do it.
6671 bool IsTemplated = !TemplateParamLists.empty();
6672 if (IsTemplated &
6673 !DVScope.TI->isExtensionActive(
6674 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6675 return;
6676
6677 IdentifierInfo *BaseII = D.getIdentifier();
6678 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6679 LookupOrdinaryName);
6680 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6681
6682 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6683 QualType FType = TInfo->getType();
6684
6685 bool IsConstexpr =
6686 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6687 bool IsConsteval =
6688 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6689
6690 for (auto *Candidate : Lookup) {
6691 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6692 FunctionDecl *UDecl = nullptr;
6693 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6694 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6695 else if (!IsTemplated)
6696 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6697 if (!UDecl)
6698 continue;
6699
6700 // Don't specialize constexpr/consteval functions with
6701 // non-constexpr/consteval functions.
6702 if (UDecl->isConstexpr() && !IsConstexpr)
6703 continue;
6704 if (UDecl->isConsteval() && !IsConsteval)
6705 continue;
6706
6707 QualType UDeclTy = UDecl->getType();
6708 if (!UDeclTy->isDependentType()) {
6709 QualType NewType = Context.mergeFunctionTypes(
6710 FType, UDeclTy, /* OfBlockPointer */ false,
6711 /* Unqualified */ false, /* AllowCXX */ true);
6712 if (NewType.isNull())
6713 continue;
6714 }
6715
6716 // Found a base!
6717 Bases.push_back(UDecl);
6718 }
6719
6720 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6721 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6722 // If no base was found we create a declaration that we use as base.
6723 if (Bases.empty() && UseImplicitBase) {
6724 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6725 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6726 BaseD->setImplicit(true);
6727 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6728 Bases.push_back(BaseTemplD->getTemplatedDecl());
6729 else
6730 Bases.push_back(cast<FunctionDecl>(BaseD));
6731 }
6732
6733 std::string MangledName;
6734 MangledName += D.getIdentifier()->getName();
6735 MangledName += getOpenMPVariantManglingSeparatorStr();
6736 MangledName += DVScope.NameSuffix;
6737 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6738
6739 VariantII.setMangledOpenMPVariantName(true);
6740 D.SetIdentifier(&VariantII, D.getBeginLoc());
6741}
6742
6743void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6744 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6745 // Do not mark function as is used to prevent its emission if this is the
6746 // only place where it is used.
6747 EnterExpressionEvaluationContext Unevaluated(
6748 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6749
6750 FunctionDecl *FD = nullptr;
6751 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6752 FD = UTemplDecl->getTemplatedDecl();
6753 else
6754 FD = cast<FunctionDecl>(D);
6755 auto *VariantFuncRef = DeclRefExpr::Create(
6756 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6757 /* RefersToEnclosingVariableOrCapture */ false,
6758 /* NameLoc */ FD->getLocation(), FD->getType(),
6759 ExprValueKind::VK_PRValue);
6760
6761 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6762 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6763 Context, VariantFuncRef, DVScope.TI);
6764 for (FunctionDecl *BaseFD : Bases)
6765 BaseFD->addAttr(OMPDeclareVariantA);
6766}
6767
6768ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6769 SourceLocation LParenLoc,
6770 MultiExprArg ArgExprs,
6771 SourceLocation RParenLoc, Expr *ExecConfig) {
6772 // The common case is a regular call we do not want to specialize at all. Try
6773 // to make that case fast by bailing early.
6774 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6775 if (!CE)
6776 return Call;
6777
6778 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6779 if (!CalleeFnDecl)
6780 return Call;
6781
6782 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6783 return Call;
6784
6785 ASTContext &Context = getASTContext();
6786 std::function<void(StringRef)> DiagUnknownTrait = [this,
6787 CE](StringRef ISATrait) {
6788 // TODO Track the selector locations in a way that is accessible here to
6789 // improve the diagnostic location.
6790 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6791 << ISATrait;
6792 };
6793 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6794 getCurFunctionDecl());
6795
6796 QualType CalleeFnType = CalleeFnDecl->getType();
6797
6798 SmallVector<Expr *, 4> Exprs;
6799 SmallVector<VariantMatchInfo, 4> VMIs;
6800 while (CalleeFnDecl) {
6801 for (OMPDeclareVariantAttr *A :
6802 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6803 Expr *VariantRef = A->getVariantFuncRef();
6804
6805 VariantMatchInfo VMI;
6806 OMPTraitInfo &TI = A->getTraitInfo();
6807 TI.getAsVariantMatchInfo(Context, VMI);
6808 if (!isVariantApplicableInContext(VMI, OMPCtx,
6809 /* DeviceSetOnly */ false))
6810 continue;
6811
6812 VMIs.push_back(VMI);
6813 Exprs.push_back(VariantRef);
6814 }
6815
6816 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6817 }
6818
6819 ExprResult NewCall;
6820 do {
6821 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6822 if (BestIdx < 0)
6823 return Call;
6824 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6825 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6826
6827 {
6828 // Try to build a (member) call expression for the current best applicable
6829 // variant expression. We allow this to fail in which case we continue
6830 // with the next best variant expression. The fail case is part of the
6831 // implementation defined behavior in the OpenMP standard when it talks
6832 // about what differences in the function prototypes: "Any differences
6833 // that the specific OpenMP context requires in the prototype of the
6834 // variant from the base function prototype are implementation defined."
6835 // This wording is there to allow the specialized variant to have a
6836 // different type than the base function. This is intended and OK but if
6837 // we cannot create a call the difference is not in the "implementation
6838 // defined range" we allow.
6839 Sema::TentativeAnalysisScope Trap(*this);
6840
6841 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6842 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6843 BestExpr = MemberExpr::CreateImplicit(
6844 Context, MemberCall->getImplicitObjectArgument(),
6845 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6846 MemberCall->getValueKind(), MemberCall->getObjectKind());
6847 }
6848 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6849 ExecConfig);
6850 if (NewCall.isUsable()) {
6851 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6852 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6853 QualType NewType = Context.mergeFunctionTypes(
6854 CalleeFnType, NewCalleeFnDecl->getType(),
6855 /* OfBlockPointer */ false,
6856 /* Unqualified */ false, /* AllowCXX */ true);
6857 if (!NewType.isNull())
6858 break;
6859 // Don't use the call if the function type was not compatible.
6860 NewCall = nullptr;
6861 }
6862 }
6863 }
6864
6865 VMIs.erase(VMIs.begin() + BestIdx);
6866 Exprs.erase(Exprs.begin() + BestIdx);
6867 } while (!VMIs.empty());
6868
6869 if (!NewCall.isUsable())
6870 return Call;
6871 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6872}
6873
6874Optional<std::pair<FunctionDecl *, Expr *>>
6875Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6876 Expr *VariantRef, OMPTraitInfo &TI,
6877 SourceRange SR) {
6878 if (!DG || DG.get().isNull())
6879 return None;
6880
6881 const int VariantId = 1;
6882 // Must be applied only to single decl.
6883 if (!DG.get().isSingleDecl()) {
6884 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6885 << VariantId << SR;
6886 return None;
6887 }
6888 Decl *ADecl = DG.get().getSingleDecl();
6889 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6890 ADecl = FTD->getTemplatedDecl();
6891
6892 // Decl must be a function.
6893 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6894 if (!FD) {
6895 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6896 << VariantId << SR;
6897 return None;
6898 }
6899
6900 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6901 return FD->hasAttrs() &&
6902 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6903 FD->hasAttr<TargetAttr>());
6904 };
6905 // OpenMP is not compatible with CPU-specific attributes.
6906 if (HasMultiVersionAttributes(FD)) {
6907 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6908 << SR;
6909 return None;
6910 }
6911
6912 // Allow #pragma omp declare variant only if the function is not used.
6913 if (FD->isUsed(false))
6914 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6915 << FD->getLocation();
6916
6917 // Check if the function was emitted already.
6918 const FunctionDecl *Definition;
6919 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6920 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6921 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6922 << FD->getLocation();
6923
6924 // The VariantRef must point to function.
6925 if (!VariantRef) {
6926 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6927 return None;
6928 }
6929
6930 auto ShouldDelayChecks = [](Expr *&E, bool) {
6931 return E && (E->isTypeDependent() || E->isValueDependent() ||
6932 E->containsUnexpandedParameterPack() ||
6933 E->isInstantiationDependent());
6934 };
6935 // Do not check templates, wait until instantiation.
6936 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6937 TI.anyScoreOrCondition(ShouldDelayChecks))
6938 return std::make_pair(FD, VariantRef);
6939
6940 // Deal with non-constant score and user condition expressions.
6941 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6942 bool IsScore) -> bool {
6943 if (!E || E->isIntegerConstantExpr(Context))
6944 return false;
6945
6946 if (IsScore) {
6947 // We warn on non-constant scores and pretend they were not present.
6948 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6949 << E;
6950 E = nullptr;
6951 } else {
6952 // We could replace a non-constant user condition with "false" but we
6953 // will soon need to handle these anyway for the dynamic version of
6954 // OpenMP context selectors.
6955 Diag(E->getExprLoc(),
6956 diag::err_omp_declare_variant_user_condition_not_constant)
6957 << E;
6958 }
6959 return true;
6960 };
6961 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6962 return None;
6963
6964 // Convert VariantRef expression to the type of the original function to
6965 // resolve possible conflicts.
6966 ExprResult VariantRefCast = VariantRef;
6967 if (LangOpts.CPlusPlus) {
6968 QualType FnPtrType;
6969 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6970 if (Method && !Method->isStatic()) {
6971 const Type *ClassType =
6972 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6973 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6974 ExprResult ER;
6975 {
6976 // Build adrr_of unary op to correctly handle type checks for member
6977 // functions.
6978 Sema::TentativeAnalysisScope Trap(*this);
6979 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6980 VariantRef);
6981 }
6982 if (!ER.isUsable()) {
6983 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6984 << VariantId << VariantRef->getSourceRange();
6985 return None;
6986 }
6987 VariantRef = ER.get();
6988 } else {
6989 FnPtrType = Context.getPointerType(FD->getType());
6990 }
6991 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6992 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6993 ImplicitConversionSequence ICS = TryImplicitConversion(
6994 VariantRef, FnPtrType.getUnqualifiedType(),
6995 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6996 /*InOverloadResolution=*/false,
6997 /*CStyle=*/false,
6998 /*AllowObjCWritebackConversion=*/false);
6999 if (ICS.isFailure()) {
7000 Diag(VariantRef->getExprLoc(),
7001 diag::err_omp_declare_variant_incompat_types)
7002 << VariantRef->getType()
7003 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7004 << VariantRef->getSourceRange();
7005 return None;
7006 }
7007 VariantRefCast = PerformImplicitConversion(
7008 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7009 if (!VariantRefCast.isUsable())
7010 return None;
7011 }
7012 // Drop previously built artificial addr_of unary op for member functions.
7013 if (Method && !Method->isStatic()) {
7014 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7015 if (auto *UO = dyn_cast<UnaryOperator>(
7016 PossibleAddrOfVariantRef->IgnoreImplicit()))
7017 VariantRefCast = UO->getSubExpr();
7018 }
7019 }
7020
7021 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7022 if (!ER.isUsable() ||
7023 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7024 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7025 << VariantId << VariantRef->getSourceRange();
7026 return None;
7027 }
7028
7029 // The VariantRef must point to function.
7030 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7031 if (!DRE) {
7032 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7033 << VariantId << VariantRef->getSourceRange();
7034 return None;
7035 }
7036 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7037 if (!NewFD) {
7038 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7039 << VariantId << VariantRef->getSourceRange();
7040 return None;
7041 }
7042
7043 // Check if function types are compatible in C.
7044 if (!LangOpts.CPlusPlus) {
7045 QualType NewType =
7046 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
7047 if (NewType.isNull()) {
7048 Diag(VariantRef->getExprLoc(),
7049 diag::err_omp_declare_variant_incompat_types)
7050 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
7051 return None;
7052 }
7053 if (NewType->isFunctionProtoType()) {
7054 if (FD->getType()->isFunctionNoProtoType())
7055 setPrototype(*this, FD, NewFD, NewType);
7056 else if (NewFD->getType()->isFunctionNoProtoType())
7057 setPrototype(*this, NewFD, FD, NewType);
7058 }
7059 }
7060
7061 // Check if variant function is not marked with declare variant directive.
7062 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7063 Diag(VariantRef->getExprLoc(),
7064 diag::warn_omp_declare_variant_marked_as_declare_variant)
7065 << VariantRef->getSourceRange();
7066 SourceRange SR =
7067 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7068 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7069 return None;
7070 }
7071
7072 enum DoesntSupport {
7073 VirtFuncs = 1,
7074 Constructors = 3,
7075 Destructors = 4,
7076 DeletedFuncs = 5,
7077 DefaultedFuncs = 6,
7078 ConstexprFuncs = 7,
7079 ConstevalFuncs = 8,
7080 };
7081 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7082 if (CXXFD->isVirtual()) {
7083 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7084 << VirtFuncs;
7085 return None;
7086 }
7087
7088 if (isa<CXXConstructorDecl>(FD)) {
7089 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7090 << Constructors;
7091 return None;
7092 }
7093
7094 if (isa<CXXDestructorDecl>(FD)) {
7095 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7096 << Destructors;
7097 return None;
7098 }
7099 }
7100
7101 if (FD->isDeleted()) {
7102 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7103 << DeletedFuncs;
7104 return None;
7105 }
7106
7107 if (FD->isDefaulted()) {
7108 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7109 << DefaultedFuncs;
7110 return None;
7111 }
7112
7113 if (FD->isConstexpr()) {
7114 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7115 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7116 return None;
7117 }
7118
7119 // Check general compatibility.
7120 if (areMultiversionVariantFunctionsCompatible(
7121 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7122 PartialDiagnosticAt(SourceLocation(),
7123 PartialDiagnostic::NullDiagnostic()),
7124 PartialDiagnosticAt(
7125 VariantRef->getExprLoc(),
7126 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7127 PartialDiagnosticAt(VariantRef->getExprLoc(),
7128 PDiag(diag::err_omp_declare_variant_diff)
7129 << FD->getLocation()),
7130 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7131 /*CLinkageMayDiffer=*/true))
7132 return None;
7133 return std::make_pair(FD, cast<Expr>(DRE));
7134}
7135
7136void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
7137 Expr *VariantRef,
7138 OMPTraitInfo &TI,
7139 SourceRange SR) {
7140 auto *NewAttr =
7141 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
7142 FD->addAttr(NewAttr);
7143}
7144
7145StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7146 Stmt *AStmt,
7147 SourceLocation StartLoc,
7148 SourceLocation EndLoc) {
7149 if (!AStmt)
7150 return StmtError();
7151
7152 auto *CS = cast<CapturedStmt>(AStmt);
7153 // 1.2.2 OpenMP Language Terminology
7154 // Structured block - An executable statement with a single entry at the
7155 // top and a single exit at the bottom.
7156 // The point of exit cannot be a branch out of the structured block.
7157 // longjmp() and throw() must not violate the entry/exit criteria.
7158 CS->getCapturedDecl()->setNothrow();
7159
7160 setFunctionHasBranchProtectedScope();
7161
7162 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7163 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
7164 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7165}
7166
7167namespace {
7168/// Iteration space of a single for loop.
7169struct LoopIterationSpace final {
7170 /// True if the condition operator is the strict compare operator (<, > or
7171 /// !=).
7172 bool IsStrictCompare = false;
7173 /// Condition of the loop.
7174 Expr *PreCond = nullptr;
7175 /// This expression calculates the number of iterations in the loop.
7176 /// It is always possible to calculate it before starting the loop.
7177 Expr *NumIterations = nullptr;
7178 /// The loop counter variable.
7179 Expr *CounterVar = nullptr;
7180 /// Private loop counter variable.
7181 Expr *PrivateCounterVar = nullptr;
7182 /// This is initializer for the initial value of #CounterVar.
7183 Expr *CounterInit = nullptr;
7184 /// This is step for the #CounterVar used to generate its update:
7185 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7186 Expr *CounterStep = nullptr;
7187 /// Should step be subtracted?
7188 bool Subtract = false;
7189 /// Source range of the loop init.
7190 SourceRange InitSrcRange;
7191 /// Source range of the loop condition.
7192 SourceRange CondSrcRange;
7193 /// Source range of the loop increment.
7194 SourceRange IncSrcRange;
7195 /// Minimum value that can have the loop control variable. Used to support
7196 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7197 /// since only such variables can be used in non-loop invariant expressions.
7198 Expr *MinValue = nullptr;
7199 /// Maximum value that can have the loop control variable. Used to support
7200 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7201 /// since only such variables can be used in non-loop invariant expressions.
7202 Expr *MaxValue = nullptr;
7203 /// true, if the lower bound depends on the outer loop control var.
7204 bool IsNonRectangularLB = false;
7205 /// true, if the upper bound depends on the outer loop control var.
7206 bool IsNonRectangularUB = false;
7207 /// Index of the loop this loop depends on and forms non-rectangular loop
7208 /// nest.
7209 unsigned LoopDependentIdx = 0;
7210 /// Final condition for the non-rectangular loop nest support. It is used to
7211 /// check that the number of iterations for this particular counter must be
7212 /// finished.
7213 Expr *FinalCondition = nullptr;
7214};
7215
7216/// Helper class for checking canonical form of the OpenMP loops and
7217/// extracting iteration space of each loop in the loop nest, that will be used
7218/// for IR generation.
7219class OpenMPIterationSpaceChecker {
7220 /// Reference to Sema.
7221 Sema &SemaRef;
7222 /// Does the loop associated directive support non-rectangular loops?
7223 bool SupportsNonRectangular;
7224 /// Data-sharing stack.
7225 DSAStackTy &Stack;
7226 /// A location for diagnostics (when there is no some better location).
7227 SourceLocation DefaultLoc;
7228 /// A location for diagnostics (when increment is not compatible).
7229 SourceLocation ConditionLoc;
7230 /// A source location for referring to loop init later.
7231 SourceRange InitSrcRange;
7232 /// A source location for referring to condition later.
7233 SourceRange ConditionSrcRange;
7234 /// A source location for referring to increment later.
7235 SourceRange IncrementSrcRange;
7236 /// Loop variable.
7237 ValueDecl *LCDecl = nullptr;
7238 /// Reference to loop variable.
7239 Expr *LCRef = nullptr;
7240 /// Lower bound (initializer for the var).
7241 Expr *LB = nullptr;
7242 /// Upper bound.
7243 Expr *UB = nullptr;
7244 /// Loop step (increment).
7245 Expr *Step = nullptr;
7246 /// This flag is true when condition is one of:
7247 /// Var < UB
7248 /// Var <= UB
7249 /// UB > Var
7250 /// UB >= Var
7251 /// This will have no value when the condition is !=
7252 llvm::Optional<bool> TestIsLessOp;
7253 /// This flag is true when condition is strict ( < or > ).
7254 bool TestIsStrictOp = false;
7255 /// This flag is true when step is subtracted on each iteration.
7256 bool SubtractStep = false;
7257 /// The outer loop counter this loop depends on (if any).
7258 const ValueDecl *DepDecl = nullptr;
7259 /// Contains number of loop (starts from 1) on which loop counter init
7260 /// expression of this loop depends on.
7261 Optional<unsigned> InitDependOnLC;
7262 /// Contains number of loop (starts from 1) on which loop counter condition
7263 /// expression of this loop depends on.
7264 Optional<unsigned> CondDependOnLC;
7265 /// Checks if the provide statement depends on the loop counter.
7266 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7267 /// Original condition required for checking of the exit condition for
7268 /// non-rectangular loop.
7269 Expr *Condition = nullptr;
7270
7271public:
7272 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7273 DSAStackTy &Stack, SourceLocation DefaultLoc)
7274 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7275 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7276 /// Check init-expr for canonical loop form and save loop counter
7277 /// variable - #Var and its initialization value - #LB.
7278 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7279 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7280 /// for less/greater and for strict/non-strict comparison.
7281 bool checkAndSetCond(Expr *S);
7282 /// Check incr-expr for canonical loop form and return true if it
7283 /// does not conform, otherwise save loop step (#Step).
7284 bool checkAndSetInc(Expr *S);
7285 /// Return the loop counter variable.
7286 ValueDecl *getLoopDecl() const { return LCDecl; }
7287 /// Return the reference expression to loop counter variable.
7288 Expr *getLoopDeclRefExpr() const { return LCRef; }
7289 /// Source range of the loop init.
7290 SourceRange getInitSrcRange() const { return InitSrcRange; }
7291 /// Source range of the loop condition.
7292 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7293 /// Source range of the loop increment.
7294 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7295 /// True if the step should be subtracted.
7296 bool shouldSubtractStep() const { return SubtractStep; }
7297 /// True, if the compare operator is strict (<, > or !=).
7298 bool isStrictTestOp() const { return TestIsStrictOp; }
7299 /// Build the expression to calculate the number of iterations.
7300 Expr *buildNumIterations(
7301 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7302 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7303 /// Build the precondition expression for the loops.
7304 Expr *
7305 buildPreCond(Scope *S, Expr *Cond,
7306 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7307 /// Build reference expression to the counter be used for codegen.
7308 DeclRefExpr *
7309 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7310 DSAStackTy &DSA) const;
7311 /// Build reference expression to the private counter be used for
7312 /// codegen.
7313 Expr *buildPrivateCounterVar() const;
7314 /// Build initialization of the counter be used for codegen.
7315 Expr *buildCounterInit() const;
7316 /// Build step of the counter be used for codegen.
7317 Expr *buildCounterStep() const;
7318 /// Build loop data with counter value for depend clauses in ordered
7319 /// directives.
7320 Expr *
7321 buildOrderedLoopData(Scope *S, Expr *Counter,
7322 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7323 SourceLocation Loc, Expr *Inc = nullptr,
7324 OverloadedOperatorKind OOK = OO_Amp);
7325 /// Builds the minimum value for the loop counter.
7326 std::pair<Expr *, Expr *> buildMinMaxValues(
7327 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7328 /// Builds final condition for the non-rectangular loops.
7329 Expr *buildFinalCondition(Scope *S) const;
7330 /// Return true if any expression is dependent.
7331 bool dependent() const;
7332 /// Returns true if the initializer forms non-rectangular loop.
7333 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7334 /// Returns true if the condition forms non-rectangular loop.
7335 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7336 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7337 unsigned getLoopDependentIdx() const {
7338 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7339 }
7340
7341private:
7342 /// Check the right-hand side of an assignment in the increment
7343 /// expression.
7344 bool checkAndSetIncRHS(Expr *RHS);
7345 /// Helper to set loop counter variable and its initializer.
7346 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7347 bool EmitDiags);
7348 /// Helper to set upper bound.
7349 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7350 SourceRange SR, SourceLocation SL);
7351 /// Helper to set loop increment.
7352 bool setStep(Expr *NewStep, bool Subtract);
7353};
7354
7355bool OpenMPIterationSpaceChecker::dependent() const {
7356 if (!LCDecl) {
7357 assert(!LB && !UB && !Step)(static_cast<void> (0));
7358 return false;
7359 }
7360 return LCDecl->getType()->isDependentType() ||
7361 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7362 (Step && Step->isValueDependent());
7363}
7364
7365bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7366 Expr *NewLCRefExpr,
7367 Expr *NewLB, bool EmitDiags) {
7368 // State consistency checking to ensure correct usage.
7369 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&(static_cast<void> (0))
7370 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)(static_cast<void> (0));
7371 if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7372 return true;
7373 LCDecl = getCanonicalDecl(NewLCDecl);
7374 LCRef = NewLCRefExpr;
7375 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7376 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7377 if ((Ctor->isCopyOrMoveConstructor() ||
7378 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7379 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7380 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7381 LB = NewLB;
7382 if (EmitDiags)
7383 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7384 return false;
7385}
7386
7387bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7388 llvm::Optional<bool> LessOp,
7389 bool StrictOp, SourceRange SR,
7390 SourceLocation SL) {
7391 // State consistency checking to ensure correct usage.
7392 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&(static_cast<void> (0))
7393 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)(static_cast<void> (0));
7394 if (!NewUB || NewUB->containsErrors())
7395 return true;
7396 UB = NewUB;
7397 if (LessOp)
7398 TestIsLessOp = LessOp;
7399 TestIsStrictOp = StrictOp;
7400 ConditionSrcRange = SR;
7401 ConditionLoc = SL;
7402 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7403 return false;
7404}
7405
7406bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7407 // State consistency checking to ensure correct usage.
7408 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)(static_cast<void> (0));
7409 if (!NewStep || NewStep->containsErrors())
7410 return true;
7411 if (!NewStep->isValueDependent()) {
7412 // Check that the step is integer expression.
7413 SourceLocation StepLoc = NewStep->getBeginLoc();
7414 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7415 StepLoc, getExprAsWritten(NewStep));
7416 if (Val.isInvalid())
7417 return true;
7418 NewStep = Val.get();
7419
7420 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7421 // If test-expr is of form var relational-op b and relational-op is < or
7422 // <= then incr-expr must cause var to increase on each iteration of the
7423 // loop. If test-expr is of form var relational-op b and relational-op is
7424 // > or >= then incr-expr must cause var to decrease on each iteration of
7425 // the loop.
7426 // If test-expr is of form b relational-op var and relational-op is < or
7427 // <= then incr-expr must cause var to decrease on each iteration of the
7428 // loop. If test-expr is of form b relational-op var and relational-op is
7429 // > or >= then incr-expr must cause var to increase on each iteration of
7430 // the loop.
7431 Optional<llvm::APSInt> Result =
7432 NewStep->getIntegerConstantExpr(SemaRef.Context);
7433 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7434 bool IsConstNeg =
7435 Result && Result->isSigned() && (Subtract != Result->isNegative());
7436 bool IsConstPos =
7437 Result && Result->isSigned() && (Subtract == Result->isNegative());
7438 bool IsConstZero = Result && !Result->getBoolValue();
7439
7440 // != with increment is treated as <; != with decrement is treated as >
7441 if (!TestIsLessOp.hasValue())
7442 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7443 if (UB && (IsConstZero ||
7444 (TestIsLessOp.getValue() ?
7445 (IsConstNeg || (IsUnsigned && Subtract)) :
7446 (IsConstPos || (IsUnsigned && !Subtract))))) {
7447 SemaRef.Diag(NewStep->getExprLoc(),
7448 diag::err_omp_loop_incr_not_compatible)
7449 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7450 SemaRef.Diag(ConditionLoc,
7451 diag::note_omp_loop_cond_requres_compatible_incr)
7452 << TestIsLessOp.getValue() << ConditionSrcRange;
7453 return true;
7454 }
7455 if (TestIsLessOp.getValue() == Subtract) {
7456 NewStep =
7457 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7458 .get();
7459 Subtract = !Subtract;
7460 }
7461 }
7462
7463 Step = NewStep;
7464 SubtractStep = Subtract;
7465 return false;
7466}
7467
7468namespace {
7469/// Checker for the non-rectangular loops. Checks if the initializer or
7470/// condition expression references loop counter variable.
7471class LoopCounterRefChecker final
7472 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7473 Sema &SemaRef;
7474 DSAStackTy &Stack;
7475 const ValueDecl *CurLCDecl = nullptr;
7476 const ValueDecl *DepDecl = nullptr;
7477 const ValueDecl *PrevDepDecl = nullptr;
7478 bool IsInitializer = true;
7479 bool SupportsNonRectangular;
7480 unsigned BaseLoopId = 0;
7481 bool checkDecl(const Expr *E, const ValueDecl *VD) {
7482 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7483 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7484 << (IsInitializer ? 0 : 1);
7485 return false;
7486 }
7487 const auto &&Data = Stack.isLoopControlVariable(VD);
7488 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7489 // The type of the loop iterator on which we depend may not have a random
7490 // access iterator type.
7491 if (Data.first && VD->getType()->isRecordType()) {
7492 SmallString<128> Name;
7493 llvm::raw_svector_ostream OS(Name);
7494 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7495 /*Qualified=*/true);
7496 SemaRef.Diag(E->getExprLoc(),
7497 diag::err_omp_wrong_dependency_iterator_type)
7498 << OS.str();
7499 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7500 return false;
7501 }
7502 if (Data.first && !SupportsNonRectangular) {
7503 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7504 return false;
7505 }
7506 if (Data.first &&
7507 (DepDecl || (PrevDepDecl &&
7508 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7509 if (!DepDecl && PrevDepDecl)
7510 DepDecl = PrevDepDecl;
7511 SmallString<128> Name;
7512 llvm::raw_svector_ostream OS(Name);
7513 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7514 /*Qualified=*/true);
7515 SemaRef.Diag(E->getExprLoc(),
7516 diag::err_omp_invariant_or_linear_dependency)
7517 << OS.str();
7518 return false;
7519 }
7520 if (Data.first) {
7521 DepDecl = VD;
7522 BaseLoopId = Data.first;
7523 }
7524 return Data.first;
7525 }
7526
7527public:
7528 bool VisitDeclRefExpr(const DeclRefExpr *E) {
7529 const ValueDecl *VD = E->getDecl();
7530 if (isa<VarDecl>(VD))
7531 return checkDecl(E, VD);
7532 return false;
7533 }
7534 bool VisitMemberExpr(const MemberExpr *E) {
7535 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7536 const ValueDecl *VD = E->getMemberDecl();
7537 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7538 return checkDecl(E, VD);
7539 }
7540 return false;
7541 }
7542 bool VisitStmt(const Stmt *S) {
7543 bool Res = false;
7544 for (const Stmt *Child : S->children())
7545 Res = (Child && Visit(Child)) || Res;
7546 return Res;
7547 }
7548 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7549 const ValueDecl *CurLCDecl, bool IsInitializer,
7550 const ValueDecl *PrevDepDecl = nullptr,
7551 bool SupportsNonRectangular = true)
7552 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7553 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7554 SupportsNonRectangular(SupportsNonRectangular) {}
7555 unsigned getBaseLoopId() const {
7556 assert(CurLCDecl && "Expected loop dependency.")(static_cast<void> (0));
7557 return BaseLoopId;
7558 }
7559 const ValueDecl *getDepDecl() const {
7560 assert(CurLCDecl && "Expected loop dependency.")(static_cast<void> (0));
7561 return DepDecl;
7562 }
7563};
7564} // namespace
7565
7566Optional<unsigned>
7567OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7568 bool IsInitializer) {
7569 // Check for the non-rectangular loops.
7570 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7571 DepDecl, SupportsNonRectangular);
7572 if (LoopStmtChecker.Visit(S)) {
7573 DepDecl = LoopStmtChecker.getDepDecl();
7574 return LoopStmtChecker.getBaseLoopId();
7575 }
7576 return llvm::None;
7577}
7578
7579bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7580 // Check init-expr for canonical loop form and save loop counter
7581 // variable - #Var and its initialization value - #LB.
7582 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7583 // var = lb
7584 // integer-type var = lb
7585 // random-access-iterator-type var = lb
7586 // pointer-type var = lb
7587 //
7588 if (!S) {
7589 if (EmitDiags) {
7590 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7591 }
7592 return true;
7593 }
7594 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7595 if (!ExprTemp->cleanupsHaveSideEffects())
7596 S = ExprTemp->getSubExpr();
7597
7598 InitSrcRange = S->getSourceRange();
7599 if (Expr *E = dyn_cast<Expr>(S))
7600 S = E->IgnoreParens();
7601 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7602 if (BO->getOpcode() == BO_Assign) {
7603 Expr *LHS = BO->getLHS()->IgnoreParens();
7604 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7605 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7606 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7607 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7608 EmitDiags);
7609 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7610 }
7611 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7612 if (ME->isArrow() &&
7613 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7614 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7615 EmitDiags);
7616 }
7617 }
7618 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7619 if (DS->isSingleDecl()) {
7620 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7621 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7622 // Accept non-canonical init form here but emit ext. warning.
7623 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7624 SemaRef.Diag(S->getBeginLoc(),
7625 diag::ext_omp_loop_not_canonical_init)
7626 << S->getSourceRange();
7627 return setLCDeclAndLB(
7628 Var,
7629 buildDeclRefExpr(SemaRef, Var,
7630 Var->getType().getNonReferenceType(),
7631 DS->getBeginLoc()),
7632 Var->getInit(), EmitDiags);
7633 }
7634 }
7635 }
7636 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7637 if (CE->getOperator() == OO_Equal) {
7638 Expr *LHS = CE->getArg(0);
7639 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7640 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7641 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7642 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7643 EmitDiags);
7644 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7645 }
7646 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7647 if (ME->isArrow() &&
7648 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7649 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7650 EmitDiags);
7651 }
7652 }
7653 }
7654
7655 if (dependent() || SemaRef.CurContext->isDependentContext())
7656 return false;
7657 if (EmitDiags) {
7658 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7659 << S->getSourceRange();
7660 }
7661 return true;
7662}
7663
7664/// Ignore parenthesizes, implicit casts, copy constructor and return the
7665/// variable (which may be the loop variable) if possible.
7666static const ValueDecl *getInitLCDecl(const Expr *E) {
7667 if (!E)
7668 return nullptr;
7669 E = getExprAsWritten(E);
7670 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7671 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7672 if ((Ctor->isCopyOrMoveConstructor() ||
7673 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7674 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7675 E = CE->getArg(0)->IgnoreParenImpCasts();
7676 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7677 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7678 return getCanonicalDecl(VD);
7679 }
7680 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7681 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7682 return getCanonicalDecl(ME->getMemberDecl());
7683 return nullptr;
7684}
7685
7686bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7687 // Check test-expr for canonical form, save upper-bound UB, flags for
7688 // less/greater and for strict/non-strict comparison.
7689 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7690 // var relational-op b
7691 // b relational-op var
7692 //
7693 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7694 if (!S) {
7695 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7696 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7697 return true;
7698 }
7699 Condition = S;
7700 S = getExprAsWritten(S);
7701 SourceLocation CondLoc = S->getBeginLoc();
7702 auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
7703 BinaryOperatorKind Opcode, const Expr *LHS,
7704 const Expr *RHS, SourceRange SR,
7705 SourceLocation OpLoc) -> llvm::Optional<bool> {
7706 if (BinaryOperator::isRelationalOp(Opcode)) {
7707 if (getInitLCDecl(LHS) == LCDecl)
7708 return setUB(const_cast<Expr *>(RHS),
7709 (Opcode == BO_LT || Opcode == BO_LE),
7710 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7711 if (getInitLCDecl(RHS) == LCDecl)
7712 return setUB(const_cast<Expr *>(LHS),
7713 (Opcode == BO_GT || Opcode == BO_GE),
7714 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7715 } else if (IneqCondIsCanonical && Opcode == BO_NE) {
7716 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
7717 /*LessOp=*/llvm::None,
7718 /*StrictOp=*/true, SR, OpLoc);
7719 }
7720 return llvm::None;
7721 };
7722 llvm::Optional<bool> Res;
7723 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
7724 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
7725 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
7726 RBO->getOperatorLoc());
7727 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7728 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
7729 BO->getSourceRange(), BO->getOperatorLoc());
7730 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7731 if (CE->getNumArgs() == 2) {
7732 Res = CheckAndSetCond(
7733 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
7734 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
7735 }
7736 }
7737 if (Res.hasValue())
7738 return *Res;
7739 if (dependent() || SemaRef.CurContext->isDependentContext())
7740 return false;
7741 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7742 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7743 return true;
7744}
7745
7746bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7747 // RHS of canonical loop form increment can be:
7748 // var + incr
7749 // incr + var
7750 // var - incr
7751 //
7752 RHS = RHS->IgnoreParenImpCasts();
7753 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7754 if (BO->isAdditiveOp()) {
7755 bool IsAdd = BO->getOpcode() == BO_Add;
7756 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7757 return setStep(BO->getRHS(), !IsAdd);
7758 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7759 return setStep(BO->getLHS(), /*Subtract=*/false);
7760 }
7761 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7762 bool IsAdd = CE->getOperator() == OO_Plus;
7763 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7764 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7765 return setStep(CE->getArg(1), !IsAdd);
7766 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7767 return setStep(CE->getArg(0), /*Subtract=*/false);
7768 }
7769 }
7770 if (dependent() || SemaRef.CurContext->isDependentContext())
7771 return false;
7772 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7773 << RHS->getSourceRange() << LCDecl;
7774 return true;
7775}
7776
7777bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7778 // Check incr-expr for canonical loop form and return true if it
7779 // does not conform.
7780 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7781 // ++var
7782 // var++
7783 // --var
7784 // var--
7785 // var += incr
7786 // var -= incr
7787 // var = var + incr
7788 // var = incr + var
7789 // var = var - incr
7790 //
7791 if (!S) {
7792 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7793 return true;
7794 }
7795 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7796 if (!ExprTemp->cleanupsHaveSideEffects())
7797 S = ExprTemp->getSubExpr();
7798
7799 IncrementSrcRange = S->getSourceRange();
7800 S = S->IgnoreParens();
7801 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7802 if (UO->isIncrementDecrementOp() &&
7803 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7804 return setStep(SemaRef
7805 .ActOnIntegerConstant(UO->getBeginLoc(),
7806 (UO->isDecrementOp() ? -1 : 1))
7807 .get(),
7808 /*Subtract=*/false);
7809 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7810 switch (BO->getOpcode()) {
7811 case BO_AddAssign:
7812 case BO_SubAssign:
7813 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7814 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7815 break;
7816 case BO_Assign:
7817 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7818 return checkAndSetIncRHS(BO->getRHS());
7819 break;
7820 default:
7821 break;
7822 }
7823 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7824 switch (CE->getOperator()) {
7825 case OO_PlusPlus:
7826 case OO_MinusMinus:
7827 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7828 return setStep(SemaRef
7829 .ActOnIntegerConstant(
7830 CE->getBeginLoc(),
7831 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7832 .get(),
7833 /*Subtract=*/false);
7834 break;
7835 case OO_PlusEqual:
7836 case OO_MinusEqual:
7837 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7838 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7839 break;
7840 case OO_Equal:
7841 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7842 return checkAndSetIncRHS(CE->getArg(1));
7843 break;
7844 default:
7845 break;
7846 }
7847 }
7848 if (dependent() || SemaRef.CurContext->isDependentContext())
7849 return false;
7850 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7851 << S->getSourceRange() << LCDecl;
7852 return true;
7853}
7854
7855static ExprResult
7856tryBuildCapture(Sema &SemaRef, Expr *Capture,
7857 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7858 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7859 return Capture;
7860 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7861 return SemaRef.PerformImplicitConversion(
7862 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7863 /*AllowExplicit=*/true);
7864 auto I = Captures.find(Capture);
7865 if (I != Captures.end())
7866 return buildCapture(SemaRef, Capture, I->second);
7867 DeclRefExpr *Ref = nullptr;
7868 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7869 Captures[Capture] = Ref;
7870 return Res;
7871}
7872
7873/// Calculate number of iterations, transforming to unsigned, if number of
7874/// iterations may be larger than the original type.
7875static Expr *
7876calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7877 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7878 bool TestIsStrictOp, bool RoundToStep,
7879 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7880 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7881 if (!NewStep.isUsable())
7882 return nullptr;
7883 llvm::APSInt LRes, SRes;
7884 bool IsLowerConst = false, IsStepConst = false;
7885 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7886 LRes = *Res;
7887 IsLowerConst = true;
7888 }
7889 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7890 SRes = *Res;
7891 IsStepConst = true;
7892 }
7893 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7894 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7895 (TestIsStrictOp && LRes.isStrictlyPositive()));
7896 bool NeedToReorganize = false;
7897 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7898 if (!NoNeedToConvert && IsLowerConst &&
7899 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7900 NoNeedToConvert = true;
7901 if (RoundToStep) {
7902 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7903 ? LRes.getBitWidth()
7904 : SRes.getBitWidth();
7905 LRes = LRes.extend(BW + 1);
7906 LRes.setIsSigned(true);
7907 SRes = SRes.extend(BW + 1);
7908 SRes.setIsSigned(true);
7909 LRes -= SRes;
7910 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7911 LRes = LRes.trunc(BW);
7912 }
7913 if (TestIsStrictOp) {
7914 unsigned BW = LRes.getBitWidth();
7915 LRes = LRes.extend(BW + 1);
7916 LRes.setIsSigned(true);
7917 ++LRes;
7918 NoNeedToConvert =
7919 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7920 // truncate to the original bitwidth.
7921 LRes = LRes.trunc(BW);
7922 }
7923 NeedToReorganize = NoNeedToConvert;
7924 }
7925 llvm::APSInt URes;
7926 bool IsUpperConst = false;
7927 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7928 URes = *Res;
7929 IsUpperConst = true;
7930 }
7931 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7932 (!RoundToStep || IsStepConst)) {
7933 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7934 : URes.getBitWidth();
7935 LRes = LRes.extend(BW + 1);
7936 LRes.setIsSigned(true);
7937 URes = URes.extend(BW + 1);
7938 URes.setIsSigned(true);
7939 URes -= LRes;
7940 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7941 NeedToReorganize = NoNeedToConvert;
7942 }
7943 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7944 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7945 // unsigned.
7946 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7947 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7948 QualType LowerTy = Lower->getType();
7949 QualType UpperTy = Upper->getType();
7950 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7951 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7952 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7953 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7954 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7955 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7956 Upper =
7957 SemaRef
7958 .PerformImplicitConversion(
7959 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7960 CastType, Sema::AA_Converting)
7961 .get();
7962 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7963 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7964 }
7965 }
7966 if (!Lower || !Upper || NewStep.isInvalid())
7967 return nullptr;
7968
7969 ExprResult Diff;
7970 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7971 // 1]).
7972 if (NeedToReorganize) {
7973 Diff = Lower;
7974
7975 if (RoundToStep) {
7976 // Lower - Step
7977 Diff =
7978 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7979 if (!Diff.isUsable())
7980 return nullptr;
7981 }
7982
7983 // Lower - Step [+ 1]
7984 if (TestIsStrictOp)
7985 Diff = SemaRef.BuildBinOp(
7986 S, DefaultLoc, BO_Add, Diff.get(),
7987 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7988 if (!Diff.isUsable())
7989 return nullptr;
7990
7991 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7992 if (!Diff.isUsable())
7993 return nullptr;
7994
7995 // Upper - (Lower - Step [+ 1]).
7996 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7997 if (!Diff.isUsable())
7998 return nullptr;
7999 } else {
8000 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8001
8002 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8003 // BuildBinOp already emitted error, this one is to point user to upper
8004 // and lower bound, and to tell what is passed to 'operator-'.
8005 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8006 << Upper->getSourceRange() << Lower->getSourceRange();
8007 return nullptr;
8008 }
8009
8010 if (!Diff.isUsable())
8011 return nullptr;
8012
8013 // Upper - Lower [- 1]
8014 if (TestIsStrictOp)
8015 Diff = SemaRef.BuildBinOp(
8016 S, DefaultLoc, BO_Sub, Diff.get(),
8017 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8018 if (!Diff.isUsable())
8019 return nullptr;
8020
8021 if (RoundToStep) {
8022 // Upper - Lower [- 1] + Step
8023 Diff =
8024 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8025 if (!Diff.isUsable())
8026 return nullptr;
8027 }
8028 }
8029
8030 // Parentheses (for dumping/debugging purposes only).
8031 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8032 if (!Diff.isUsable())
8033 return nullptr;
8034
8035 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8036 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8037 if (!Diff.isUsable())
8038 return nullptr;
8039
8040 return Diff.get();
8041}
8042
8043/// Build the expression to calculate the number of iterations.
8044Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8045 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8046 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8047 QualType VarType = LCDecl->getType().getNonReferenceType();
8048 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8049 !SemaRef.getLangOpts().CPlusPlus)
8050 return nullptr;
8051 Expr *LBVal = LB;
8052 Expr *UBVal = UB;
8053 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8054 // max(LB(MinVal), LB(MaxVal))
8055 if (InitDependOnLC) {
8056 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8057 if (!IS.MinValue || !IS.MaxValue)
8058 return nullptr;
8059 // OuterVar = Min
8060 ExprResult MinValue =
8061 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8062 if (!MinValue.isUsable())
8063 return nullptr;
8064
8065 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8066 IS.CounterVar, MinValue.get());
8067 if (!LBMinVal.isUsable())
8068 return nullptr;
8069 // OuterVar = Min, LBVal
8070 LBMinVal =
8071 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8072 if (!LBMinVal.isUsable())
8073 return nullptr;
8074 // (OuterVar = Min, LBVal)
8075 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8076 if (!LBMinVal.isUsable())
8077 return nullptr;
8078
8079 // OuterVar = Max
8080 ExprResult MaxValue =
8081 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8082 if (!MaxValue.isUsable())
8083 return nullptr;
8084
8085 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8086 IS.CounterVar, MaxValue.get());
8087 if (!LBMaxVal.isUsable())
8088 return nullptr;
8089 // OuterVar = Max, LBVal
8090 LBMaxVal =
8091 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8092 if (!LBMaxVal.isUsable())
8093 return nullptr;
8094 // (OuterVar = Max, LBVal)
8095 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8096 if (!LBMaxVal.isUsable())
8097 return nullptr;
8098
8099 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8100 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8101 if (!LBMin || !LBMax)
8102 return nullptr;
8103 // LB(MinVal) < LB(MaxVal)
8104 ExprResult MinLessMaxRes =
8105 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8106 if (!MinLessMaxRes.isUsable())
8107 return nullptr;
8108 Expr *MinLessMax =
8109 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8110 if (!MinLessMax)
8111 return nullptr;
8112 if (TestIsLessOp.getValue()) {
8113 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8114 // LB(MaxVal))
8115 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8116 MinLessMax, LBMin, LBMax);
8117 if (!MinLB.isUsable())
8118 return nullptr;
8119 LBVal = MinLB.get();
8120 } else {
8121 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8122 // LB(MaxVal))
8123 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8124 MinLessMax, LBMax, LBMin);
8125 if (!MaxLB.isUsable())
8126 return nullptr;
8127 LBVal = MaxLB.get();
8128 }
8129 }
8130 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8131 // min(UB(MinVal), UB(MaxVal))
8132 if (CondDependOnLC) {
8133 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8134 if (!IS.MinValue || !IS.MaxValue)
8135 return nullptr;
8136 // OuterVar = Min
8137 ExprResult MinValue =
8138 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8139 if (!MinValue.isUsable())
8140 return nullptr;
8141
8142 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8143 IS.CounterVar, MinValue.get());
8144 if (!UBMinVal.isUsable())
8145 return nullptr;
8146 // OuterVar = Min, UBVal
8147 UBMinVal =
8148 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8149 if (!UBMinVal.isUsable())
8150 return nullptr;
8151 // (OuterVar = Min, UBVal)
8152 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8153 if (!UBMinVal.isUsable())
8154 return nullptr;
8155
8156 // OuterVar = Max
8157 ExprResult MaxValue =
8158 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8159 if (!MaxValue.isUsable())
8160 return nullptr;
8161
8162 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8163 IS.CounterVar, MaxValue.get());
8164 if (!UBMaxVal.isUsable())
8165 return nullptr;
8166 // OuterVar = Max, UBVal
8167 UBMaxVal =
8168 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8169 if (!UBMaxVal.isUsable())
8170 return nullptr;
8171 // (OuterVar = Max, UBVal)
8172 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8173 if (!UBMaxVal.isUsable())
8174 return nullptr;
8175
8176 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8177 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8178 if (!UBMin || !UBMax)
8179 return nullptr;
8180 // UB(MinVal) > UB(MaxVal)
8181 ExprResult MinGreaterMaxRes =
8182 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8183 if (!MinGreaterMaxRes.isUsable())
8184 return nullptr;
8185 Expr *MinGreaterMax =
8186 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8187 if (!MinGreaterMax)
8188 return nullptr;
8189 if (TestIsLessOp.getValue()) {
8190 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8191 // UB(MaxVal))
8192 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8193 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8194 if (!MaxUB.isUsable())
8195 return nullptr;
8196 UBVal = MaxUB.get();
8197 } else {
8198 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8199 // UB(MaxVal))
8200 ExprResult MinUB = SemaRef.ActOnConditionalOp(
8201 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8202 if (!MinUB.isUsable())
8203 return nullptr;
8204 UBVal = MinUB.get();
8205 }
8206 }
8207 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8208 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8209 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8210 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8211 if (!Upper || !Lower)
8212 return nullptr;
8213
8214 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8215 Step, VarType, TestIsStrictOp,
8216 /*RoundToStep=*/true, Captures);
8217 if (!Diff.isUsable())
8218 return nullptr;
8219
8220 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8221 QualType Type = Diff.get()->getType();
8222 ASTContext &C = SemaRef.Context;
8223 bool UseVarType = VarType->hasIntegerRepresentation() &&
8224 C.getTypeSize(Type) > C.getTypeSize(VarType);
8225 if (!Type->isIntegerType() || UseVarType) {
8226 unsigned NewSize =
8227 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8228 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8229 : Type->hasSignedIntegerRepresentation();
8230 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8231 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8232 Diff = SemaRef.PerformImplicitConversion(
8233 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8234 if (!Diff.isUsable())
8235 return nullptr;
8236 }
8237 }
8238 if (LimitedType) {
8239 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8240 if (NewSize != C.getTypeSize(Type)) {
8241 if (NewSize < C.getTypeSize(Type)) {
8242 assert(NewSize == 64 && "incorrect loop var size")(static_cast<void> (0));
8243 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8244 << InitSrcRange << ConditionSrcRange;
8245 }
8246 QualType NewType = C.getIntTypeForBitwidth(
8247 NewSize, Type->hasSignedIntegerRepresentation() ||
8248 C.getTypeSize(Type) < NewSize);
8249 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8250 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8251 Sema::AA_Converting, true);
8252 if (!Diff.isUsable())
8253 return nullptr;
8254 }
8255 }
8256 }
8257
8258 return Diff.get();
8259}
8260
8261std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8262 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8263 // Do not build for iterators, they cannot be used in non-rectangular loop
8264 // nests.
8265 if (LCDecl->getType()->isRecordType())
8266 return std::make_pair(nullptr, nullptr);
8267 // If we subtract, the min is in the condition, otherwise the min is in the
8268 // init value.
8269 Expr *MinExpr = nullptr;
8270 Expr *MaxExpr = nullptr;
8271 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8272 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8273 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8274 : CondDependOnLC.hasValue();
8275 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8276 : InitDependOnLC.hasValue();
8277 Expr *Lower =
8278 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8279 Expr *Upper =
8280 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8281 if (!Upper || !Lower)
8282 return std::make_pair(nullptr, nullptr);
8283
8284 if (TestIsLessOp.getValue())
8285 MinExpr = Lower;
8286 else
8287 MaxExpr = Upper;
8288
8289 // Build minimum/maximum value based on number of iterations.
8290 QualType VarType = LCDecl->getType().getNonReferenceType();
8291
8292 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8293 Step, VarType, TestIsStrictOp,
8294 /*RoundToStep=*/false, Captures);
8295 if (!Diff.isUsable())
8296 return std::make_pair(nullptr, nullptr);
8297
8298 // ((Upper - Lower [- 1]) / Step) * Step
8299 // Parentheses (for dumping/debugging purposes only).
8300 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8301 if (!Diff.isUsable())
8302 return std::make_pair(nullptr, nullptr);
8303
8304 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8305 if (!NewStep.isUsable())
8306 return std::make_pair(nullptr, nullptr);
8307 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8308 if (!Diff.isUsable())
8309 return std::make_pair(nullptr, nullptr);
8310
8311 // Parentheses (for dumping/debugging purposes only).
8312 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8313 if (!Diff.isUsable())
8314 return std::make_pair(nullptr, nullptr);
8315
8316 // Convert to the ptrdiff_t, if original type is pointer.
8317 if (VarType->isAnyPointerType() &&
8318 !SemaRef.Context.hasSameType(
8319 Diff.get()->getType(),
8320 SemaRef.Context.getUnsignedPointerDiffType())) {
8321 Diff = SemaRef.PerformImplicitConversion(
8322 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8323 Sema::AA_Converting, /*AllowExplicit=*/true);
8324 }
8325 if (!Diff.isUsable())
8326 return std::make_pair(nullptr, nullptr);
8327
8328 if (TestIsLessOp.getValue()) {
8329 // MinExpr = Lower;
8330 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8331 Diff = SemaRef.BuildBinOp(
8332 S, DefaultLoc, BO_Add,
8333 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8334 Diff.get());
8335 if (!Diff.isUsable())
8336 return std::make_pair(nullptr, nullptr);
8337 } else {
8338 // MaxExpr = Upper;
8339 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8340 Diff = SemaRef.BuildBinOp(
8341 S, DefaultLoc, BO_Sub,
8342 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8343 Diff.get());
8344 if (!Diff.isUsable())
8345 return std::make_pair(nullptr, nullptr);
8346 }
8347
8348 // Convert to the original type.
8349 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8350 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8351 Sema::AA_Converting,
8352 /*AllowExplicit=*/true);
8353 if (!Diff.isUsable())
8354 return std::make_pair(nullptr, nullptr);
8355
8356 Sema::TentativeAnalysisScope Trap(SemaRef);
8357 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8358 if (!Diff.isUsable())
8359 return std::make_pair(nullptr, nullptr);
8360
8361 if (TestIsLessOp.getValue())
8362 MaxExpr = Diff.get();
8363 else
8364 MinExpr = Diff.get();
8365
8366 return std::make_pair(MinExpr, MaxExpr);
8367}
8368
8369Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8370 if (InitDependOnLC || CondDependOnLC)
8371 return Condition;
8372 return nullptr;
8373}
8374
8375Expr *OpenMPIterationSpaceChecker::buildPreCond(
8376 Scope *S, Expr *Cond,
8377 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8378 // Do not build a precondition when the condition/initialization is dependent
8379 // to prevent pessimistic early loop exit.
8380 // TODO: this can be improved by calculating min/max values but not sure that
8381 // it will be very effective.
8382 if (CondDependOnLC || InitDependOnLC)
8383 return SemaRef.PerformImplicitConversion(
8384 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8385 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8386 /*AllowExplicit=*/true).get();
8387
8388 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8389 Sema::TentativeAnalysisScope Trap(SemaRef);
8390
8391 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8392 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8393 if (!NewLB.isUsable() || !NewUB.isUsable())
8394 return nullptr;
8395
8396 ExprResult CondExpr =
8397 SemaRef.BuildBinOp(S, DefaultLoc,
8398 TestIsLessOp.getValue() ?
8399 (TestIsStrictOp ? BO_LT : BO_LE) :
8400 (TestIsStrictOp ? BO_GT : BO_GE),
8401 NewLB.get(), NewUB.get());
8402 if (CondExpr.isUsable()) {
8403 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8404 SemaRef.Context.BoolTy))
8405 CondExpr = SemaRef.PerformImplicitConversion(
8406 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8407 /*AllowExplicit=*/true);
8408 }
8409
8410 // Otherwise use original loop condition and evaluate it in runtime.
8411 return CondExpr.isUsable() ? CondExpr.get() : Cond;
8412}
8413
8414/// Build reference expression to the counter be used for codegen.
8415DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8416 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8417 DSAStackTy &DSA) const {
8418 auto *VD = dyn_cast<VarDecl>(LCDecl);
8419 if (!VD) {
8420 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8421 DeclRefExpr *Ref = buildDeclRefExpr(
8422 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8423 const DSAStackTy::DSAVarData Data =
8424 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8425 // If the loop control decl is explicitly marked as private, do not mark it
8426 // as captured again.
8427 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8428 Captures.insert(std::make_pair(LCRef, Ref));
8429 return Ref;
8430 }
8431 return cast<DeclRefExpr>(LCRef);
8432}
8433
8434Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8435 if (LCDecl && !LCDecl->isInvalidDecl()) {
8436 QualType Type = LCDecl->getType().getNonReferenceType();
8437 VarDecl *PrivateVar = buildVarDecl(
8438 SemaRef, DefaultLoc, Type, LCDecl->getName(),
8439 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8440 isa<VarDecl>(LCDecl)
8441 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8442 : nullptr);
8443 if (PrivateVar->isInvalidDecl())
8444 return nullptr;
8445 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8446 }
8447 return nullptr;
8448}
8449
8450/// Build initialization of the counter to be used for codegen.
8451Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8452
8453/// Build step of the counter be used for codegen.
8454Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8455
8456Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8457 Scope *S, Expr *Counter,
8458 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8459 Expr *Inc, OverloadedOperatorKind OOK) {
8460 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8461 if (!Cnt)
8462 return nullptr;
8463 if (Inc) {
8464 assert((OOK == OO_Plus || OOK == OO_Minus) &&(static_cast<void> (0))
8465 "Expected only + or - operations for depend clauses.")(static_cast<void> (0));
8466 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8467 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8468 if (!Cnt)
8469 return nullptr;
8470 }
8471 QualType VarType = LCDecl->getType().getNonReferenceType();
8472 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8473 !SemaRef.getLangOpts().CPlusPlus)
8474 return nullptr;
8475 // Upper - Lower
8476 Expr *Upper = TestIsLessOp.getValue()
8477 ? Cnt
8478 : tryBuildCapture(SemaRef, LB, Captures).get();
8479 Expr *Lower = TestIsLessOp.getValue()
8480 ? tryBuildCapture(SemaRef, LB, Captures).get()
8481 : Cnt;
8482 if (!Upper || !Lower)
8483 return nullptr;
8484
8485 ExprResult Diff = calculateNumIters(
8486 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8487 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8488 if (!Diff.isUsable())
8489 return nullptr;
8490
8491 return Diff.get();
8492}
8493} // namespace
8494
8495void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8496 assert(getLangOpts().OpenMP && "OpenMP is not active.")(static_cast<void> (0));
8497 assert(Init && "Expected loop in canonical form.")(static_cast<void> (0));
8498 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
8499 if (AssociatedLoops > 0 &&
8500 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
8501 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
8502 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8503 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
8504 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8505 if (ValueDecl *D = ISC.getLoopDecl()) {
8506 auto *VD = dyn_cast<VarDecl>(D);
8507 DeclRefExpr *PrivateRef = nullptr;
8508 if (!VD) {
8509 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8510 VD = Private;
8511 } else {
8512 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8513 /*WithInit=*/false);
8514 VD = cast<VarDecl>(PrivateRef->getDecl());
8515 }
8516 }
8517 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
8518 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
8519 if (LD != D->getCanonicalDecl()) {
8520 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
8521 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8522 MarkDeclarationsReferencedInExpr(
8523 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8524 Var->getType().getNonLValueExprType(Context),
8525 ForLoc, /*RefersToCapture=*/true));
8526 }
8527 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
8528 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8529 // Referenced in a Construct, C/C++]. The loop iteration variable in the
8530 // associated for-loop of a simd construct with just one associated
8531 // for-loop may be listed in a linear clause with a constant-linear-step
8532 // that is the increment of the associated for-loop. The loop iteration
8533 // variable(s) in the associated for-loop(s) of a for or parallel for
8534 // construct may be listed in a private or lastprivate clause.
8535 DSAStackTy::DSAVarData DVar =
8536 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
8537 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8538 // is declared in the loop and it is predetermined as a private.
8539 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8540 OpenMPClauseKind PredeterminedCKind =
8541 isOpenMPSimdDirective(DKind)
8542 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8543 : OMPC_private;
8544 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8545 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8546 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8547 DVar.CKind != OMPC_private))) ||
8548 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8549 DKind == OMPD_master_taskloop ||
8550 DKind == OMPD_parallel_master_taskloop ||
8551 isOpenMPDistributeDirective(DKind)) &&
8552 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8553 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8554 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8555 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8556 << getOpenMPClauseName(DVar.CKind)
8557 << getOpenMPDirectiveName(DKind)
8558 << getOpenMPClauseName(PredeterminedCKind);
8559 if (DVar.RefExpr == nullptr)
8560 DVar.CKind = PredeterminedCKind;
8561 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
8562 /*IsLoopIterVar=*/true);
8563 } else if (LoopDeclRefExpr) {
8564 // Make the loop iteration variable private (for worksharing
8565 // constructs), linear (for simd directives with the only one
8566 // associated loop) or lastprivate (for simd directives with several
8567 // collapsed or ordered loops).
8568 if (DVar.CKind == OMPC_unknown)
8569 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8570 PrivateRef);
8571 }
8572 }
8573 }
8574 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
8575 }
8576}
8577
8578/// Called on a for stmt to check and extract its iteration space
8579/// for further processing (such as collapsing).
8580static bool checkOpenMPIterationSpace(
8581 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8582 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8583 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8584 Expr *OrderedLoopCountExpr,
8585 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8586 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8587 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8588 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8589 // OpenMP [2.9.1, Canonical Loop Form]
8590 // for (init-expr; test-expr; incr-expr) structured-block
8591 // for (range-decl: range-expr) structured-block
8592 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8593 S = CanonLoop->getLoopStmt();
8594 auto *For = dyn_cast_or_null<ForStmt>(S);
8595 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8596 // Ranged for is supported only in OpenMP 5.0.
8597 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8598 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8599 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8600 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8601 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8602 if (TotalNestedLoopCount > 1) {
8603 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8604 SemaRef.Diag(DSA.getConstructLoc(),
8605 diag::note_omp_collapse_ordered_expr)
8606 << 2 << CollapseLoopCountExpr->getSourceRange()
8607 << OrderedLoopCountExpr->getSourceRange();
8608 else if (CollapseLoopCountExpr)
8609 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8610 diag::note_omp_collapse_ordered_expr)
8611 << 0 << CollapseLoopCountExpr->getSourceRange();
8612 else
8613 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8614 diag::note_omp_collapse_ordered_expr)
8615 << 1 << OrderedLoopCountExpr->getSourceRange();
8616 }
8617 return true;
8618 }
8619 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&(static_cast<void> (0))
8620 "No loop body.")(static_cast<void> (0));
8621
8622 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8623 For ? For->getForLoc() : CXXFor->getForLoc());
8624
8625 // Check init.
8626 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8627 if (ISC.checkAndSetInit(Init))
8628 return true;
8629
8630 bool HasErrors = false;
8631
8632 // Check loop variable's type.
8633 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8634 // OpenMP [2.6, Canonical Loop Form]
8635 // Var is one of the following:
8636 // A variable of signed or unsigned integer type.
8637 // For C++, a variable of a random access iterator type.
8638 // For C, a variable of a pointer type.
8639 QualType VarType = LCDecl->getType().getNonReferenceType();
8640 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8641 !VarType->isPointerType() &&
8642 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8643 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8644 << SemaRef.getLangOpts().CPlusPlus;
8645 HasErrors = true;
8646 }
8647
8648 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8649 // a Construct
8650 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8651 // parallel for construct is (are) private.
8652 // The loop iteration variable in the associated for-loop of a simd
8653 // construct with just one associated for-loop is linear with a
8654 // constant-linear-step that is the increment of the associated for-loop.
8655 // Exclude loop var from the list of variables with implicitly defined data
8656 // sharing attributes.
8657 VarsWithImplicitDSA.erase(LCDecl);
8658
8659 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")(static_cast<void> (0));
8660
8661 // Check test-expr.
8662 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8663
8664 // Check incr-expr.
8665 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8666 }
8667
8668 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8669 return HasErrors;
8670
8671 // Build the loop's iteration space representation.
8672 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8673 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8674 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8675 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8676 (isOpenMPWorksharingDirective(DKind) ||
8677 isOpenMPTaskLoopDirective(DKind) ||
8678 isOpenMPDistributeDirective(DKind) ||
8679 isOpenMPLoopTransformationDirective(DKind)),
8680 Captures);
8681 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8682 ISC.buildCounterVar(Captures, DSA);
8683 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8684 ISC.buildPrivateCounterVar();
8685 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8686 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8687 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8688 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8689 ISC.getConditionSrcRange();
8690 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8691 ISC.getIncrementSrcRange();
8692 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8693 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8694 ISC.isStrictTestOp();
8695 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8696 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8697 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8698 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8699 ISC.buildFinalCondition(DSA.getCurScope());
8700 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8701 ISC.doesInitDependOnLC();
8702 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8703 ISC.doesCondDependOnLC();
8704 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8705 ISC.getLoopDependentIdx();
8706
8707 HasErrors |=
8708 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8709 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8710 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8711 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8712 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8713 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8714 if (!HasErrors && DSA.isOrderedRegion()) {
8715 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8716 if (CurrentNestedLoopCount <
8717 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8718 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8719 CurrentNestedLoopCount,
8720 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8721 DSA.getOrderedRegionParam().second->setLoopCounter(
8722 CurrentNestedLoopCount,
8723 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8724 }
8725 }
8726 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8727 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8728 // Erroneous case - clause has some problems.
8729 continue;
8730 }
8731 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8732 Pair.second.size() <= CurrentNestedLoopCount) {
8733 // Erroneous case - clause has some problems.
8734 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8735 continue;
8736 }
8737 Expr *CntValue;
8738 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8739 CntValue = ISC.buildOrderedLoopData(
8740 DSA.getCurScope(),
8741 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8742 Pair.first->getDependencyLoc());
8743 else
8744 CntValue = ISC.buildOrderedLoopData(
8745 DSA.getCurScope(),
8746 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8747 Pair.first->getDependencyLoc(),
8748 Pair.second[CurrentNestedLoopCount].first,
8749 Pair.second[CurrentNestedLoopCount].second);
8750 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8751 }
8752 }
8753
8754 return HasErrors;
8755}
8756
8757/// Build 'VarRef = Start.
8758static ExprResult
8759buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8760 ExprResult Start, bool IsNonRectangularLB,
8761 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8762 // Build 'VarRef = Start.
8763 ExprResult NewStart = IsNonRectangularLB
8764 ? Start.get()
8765 : tryBuildCapture(SemaRef, Start.get(), Captures);
8766 if (!NewStart.isUsable())
8767 return ExprError();
8768 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8769 VarRef.get()->getType())) {
8770 NewStart = SemaRef.PerformImplicitConversion(
8771 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8772 /*AllowExplicit=*/true);
8773 if (!NewStart.isUsable())
8774 return ExprError();
8775 }
8776
8777 ExprResult Init =
8778 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8779 return Init;
8780}
8781
8782/// Build 'VarRef = Start + Iter * Step'.
8783static ExprResult buildCounterUpdate(
8784 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8785 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8786 bool IsNonRectangularLB,
8787 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8788 // Add parentheses (for debugging purposes only).
8789 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8790 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8791 !Step.isUsable())
8792 return ExprError();
8793
8794 ExprResult NewStep = Step;
8795 if (Captures)
8796 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8797 if (NewStep.isInvalid())
8798 return ExprError();
8799 ExprResult Update =
8800 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8801 if (!Update.isUsable())
8802 return ExprError();
8803
8804 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8805 // 'VarRef = Start (+|-) Iter * Step'.
8806 if (!Start.isUsable())
8807 return ExprError();
8808 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8809 if (!NewStart.isUsable())
8810 return ExprError();
8811 if (Captures && !IsNonRectangularLB)
8812 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8813 if (NewStart.isInvalid())
8814 return ExprError();
8815
8816 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8817 ExprResult SavedUpdate = Update;
8818 ExprResult UpdateVal;
8819 if (VarRef.get()->getType()->isOverloadableType() ||
8820 NewStart.get()->getType()->isOverloadableType() ||
8821 Update.get()->getType()->isOverloadableType()) {
8822 Sema::TentativeAnalysisScope Trap(SemaRef);
8823
8824 Update =
8825 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8826 if (Update.isUsable()) {
8827 UpdateVal =
8828 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8829 VarRef.get(), SavedUpdate.get());
8830 if (UpdateVal.isUsable()) {
8831 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8832 UpdateVal.get());
8833 }
8834 }
8835 }
8836
8837 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8838 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8839 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8840 NewStart.get(), SavedUpdate.get());
8841 if (!Update.isUsable())
8842 return ExprError();
8843
8844 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8845 VarRef.get()->getType())) {
8846 Update = SemaRef.PerformImplicitConversion(
8847 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8848 if (!Update.isUsable())
8849 return ExprError();
8850 }
8851
8852 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8853 }
8854 return Update;
8855}
8856
8857/// Convert integer expression \a E to make it have at least \a Bits
8858/// bits.
8859static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8860 if (E == nullptr)
8861 return ExprError();
8862 ASTContext &C = SemaRef.Context;
8863 QualType OldType = E->getType();
8864 unsigned HasBits = C.getTypeSize(OldType);
8865 if (HasBits >= Bits)
8866 return ExprResult(E);
8867 // OK to convert to signed, because new type has more bits than old.
8868 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8869 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8870 true);
8871}
8872
8873/// Check if the given expression \a E is a constant integer that fits
8874/// into \a Bits bits.
8875static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8876 if (E == nullptr)
8877 return false;
8878 if (Optional<llvm::APSInt> Result =
8879 E->getIntegerConstantExpr(SemaRef.Context))
8880 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8881 return false;
8882}
8883
8884/// Build preinits statement for the given declarations.
8885static Stmt *buildPreInits(ASTContext &Context,
8886 MutableArrayRef<Decl *> PreInits) {
8887 if (!PreInits.empty()) {
8888 return new (Context) DeclStmt(
8889 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8890 SourceLocation(), SourceLocation());
8891 }
8892 return nullptr;
8893}
8894
8895/// Build preinits statement for the given declarations.
8896static Stmt *
8897buildPreInits(ASTContext &Context,
8898 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8899 if (!Captures.empty()) {
8900 SmallVector<Decl *, 16> PreInits;
8901 for (const auto &Pair : Captures)
8902 PreInits.push_back(Pair.second->getDecl());
8903 return buildPreInits(Context, PreInits);
8904 }
8905 return nullptr;
8906}
8907
8908/// Build postupdate expression for the given list of postupdates expressions.
8909static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8910 Expr *PostUpdate = nullptr;
8911 if (!PostUpdates.empty()) {
8912 for (Expr *E : PostUpdates) {
8913 Expr *ConvE = S.BuildCStyleCastExpr(
8914 E->getExprLoc(),
8915 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8916 E->getExprLoc(), E)
8917 .get();
8918 PostUpdate = PostUpdate
8919 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8920 PostUpdate, ConvE)
8921 .get()
8922 : ConvE;
8923 }
8924 }
8925 return PostUpdate;
8926}
8927
8928/// Called on a for stmt to check itself and nested loops (if any).
8929/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8930/// number of collapsed loops otherwise.
8931static unsigned
8932checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8933 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8934 DSAStackTy &DSA,
8935 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8936 OMPLoopBasedDirective::HelperExprs &Built) {
8937 unsigned NestedLoopCount = 1;
8938 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8939 !isOpenMPLoopTransformationDirective(DKind);
8940
8941 if (CollapseLoopCountExpr) {
8942 // Found 'collapse' clause - calculate collapse number.
8943 Expr::EvalResult Result;
8944 if (!CollapseLoopCountExpr->isValueDependent() &&
8945 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8946 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8947 } else {
8948 Built.clear(/*Size=*/1);
8949 return 1;
8950 }
8951 }
8952 unsigned OrderedLoopCount = 1;
8953 if (OrderedLoopCountExpr) {
8954 // Found 'ordered' clause - calculate collapse number.
8955 Expr::EvalResult EVResult;
8956 if (!OrderedLoopCountExpr->isValueDependent() &&
8957 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8958 SemaRef.getASTContext())) {
8959 llvm::APSInt Result = EVResult.Val.getInt();
8960 if (Result.getLimitedValue() < NestedLoopCount) {
8961 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8962 diag::err_omp_wrong_ordered_loop_count)
8963 << OrderedLoopCountExpr->getSourceRange();
8964 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8965 diag::note_collapse_loop_count)
8966 << CollapseLoopCountExpr->getSourceRange();
8967 }
8968 OrderedLoopCount = Result.getLimitedValue();
8969 } else {
8970 Built.clear(/*Size=*/1);
8971 return 1;
8972 }
8973 }
8974 // This is helper routine for loop directives (e.g., 'for', 'simd',
8975 // 'for simd', etc.).
8976 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8977 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
8978 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
8979 if (!OMPLoopBasedDirective::doForAllLoops(
8980 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
8981 SupportsNonPerfectlyNested, NumLoops,
8982 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
8983 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
8984 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
8985 if (checkOpenMPIterationSpace(
8986 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8987 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
8988 VarsWithImplicitDSA, IterSpaces, Captures))
8989 return true;
8990 if (Cnt > 0 && Cnt >= NestedLoopCount &&
8991 IterSpaces[Cnt].CounterVar) {
8992 // Handle initialization of captured loop iterator variables.
8993 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8994 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8995 Captures[DRE] = DRE;
8996 }
8997 }
8998 return false;
8999 },
9000 [&SemaRef, &Captures](OMPLoopBasedDirective *Transform) {
9001 Stmt *DependentPreInits;
9002 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) {
9003 DependentPreInits = Dir->getPreInits();
9004 } else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) {
9005 DependentPreInits = Dir->getPreInits();
9006 } else {
9007 llvm_unreachable("Unexpected loop transformation")__builtin_unreachable();
9008 }
9009 if (!DependentPreInits)
9010 return;
9011 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9012 auto *D = cast<VarDecl>(C);
9013 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9014 Transform->getBeginLoc());
9015 Captures[Ref] = Ref;
9016 }
9017 }))
9018 return 0;
9019
9020 Built.clear(/* size */ NestedLoopCount);
9021
9022 if (SemaRef.CurContext->isDependentContext())
9023 return NestedLoopCount;
9024
9025 // An example of what is generated for the following code:
9026 //
9027 // #pragma omp simd collapse(2) ordered(2)
9028 // for (i = 0; i < NI; ++i)
9029 // for (k = 0; k < NK; ++k)
9030 // for (j = J0; j < NJ; j+=2) {
9031 // <loop body>
9032 // }
9033 //
9034 // We generate the code below.
9035 // Note: the loop body may be outlined in CodeGen.
9036 // Note: some counters may be C++ classes, operator- is used to find number of
9037 // iterations and operator+= to calculate counter value.
9038 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9039 // or i64 is currently supported).
9040 //
9041 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9042 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9043 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9044 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9045 // // similar updates for vars in clauses (e.g. 'linear')
9046 // <loop body (using local i and j)>
9047 // }
9048 // i = NI; // assign final values of counters
9049 // j = NJ;
9050 //
9051
9052 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9053 // the iteration counts of the collapsed for loops.
9054 // Precondition tests if there is at least one iteration (all conditions are
9055 // true).
9056 auto PreCond = ExprResult(IterSpaces[0].PreCond);
9057 Expr *N0 = IterSpaces[0].NumIterations;
9058 ExprResult LastIteration32 =
9059 widenIterationCount(/*Bits=*/32,
9060 SemaRef
9061 .PerformImplicitConversion(
9062 N0->IgnoreImpCasts(), N0->getType(),
9063 Sema::AA_Converting, /*AllowExplicit=*/true)
9064 .get(),
9065 SemaRef);
9066 ExprResult LastIteration64 = widenIterationCount(
9067 /*Bits=*/64,
9068 SemaRef
9069 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9070 Sema::AA_Converting,
9071 /*AllowExplicit=*/true)
9072 .get(),
9073 SemaRef);
9074
9075 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9076 return NestedLoopCount;
9077
9078 ASTContext &C = SemaRef.Context;
9079 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9080
9081 Scope *CurScope = DSA.getCurScope();
9082 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9083 if (PreCond.isUsable()) {
9084 PreCond =
9085 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9086 PreCond.get(), IterSpaces[Cnt].PreCond);
9087 }
9088 Expr *N = IterSpaces[Cnt].NumIterations;
9089 SourceLocation Loc = N->getExprLoc();
9090 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9091 if (LastIteration32.isUsable())
9092 LastIteration32 = SemaRef.BuildBinOp(
9093 CurScope, Loc, BO_Mul, LastIteration32.get(),
9094 SemaRef
9095 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9096 Sema::AA_Converting,
9097 /*AllowExplicit=*/true)
9098 .get());
9099 if (LastIteration64.isUsable())
9100 LastIteration64 = SemaRef.BuildBinOp(
9101 CurScope, Loc, BO_Mul, LastIteration64.get(),
9102 SemaRef
9103 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9104 Sema::AA_Converting,
9105 /*AllowExplicit=*/true)
9106 .get());
9107 }
9108
9109 // Choose either the 32-bit or 64-bit version.
9110 ExprResult LastIteration = LastIteration64;
9111 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9112 (LastIteration32.isUsable() &&
9113 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9114 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9115 fitsInto(
9116 /*Bits=*/32,
9117 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9118 LastIteration64.get(), SemaRef))))
9119 LastIteration = LastIteration32;
9120 QualType VType = LastIteration.get()->getType();
9121 QualType RealVType = VType;
9122 QualType StrideVType = VType;
9123 if (isOpenMPTaskLoopDirective(DKind)) {
9124 VType =
9125 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9126 StrideVType =
9127 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9128 }
9129
9130 if (!LastIteration.isUsable())
9131 return 0;
9132
9133 // Save the number of iterations.
9134 ExprResult NumIterations = LastIteration;
9135 {
9136 LastIteration = SemaRef.BuildBinOp(
9137 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9138 LastIteration.get(),
9139 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9140 if (!LastIteration.isUsable())
9141 return 0;
9142 }
9143
9144 // Calculate the last iteration number beforehand instead of doing this on
9145 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9146 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9147 ExprResult CalcLastIteration;
9148 if (!IsConstant) {
9149 ExprResult SaveRef =
9150 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9151 LastIteration = SaveRef;
9152
9153 // Prepare SaveRef + 1.
9154 NumIterations = SemaRef.BuildBinOp(
9155 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9156 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9157 if (!NumIterations.isUsable())
9158 return 0;
9159 }
9160
9161 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9162
9163 // Build variables passed into runtime, necessary for worksharing directives.
9164 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9165 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9166 isOpenMPDistributeDirective(DKind) ||
9167 isOpenMPLoopTransformationDirective(DKind)) {
9168 // Lower bound variable, initialized with zero.
9169 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9170 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9171 SemaRef.AddInitializerToDecl(LBDecl,
9172 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9173 /*DirectInit*/ false);
9174
9175 // Upper bound variable, initialized with last iteration number.
9176 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9177 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9178 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9179 /*DirectInit*/ false);
9180
9181 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9182 // This will be used to implement clause 'lastprivate'.
9183 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9184 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9185 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9186 SemaRef.AddInitializerToDecl(ILDecl,
9187 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9188 /*DirectInit*/ false);
9189
9190 // Stride variable returned by runtime (we initialize it to 1 by default).
9191 VarDecl *STDecl =
9192 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9193 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9194 SemaRef.AddInitializerToDecl(STDecl,
9195 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9196 /*DirectInit*/ false);
9197
9198 // Build expression: UB = min(UB, LastIteration)
9199 // It is necessary for CodeGen of directives with static scheduling.
9200 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9201 UB.get(), LastIteration.get());
9202 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9203 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9204 LastIteration.get(), UB.get());
9205 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9206 CondOp.get());
9207 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9208
9209 // If we have a combined directive that combines 'distribute', 'for' or
9210 // 'simd' we need to be able to access the bounds of the schedule of the
9211 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9212 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9213 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9214 // Lower bound variable, initialized with zero.
9215 VarDecl *CombLBDecl =
9216 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9217 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9218 SemaRef.AddInitializerToDecl(
9219 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9220 /*DirectInit*/ false);
9221
9222 // Upper bound variable, initialized with last iteration number.
9223 VarDecl *CombUBDecl =
9224 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9225 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9226 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9227 /*DirectInit*/ false);
9228
9229 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9230 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9231 ExprResult CombCondOp =
9232 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9233 LastIteration.get(), CombUB.get());
9234 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9235 CombCondOp.get());
9236 CombEUB =
9237 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9238
9239 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9240 // We expect to have at least 2 more parameters than the 'parallel'
9241 // directive does - the lower and upper bounds of the previous schedule.
9242 assert(CD->getNumParams() >= 4 &&(static_cast<void> (0))
9243 "Unexpected number of parameters in loop combined directive")(static_cast<void> (0));
9244
9245 // Set the proper type for the bounds given what we learned from the
9246 // enclosed loops.
9247 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9248 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9249
9250 // Previous lower and upper bounds are obtained from the region
9251 // parameters.
9252 PrevLB =
9253 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9254 PrevUB =
9255 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9256 }
9257 }
9258
9259 // Build the iteration variable and its initialization before loop.
9260 ExprResult IV;
9261 ExprResult Init, CombInit;
9262 {
9263 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9264 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9265 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9266 isOpenMPTaskLoopDirective(DKind) ||
9267 isOpenMPDistributeDirective(DKind) ||
9268 isOpenMPLoopTransformationDirective(DKind))
9269 ? LB.get()
9270 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9271 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9272 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9273
9274 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9275 Expr *CombRHS =
9276 (isOpenMPWorksharingDirective(DKind) ||
9277 isOpenMPTaskLoopDirective(DKind) ||
9278 isOpenMPDistributeDirective(DKind))
9279 ? CombLB.get()
9280 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9281 CombInit =
9282 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9283 CombInit =
9284 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9285 }
9286 }
9287
9288 bool UseStrictCompare =
9289 RealVType->hasUnsignedIntegerRepresentation() &&
9290 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9291 return LIS.IsStrictCompare;
9292 });
9293 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9294 // unsigned IV)) for worksharing loops.
9295 SourceLocation CondLoc = AStmt->getBeginLoc();
9296 Expr *BoundUB = UB.get();
9297 if (UseStrictCompare) {
9298 BoundUB =
9299 SemaRef
9300 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9301 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9302 .get();
9303 BoundUB =
9304 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9305 }
9306 ExprResult Cond =
9307 (isOpenMPWorksharingDirective(DKind) ||
9308 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9309 isOpenMPLoopTransformationDirective(DKind))
9310 ? SemaRef.BuildBinOp(CurScope, CondLoc,
9311 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9312 BoundUB)
9313 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9314 NumIterations.get());
9315 ExprResult CombDistCond;
9316 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9317 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9318 NumIterations.get());
9319 }
9320
9321 ExprResult CombCond;
9322 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9323 Expr *BoundCombUB = CombUB.get();
9324 if (UseStrictCompare) {
9325 BoundCombUB =
9326 SemaRef
9327 .BuildBinOp(
9328 CurScope, CondLoc, BO_Add, BoundCombUB,
9329 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9330 .get();
9331 BoundCombUB =
9332 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9333 .get();
9334 }
9335 CombCond =
9336 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9337 IV.get(), BoundCombUB);
9338 }
9339 // Loop increment (IV = IV + 1)
9340 SourceLocation IncLoc = AStmt->getBeginLoc();
9341 ExprResult Inc =
9342 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9343 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9344 if (!Inc.isUsable())
9345 return 0;
9346 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9347 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9348 if (!Inc.isUsable())
9349 return 0;
9350
9351 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9352 // Used for directives with static scheduling.
9353 // In combined construct, add combined version that use CombLB and CombUB
9354 // base variables for the update
9355 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9356 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9357 isOpenMPDistributeDirective(DKind) ||
9358 isOpenMPLoopTransformationDirective(DKind)) {
9359 // LB + ST
9360 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9361 if (!NextLB.isUsable())
9362 return 0;
9363 // LB = LB + ST
9364 NextLB =
9365 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9366 NextLB =
9367 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9368 if (!NextLB.isUsable())
9369 return 0;
9370 // UB + ST
9371 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9372 if (!NextUB.isUsable())
9373 return 0;
9374 // UB = UB + ST
9375 NextUB =
9376 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9377 NextUB =
9378 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9379 if (!NextUB.isUsable())
9380 return 0;
9381 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9382 CombNextLB =
9383 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9384 if (!NextLB.isUsable())
9385 return 0;
9386 // LB = LB + ST
9387 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9388 CombNextLB.get());
9389 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9390 /*DiscardedValue*/ false);
9391 if (!CombNextLB.isUsable())
9392 return 0;
9393 // UB + ST
9394 CombNextUB =
9395 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9396 if (!CombNextUB.isUsable())
9397 return 0;
9398 // UB = UB + ST
9399 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9400 CombNextUB.get());
9401 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9402 /*DiscardedValue*/ false);
9403 if (!CombNextUB.isUsable())
9404 return 0;
9405 }
9406 }
9407
9408 // Create increment expression for distribute loop when combined in a same
9409 // directive with for as IV = IV + ST; ensure upper bound expression based
9410 // on PrevUB instead of NumIterations - used to implement 'for' when found
9411 // in combination with 'distribute', like in 'distribute parallel for'
9412 SourceLocation DistIncLoc = AStmt->getBeginLoc();
9413 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9414 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9415 DistCond = SemaRef.BuildBinOp(
9416 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9417 assert(DistCond.isUsable() && "distribute cond expr was not built")(static_cast<void> (0));
9418
9419 DistInc =
9420 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9421 assert(DistInc.isUsable() && "distribute inc expr was not built")(static_cast<void> (0));
9422 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9423 DistInc.get());
9424 DistInc =
9425 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9426 assert(DistInc.isUsable() && "distribute inc expr was not built")(static_cast<void> (0));
9427
9428 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9429 // construct
9430 ExprResult NewPrevUB = PrevUB;
9431 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9432 if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9433 PrevUB.get()->getType())) {
9434 NewPrevUB = SemaRef.BuildCStyleCastExpr(
9435 DistEUBLoc,
9436 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9437 DistEUBLoc, NewPrevUB.get());
9438 if (!NewPrevUB.isUsable())
9439 return 0;
9440 }
9441 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9442 UB.get(), NewPrevUB.get());
9443 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9444 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9445 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9446 CondOp.get());
9447 PrevEUB =
9448 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9449
9450 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9451 // parallel for is in combination with a distribute directive with
9452 // schedule(static, 1)
9453 Expr *BoundPrevUB = PrevUB.get();
9454 if (UseStrictCompare) {
9455 BoundPrevUB =
9456 SemaRef
9457 .BuildBinOp(
9458 CurScope, CondLoc, BO_Add, BoundPrevUB,
9459 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9460 .get();
9461 BoundPrevUB =
9462 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9463 .get();
9464 }
9465 ParForInDistCond =
9466 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9467 IV.get(), BoundPrevUB);
9468 }
9469
9470 // Build updates and final values of the loop counters.
9471 bool HasErrors = false;
9472 Built.Counters.resize(NestedLoopCount);
9473 Built.Inits.resize(NestedLoopCount);
9474 Built.Updates.resize(NestedLoopCount);
9475 Built.Finals.resize(NestedLoopCount);
9476 Built.DependentCounters.resize(NestedLoopCount);
9477 Built.DependentInits.resize(NestedLoopCount);
9478 Built.FinalsConditions.resize(NestedLoopCount);
9479 {
9480 // We implement the following algorithm for obtaining the
9481 // original loop iteration variable values based on the
9482 // value of the collapsed loop iteration variable IV.
9483 //
9484 // Let n+1 be the number of collapsed loops in the nest.
9485 // Iteration variables (I0, I1, .... In)
9486 // Iteration counts (N0, N1, ... Nn)
9487 //
9488 // Acc = IV;
9489 //
9490 // To compute Ik for loop k, 0 <= k <= n, generate:
9491 // Prod = N(k+1) * N(k+2) * ... * Nn;
9492 // Ik = Acc / Prod;
9493 // Acc -= Ik * Prod;
9494 //
9495 ExprResult Acc = IV;
9496 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9497 LoopIterationSpace &IS = IterSpaces[Cnt];
9498 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9499 ExprResult Iter;
9500
9501 // Compute prod
9502 ExprResult Prod =
9503 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9504 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9505 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9506 IterSpaces[K].NumIterations);
9507
9508 // Iter = Acc / Prod
9509 // If there is at least one more inner loop to avoid
9510 // multiplication by 1.
9511 if (Cnt + 1 < NestedLoopCount)
9512 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9513 Acc.get(), Prod.get());
9514 else
9515 Iter = Acc;
9516 if (!Iter.isUsable()) {
9517 HasErrors = true;
9518 break;
9519 }
9520
9521 // Update Acc:
9522 // Acc -= Iter * Prod
9523 // Check if there is at least one more inner loop to avoid
9524 // multiplication by 1.
9525 if (Cnt + 1 < NestedLoopCount)
9526 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9527 Iter.get(), Prod.get());
9528 else
9529 Prod = Iter;
9530 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9531 Acc.get(), Prod.get());
9532
9533 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9534 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9535 DeclRefExpr *CounterVar = buildDeclRefExpr(
9536 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9537 /*RefersToCapture=*/true);
9538 ExprResult Init =
9539 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9540 IS.CounterInit, IS.IsNonRectangularLB, Captures);
9541 if (!Init.isUsable()) {
9542 HasErrors = true;
9543 break;
9544 }
9545 ExprResult Update = buildCounterUpdate(
9546 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9547 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9548 if (!Update.isUsable()) {
9549 HasErrors = true;
9550 break;
9551 }
9552
9553 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9554 ExprResult Final =
9555 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9556 IS.CounterInit, IS.NumIterations, IS.CounterStep,
9557 IS.Subtract, IS.IsNonRectangularLB, &Captures);
9558 if (!Final.isUsable()) {
9559 HasErrors = true;
9560 break;
9561 }
9562
9563 if (!Update.isUsable() || !Final.isUsable()) {
9564 HasErrors = true;
9565 break;
9566 }
9567 // Save results
9568 Built.Counters[Cnt] = IS.CounterVar;
9569 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9570 Built.Inits[Cnt] = Init.get();
9571 Built.Updates[Cnt] = Update.get();
9572 Built.Finals[Cnt] = Final.get();
9573 Built.DependentCounters[Cnt] = nullptr;
9574 Built.DependentInits[Cnt] = nullptr;
9575 Built.FinalsConditions[Cnt] = nullptr;
9576 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9577 Built.DependentCounters[Cnt] =
9578 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9579 Built.DependentInits[Cnt] =
9580 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9581 Built.FinalsConditions[Cnt] = IS.FinalCondition;
9582 }
9583 }
9584 }
9585
9586 if (HasErrors)
9587 return 0;
9588
9589 // Save results
9590 Built.IterationVarRef = IV.get();
9591 Built.LastIteration = LastIteration.get();
9592 Built.NumIterations = NumIterations.get();
9593 Built.CalcLastIteration = SemaRef
9594 .ActOnFinishFullExpr(CalcLastIteration.get(),
9595 /*DiscardedValue=*/false)
9596 .get();
9597 Built.PreCond = PreCond.get();
9598 Built.PreInits = buildPreInits(C, Captures);
9599 Built.Cond = Cond.get();
9600 Built.Init = Init.get();
9601 Built.Inc = Inc.get();
9602 Built.LB = LB.get();
9603 Built.UB = UB.get();
9604 Built.IL = IL.get();
9605 Built.ST = ST.get();
9606 Built.EUB = EUB.get();
9607 Built.NLB = NextLB.get();
9608 Built.NUB = NextUB.get();
9609 Built.PrevLB = PrevLB.get();
9610 Built.PrevUB = PrevUB.get();
9611 Built.DistInc = DistInc.get();
9612 Built.PrevEUB = PrevEUB.get();
9613 Built.DistCombinedFields.LB = CombLB.get();
9614 Built.DistCombinedFields.UB = CombUB.get();
9615 Built.DistCombinedFields.EUB = CombEUB.get();
9616 Built.DistCombinedFields.Init = CombInit.get();
9617 Built.DistCombinedFields.Cond = CombCond.get();
9618 Built.DistCombinedFields.NLB = CombNextLB.get();
9619 Built.DistCombinedFields.NUB = CombNextUB.get();
9620 Built.DistCombinedFields.DistCond = CombDistCond.get();
9621 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9622
9623 return NestedLoopCount;
9624}
9625
9626static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9627 auto CollapseClauses =
9628 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9629 if (CollapseClauses.begin() != CollapseClauses.end())
9630 return (*CollapseClauses.begin())->getNumForLoops();
9631 return nullptr;
9632}
9633
9634static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9635 auto OrderedClauses =
9636 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9637 if (OrderedClauses.begin() != OrderedClauses.end())
9638 return (*OrderedClauses.begin())->getNumForLoops();
9639 return nullptr;
9640}
9641
9642static bool checkSimdlenSafelenSpecified(Sema &S,
9643 const ArrayRef<OMPClause *> Clauses) {
9644 const OMPSafelenClause *Safelen = nullptr;
9645 const OMPSimdlenClause *Simdlen = nullptr;
9646
9647 for (const OMPClause *Clause : Clauses) {
9648 if (Clause->getClauseKind() == OMPC_safelen)
9649 Safelen = cast<OMPSafelenClause>(Clause);
9650 else if (Clause->getClauseKind() == OMPC_simdlen)
9651 Simdlen = cast<OMPSimdlenClause>(Clause);
9652 if (Safelen && Simdlen)
9653 break;
9654 }
9655
9656 if (Simdlen && Safelen) {
9657 const Expr *SimdlenLength = Simdlen->getSimdlen();
9658 const Expr *SafelenLength = Safelen->getSafelen();
9659 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9660 SimdlenLength->isInstantiationDependent() ||
9661 SimdlenLength->containsUnexpandedParameterPack())
9662 return false;
9663 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9664 SafelenLength->isInstantiationDependent() ||
9665 SafelenLength->containsUnexpandedParameterPack())
9666 return false;
9667 Expr::EvalResult SimdlenResult, SafelenResult;
9668 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9669 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9670 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9671 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9672 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9673 // If both simdlen and safelen clauses are specified, the value of the
9674 // simdlen parameter must be less than or equal to the value of the safelen
9675 // parameter.
9676 if (SimdlenRes > SafelenRes) {
9677 S.Diag(SimdlenLength->getExprLoc(),
9678 diag::err_omp_wrong_simdlen_safelen_values)
9679 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9680 return true;
9681 }
9682 }
9683 return false;
9684}
9685
9686StmtResult
9687Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9688 SourceLocation StartLoc, SourceLocation EndLoc,
9689 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9690 if (!AStmt)
9691 return StmtError();
9692
9693 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
9694 OMPLoopBasedDirective::HelperExprs B;
9695 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9696 // define the nested loops number.
9697 unsigned NestedLoopCount = checkOpenMPLoop(
9698 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9699 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9700 if (NestedLoopCount == 0)
9701 return StmtError();
9702
9703 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
9704 "omp simd loop exprs were not built")(static_cast<void> (0));
9705
9706 if (!CurContext->isDependentContext()) {
9707 // Finalize the clauses that need pre-built expressions for CodeGen.
9708 for (OMPClause *C : Clauses) {
9709 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9710 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9711 B.NumIterations, *this, CurScope,
9712 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9713 return StmtError();
9714 }
9715 }
9716
9717 if (checkSimdlenSafelenSpecified(*this, Clauses))
9718 return StmtError();
9719
9720 setFunctionHasBranchProtectedScope();
9721 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9722 Clauses, AStmt, B);
9723}
9724
9725StmtResult
9726Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9727 SourceLocation StartLoc, SourceLocation EndLoc,
9728 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9729 if (!AStmt)
9730 return StmtError();
9731
9732 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
9733 OMPLoopBasedDirective::HelperExprs B;
9734 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9735 // define the nested loops number.
9736 unsigned NestedLoopCount = checkOpenMPLoop(
9737 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9738 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9739 if (NestedLoopCount == 0)
9740 return StmtError();
9741
9742 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
9743 "omp for loop exprs were not built")(static_cast<void> (0));
9744
9745 if (!CurContext->isDependentContext()) {
9746 // Finalize the clauses that need pre-built expressions for CodeGen.
9747 for (OMPClause *C : Clauses) {
9748 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9749 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9750 B.NumIterations, *this, CurScope,
9751 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9752 return StmtError();
9753 }
9754 }
9755
9756 setFunctionHasBranchProtectedScope();
9757 return OMPForDirective::Create(
9758 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9759 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9760}
9761
9762StmtResult Sema::ActOnOpenMPForSimdDirective(
9763 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9764 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9765 if (!AStmt)
9766 return StmtError();
9767
9768 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
9769 OMPLoopBasedDirective::HelperExprs B;
9770 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9771 // define the nested loops number.
9772 unsigned NestedLoopCount =
9773 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9774 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9775 VarsWithImplicitDSA, B);
9776 if (NestedLoopCount == 0)
9777 return StmtError();
9778
9779 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
9780 "omp for simd loop exprs were not built")(static_cast<void> (0));
9781
9782 if (!CurContext->isDependentContext()) {
9783 // Finalize the clauses that need pre-built expressions for CodeGen.
9784 for (OMPClause *C : Clauses) {
9785 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9786 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9787 B.NumIterations, *this, CurScope,
9788 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9789 return StmtError();
9790 }
9791 }
9792
9793 if (checkSimdlenSafelenSpecified(*this, Clauses))
9794 return StmtError();
9795
9796 setFunctionHasBranchProtectedScope();
9797 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9798 Clauses, AStmt, B);
9799}
9800
9801StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9802 Stmt *AStmt,
9803 SourceLocation StartLoc,
9804 SourceLocation EndLoc) {
9805 if (!AStmt)
9806 return StmtError();
9807
9808 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
9809 auto BaseStmt = AStmt;
9810 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9811 BaseStmt = CS->getCapturedStmt();
9812 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9813 auto S = C->children();
9814 if (S.begin() == S.end())
9815 return StmtError();
9816 // All associated statements must be '#pragma omp section' except for
9817 // the first one.
9818 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9819 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9820 if (SectionStmt)
9821 Diag(SectionStmt->getBeginLoc(),
9822 diag::err_omp_sections_substmt_not_section);
9823 return StmtError();
9824 }
9825 cast<OMPSectionDirective>(SectionStmt)
9826 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9827 }
9828 } else {
9829 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9830 return StmtError();
9831 }
9832
9833 setFunctionHasBranchProtectedScope();
9834
9835 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9836 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
9837 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9838}
9839
9840StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9841 SourceLocation StartLoc,
9842 SourceLocation EndLoc) {
9843 if (!AStmt)
9844 return StmtError();
9845
9846 setFunctionHasBranchProtectedScope();
9847 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9848
9849 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9850 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9851}
9852
9853static Expr *getDirectCallExpr(Expr *E) {
9854 E = E->IgnoreParenCasts()->IgnoreImplicit();
9855 if (auto *CE = dyn_cast<CallExpr>(E))
9856 if (CE->getDirectCallee())
9857 return E;
9858 return nullptr;
9859}
9860
9861StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
9862 Stmt *AStmt,
9863 SourceLocation StartLoc,
9864 SourceLocation EndLoc) {
9865 if (!AStmt)
9866 return StmtError();
9867
9868 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
9869
9870 // 5.1 OpenMP
9871 // expression-stmt : an expression statement with one of the following forms:
9872 // expression = target-call ( [expression-list] );
9873 // target-call ( [expression-list] );
9874
9875 SourceLocation TargetCallLoc;
9876
9877 if (!CurContext->isDependentContext()) {
9878 Expr *TargetCall = nullptr;
9879
9880 auto *E = dyn_cast<Expr>(S);
9881 if (!E) {
9882 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9883 return StmtError();
9884 }
9885
9886 E = E->IgnoreParenCasts()->IgnoreImplicit();
9887
9888 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
9889 if (BO->getOpcode() == BO_Assign)
9890 TargetCall = getDirectCallExpr(BO->getRHS());
9891 } else {
9892 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
9893 if (COCE->getOperator() == OO_Equal)
9894 TargetCall = getDirectCallExpr(COCE->getArg(1));
9895 if (!TargetCall)
9896 TargetCall = getDirectCallExpr(E);
9897 }
9898 if (!TargetCall) {
9899 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9900 return StmtError();
9901 }
9902 TargetCallLoc = TargetCall->getExprLoc();
9903 }
9904
9905 setFunctionHasBranchProtectedScope();
9906
9907 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9908 TargetCallLoc);
9909}
9910
9911StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9912 Stmt *AStmt,
9913 SourceLocation StartLoc,
9914 SourceLocation EndLoc) {
9915 if (!AStmt)
9916 return StmtError();
9917
9918 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
9919
9920 setFunctionHasBranchProtectedScope();
9921
9922 // OpenMP [2.7.3, single Construct, Restrictions]
9923 // The copyprivate clause must not be used with the nowait clause.
9924 const OMPClause *Nowait = nullptr;
9925 const OMPClause *Copyprivate = nullptr;
9926 for (const OMPClause *Clause : Clauses) {
9927 if (Clause->getClauseKind() == OMPC_nowait)
9928 Nowait = Clause;
9929 else if (Clause->getClauseKind() == OMPC_copyprivate)
9930 Copyprivate = Clause;
9931 if (Copyprivate && Nowait) {
9932 Diag(Copyprivate->getBeginLoc(),
9933 diag::err_omp_single_copyprivate_with_nowait);
9934 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9935 return StmtError();
9936 }
9937 }
9938
9939 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9940}
9941
9942StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9943 SourceLocation StartLoc,
9944 SourceLocation EndLoc) {
9945 if (!AStmt)
9946 return StmtError();
9947
9948 setFunctionHasBranchProtectedScope();
9949
9950 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9951}
9952
9953StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
9954 Stmt *AStmt,
9955 SourceLocation StartLoc,
9956 SourceLocation EndLoc) {
9957 if (!AStmt)
9958 return StmtError();
9959
9960 setFunctionHasBranchProtectedScope();
9961
9962 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9963}
9964
9965StmtResult Sema::ActOnOpenMPCriticalDirective(
9966 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9967 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9968 if (!AStmt)
9969 return StmtError();
9970
9971 bool ErrorFound = false;
9972 llvm::APSInt Hint;
9973 SourceLocation HintLoc;
9974 bool DependentHint = false;
9975 for (const OMPClause *C : Clauses) {
9976 if (C->getClauseKind() == OMPC_hint) {
9977 if (!DirName.getName()) {
9978 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9979 ErrorFound = true;
9980 }
9981 Expr *E = cast<OMPHintClause>(C)->getHint();
9982 if (E->isTypeDependent() || E->isValueDependent() ||
9983 E->isInstantiationDependent()) {
9984 DependentHint = true;
9985 } else {
9986 Hint = E->EvaluateKnownConstInt(Context);
9987 HintLoc = C->getBeginLoc();
9988 }
9989 }
9990 }
9991 if (ErrorFound)
9992 return StmtError();
9993 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
9994 if (Pair.first && DirName.getName() && !DependentHint) {
9995 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9996 Diag(StartLoc, diag::err_omp_critical_with_hint);
9997 if (HintLoc.isValid())
9998 Diag(HintLoc, diag::note_omp_critical_hint_here)
9999 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10000 else
10001 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10002 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10003 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10004 << 1
10005 << toString(C->getHint()->EvaluateKnownConstInt(Context),
10006 /*Radix=*/10, /*Signed=*/false);
10007 } else {
10008 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10009 }
10010 }
10011 }
10012
10013 setFunctionHasBranchProtectedScope();
10014
10015 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10016 Clauses, AStmt);
10017 if (!Pair.first && DirName.getName() && !DependentHint)
10018 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
10019 return Dir;
10020}
10021
10022StmtResult Sema::ActOnOpenMPParallelForDirective(
10023 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10024 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10025 if (!AStmt)
10026 return StmtError();
10027
10028 auto *CS = cast<CapturedStmt>(AStmt);
10029 // 1.2.2 OpenMP Language Terminology
10030 // Structured block - An executable statement with a single entry at the
10031 // top and a single exit at the bottom.
10032 // The point of exit cannot be a branch out of the structured block.
10033 // longjmp() and throw() must not violate the entry/exit criteria.
10034 CS->getCapturedDecl()->setNothrow();
10035
10036 OMPLoopBasedDirective::HelperExprs B;
10037 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10038 // define the nested loops number.
10039 unsigned NestedLoopCount =
10040 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10041 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10042 VarsWithImplicitDSA, B);
10043 if (NestedLoopCount == 0)
10044 return StmtError();
10045
10046 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
10047 "omp parallel for loop exprs were not built")(static_cast<void> (0));
10048
10049 if (!CurContext->isDependentContext()) {
10050 // Finalize the clauses that need pre-built expressions for CodeGen.
10051 for (OMPClause *C : Clauses) {
10052 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10053 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10054 B.NumIterations, *this, CurScope,
10055 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10056 return StmtError();
10057 }
10058 }
10059
10060 setFunctionHasBranchProtectedScope();
10061 return OMPParallelForDirective::Create(
10062 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10063 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10064}
10065
10066StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10067 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10068 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10069 if (!AStmt)
10070 return StmtError();
10071
10072 auto *CS = cast<CapturedStmt>(AStmt);
10073 // 1.2.2 OpenMP Language Terminology
10074 // Structured block - An executable statement with a single entry at the
10075 // top and a single exit at the bottom.
10076 // The point of exit cannot be a branch out of the structured block.
10077 // longjmp() and throw() must not violate the entry/exit criteria.
10078 CS->getCapturedDecl()->setNothrow();
10079
10080 OMPLoopBasedDirective::HelperExprs B;
10081 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10082 // define the nested loops number.
10083 unsigned NestedLoopCount =
10084 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10085 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10086 VarsWithImplicitDSA, B);
10087 if (NestedLoopCount == 0)
10088 return StmtError();
10089
10090 if (!CurContext->isDependentContext()) {
10091 // Finalize the clauses that need pre-built expressions for CodeGen.
10092 for (OMPClause *C : Clauses) {
10093 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10094 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10095 B.NumIterations, *this, CurScope,
10096 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10097 return StmtError();
10098 }
10099 }
10100
10101 if (checkSimdlenSafelenSpecified(*this, Clauses))
10102 return StmtError();
10103
10104 setFunctionHasBranchProtectedScope();
10105 return OMPParallelForSimdDirective::Create(
10106 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10107}
10108
10109StmtResult
10110Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10111 Stmt *AStmt, SourceLocation StartLoc,
10112 SourceLocation EndLoc) {
10113 if (!AStmt)
10114 return StmtError();
10115
10116 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
10117 auto *CS = cast<CapturedStmt>(AStmt);
10118 // 1.2.2 OpenMP Language Terminology
10119 // Structured block - An executable statement with a single entry at the
10120 // top and a single exit at the bottom.
10121 // The point of exit cannot be a branch out of the structured block.
10122 // longjmp() and throw() must not violate the entry/exit criteria.
10123 CS->getCapturedDecl()->setNothrow();
10124
10125 setFunctionHasBranchProtectedScope();
10126
10127 return OMPParallelMasterDirective::Create(
10128 Context, StartLoc, EndLoc, Clauses, AStmt,
10129 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10130}
10131
10132StmtResult
10133Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10134 Stmt *AStmt, SourceLocation StartLoc,
10135 SourceLocation EndLoc) {
10136 if (!AStmt)
10137 return StmtError();
10138
10139 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
10140 auto BaseStmt = AStmt;
10141 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10142 BaseStmt = CS->getCapturedStmt();
10143 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10144 auto S = C->children();
10145 if (S.begin() == S.end())
10146 return StmtError();
10147 // All associated statements must be '#pragma omp section' except for
10148 // the first one.
10149 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
10150 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10151 if (SectionStmt)
10152 Diag(SectionStmt->getBeginLoc(),
10153 diag::err_omp_parallel_sections_substmt_not_section);
10154 return StmtError();
10155 }
10156 cast<OMPSectionDirective>(SectionStmt)
10157 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10158 }
10159 } else {
10160 Diag(AStmt->getBeginLoc(),
10161 diag::err_omp_parallel_sections_not_compound_stmt);
10162 return StmtError();
10163 }
10164
10165 setFunctionHasBranchProtectedScope();
10166
10167 return OMPParallelSectionsDirective::Create(
10168 Context, StartLoc, EndLoc, Clauses, AStmt,
10169 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10170}
10171
10172/// Find and diagnose mutually exclusive clause kinds.
10173static bool checkMutuallyExclusiveClauses(
10174 Sema &S, ArrayRef<OMPClause *> Clauses,
10175 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10176 const OMPClause *PrevClause = nullptr;
10177 bool ErrorFound = false;
10178 for (const OMPClause *C : Clauses) {
10179 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10180 if (!PrevClause) {
10181 PrevClause = C;
10182 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10183 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10184 << getOpenMPClauseName(C->getClauseKind())
10185 << getOpenMPClauseName(PrevClause->getClauseKind());
10186 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10187 << getOpenMPClauseName(PrevClause->getClauseKind());
10188 ErrorFound = true;
10189 }
10190 }
10191 }
10192 return ErrorFound;
10193}
10194
10195StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10196 Stmt *AStmt, SourceLocation StartLoc,
10197 SourceLocation EndLoc) {
10198 if (!AStmt)
10199 return StmtError();
10200
10201 // OpenMP 5.0, 2.10.1 task Construct
10202 // If a detach clause appears on the directive, then a mergeable clause cannot
10203 // appear on the same directive.
10204 if (checkMutuallyExclusiveClauses(*this, Clauses,
10205 {OMPC_detach, OMPC_mergeable}))
10206 return StmtError();
10207
10208 auto *CS = cast<CapturedStmt>(AStmt);
10209 // 1.2.2 OpenMP Language Terminology
10210 // Structured block - An executable statement with a single entry at the
10211 // top and a single exit at the bottom.
10212 // The point of exit cannot be a branch out of the structured block.
10213 // longjmp() and throw() must not violate the entry/exit criteria.
10214 CS->getCapturedDecl()->setNothrow();
10215
10216 setFunctionHasBranchProtectedScope();
10217
10218 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10219 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10220}
10221
10222StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10223 SourceLocation EndLoc) {
10224 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10225}
10226
10227StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10228 SourceLocation EndLoc) {
10229 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10230}
10231
10232StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
10233 SourceLocation EndLoc) {
10234 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
10235}
10236
10237StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10238 Stmt *AStmt,
10239 SourceLocation StartLoc,
10240 SourceLocation EndLoc) {
10241 if (!AStmt)
10242 return StmtError();
10243
10244 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
10245
10246 setFunctionHasBranchProtectedScope();
10247
10248 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10249 AStmt,
10250 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10251}
10252
10253StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10254 SourceLocation StartLoc,
10255 SourceLocation EndLoc) {
10256 OMPFlushClause *FC = nullptr;
10257 OMPClause *OrderClause = nullptr;
10258 for (OMPClause *C : Clauses) {
10259 if (C->getClauseKind() == OMPC_flush)
10260 FC = cast<OMPFlushClause>(C);
10261 else
10262 OrderClause = C;
10263 }
10264 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10265 SourceLocation MemOrderLoc;
10266 for (const OMPClause *C : Clauses) {
10267 if (C->getClauseKind() == OMPC_acq_rel ||
10268 C->getClauseKind() == OMPC_acquire ||
10269 C->getClauseKind() == OMPC_release) {
10270 if (MemOrderKind != OMPC_unknown) {
10271 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10272 << getOpenMPDirectiveName(OMPD_flush) << 1
10273 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10274 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10275 << getOpenMPClauseName(MemOrderKind);
10276 } else {
10277 MemOrderKind = C->getClauseKind();
10278 MemOrderLoc = C->getBeginLoc();
10279 }
10280 }
10281 }
10282 if (FC && OrderClause) {
10283 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10284 << getOpenMPClauseName(OrderClause->getClauseKind());
10285 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10286 << getOpenMPClauseName(OrderClause->getClauseKind());
10287 return StmtError();
10288 }
10289 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10290}
10291
10292StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10293 SourceLocation StartLoc,
10294 SourceLocation EndLoc) {
10295 if (Clauses.empty()) {
10296 Diag(StartLoc, diag::err_omp_depobj_expected);
10297 return StmtError();
10298 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10299 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10300 return StmtError();
10301 }
10302 // Only depobj expression and another single clause is allowed.
10303 if (Clauses.size() > 2) {
10304 Diag(Clauses[2]->getBeginLoc(),
10305 diag::err_omp_depobj_single_clause_expected);
10306 return StmtError();
10307 } else if (Clauses.size() < 1) {
10308 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10309 return StmtError();
10310 }
10311 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10312}
10313
10314StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10315 SourceLocation StartLoc,
10316 SourceLocation EndLoc) {
10317 // Check that exactly one clause is specified.
10318 if (Clauses.size() != 1) {
10319 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10320 diag::err_omp_scan_single_clause_expected);
10321 return StmtError();
10322 }
10323 // Check that scan directive is used in the scopeof the OpenMP loop body.
10324 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
10325 Scope *ParentS = S->getParent();
10326 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10327 !ParentS->getBreakParent()->isOpenMPLoopScope())
10328 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10329 << getOpenMPDirectiveName(OMPD_scan) << 5);
10330 }
10331 // Check that only one instance of scan directives is used in the same outer
10332 // region.
10333 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
10334 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10335 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
10336 diag::note_omp_previous_directive)
10337 << "scan";
10338 return StmtError();
10339 }
10340 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
10341 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10342}
10343
10344StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10345 Stmt *AStmt,
10346 SourceLocation StartLoc,
10347 SourceLocation EndLoc) {
10348 const OMPClause *DependFound = nullptr;
10349 const OMPClause *DependSourceClause = nullptr;
10350 const OMPClause *DependSinkClause = nullptr;
10351 bool ErrorFound = false;
10352 const OMPThreadsClause *TC = nullptr;
10353 const OMPSIMDClause *SC = nullptr;
10354 for (const OMPClause *C : Clauses) {
10355 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10356 DependFound = C;
10357 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10358 if (DependSourceClause) {
10359 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10360 << getOpenMPDirectiveName(OMPD_ordered)
10361 << getOpenMPClauseName(OMPC_depend) << 2;
10362 ErrorFound = true;
10363 } else {
10364 DependSourceClause = C;
10365 }
10366 if (DependSinkClause) {
10367 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10368 << 0;
10369 ErrorFound = true;
10370 }
10371 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10372 if (DependSourceClause) {
10373 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10374 << 1;
10375 ErrorFound = true;
10376 }
10377 DependSinkClause = C;
10378 }
10379 } else if (C->getClauseKind() == OMPC_threads) {
10380 TC = cast<OMPThreadsClause>(C);
10381 } else if (C->getClauseKind() == OMPC_simd) {
10382 SC = cast<OMPSIMDClause>(C);
10383 }
10384 }
10385 if (!ErrorFound && !SC &&
10386 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
10387 // OpenMP [2.8.1,simd Construct, Restrictions]
10388 // An ordered construct with the simd clause is the only OpenMP construct
10389 // that can appear in the simd region.
10390 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10391 << (LangOpts.OpenMP >= 50 ? 1 : 0);
10392 ErrorFound = true;
10393 } else if (DependFound && (TC || SC)) {
10394 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10395 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10396 ErrorFound = true;
10397 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10398 Diag(DependFound->getBeginLoc(),
10399 diag::err_omp_ordered_directive_without_param);
10400 ErrorFound = true;
10401 } else if (TC || Clauses.empty()) {
10402 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10403 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10404 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10405 << (TC != nullptr);
10406 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10407 ErrorFound = true;
10408 }
10409 }
10410 if ((!AStmt && !DependFound) || ErrorFound)
10411 return StmtError();
10412
10413 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10414 // During execution of an iteration of a worksharing-loop or a loop nest
10415 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10416 // must not execute more than one ordered region corresponding to an ordered
10417 // construct without a depend clause.
10418 if (!DependFound) {
10419 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
10420 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10421 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
10422 diag::note_omp_previous_directive)
10423 << "ordered";
10424 return StmtError();
10425 }
10426 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
10427 }
10428
10429 if (AStmt) {
10430 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
10431
10432 setFunctionHasBranchProtectedScope();
10433 }
10434
10435 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10436}
10437
10438namespace {
10439/// Helper class for checking expression in 'omp atomic [update]'
10440/// construct.
10441class OpenMPAtomicUpdateChecker {
10442 /// Error results for atomic update expressions.
10443 enum ExprAnalysisErrorCode {
10444 /// A statement is not an expression statement.
10445 NotAnExpression,
10446 /// Expression is not builtin binary or unary operation.
10447 NotABinaryOrUnaryExpression,
10448 /// Unary operation is not post-/pre- increment/decrement operation.
10449 NotAnUnaryIncDecExpression,
10450 /// An expression is not of scalar type.
10451 NotAScalarType,
10452 /// A binary operation is not an assignment operation.
10453 NotAnAssignmentOp,
10454 /// RHS part of the binary operation is not a binary expression.
10455 NotABinaryExpression,
10456 /// RHS part is not additive/multiplicative/shift/biwise binary
10457 /// expression.
10458 NotABinaryOperator,
10459 /// RHS binary operation does not have reference to the updated LHS
10460 /// part.
10461 NotAnUpdateExpression,
10462 /// No errors is found.
10463 NoError
10464 };
10465 /// Reference to Sema.
10466 Sema &SemaRef;
10467 /// A location for note diagnostics (when error is found).
10468 SourceLocation NoteLoc;
10469 /// 'x' lvalue part of the source atomic expression.
10470 Expr *X;
10471 /// 'expr' rvalue part of the source atomic expression.
10472 Expr *E;
10473 /// Helper expression of the form
10474 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10475 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10476 Expr *UpdateExpr;
10477 /// Is 'x' a LHS in a RHS part of full update expression. It is
10478 /// important for non-associative operations.
10479 bool IsXLHSInRHSPart;
10480 BinaryOperatorKind Op;
10481 SourceLocation OpLoc;
10482 /// true if the source expression is a postfix unary operation, false
10483 /// if it is a prefix unary operation.
10484 bool IsPostfixUpdate;
10485
10486public:
10487 OpenMPAtomicUpdateChecker(Sema &SemaRef)
10488 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10489 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10490 /// Check specified statement that it is suitable for 'atomic update'
10491 /// constructs and extract 'x', 'expr' and Operation from the original
10492 /// expression. If DiagId and NoteId == 0, then only check is performed
10493 /// without error notification.
10494 /// \param DiagId Diagnostic which should be emitted if error is found.
10495 /// \param NoteId Diagnostic note for the main error message.
10496 /// \return true if statement is not an update expression, false otherwise.
10497 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10498 /// Return the 'x' lvalue part of the source atomic expression.
10499 Expr *getX() const { return X; }
10500 /// Return the 'expr' rvalue part of the source atomic expression.
10501 Expr *getExpr() const { return E; }
10502 /// Return the update expression used in calculation of the updated
10503 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10504 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10505 Expr *getUpdateExpr() const { return UpdateExpr; }
10506 /// Return true if 'x' is LHS in RHS part of full update expression,
10507 /// false otherwise.
10508 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10509
10510 /// true if the source expression is a postfix unary operation, false
10511 /// if it is a prefix unary operation.
10512 bool isPostfixUpdate() const { return IsPostfixUpdate; }
10513
10514private:
10515 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10516 unsigned NoteId = 0);
10517};
10518} // namespace
10519
10520bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10521 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10522 ExprAnalysisErrorCode ErrorFound = NoError;
10523 SourceLocation ErrorLoc, NoteLoc;
10524 SourceRange ErrorRange, NoteRange;
10525 // Allowed constructs are:
10526 // x = x binop expr;
10527 // x = expr binop x;
10528 if (AtomicBinOp->getOpcode() == BO_Assign) {
10529 X = AtomicBinOp->getLHS();
10530 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10531 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10532 if (AtomicInnerBinOp->isMultiplicativeOp() ||
10533 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10534 AtomicInnerBinOp->isBitwiseOp()) {
10535 Op = AtomicInnerBinOp->getOpcode();
10536 OpLoc = AtomicInnerBinOp->getOperatorLoc();
10537 Expr *LHS = AtomicInnerBinOp->getLHS();
10538 Expr *RHS = AtomicInnerBinOp->getRHS();
10539 llvm::FoldingSetNodeID XId, LHSId, RHSId;
10540 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10541 /*Canonical=*/true);
10542 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10543 /*Canonical=*/true);
10544 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10545 /*Canonical=*/true);
10546 if (XId == LHSId) {
10547 E = RHS;
10548 IsXLHSInRHSPart = true;
10549 } else if (XId == RHSId) {
10550 E = LHS;
10551 IsXLHSInRHSPart = false;
10552 } else {
10553 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10554 ErrorRange = AtomicInnerBinOp->getSourceRange();
10555 NoteLoc = X->getExprLoc();
10556 NoteRange = X->getSourceRange();
10557 ErrorFound = NotAnUpdateExpression;
10558 }
10559 } else {
10560 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10561 ErrorRange = AtomicInnerBinOp->getSourceRange();
10562 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10563 NoteRange = SourceRange(NoteLoc, NoteLoc);
10564 ErrorFound = NotABinaryOperator;
10565 }
10566 } else {
10567 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10568 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10569 ErrorFound = NotABinaryExpression;
10570 }
10571 } else {
10572 ErrorLoc = AtomicBinOp->getExprLoc();
10573 ErrorRange = AtomicBinOp->getSourceRange();
10574 NoteLoc = AtomicBinOp->getOperatorLoc();
10575 NoteRange = SourceRange(NoteLoc, NoteLoc);
10576 ErrorFound = NotAnAssignmentOp;
10577 }
10578 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10579 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10580 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10581 return true;
10582 }
10583 if (SemaRef.CurContext->isDependentContext())
10584 E = X = UpdateExpr = nullptr;
10585 return ErrorFound != NoError;
10586}
10587
10588bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10589 unsigned NoteId) {
10590 ExprAnalysisErrorCode ErrorFound = NoError;
10591 SourceLocation ErrorLoc, NoteLoc;
10592 SourceRange ErrorRange, NoteRange;
10593 // Allowed constructs are:
10594 // x++;
10595 // x--;
10596 // ++x;
10597 // --x;
10598 // x binop= expr;
10599 // x = x binop expr;
10600 // x = expr binop x;
10601 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10602 AtomicBody = AtomicBody->IgnoreParenImpCasts();
10603 if (AtomicBody->getType()->isScalarType() ||
10604 AtomicBody->isInstantiationDependent()) {
10605 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10606 AtomicBody->IgnoreParenImpCasts())) {
10607 // Check for Compound Assignment Operation
10608 Op = BinaryOperator::getOpForCompoundAssignment(
10609 AtomicCompAssignOp->getOpcode());
10610 OpLoc = AtomicCompAssignOp->getOperatorLoc();
10611 E = AtomicCompAssignOp->getRHS();
10612 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10613 IsXLHSInRHSPart = true;
10614 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10615 AtomicBody->IgnoreParenImpCasts())) {
10616 // Check for Binary Operation
10617 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10618 return true;
10619 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10620 AtomicBody->IgnoreParenImpCasts())) {
10621 // Check for Unary Operation
10622 if (AtomicUnaryOp->isIncrementDecrementOp()) {
10623 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10624 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10625 OpLoc = AtomicUnaryOp->getOperatorLoc();
10626 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10627 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10628 IsXLHSInRHSPart = true;
10629 } else {
10630 ErrorFound = NotAnUnaryIncDecExpression;
10631 ErrorLoc = AtomicUnaryOp->getExprLoc();
10632 ErrorRange = AtomicUnaryOp->getSourceRange();
10633 NoteLoc = AtomicUnaryOp->getOperatorLoc();
10634 NoteRange = SourceRange(NoteLoc, NoteLoc);
10635 }
10636 } else if (!AtomicBody->isInstantiationDependent()) {
10637 ErrorFound = NotABinaryOrUnaryExpression;
10638 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10639 NoteRange = ErrorRange = AtomicBody->getSourceRange();
10640 }
10641 } else {
10642 ErrorFound = NotAScalarType;
10643 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10644 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10645 }
10646 } else {
10647 ErrorFound = NotAnExpression;
10648 NoteLoc = ErrorLoc = S->getBeginLoc();
10649 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10650 }
10651 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10652 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10653 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10654 return true;
10655 }
10656 if (SemaRef.CurContext->isDependentContext())
10657 E = X = UpdateExpr = nullptr;
10658 if (ErrorFound == NoError && E && X) {
10659 // Build an update expression of form 'OpaqueValueExpr(x) binop
10660 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10661 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10662 auto *OVEX = new (SemaRef.getASTContext())
10663 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
10664 auto *OVEExpr = new (SemaRef.getASTContext())
10665 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
10666 ExprResult Update =
10667 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10668 IsXLHSInRHSPart ? OVEExpr : OVEX);
10669 if (Update.isInvalid())
10670 return true;
10671 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10672 Sema::AA_Casting);
10673 if (Update.isInvalid())
10674 return true;
10675 UpdateExpr = Update.get();
10676 }
10677 return ErrorFound != NoError;
10678}
10679
10680StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10681 Stmt *AStmt,
10682 SourceLocation StartLoc,
10683 SourceLocation EndLoc) {
10684 // Register location of the first atomic directive.
10685 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
10686 if (!AStmt)
10687 return StmtError();
10688
10689 // 1.2.2 OpenMP Language Terminology
10690 // Structured block - An executable statement with a single entry at the
10691 // top and a single exit at the bottom.
10692 // The point of exit cannot be a branch out of the structured block.
10693 // longjmp() and throw() must not violate the entry/exit criteria.
10694 OpenMPClauseKind AtomicKind = OMPC_unknown;
10695 SourceLocation AtomicKindLoc;
10696 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10697 SourceLocation MemOrderLoc;
10698 for (const OMPClause *C : Clauses) {
10699 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10700 C->getClauseKind() == OMPC_update ||
10701 C->getClauseKind() == OMPC_capture) {
10702 if (AtomicKind != OMPC_unknown) {
10703 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10704 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10705 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10706 << getOpenMPClauseName(AtomicKind);
10707 } else {
10708 AtomicKind = C->getClauseKind();
10709 AtomicKindLoc = C->getBeginLoc();
10710 }
10711 }
10712 if (C->getClauseKind() == OMPC_seq_cst ||
10713 C->getClauseKind() == OMPC_acq_rel ||
10714 C->getClauseKind() == OMPC_acquire ||
10715 C->getClauseKind() == OMPC_release ||
10716 C->getClauseKind() == OMPC_relaxed) {
10717 if (MemOrderKind != OMPC_unknown) {
10718 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10719 << getOpenMPDirectiveName(OMPD_atomic) << 0
10720 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10721 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10722 << getOpenMPClauseName(MemOrderKind);
10723 } else {
10724 MemOrderKind = C->getClauseKind();
10725 MemOrderLoc = C->getBeginLoc();
10726 }
10727 }
10728 }
10729 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10730 // If atomic-clause is read then memory-order-clause must not be acq_rel or
10731 // release.
10732 // If atomic-clause is write then memory-order-clause must not be acq_rel or
10733 // acquire.
10734 // If atomic-clause is update or not present then memory-order-clause must not
10735 // be acq_rel or acquire.
10736 if ((AtomicKind == OMPC_read &&
10737 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10738 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10739 AtomicKind == OMPC_unknown) &&
10740 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10741 SourceLocation Loc = AtomicKindLoc;
10742 if (AtomicKind == OMPC_unknown)
10743 Loc = StartLoc;
10744 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10745 << getOpenMPClauseName(AtomicKind)
10746 << (AtomicKind == OMPC_unknown ? 1 : 0)
10747 << getOpenMPClauseName(MemOrderKind);
10748 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10749 << getOpenMPClauseName(MemOrderKind);
10750 }
10751
10752 Stmt *Body = AStmt;
10753 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10754 Body = EWC->getSubExpr();
10755
10756 Expr *X = nullptr;
10757 Expr *V = nullptr;
10758 Expr *E = nullptr;
10759 Expr *UE = nullptr;
10760 bool IsXLHSInRHSPart = false;
10761 bool IsPostfixUpdate = false;
10762 // OpenMP [2.12.6, atomic Construct]
10763 // In the next expressions:
10764 // * x and v (as applicable) are both l-value expressions with scalar type.
10765 // * During the execution of an atomic region, multiple syntactic
10766 // occurrences of x must designate the same storage location.
10767 // * Neither of v and expr (as applicable) may access the storage location
10768 // designated by x.
10769 // * Neither of x and expr (as applicable) may access the storage location
10770 // designated by v.
10771 // * expr is an expression with scalar type.
10772 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10773 // * binop, binop=, ++, and -- are not overloaded operators.
10774 // * The expression x binop expr must be numerically equivalent to x binop
10775 // (expr). This requirement is satisfied if the operators in expr have
10776 // precedence greater than binop, or by using parentheses around expr or
10777 // subexpressions of expr.
10778 // * The expression expr binop x must be numerically equivalent to (expr)
10779 // binop x. This requirement is satisfied if the operators in expr have
10780 // precedence equal to or greater than binop, or by using parentheses around
10781 // expr or subexpressions of expr.
10782 // * For forms that allow multiple occurrences of x, the number of times
10783 // that x is evaluated is unspecified.
10784 if (AtomicKind == OMPC_read) {
10785 enum {
10786 NotAnExpression,
10787 NotAnAssignmentOp,
10788 NotAScalarType,
10789 NotAnLValue,
10790 NoError
10791 } ErrorFound = NoError;
10792 SourceLocation ErrorLoc, NoteLoc;
10793 SourceRange ErrorRange, NoteRange;
10794 // If clause is read:
10795 // v = x;
10796 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10797 const auto *AtomicBinOp =
10798 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10799 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10800 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10801 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10802 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10803 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10804 if (!X->isLValue() || !V->isLValue()) {
10805 const Expr *NotLValueExpr = X->isLValue() ? V : X;
10806 ErrorFound = NotAnLValue;
10807 ErrorLoc = AtomicBinOp->getExprLoc();
10808 ErrorRange = AtomicBinOp->getSourceRange();
10809 NoteLoc = NotLValueExpr->getExprLoc();
10810 NoteRange = NotLValueExpr->getSourceRange();
10811 }
10812 } else if (!X->isInstantiationDependent() ||
10813 !V->isInstantiationDependent()) {
10814 const Expr *NotScalarExpr =
10815 (X->isInstantiationDependent() || X->getType()->isScalarType())
10816 ? V
10817 : X;
10818 ErrorFound = NotAScalarType;
10819 ErrorLoc = AtomicBinOp->getExprLoc();
10820 ErrorRange = AtomicBinOp->getSourceRange();
10821 NoteLoc = NotScalarExpr->getExprLoc();
10822 NoteRange = NotScalarExpr->getSourceRange();
10823 }
10824 } else if (!AtomicBody->isInstantiationDependent()) {
10825 ErrorFound = NotAnAssignmentOp;
10826 ErrorLoc = AtomicBody->getExprLoc();
10827 ErrorRange = AtomicBody->getSourceRange();
10828 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10829 : AtomicBody->getExprLoc();
10830 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10831 : AtomicBody->getSourceRange();
10832 }
10833 } else {
10834 ErrorFound = NotAnExpression;
10835 NoteLoc = ErrorLoc = Body->getBeginLoc();
10836 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10837 }
10838 if (ErrorFound != NoError) {
10839 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10840 << ErrorRange;
10841 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10842 << NoteRange;
10843 return StmtError();
10844 }
10845 if (CurContext->isDependentContext())
10846 V = X = nullptr;
10847 } else if (AtomicKind == OMPC_write) {
10848 enum {
10849 NotAnExpression,
10850 NotAnAssignmentOp,
10851 NotAScalarType,
10852 NotAnLValue,
10853 NoError
10854 } ErrorFound = NoError;
10855 SourceLocation ErrorLoc, NoteLoc;
10856 SourceRange ErrorRange, NoteRange;
10857 // If clause is write:
10858 // x = expr;
10859 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10860 const auto *AtomicBinOp =
10861 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10862 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10863 X = AtomicBinOp->getLHS();
10864 E = AtomicBinOp->getRHS();
10865 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10866 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10867 if (!X->isLValue()) {
10868 ErrorFound = NotAnLValue;
10869 ErrorLoc = AtomicBinOp->getExprLoc();
10870 ErrorRange = AtomicBinOp->getSourceRange();
10871 NoteLoc = X->getExprLoc();
10872 NoteRange = X->getSourceRange();
10873 }
10874 } else if (!X->isInstantiationDependent() ||
10875 !E->isInstantiationDependent()) {
10876 const Expr *NotScalarExpr =
10877 (X->isInstantiationDependent() || X->getType()->isScalarType())
10878 ? E
10879 : X;
10880 ErrorFound = NotAScalarType;
10881 ErrorLoc = AtomicBinOp->getExprLoc();
10882 ErrorRange = AtomicBinOp->getSourceRange();
10883 NoteLoc = NotScalarExpr->getExprLoc();
10884 NoteRange = NotScalarExpr->getSourceRange();
10885 }
10886 } else if (!AtomicBody->isInstantiationDependent()) {
10887 ErrorFound = NotAnAssignmentOp;
10888 ErrorLoc = AtomicBody->getExprLoc();
10889 ErrorRange = AtomicBody->getSourceRange();
10890 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10891 : AtomicBody->getExprLoc();
10892 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10893 : AtomicBody->getSourceRange();
10894 }
10895 } else {
10896 ErrorFound = NotAnExpression;
10897 NoteLoc = ErrorLoc = Body->getBeginLoc();
10898 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10899 }
10900 if (ErrorFound != NoError) {
10901 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10902 << ErrorRange;
10903 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10904 << NoteRange;
10905 return StmtError();
10906 }
10907 if (CurContext->isDependentContext())
10908 E = X = nullptr;
10909 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10910 // If clause is update:
10911 // x++;
10912 // x--;
10913 // ++x;
10914 // --x;
10915 // x binop= expr;
10916 // x = x binop expr;
10917 // x = expr binop x;
10918 OpenMPAtomicUpdateChecker Checker(*this);
10919 if (Checker.checkStatement(
10920 Body, (AtomicKind == OMPC_update)
10921 ? diag::err_omp_atomic_update_not_expression_statement
10922 : diag::err_omp_atomic_not_expression_statement,
10923 diag::note_omp_atomic_update))
10924 return StmtError();
10925 if (!CurContext->isDependentContext()) {
10926 E = Checker.getExpr();
10927 X = Checker.getX();
10928 UE = Checker.getUpdateExpr();
10929 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10930 }
10931 } else if (AtomicKind == OMPC_capture) {
10932 enum {
10933 NotAnAssignmentOp,
10934 NotACompoundStatement,
10935 NotTwoSubstatements,
10936 NotASpecificExpression,
10937 NoError
10938 } ErrorFound = NoError;
10939 SourceLocation ErrorLoc, NoteLoc;
10940 SourceRange ErrorRange, NoteRange;
10941 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10942 // If clause is a capture:
10943 // v = x++;
10944 // v = x--;
10945 // v = ++x;
10946 // v = --x;
10947 // v = x binop= expr;
10948 // v = x = x binop expr;
10949 // v = x = expr binop x;
10950 const auto *AtomicBinOp =
10951 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10952 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10953 V = AtomicBinOp->getLHS();
10954 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10955 OpenMPAtomicUpdateChecker Checker(*this);
10956 if (Checker.checkStatement(
10957 Body, diag::err_omp_atomic_capture_not_expression_statement,
10958 diag::note_omp_atomic_update))
10959 return StmtError();
10960 E = Checker.getExpr();
10961 X = Checker.getX();
10962 UE = Checker.getUpdateExpr();
10963 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10964 IsPostfixUpdate = Checker.isPostfixUpdate();
10965 } else if (!AtomicBody->isInstantiationDependent()) {
10966 ErrorLoc = AtomicBody->getExprLoc();
10967 ErrorRange = AtomicBody->getSourceRange();
10968 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10969 : AtomicBody->getExprLoc();
10970 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10971 : AtomicBody->getSourceRange();
10972 ErrorFound = NotAnAssignmentOp;
10973 }
10974 if (ErrorFound != NoError) {
10975 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10976 << ErrorRange;
10977 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10978 return StmtError();
10979 }
10980 if (CurContext->isDependentContext())
10981 UE = V = E = X = nullptr;
10982 } else {
10983 // If clause is a capture:
10984 // { v = x; x = expr; }
10985 // { v = x; x++; }
10986 // { v = x; x--; }
10987 // { v = x; ++x; }
10988 // { v = x; --x; }
10989 // { v = x; x binop= expr; }
10990 // { v = x; x = x binop expr; }
10991 // { v = x; x = expr binop x; }
10992 // { x++; v = x; }
10993 // { x--; v = x; }
10994 // { ++x; v = x; }
10995 // { --x; v = x; }
10996 // { x binop= expr; v = x; }
10997 // { x = x binop expr; v = x; }
10998 // { x = expr binop x; v = x; }
10999 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
11000 // Check that this is { expr1; expr2; }
11001 if (CS->size() == 2) {
11002 Stmt *First = CS->body_front();
11003 Stmt *Second = CS->body_back();
11004 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
11005 First = EWC->getSubExpr()->IgnoreParenImpCasts();
11006 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
11007 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
11008 // Need to find what subexpression is 'v' and what is 'x'.
11009 OpenMPAtomicUpdateChecker Checker(*this);
11010 bool IsUpdateExprFound = !Checker.checkStatement(Second);
11011 BinaryOperator *BinOp = nullptr;
11012 if (IsUpdateExprFound) {
11013 BinOp = dyn_cast<BinaryOperator>(First);
11014 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
11015 }
11016 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
11017 // { v = x; x++; }
11018 // { v = x; x--; }
11019 // { v = x; ++x; }
11020 // { v = x; --x; }
11021 // { v = x; x binop= expr; }
11022 // { v = x; x = x binop expr; }
11023 // { v = x; x = expr binop x; }
11024 // Check that the first expression has form v = x.
11025 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11026 llvm::FoldingSetNodeID XId, PossibleXId;
11027 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11028 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11029 IsUpdateExprFound = XId == PossibleXId;
11030 if (IsUpdateExprFound) {
11031 V = BinOp->getLHS();
11032 X = Checker.getX();
11033 E = Checker.getExpr();
11034 UE = Checker.getUpdateExpr();
11035 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11036 IsPostfixUpdate = true;
11037 }
11038 }
11039 if (!IsUpdateExprFound) {
11040 IsUpdateExprFound = !Checker.checkStatement(First);
11041 BinOp = nullptr;
11042 if (IsUpdateExprFound) {
11043 BinOp = dyn_cast<BinaryOperator>(Second);
11044 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
11045 }
11046 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
11047 // { x++; v = x; }
11048 // { x--; v = x; }
11049 // { ++x; v = x; }
11050 // { --x; v = x; }
11051 // { x binop= expr; v = x; }
11052 // { x = x binop expr; v = x; }
11053 // { x = expr binop x; v = x; }
11054 // Check that the second expression has form v = x.
11055 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11056 llvm::FoldingSetNodeID XId, PossibleXId;
11057 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11058 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11059 IsUpdateExprFound = XId == PossibleXId;
11060 if (IsUpdateExprFound) {
11061 V = BinOp->getLHS();
11062 X = Checker.getX();
11063 E = Checker.getExpr();
11064 UE = Checker.getUpdateExpr();
11065 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11066 IsPostfixUpdate = false;
11067 }
11068 }
11069 }
11070 if (!IsUpdateExprFound) {
11071 // { v = x; x = expr; }
11072 auto *FirstExpr = dyn_cast<Expr>(First);
11073 auto *SecondExpr = dyn_cast<Expr>(Second);
11074 if (!FirstExpr || !SecondExpr ||
11075 !(FirstExpr->isInstantiationDependent() ||
11076 SecondExpr->isInstantiationDependent())) {
11077 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
11078 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
11079 ErrorFound = NotAnAssignmentOp;
11080 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
11081 : First->getBeginLoc();
11082 NoteRange = ErrorRange = FirstBinOp
11083 ? FirstBinOp->getSourceRange()
11084 : SourceRange(ErrorLoc, ErrorLoc);
11085 } else {
11086 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
11087 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
11088 ErrorFound = NotAnAssignmentOp;
11089 NoteLoc = ErrorLoc = SecondBinOp
11090 ? SecondBinOp->getOperatorLoc()
11091 : Second->getBeginLoc();
11092 NoteRange = ErrorRange =
11093 SecondBinOp ? SecondBinOp->getSourceRange()
11094 : SourceRange(ErrorLoc, ErrorLoc);
11095 } else {
11096 Expr *PossibleXRHSInFirst =
11097 FirstBinOp->getRHS()->IgnoreParenImpCasts();
11098 Expr *PossibleXLHSInSecond =
11099 SecondBinOp->getLHS()->IgnoreParenImpCasts();
11100 llvm::FoldingSetNodeID X1Id, X2Id;
11101 PossibleXRHSInFirst->Profile(X1Id, Context,
11102 /*Canonical=*/true);
11103 PossibleXLHSInSecond->Profile(X2Id, Context,
11104 /*Canonical=*/true);
11105 IsUpdateExprFound = X1Id == X2Id;
11106 if (IsUpdateExprFound) {
11107 V = FirstBinOp->getLHS();
11108 X = SecondBinOp->getLHS();
11109 E = SecondBinOp->getRHS();
11110 UE = nullptr;
11111 IsXLHSInRHSPart = false;
11112 IsPostfixUpdate = true;
11113 } else {
11114 ErrorFound = NotASpecificExpression;
11115 ErrorLoc = FirstBinOp->getExprLoc();
11116 ErrorRange = FirstBinOp->getSourceRange();
11117 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
11118 NoteRange = SecondBinOp->getRHS()->getSourceRange();
11119 }
11120 }
11121 }
11122 }
11123 }
11124 } else {
11125 NoteLoc = ErrorLoc = Body->getBeginLoc();
11126 NoteRange = ErrorRange =
11127 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11128 ErrorFound = NotTwoSubstatements;
11129 }
11130 } else {
11131 NoteLoc = ErrorLoc = Body->getBeginLoc();
11132 NoteRange = ErrorRange =
11133 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11134 ErrorFound = NotACompoundStatement;
11135 }
11136 if (ErrorFound != NoError) {
11137 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
11138 << ErrorRange;
11139 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11140 return StmtError();
11141 }
11142 if (CurContext->isDependentContext())
11143 UE = V = E = X = nullptr;
11144 }
11145 }
11146
11147 setFunctionHasBranchProtectedScope();
11148
11149 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11150 X, V, E, UE, IsXLHSInRHSPart,
11151 IsPostfixUpdate);
11152}
11153
11154StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
11155 Stmt *AStmt,
11156 SourceLocation StartLoc,
11157 SourceLocation EndLoc) {
11158 if (!AStmt)
11159 return StmtError();
11160
11161 auto *CS = cast<CapturedStmt>(AStmt);
11162 // 1.2.2 OpenMP Language Terminology
11163 // Structured block - An executable statement with a single entry at the
11164 // top and a single exit at the bottom.
11165 // The point of exit cannot be a branch out of the structured block.
11166 // longjmp() and throw() must not violate the entry/exit criteria.
11167 CS->getCapturedDecl()->setNothrow();
11168 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
11169 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11170 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11171 // 1.2.2 OpenMP Language Terminology
11172 // Structured block - An executable statement with a single entry at the
11173 // top and a single exit at the bottom.
11174 // The point of exit cannot be a branch out of the structured block.
11175 // longjmp() and throw() must not violate the entry/exit criteria.
11176 CS->getCapturedDecl()->setNothrow();
11177 }
11178
11179 // OpenMP [2.16, Nesting of Regions]
11180 // If specified, a teams construct must be contained within a target
11181 // construct. That target construct must contain no statements or directives
11182 // outside of the teams construct.
11183 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
11184 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
11185 bool OMPTeamsFound = true;
11186 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
11187 auto I = CS->body_begin();
11188 while (I != CS->body_end()) {
11189 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
11190 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
11191 OMPTeamsFound) {
11192
11193 OMPTeamsFound = false;
11194 break;
11195 }
11196 ++I;
11197 }
11198 assert(I != CS->body_end() && "Not found statement")(static_cast<void> (0));
11199 S = *I;
11200 } else {
11201 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
11202 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
11203 }
11204 if (!OMPTeamsFound) {
11205 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
11206 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
11207 diag::note_omp_nested_teams_construct_here);
11208 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
11209 << isa<OMPExecutableDirective>(S);
11210 return StmtError();
11211 }
11212 }
11213
11214 setFunctionHasBranchProtectedScope();
11215
11216 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11217}
11218
11219StmtResult
11220Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
11221 Stmt *AStmt, SourceLocation StartLoc,
11222 SourceLocation EndLoc) {
11223 if (!AStmt)
11224 return StmtError();
11225
11226 auto *CS = cast<CapturedStmt>(AStmt);
11227 // 1.2.2 OpenMP Language Terminology
11228 // Structured block - An executable statement with a single entry at the
11229 // top and a single exit at the bottom.
11230 // The point of exit cannot be a branch out of the structured block.
11231 // longjmp() and throw() must not violate the entry/exit criteria.
11232 CS->getCapturedDecl()->setNothrow();
11233 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
11234 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11235 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11236 // 1.2.2 OpenMP Language Terminology
11237 // Structured block - An executable statement with a single entry at the
11238 // top and a single exit at the bottom.
11239 // The point of exit cannot be a branch out of the structured block.
11240 // longjmp() and throw() must not violate the entry/exit criteria.
11241 CS->getCapturedDecl()->setNothrow();
11242 }
11243
11244 setFunctionHasBranchProtectedScope();
11245
11246 return OMPTargetParallelDirective::Create(
11247 Context, StartLoc, EndLoc, Clauses, AStmt,
11248 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11249}
11250
11251StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
11252 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11253 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11254 if (!AStmt)
11255 return StmtError();
11256
11257 auto *CS = cast<CapturedStmt>(AStmt);
11258 // 1.2.2 OpenMP Language Terminology
11259 // Structured block - An executable statement with a single entry at the
11260 // top and a single exit at the bottom.
11261 // The point of exit cannot be a branch out of the structured block.
11262 // longjmp() and throw() must not violate the entry/exit criteria.
11263 CS->getCapturedDecl()->setNothrow();
11264 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11265 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11266 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11267 // 1.2.2 OpenMP Language Terminology
11268 // Structured block - An executable statement with a single entry at the
11269 // top and a single exit at the bottom.
11270 // The point of exit cannot be a branch out of the structured block.
11271 // longjmp() and throw() must not violate the entry/exit criteria.
11272 CS->getCapturedDecl()->setNothrow();
11273 }
11274
11275 OMPLoopBasedDirective::HelperExprs B;
11276 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11277 // define the nested loops number.
11278 unsigned NestedLoopCount =
11279 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
11280 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11281 VarsWithImplicitDSA, B);
11282 if (NestedLoopCount == 0)
11283 return StmtError();
11284
11285 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11286 "omp target parallel for loop exprs were not built")(static_cast<void> (0));
11287
11288 if (!CurContext->isDependentContext()) {
11289 // Finalize the clauses that need pre-built expressions for CodeGen.
11290 for (OMPClause *C : Clauses) {
11291 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11292 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11293 B.NumIterations, *this, CurScope,
11294 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11295 return StmtError();
11296 }
11297 }
11298
11299 setFunctionHasBranchProtectedScope();
11300 return OMPTargetParallelForDirective::Create(
11301 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11302 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11303}
11304
11305/// Check for existence of a map clause in the list of clauses.
11306static bool hasClauses(ArrayRef<OMPClause *> Clauses,
11307 const OpenMPClauseKind K) {
11308 return llvm::any_of(
11309 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
11310}
11311
11312template <typename... Params>
11313static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
11314 const Params... ClauseTypes) {
11315 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
11316}
11317
11318StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
11319 Stmt *AStmt,
11320 SourceLocation StartLoc,
11321 SourceLocation EndLoc) {
11322 if (!AStmt)
11323 return StmtError();
11324
11325 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11326
11327 // OpenMP [2.12.2, target data Construct, Restrictions]
11328 // At least one map, use_device_addr or use_device_ptr clause must appear on
11329 // the directive.
11330 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
11331 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
11332 StringRef Expected;
11333 if (LangOpts.OpenMP < 50)
11334 Expected = "'map' or 'use_device_ptr'";
11335 else
11336 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
11337 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11338 << Expected << getOpenMPDirectiveName(OMPD_target_data);
11339 return StmtError();
11340 }
11341
11342 setFunctionHasBranchProtectedScope();
11343
11344 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11345 AStmt);
11346}
11347
11348StmtResult
11349Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
11350 SourceLocation StartLoc,
11351 SourceLocation EndLoc, Stmt *AStmt) {
11352 if (!AStmt)
11353 return StmtError();
11354
11355 auto *CS = cast<CapturedStmt>(AStmt);
11356 // 1.2.2 OpenMP Language Terminology
11357 // Structured block - An executable statement with a single entry at the
11358 // top and a single exit at the bottom.
11359 // The point of exit cannot be a branch out of the structured block.
11360 // longjmp() and throw() must not violate the entry/exit criteria.
11361 CS->getCapturedDecl()->setNothrow();
11362 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
11363 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11364 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11365 // 1.2.2 OpenMP Language Terminology
11366 // Structured block - An executable statement with a single entry at the
11367 // top and a single exit at the bottom.
11368 // The point of exit cannot be a branch out of the structured block.
11369 // longjmp() and throw() must not violate the entry/exit criteria.
11370 CS->getCapturedDecl()->setNothrow();
11371 }
11372
11373 // OpenMP [2.10.2, Restrictions, p. 99]
11374 // At least one map clause must appear on the directive.
11375 if (!hasClauses(Clauses, OMPC_map)) {
11376 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11377 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
11378 return StmtError();
11379 }
11380
11381 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11382 AStmt);
11383}
11384
11385StmtResult
11386Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
11387 SourceLocation StartLoc,
11388 SourceLocation EndLoc, Stmt *AStmt) {
11389 if (!AStmt)
11390 return StmtError();
11391
11392 auto *CS = cast<CapturedStmt>(AStmt);
11393 // 1.2.2 OpenMP Language Terminology
11394 // Structured block - An executable statement with a single entry at the
11395 // top and a single exit at the bottom.
11396 // The point of exit cannot be a branch out of the structured block.
11397 // longjmp() and throw() must not violate the entry/exit criteria.
11398 CS->getCapturedDecl()->setNothrow();
11399 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
11400 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11401 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11402 // 1.2.2 OpenMP Language Terminology
11403 // Structured block - An executable statement with a single entry at the
11404 // top and a single exit at the bottom.
11405 // The point of exit cannot be a branch out of the structured block.
11406 // longjmp() and throw() must not violate the entry/exit criteria.
11407 CS->getCapturedDecl()->setNothrow();
11408 }
11409
11410 // OpenMP [2.10.3, Restrictions, p. 102]
11411 // At least one map clause must appear on the directive.
11412 if (!hasClauses(Clauses, OMPC_map)) {
11413 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11414 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
11415 return StmtError();
11416 }
11417
11418 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11419 AStmt);
11420}
11421
11422StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
11423 SourceLocation StartLoc,
11424 SourceLocation EndLoc,
11425 Stmt *AStmt) {
11426 if (!AStmt)
11427 return StmtError();
11428
11429 auto *CS = cast<CapturedStmt>(AStmt);
11430 // 1.2.2 OpenMP Language Terminology
11431 // Structured block - An executable statement with a single entry at the
11432 // top and a single exit at the bottom.
11433 // The point of exit cannot be a branch out of the structured block.
11434 // longjmp() and throw() must not violate the entry/exit criteria.
11435 CS->getCapturedDecl()->setNothrow();
11436 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
11437 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11438 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11439 // 1.2.2 OpenMP Language Terminology
11440 // Structured block - An executable statement with a single entry at the
11441 // top and a single exit at the bottom.
11442 // The point of exit cannot be a branch out of the structured block.
11443 // longjmp() and throw() must not violate the entry/exit criteria.
11444 CS->getCapturedDecl()->setNothrow();
11445 }
11446
11447 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
11448 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
11449 return StmtError();
11450 }
11451 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
11452 AStmt);
11453}
11454
11455StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
11456 Stmt *AStmt, SourceLocation StartLoc,
11457 SourceLocation EndLoc) {
11458 if (!AStmt)
11459 return StmtError();
11460
11461 auto *CS = cast<CapturedStmt>(AStmt);
11462 // 1.2.2 OpenMP Language Terminology
11463 // Structured block - An executable statement with a single entry at the
11464 // top and a single exit at the bottom.
11465 // The point of exit cannot be a branch out of the structured block.
11466 // longjmp() and throw() must not violate the entry/exit criteria.
11467 CS->getCapturedDecl()->setNothrow();
11468
11469 setFunctionHasBranchProtectedScope();
11470
11471 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11472
11473 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11474}
11475
11476StmtResult
11477Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
11478 SourceLocation EndLoc,
11479 OpenMPDirectiveKind CancelRegion) {
11480 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
11481 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
11482 return StmtError();
11483 }
11484 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
11485 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
11486 return StmtError();
11487 }
11488 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
11489 CancelRegion);
11490}
11491
11492StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
11493 SourceLocation StartLoc,
11494 SourceLocation EndLoc,
11495 OpenMPDirectiveKind CancelRegion) {
11496 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
11497 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
11498 return StmtError();
11499 }
11500 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
11501 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
11502 return StmtError();
11503 }
11504 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
11505 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
11506 CancelRegion);
11507}
11508
11509static bool checkReductionClauseWithNogroup(Sema &S,
11510 ArrayRef<OMPClause *> Clauses) {
11511 const OMPClause *ReductionClause = nullptr;
11512 const OMPClause *NogroupClause = nullptr;
11513 for (const OMPClause *C : Clauses) {
11514 if (C->getClauseKind() == OMPC_reduction) {
11515 ReductionClause = C;
11516 if (NogroupClause)
11517 break;
11518 continue;
11519 }
11520 if (C->getClauseKind() == OMPC_nogroup) {
11521 NogroupClause = C;
11522 if (ReductionClause)
11523 break;
11524 continue;
11525 }
11526 }
11527 if (ReductionClause && NogroupClause) {
11528 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
11529 << SourceRange(NogroupClause->getBeginLoc(),
11530 NogroupClause->getEndLoc());
11531 return true;
11532 }
11533 return false;
11534}
11535
11536StmtResult Sema::ActOnOpenMPTaskLoopDirective(
11537 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11538 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11539 if (!AStmt)
11540 return StmtError();
11541
11542 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11543 OMPLoopBasedDirective::HelperExprs B;
11544 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11545 // define the nested loops number.
11546 unsigned NestedLoopCount =
11547 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11548 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11549 VarsWithImplicitDSA, B);
11550 if (NestedLoopCount == 0)
11551 return StmtError();
11552
11553 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11554 "omp for loop exprs were not built")(static_cast<void> (0));
11555
11556 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11557 // The grainsize clause and num_tasks clause are mutually exclusive and may
11558 // not appear on the same taskloop directive.
11559 if (checkMutuallyExclusiveClauses(*this, Clauses,
11560 {OMPC_grainsize, OMPC_num_tasks}))
11561 return StmtError();
11562 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11563 // If a reduction clause is present on the taskloop directive, the nogroup
11564 // clause must not be specified.
11565 if (checkReductionClauseWithNogroup(*this, Clauses))
11566 return StmtError();
11567
11568 setFunctionHasBranchProtectedScope();
11569 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11570 NestedLoopCount, Clauses, AStmt, B,
11571 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11572}
11573
11574StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11575 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11576 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11577 if (!AStmt)
11578 return StmtError();
11579
11580 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11581 OMPLoopBasedDirective::HelperExprs B;
11582 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11583 // define the nested loops number.
11584 unsigned NestedLoopCount =
11585 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11586 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11587 VarsWithImplicitDSA, B);
11588 if (NestedLoopCount == 0)
11589 return StmtError();
11590
11591 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11592 "omp for loop exprs were not built")(static_cast<void> (0));
11593
11594 if (!CurContext->isDependentContext()) {
11595 // Finalize the clauses that need pre-built expressions for CodeGen.
11596 for (OMPClause *C : Clauses) {
11597 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11598 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11599 B.NumIterations, *this, CurScope,
11600 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11601 return StmtError();
11602 }
11603 }
11604
11605 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11606 // The grainsize clause and num_tasks clause are mutually exclusive and may
11607 // not appear on the same taskloop directive.
11608 if (checkMutuallyExclusiveClauses(*this, Clauses,
11609 {OMPC_grainsize, OMPC_num_tasks}))
11610 return StmtError();
11611 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11612 // If a reduction clause is present on the taskloop directive, the nogroup
11613 // clause must not be specified.
11614 if (checkReductionClauseWithNogroup(*this, Clauses))
11615 return StmtError();
11616 if (checkSimdlenSafelenSpecified(*this, Clauses))
11617 return StmtError();
11618
11619 setFunctionHasBranchProtectedScope();
11620 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11621 NestedLoopCount, Clauses, AStmt, B);
11622}
11623
11624StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11625 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11626 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11627 if (!AStmt)
11628 return StmtError();
11629
11630 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11631 OMPLoopBasedDirective::HelperExprs B;
11632 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11633 // define the nested loops number.
11634 unsigned NestedLoopCount =
11635 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11636 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11637 VarsWithImplicitDSA, B);
11638 if (NestedLoopCount == 0)
11639 return StmtError();
11640
11641 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11642 "omp for loop exprs were not built")(static_cast<void> (0));
11643
11644 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11645 // The grainsize clause and num_tasks clause are mutually exclusive and may
11646 // not appear on the same taskloop directive.
11647 if (checkMutuallyExclusiveClauses(*this, Clauses,
11648 {OMPC_grainsize, OMPC_num_tasks}))
11649 return StmtError();
11650 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11651 // If a reduction clause is present on the taskloop directive, the nogroup
11652 // clause must not be specified.
11653 if (checkReductionClauseWithNogroup(*this, Clauses))
11654 return StmtError();
11655
11656 setFunctionHasBranchProtectedScope();
11657 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11658 NestedLoopCount, Clauses, AStmt, B,
11659 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11660}
11661
11662StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11663 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11664 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11665 if (!AStmt)
11666 return StmtError();
11667
11668 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11669 OMPLoopBasedDirective::HelperExprs B;
11670 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11671 // define the nested loops number.
11672 unsigned NestedLoopCount =
11673 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11674 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11675 VarsWithImplicitDSA, B);
11676 if (NestedLoopCount == 0)
11677 return StmtError();
11678
11679 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11680 "omp for loop exprs were not built")(static_cast<void> (0));
11681
11682 if (!CurContext->isDependentContext()) {
11683 // Finalize the clauses that need pre-built expressions for CodeGen.
11684 for (OMPClause *C : Clauses) {
11685 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11686 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11687 B.NumIterations, *this, CurScope,
11688 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11689 return StmtError();
11690 }
11691 }
11692
11693 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11694 // The grainsize clause and num_tasks clause are mutually exclusive and may
11695 // not appear on the same taskloop directive.
11696 if (checkMutuallyExclusiveClauses(*this, Clauses,
11697 {OMPC_grainsize, OMPC_num_tasks}))
11698 return StmtError();
11699 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11700 // If a reduction clause is present on the taskloop directive, the nogroup
11701 // clause must not be specified.
11702 if (checkReductionClauseWithNogroup(*this, Clauses))
11703 return StmtError();
11704 if (checkSimdlenSafelenSpecified(*this, Clauses))
11705 return StmtError();
11706
11707 setFunctionHasBranchProtectedScope();
11708 return OMPMasterTaskLoopSimdDirective::Create(
11709 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11710}
11711
11712StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11713 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11714 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11715 if (!AStmt)
11716 return StmtError();
11717
11718 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11719 auto *CS = cast<CapturedStmt>(AStmt);
11720 // 1.2.2 OpenMP Language Terminology
11721 // Structured block - An executable statement with a single entry at the
11722 // top and a single exit at the bottom.
11723 // The point of exit cannot be a branch out of the structured block.
11724 // longjmp() and throw() must not violate the entry/exit criteria.
11725 CS->getCapturedDecl()->setNothrow();
11726 for (int ThisCaptureLevel =
11727 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11728 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11729 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11730 // 1.2.2 OpenMP Language Terminology
11731 // Structured block - An executable statement with a single entry at the
11732 // top and a single exit at the bottom.
11733 // The point of exit cannot be a branch out of the structured block.
11734 // longjmp() and throw() must not violate the entry/exit criteria.
11735 CS->getCapturedDecl()->setNothrow();
11736 }
11737
11738 OMPLoopBasedDirective::HelperExprs B;
11739 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11740 // define the nested loops number.
11741 unsigned NestedLoopCount = checkOpenMPLoop(
11742 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11743 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11744 VarsWithImplicitDSA, B);
11745 if (NestedLoopCount == 0)
11746 return StmtError();
11747
11748 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11749 "omp for loop exprs were not built")(static_cast<void> (0));
11750
11751 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11752 // The grainsize clause and num_tasks clause are mutually exclusive and may
11753 // not appear on the same taskloop directive.
11754 if (checkMutuallyExclusiveClauses(*this, Clauses,
11755 {OMPC_grainsize, OMPC_num_tasks}))
11756 return StmtError();
11757 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11758 // If a reduction clause is present on the taskloop directive, the nogroup
11759 // clause must not be specified.
11760 if (checkReductionClauseWithNogroup(*this, Clauses))
11761 return StmtError();
11762
11763 setFunctionHasBranchProtectedScope();
11764 return OMPParallelMasterTaskLoopDirective::Create(
11765 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11766 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11767}
11768
11769StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11770 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11771 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11772 if (!AStmt)
11773 return StmtError();
11774
11775 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11776 auto *CS = cast<CapturedStmt>(AStmt);
11777 // 1.2.2 OpenMP Language Terminology
11778 // Structured block - An executable statement with a single entry at the
11779 // top and a single exit at the bottom.
11780 // The point of exit cannot be a branch out of the structured block.
11781 // longjmp() and throw() must not violate the entry/exit criteria.
11782 CS->getCapturedDecl()->setNothrow();
11783 for (int ThisCaptureLevel =
11784 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11785 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11786 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11787 // 1.2.2 OpenMP Language Terminology
11788 // Structured block - An executable statement with a single entry at the
11789 // top and a single exit at the bottom.
11790 // The point of exit cannot be a branch out of the structured block.
11791 // longjmp() and throw() must not violate the entry/exit criteria.
11792 CS->getCapturedDecl()->setNothrow();
11793 }
11794
11795 OMPLoopBasedDirective::HelperExprs B;
11796 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11797 // define the nested loops number.
11798 unsigned NestedLoopCount = checkOpenMPLoop(
11799 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11800 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11801 VarsWithImplicitDSA, B);
11802 if (NestedLoopCount == 0)
11803 return StmtError();
11804
11805 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11806 "omp for loop exprs were not built")(static_cast<void> (0));
11807
11808 if (!CurContext->isDependentContext()) {
11809 // Finalize the clauses that need pre-built expressions for CodeGen.
11810 for (OMPClause *C : Clauses) {
11811 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11812 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11813 B.NumIterations, *this, CurScope,
11814 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11815 return StmtError();
11816 }
11817 }
11818
11819 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11820 // The grainsize clause and num_tasks clause are mutually exclusive and may
11821 // not appear on the same taskloop directive.
11822 if (checkMutuallyExclusiveClauses(*this, Clauses,
11823 {OMPC_grainsize, OMPC_num_tasks}))
11824 return StmtError();
11825 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11826 // If a reduction clause is present on the taskloop directive, the nogroup
11827 // clause must not be specified.
11828 if (checkReductionClauseWithNogroup(*this, Clauses))
11829 return StmtError();
11830 if (checkSimdlenSafelenSpecified(*this, Clauses))
11831 return StmtError();
11832
11833 setFunctionHasBranchProtectedScope();
11834 return OMPParallelMasterTaskLoopSimdDirective::Create(
11835 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11836}
11837
11838StmtResult Sema::ActOnOpenMPDistributeDirective(
11839 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11840 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11841 if (!AStmt)
11842 return StmtError();
11843
11844 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast<void> (0));
11845 OMPLoopBasedDirective::HelperExprs B;
11846 // In presence of clause 'collapse' with number of loops, it will
11847 // define the nested loops number.
11848 unsigned NestedLoopCount =
11849 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11850 nullptr /*ordered not a clause on distribute*/, AStmt,
11851 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11852 if (NestedLoopCount == 0)
11853 return StmtError();
11854
11855 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11856 "omp for loop exprs were not built")(static_cast<void> (0));
11857
11858 setFunctionHasBranchProtectedScope();
11859 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11860 NestedLoopCount, Clauses, AStmt, B);
11861}
11862
11863StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11864 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11865 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11866 if (!AStmt)
11867 return StmtError();
11868
11869 auto *CS = cast<CapturedStmt>(AStmt);
11870 // 1.2.2 OpenMP Language Terminology
11871 // Structured block - An executable statement with a single entry at the
11872 // top and a single exit at the bottom.
11873 // The point of exit cannot be a branch out of the structured block.
11874 // longjmp() and throw() must not violate the entry/exit criteria.
11875 CS->getCapturedDecl()->setNothrow();
11876 for (int ThisCaptureLevel =
11877 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11878 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11879 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11880 // 1.2.2 OpenMP Language Terminology
11881 // Structured block - An executable statement with a single entry at the
11882 // top and a single exit at the bottom.
11883 // The point of exit cannot be a branch out of the structured block.
11884 // longjmp() and throw() must not violate the entry/exit criteria.
11885 CS->getCapturedDecl()->setNothrow();
11886 }
11887
11888 OMPLoopBasedDirective::HelperExprs B;
11889 // In presence of clause 'collapse' with number of loops, it will
11890 // define the nested loops number.
11891 unsigned NestedLoopCount = checkOpenMPLoop(
11892 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11893 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11894 VarsWithImplicitDSA, B);
11895 if (NestedLoopCount == 0)
11896 return StmtError();
11897
11898 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11899 "omp for loop exprs were not built")(static_cast<void> (0));
11900
11901 setFunctionHasBranchProtectedScope();
11902 return OMPDistributeParallelForDirective::Create(
11903 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11904 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11905}
11906
11907StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11908 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11909 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11910 if (!AStmt)
11911 return StmtError();
11912
11913 auto *CS = cast<CapturedStmt>(AStmt);
11914 // 1.2.2 OpenMP Language Terminology
11915 // Structured block - An executable statement with a single entry at the
11916 // top and a single exit at the bottom.
11917 // The point of exit cannot be a branch out of the structured block.
11918 // longjmp() and throw() must not violate the entry/exit criteria.
11919 CS->getCapturedDecl()->setNothrow();
11920 for (int ThisCaptureLevel =
11921 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11922 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11923 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11924 // 1.2.2 OpenMP Language Terminology
11925 // Structured block - An executable statement with a single entry at the
11926 // top and a single exit at the bottom.
11927 // The point of exit cannot be a branch out of the structured block.
11928 // longjmp() and throw() must not violate the entry/exit criteria.
11929 CS->getCapturedDecl()->setNothrow();
11930 }
11931
11932 OMPLoopBasedDirective::HelperExprs B;
11933 // In presence of clause 'collapse' with number of loops, it will
11934 // define the nested loops number.
11935 unsigned NestedLoopCount = checkOpenMPLoop(
11936 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11937 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11938 VarsWithImplicitDSA, B);
11939 if (NestedLoopCount == 0)
11940 return StmtError();
11941
11942 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11943 "omp for loop exprs were not built")(static_cast<void> (0));
11944
11945 if (!CurContext->isDependentContext()) {
11946 // Finalize the clauses that need pre-built expressions for CodeGen.
11947 for (OMPClause *C : Clauses) {
11948 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11949 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11950 B.NumIterations, *this, CurScope,
11951 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11952 return StmtError();
11953 }
11954 }
11955
11956 if (checkSimdlenSafelenSpecified(*this, Clauses))
11957 return StmtError();
11958
11959 setFunctionHasBranchProtectedScope();
11960 return OMPDistributeParallelForSimdDirective::Create(
11961 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11962}
11963
11964StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11965 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11966 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11967 if (!AStmt)
11968 return StmtError();
11969
11970 auto *CS = cast<CapturedStmt>(AStmt);
11971 // 1.2.2 OpenMP Language Terminology
11972 // Structured block - An executable statement with a single entry at the
11973 // top and a single exit at the bottom.
11974 // The point of exit cannot be a branch out of the structured block.
11975 // longjmp() and throw() must not violate the entry/exit criteria.
11976 CS->getCapturedDecl()->setNothrow();
11977 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11978 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11979 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11980 // 1.2.2 OpenMP Language Terminology
11981 // Structured block - An executable statement with a single entry at the
11982 // top and a single exit at the bottom.
11983 // The point of exit cannot be a branch out of the structured block.
11984 // longjmp() and throw() must not violate the entry/exit criteria.
11985 CS->getCapturedDecl()->setNothrow();
11986 }
11987
11988 OMPLoopBasedDirective::HelperExprs B;
11989 // In presence of clause 'collapse' with number of loops, it will
11990 // define the nested loops number.
11991 unsigned NestedLoopCount =
11992 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11993 nullptr /*ordered not a clause on distribute*/, CS, *this,
11994 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11995 if (NestedLoopCount == 0)
11996 return StmtError();
11997
11998 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
11999 "omp for loop exprs were not built")(static_cast<void> (0));
12000
12001 if (!CurContext->isDependentContext()) {
12002 // Finalize the clauses that need pre-built expressions for CodeGen.
12003 for (OMPClause *C : Clauses) {
12004 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12005 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12006 B.NumIterations, *this, CurScope,
12007 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12008 return StmtError();
12009 }
12010 }
12011
12012 if (checkSimdlenSafelenSpecified(*this, Clauses))
12013 return StmtError();
12014
12015 setFunctionHasBranchProtectedScope();
12016 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
12017 NestedLoopCount, Clauses, AStmt, B);
12018}
12019
12020StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
12021 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12022 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12023 if (!AStmt)
12024 return StmtError();
12025
12026 auto *CS = cast<CapturedStmt>(AStmt);
12027 // 1.2.2 OpenMP Language Terminology
12028 // Structured block - An executable statement with a single entry at the
12029 // top and a single exit at the bottom.
12030 // The point of exit cannot be a branch out of the structured block.
12031 // longjmp() and throw() must not violate the entry/exit criteria.
12032 CS->getCapturedDecl()->setNothrow();
12033 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12034 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12035 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12036 // 1.2.2 OpenMP Language Terminology
12037 // Structured block - An executable statement with a single entry at the
12038 // top and a single exit at the bottom.
12039 // The point of exit cannot be a branch out of the structured block.
12040 // longjmp() and throw() must not violate the entry/exit criteria.
12041 CS->getCapturedDecl()->setNothrow();
12042 }
12043
12044 OMPLoopBasedDirective::HelperExprs B;
12045 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12046 // define the nested loops number.
12047 unsigned NestedLoopCount = checkOpenMPLoop(
12048 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
12049 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12050 VarsWithImplicitDSA, B);
12051 if (NestedLoopCount == 0)
12052 return StmtError();
12053
12054 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12055 "omp target parallel for simd loop exprs were not built")(static_cast<void> (0));
12056
12057 if (!CurContext->isDependentContext()) {
12058 // Finalize the clauses that need pre-built expressions for CodeGen.
12059 for (OMPClause *C : Clauses) {
12060 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12061 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12062 B.NumIterations, *this, CurScope,
12063 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12064 return StmtError();
12065 }
12066 }
12067 if (checkSimdlenSafelenSpecified(*this, Clauses))
12068 return StmtError();
12069
12070 setFunctionHasBranchProtectedScope();
12071 return OMPTargetParallelForSimdDirective::Create(
12072 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12073}
12074
12075StmtResult Sema::ActOnOpenMPTargetSimdDirective(
12076 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12077 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12078 if (!AStmt)
12079 return StmtError();
12080
12081 auto *CS = cast<CapturedStmt>(AStmt);
12082 // 1.2.2 OpenMP Language Terminology
12083 // Structured block - An executable statement with a single entry at the
12084 // top and a single exit at the bottom.
12085 // The point of exit cannot be a branch out of the structured block.
12086 // longjmp() and throw() must not violate the entry/exit criteria.
12087 CS->getCapturedDecl()->setNothrow();
12088 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
12089 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12090 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12091 // 1.2.2 OpenMP Language Terminology
12092 // Structured block - An executable statement with a single entry at the
12093 // top and a single exit at the bottom.
12094 // The point of exit cannot be a branch out of the structured block.
12095 // longjmp() and throw() must not violate the entry/exit criteria.
12096 CS->getCapturedDecl()->setNothrow();
12097 }
12098
12099 OMPLoopBasedDirective::HelperExprs B;
12100 // In presence of clause 'collapse' with number of loops, it will define the
12101 // nested loops number.
12102 unsigned NestedLoopCount =
12103 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
12104 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12105 VarsWithImplicitDSA, B);
12106 if (NestedLoopCount == 0)
12107 return StmtError();
12108
12109 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12110 "omp target simd loop exprs were not built")(static_cast<void> (0));
12111
12112 if (!CurContext->isDependentContext()) {
12113 // Finalize the clauses that need pre-built expressions for CodeGen.
12114 for (OMPClause *C : Clauses) {
12115 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12116 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12117 B.NumIterations, *this, CurScope,
12118 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12119 return StmtError();
12120 }
12121 }
12122
12123 if (checkSimdlenSafelenSpecified(*this, Clauses))
12124 return StmtError();
12125
12126 setFunctionHasBranchProtectedScope();
12127 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
12128 NestedLoopCount, Clauses, AStmt, B);
12129}
12130
12131StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
12132 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12133 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12134 if (!AStmt)
12135 return StmtError();
12136
12137 auto *CS = cast<CapturedStmt>(AStmt);
12138 // 1.2.2 OpenMP Language Terminology
12139 // Structured block - An executable statement with a single entry at the
12140 // top and a single exit at the bottom.
12141 // The point of exit cannot be a branch out of the structured block.
12142 // longjmp() and throw() must not violate the entry/exit criteria.
12143 CS->getCapturedDecl()->setNothrow();
12144 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
12145 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12146 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12147 // 1.2.2 OpenMP Language Terminology
12148 // Structured block - An executable statement with a single entry at the
12149 // top and a single exit at the bottom.
12150 // The point of exit cannot be a branch out of the structured block.
12151 // longjmp() and throw() must not violate the entry/exit criteria.
12152 CS->getCapturedDecl()->setNothrow();
12153 }
12154
12155 OMPLoopBasedDirective::HelperExprs B;
12156 // In presence of clause 'collapse' with number of loops, it will
12157 // define the nested loops number.
12158 unsigned NestedLoopCount =
12159 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
12160 nullptr /*ordered not a clause on distribute*/, CS, *this,
12161 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
12162 if (NestedLoopCount == 0)
12163 return StmtError();
12164
12165 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12166 "omp teams distribute loop exprs were not built")(static_cast<void> (0));
12167
12168 setFunctionHasBranchProtectedScope();
12169
12170 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12171
12172 return OMPTeamsDistributeDirective::Create(
12173 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12174}
12175
12176StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
12177 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12178 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12179 if (!AStmt)
12180 return StmtError();
12181
12182 auto *CS = cast<CapturedStmt>(AStmt);
12183 // 1.2.2 OpenMP Language Terminology
12184 // Structured block - An executable statement with a single entry at the
12185 // top and a single exit at the bottom.
12186 // The point of exit cannot be a branch out of the structured block.
12187 // longjmp() and throw() must not violate the entry/exit criteria.
12188 CS->getCapturedDecl()->setNothrow();
12189 for (int ThisCaptureLevel =
12190 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
12191 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12192 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12193 // 1.2.2 OpenMP Language Terminology
12194 // Structured block - An executable statement with a single entry at the
12195 // top and a single exit at the bottom.
12196 // The point of exit cannot be a branch out of the structured block.
12197 // longjmp() and throw() must not violate the entry/exit criteria.
12198 CS->getCapturedDecl()->setNothrow();
12199 }
12200
12201 OMPLoopBasedDirective::HelperExprs B;
12202 // In presence of clause 'collapse' with number of loops, it will
12203 // define the nested loops number.
12204 unsigned NestedLoopCount = checkOpenMPLoop(
12205 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12206 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12207 VarsWithImplicitDSA, B);
12208
12209 if (NestedLoopCount == 0)
12210 return StmtError();
12211
12212 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12213 "omp teams distribute simd loop exprs were not built")(static_cast<void> (0));
12214
12215 if (!CurContext->isDependentContext()) {
12216 // Finalize the clauses that need pre-built expressions for CodeGen.
12217 for (OMPClause *C : Clauses) {
12218 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12219 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12220 B.NumIterations, *this, CurScope,
12221 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12222 return StmtError();
12223 }
12224 }
12225
12226 if (checkSimdlenSafelenSpecified(*this, Clauses))
12227 return StmtError();
12228
12229 setFunctionHasBranchProtectedScope();
12230
12231 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12232
12233 return OMPTeamsDistributeSimdDirective::Create(
12234 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12235}
12236
12237StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
12238 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12239 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12240 if (!AStmt)
12241 return StmtError();
12242
12243 auto *CS = cast<CapturedStmt>(AStmt);
12244 // 1.2.2 OpenMP Language Terminology
12245 // Structured block - An executable statement with a single entry at the
12246 // top and a single exit at the bottom.
12247 // The point of exit cannot be a branch out of the structured block.
12248 // longjmp() and throw() must not violate the entry/exit criteria.
12249 CS->getCapturedDecl()->setNothrow();
12250
12251 for (int ThisCaptureLevel =
12252 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
12253 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12254 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12255 // 1.2.2 OpenMP Language Terminology
12256 // Structured block - An executable statement with a single entry at the
12257 // top and a single exit at the bottom.
12258 // The point of exit cannot be a branch out of the structured block.
12259 // longjmp() and throw() must not violate the entry/exit criteria.
12260 CS->getCapturedDecl()->setNothrow();
12261 }
12262
12263 OMPLoopBasedDirective::HelperExprs B;
12264 // In presence of clause 'collapse' with number of loops, it will
12265 // define the nested loops number.
12266 unsigned NestedLoopCount = checkOpenMPLoop(
12267 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
12268 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12269 VarsWithImplicitDSA, B);
12270
12271 if (NestedLoopCount == 0)
12272 return StmtError();
12273
12274 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12275 "omp for loop exprs were not built")(static_cast<void> (0));
12276
12277 if (!CurContext->isDependentContext()) {
12278 // Finalize the clauses that need pre-built expressions for CodeGen.
12279 for (OMPClause *C : Clauses) {
12280 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12281 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12282 B.NumIterations, *this, CurScope,
12283 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12284 return StmtError();
12285 }
12286 }
12287
12288 if (checkSimdlenSafelenSpecified(*this, Clauses))
12289 return StmtError();
12290
12291 setFunctionHasBranchProtectedScope();
12292
12293 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12294
12295 return OMPTeamsDistributeParallelForSimdDirective::Create(
12296 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12297}
12298
12299StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
12300 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12301 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12302 if (!AStmt)
12303 return StmtError();
12304
12305 auto *CS = cast<CapturedStmt>(AStmt);
12306 // 1.2.2 OpenMP Language Terminology
12307 // Structured block - An executable statement with a single entry at the
12308 // top and a single exit at the bottom.
12309 // The point of exit cannot be a branch out of the structured block.
12310 // longjmp() and throw() must not violate the entry/exit criteria.
12311 CS->getCapturedDecl()->setNothrow();
12312
12313 for (int ThisCaptureLevel =
12314 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
12315 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12316 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12317 // 1.2.2 OpenMP Language Terminology
12318 // Structured block - An executable statement with a single entry at the
12319 // top and a single exit at the bottom.
12320 // The point of exit cannot be a branch out of the structured block.
12321 // longjmp() and throw() must not violate the entry/exit criteria.
12322 CS->getCapturedDecl()->setNothrow();
12323 }
12324
12325 OMPLoopBasedDirective::HelperExprs B;
12326 // In presence of clause 'collapse' with number of loops, it will
12327 // define the nested loops number.
12328 unsigned NestedLoopCount = checkOpenMPLoop(
12329 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12330 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12331 VarsWithImplicitDSA, B);
12332
12333 if (NestedLoopCount == 0)
12334 return StmtError();
12335
12336 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12337 "omp for loop exprs were not built")(static_cast<void> (0));
12338
12339 setFunctionHasBranchProtectedScope();
12340
12341 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12342
12343 return OMPTeamsDistributeParallelForDirective::Create(
12344 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12345 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12346}
12347
12348StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
12349 Stmt *AStmt,
12350 SourceLocation StartLoc,
12351 SourceLocation EndLoc) {
12352 if (!AStmt)
12353 return StmtError();
12354
12355 auto *CS = cast<CapturedStmt>(AStmt);
12356 // 1.2.2 OpenMP Language Terminology
12357 // Structured block - An executable statement with a single entry at the
12358 // top and a single exit at the bottom.
12359 // The point of exit cannot be a branch out of the structured block.
12360 // longjmp() and throw() must not violate the entry/exit criteria.
12361 CS->getCapturedDecl()->setNothrow();
12362
12363 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
12364 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12365 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12366 // 1.2.2 OpenMP Language Terminology
12367 // Structured block - An executable statement with a single entry at the
12368 // top and a single exit at the bottom.
12369 // The point of exit cannot be a branch out of the structured block.
12370 // longjmp() and throw() must not violate the entry/exit criteria.
12371 CS->getCapturedDecl()->setNothrow();
12372 }
12373 setFunctionHasBranchProtectedScope();
12374
12375 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
12376 AStmt);
12377}
12378
12379StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
12380 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12381 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12382 if (!AStmt)
12383 return StmtError();
12384
12385 auto *CS = cast<CapturedStmt>(AStmt);
12386 // 1.2.2 OpenMP Language Terminology
12387 // Structured block - An executable statement with a single entry at the
12388 // top and a single exit at the bottom.
12389 // The point of exit cannot be a branch out of the structured block.
12390 // longjmp() and throw() must not violate the entry/exit criteria.
12391 CS->getCapturedDecl()->setNothrow();
12392 for (int ThisCaptureLevel =
12393 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
12394 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12395 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12396 // 1.2.2 OpenMP Language Terminology
12397 // Structured block - An executable statement with a single entry at the
12398 // top and a single exit at the bottom.
12399 // The point of exit cannot be a branch out of the structured block.
12400 // longjmp() and throw() must not violate the entry/exit criteria.
12401 CS->getCapturedDecl()->setNothrow();
12402 }
12403
12404 OMPLoopBasedDirective::HelperExprs B;
12405 // In presence of clause 'collapse' with number of loops, it will
12406 // define the nested loops number.
12407 unsigned NestedLoopCount = checkOpenMPLoop(
12408 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
12409 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12410 VarsWithImplicitDSA, B);
12411 if (NestedLoopCount == 0)
12412 return StmtError();
12413
12414 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12415 "omp target teams distribute loop exprs were not built")(static_cast<void> (0));
12416
12417 setFunctionHasBranchProtectedScope();
12418 return OMPTargetTeamsDistributeDirective::Create(
12419 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12420}
12421
12422StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
12423 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12424 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12425 if (!AStmt)
12426 return StmtError();
12427
12428 auto *CS = cast<CapturedStmt>(AStmt);
12429 // 1.2.2 OpenMP Language Terminology
12430 // Structured block - An executable statement with a single entry at the
12431 // top and a single exit at the bottom.
12432 // The point of exit cannot be a branch out of the structured block.
12433 // longjmp() and throw() must not violate the entry/exit criteria.
12434 CS->getCapturedDecl()->setNothrow();
12435 for (int ThisCaptureLevel =
12436 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
12437 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12438 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12439 // 1.2.2 OpenMP Language Terminology
12440 // Structured block - An executable statement with a single entry at the
12441 // top and a single exit at the bottom.
12442 // The point of exit cannot be a branch out of the structured block.
12443 // longjmp() and throw() must not violate the entry/exit criteria.
12444 CS->getCapturedDecl()->setNothrow();
12445 }
12446
12447 OMPLoopBasedDirective::HelperExprs B;
12448 // In presence of clause 'collapse' with number of loops, it will
12449 // define the nested loops number.
12450 unsigned NestedLoopCount = checkOpenMPLoop(
12451 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12452 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12453 VarsWithImplicitDSA, B);
12454 if (NestedLoopCount == 0)
12455 return StmtError();
12456
12457 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12458 "omp target teams distribute parallel for loop exprs were not built")(static_cast<void> (0));
12459
12460 if (!CurContext->isDependentContext()) {
12461 // Finalize the clauses that need pre-built expressions for CodeGen.
12462 for (OMPClause *C : Clauses) {
12463 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12464 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12465 B.NumIterations, *this, CurScope,
12466 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12467 return StmtError();
12468 }
12469 }
12470
12471 setFunctionHasBranchProtectedScope();
12472 return OMPTargetTeamsDistributeParallelForDirective::Create(
12473 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12474 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12475}
12476
12477StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
12478 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12479 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12480 if (!AStmt)
12481 return StmtError();
12482
12483 auto *CS = cast<CapturedStmt>(AStmt);
12484 // 1.2.2 OpenMP Language Terminology
12485 // Structured block - An executable statement with a single entry at the
12486 // top and a single exit at the bottom.
12487 // The point of exit cannot be a branch out of the structured block.
12488 // longjmp() and throw() must not violate the entry/exit criteria.
12489 CS->getCapturedDecl()->setNothrow();
12490 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
12491 OMPD_target_teams_distribute_parallel_for_simd);
12492 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12493 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12494 // 1.2.2 OpenMP Language Terminology
12495 // Structured block - An executable statement with a single entry at the
12496 // top and a single exit at the bottom.
12497 // The point of exit cannot be a branch out of the structured block.
12498 // longjmp() and throw() must not violate the entry/exit criteria.
12499 CS->getCapturedDecl()->setNothrow();
12500 }
12501
12502 OMPLoopBasedDirective::HelperExprs B;
12503 // In presence of clause 'collapse' with number of loops, it will
12504 // define the nested loops number.
12505 unsigned NestedLoopCount =
12506 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
12507 getCollapseNumberExpr(Clauses),
12508 nullptr /*ordered not a clause on distribute*/, CS, *this,
12509 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
12510 if (NestedLoopCount == 0)
12511 return StmtError();
12512
12513 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12514 "omp target teams distribute parallel for simd loop exprs were not "(static_cast<void> (0))
12515 "built")(static_cast<void> (0));
12516
12517 if (!CurContext->isDependentContext()) {
12518 // Finalize the clauses that need pre-built expressions for CodeGen.
12519 for (OMPClause *C : Clauses) {
12520 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12521 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12522 B.NumIterations, *this, CurScope,
12523 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12524 return StmtError();
12525 }
12526 }
12527
12528 if (checkSimdlenSafelenSpecified(*this, Clauses))
12529 return StmtError();
12530
12531 setFunctionHasBranchProtectedScope();
12532 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
12533 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12534}
12535
12536StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
12537 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12538 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12539 if (!AStmt)
12540 return StmtError();
12541
12542 auto *CS = cast<CapturedStmt>(AStmt);
12543 // 1.2.2 OpenMP Language Terminology
12544 // Structured block - An executable statement with a single entry at the
12545 // top and a single exit at the bottom.
12546 // The point of exit cannot be a branch out of the structured block.
12547 // longjmp() and throw() must not violate the entry/exit criteria.
12548 CS->getCapturedDecl()->setNothrow();
12549 for (int ThisCaptureLevel =
12550 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12551 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12552 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12553 // 1.2.2 OpenMP Language Terminology
12554 // Structured block - An executable statement with a single entry at the
12555 // top and a single exit at the bottom.
12556 // The point of exit cannot be a branch out of the structured block.
12557 // longjmp() and throw() must not violate the entry/exit criteria.
12558 CS->getCapturedDecl()->setNothrow();
12559 }
12560
12561 OMPLoopBasedDirective::HelperExprs B;
12562 // In presence of clause 'collapse' with number of loops, it will
12563 // define the nested loops number.
12564 unsigned NestedLoopCount = checkOpenMPLoop(
12565 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12566 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12567 VarsWithImplicitDSA, B);
12568 if (NestedLoopCount == 0)
12569 return StmtError();
12570
12571 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast<void> (0))
12572 "omp target teams distribute simd loop exprs were not built")(static_cast<void> (0));
12573
12574 if (!CurContext->isDependentContext()) {
12575 // Finalize the clauses that need pre-built expressions for CodeGen.
12576 for (OMPClause *C : Clauses) {
12577 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12578 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12579 B.NumIterations, *this, CurScope,
12580 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12581 return StmtError();
12582 }
12583 }
12584
12585 if (checkSimdlenSafelenSpecified(*this, Clauses))
12586 return StmtError();
12587
12588 setFunctionHasBranchProtectedScope();
12589 return OMPTargetTeamsDistributeSimdDirective::Create(
12590 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12591}
12592
12593bool Sema::checkTransformableLoopNest(
12594 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
12595 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
12596 Stmt *&Body,
12597 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
12598 &OriginalInits) {
12599 OriginalInits.emplace_back();
12600 bool Result = OMPLoopBasedDirective::doForAllLoops(
12601 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
12602 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
12603 Stmt *CurStmt) {
12604 VarsWithInheritedDSAType TmpDSA;
12605 unsigned SingleNumLoops =
12606 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12607 TmpDSA, LoopHelpers[Cnt]);
12608 if (SingleNumLoops == 0)
12609 return true;
12610 assert(SingleNumLoops == 1 && "Expect single loop iteration space")(static_cast<void> (0));
12611 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12612 OriginalInits.back().push_back(For->getInit());
12613 Body = For->getBody();
12614 } else {
12615 assert(isa<CXXForRangeStmt>(CurStmt) &&(static_cast<void> (0))
12616 "Expected canonical for or range-based for loops.")(static_cast<void> (0));
12617 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12618 OriginalInits.back().push_back(CXXFor->getBeginStmt());
12619 Body = CXXFor->getBody();
12620 }
12621 OriginalInits.emplace_back();
12622 return false;
12623 },
12624 [&OriginalInits](OMPLoopBasedDirective *Transform) {
12625 Stmt *DependentPreInits;
12626 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
12627 DependentPreInits = Dir->getPreInits();
12628 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
12629 DependentPreInits = Dir->getPreInits();
12630 else
12631 llvm_unreachable("Unhandled loop transformation")__builtin_unreachable();
12632 if (!DependentPreInits)
12633 return;
12634 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup())
12635 OriginalInits.back().push_back(C);
12636 });
12637 assert(OriginalInits.back().empty() && "No preinit after innermost loop")(static_cast<void> (0));
12638 OriginalInits.pop_back();
12639 return Result;
12640}
12641
12642StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12643 Stmt *AStmt, SourceLocation StartLoc,
12644 SourceLocation EndLoc) {
12645 auto SizesClauses =
12646 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12647 if (SizesClauses.empty()) {
12648 // A missing 'sizes' clause is already reported by the parser.
12649 return StmtError();
12650 }
12651 const OMPSizesClause *SizesClause = *SizesClauses.begin();
12652 unsigned NumLoops = SizesClause->getNumSizes();
12653
12654 // Empty statement should only be possible if there already was an error.
12655 if (!AStmt)
12656 return StmtError();
12657
12658 // Verify and diagnose loop nest.
12659 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12660 Stmt *Body = nullptr;
12661 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
12662 OriginalInits;
12663 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
12664 OriginalInits))
12665 return StmtError();
12666
12667 // Delay tiling to when template is completely instantiated.
12668 if (CurContext->isDependentContext())
12669 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12670 NumLoops, AStmt, nullptr, nullptr);
12671
12672 SmallVector<Decl *, 4> PreInits;
12673
12674 // Create iteration variables for the generated loops.
12675 SmallVector<VarDecl *, 4> FloorIndVars;
12676 SmallVector<VarDecl *, 4> TileIndVars;
12677 FloorIndVars.resize(NumLoops);
12678 TileIndVars.resize(NumLoops);
12679 for (unsigned I = 0; I < NumLoops; ++I) {
12680 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12681
12682 assert(LoopHelper.Counters.size() == 1 &&(static_cast<void> (0))
12683 "Expect single-dimensional loop iteration space")(static_cast<void> (0));
12684 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12685 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12686 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12687 QualType CntTy = IterVarRef->getType();
12688
12689 // Iteration variable for the floor (i.e. outer) loop.
12690 {
12691 std::string FloorCntName =
12692 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12693 VarDecl *FloorCntDecl =
12694 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12695 FloorIndVars[I] = FloorCntDecl;
12696 }
12697
12698 // Iteration variable for the tile (i.e. inner) loop.
12699 {
12700 std::string TileCntName =
12701 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12702
12703 // Reuse the iteration variable created by checkOpenMPLoop. It is also
12704 // used by the expressions to derive the original iteration variable's
12705 // value from the logical iteration number.
12706 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12707 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12708 TileIndVars[I] = TileCntDecl;
12709 }
12710 for (auto &P : OriginalInits[I]) {
12711 if (auto *D = P.dyn_cast<Decl *>())
12712 PreInits.push_back(D);
12713 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
12714 PreInits.append(PI->decl_begin(), PI->decl_end());
12715 }
12716 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12717 PreInits.append(PI->decl_begin(), PI->decl_end());
12718 // Gather declarations for the data members used as counters.
12719 for (Expr *CounterRef : LoopHelper.Counters) {
12720 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12721 if (isa<OMPCapturedExprDecl>(CounterDecl))
12722 PreInits.push_back(CounterDecl);
12723 }
12724 }
12725
12726 // Once the original iteration values are set, append the innermost body.
12727 Stmt *Inner = Body;
12728
12729 // Create tile loops from the inside to the outside.
12730 for (int I = NumLoops - 1; I >= 0; --I) {
12731 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12732 Expr *NumIterations = LoopHelper.NumIterations;
12733 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12734 QualType CntTy = OrigCntVar->getType();
12735 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12736 Scope *CurScope = getCurScope();
12737
12738 // Commonly used variables.
12739 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12740 OrigCntVar->getExprLoc());
12741 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12742 OrigCntVar->getExprLoc());
12743
12744 // For init-statement: auto .tile.iv = .floor.iv
12745 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12746 /*DirectInit=*/false);
12747 Decl *CounterDecl = TileIndVars[I];
12748 StmtResult InitStmt = new (Context)
12749 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12750 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12751 if (!InitStmt.isUsable())
12752 return StmtError();
12753
12754 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12755 // NumIterations)
12756 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12757 BO_Add, FloorIV, DimTileSize);
12758 if (!EndOfTile.isUsable())
12759 return StmtError();
12760 ExprResult IsPartialTile =
12761 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12762 NumIterations, EndOfTile.get());
12763 if (!IsPartialTile.isUsable())
12764 return StmtError();
12765 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12766 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12767 IsPartialTile.get(), NumIterations, EndOfTile.get());
12768 if (!MinTileAndIterSpace.isUsable())
12769 return StmtError();
12770 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12771 BO_LT, TileIV, MinTileAndIterSpace.get());
12772 if (!CondExpr.isUsable())
12773 return StmtError();
12774
12775 // For incr-statement: ++.tile.iv
12776 ExprResult IncrStmt =
12777 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12778 if (!IncrStmt.isUsable())
12779 return StmtError();
12780
12781 // Statements to set the original iteration variable's value from the
12782 // logical iteration number.
12783 // Generated for loop is:
12784 // Original_for_init;
12785 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12786 // NumIterations); ++.tile.iv) {
12787 // Original_Body;
12788 // Original_counter_update;
12789 // }
12790 // FIXME: If the innermost body is an loop itself, inserting these
12791 // statements stops it being recognized as a perfectly nested loop (e.g.
12792 // for applying tiling again). If this is the case, sink the expressions
12793 // further into the inner loop.
12794 SmallVector<Stmt *, 4> BodyParts;
12795 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12796 BodyParts.push_back(Inner);
12797 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12798 Inner->getEndLoc());
12799 Inner = new (Context)
12800 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12801 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12802 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12803 }
12804
12805 // Create floor loops from the inside to the outside.
12806 for (int I = NumLoops - 1; I >= 0; --I) {
12807 auto &LoopHelper = LoopHelpers[I];
12808 Expr *NumIterations = LoopHelper.NumIterations;
12809 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12810 QualType CntTy = OrigCntVar->getType();
12811 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12812 Scope *CurScope = getCurScope();
12813
12814 // Commonly used variables.
12815 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12816 OrigCntVar->getExprLoc());
12817
12818 // For init-statement: auto .floor.iv = 0
12819 AddInitializerToDecl(
12820 FloorIndVars[I],
12821 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12822 /*DirectInit=*/false);
12823 Decl *CounterDecl = FloorIndVars[I];
12824 StmtResult InitStmt = new (Context)
12825 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12826 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12827 if (!InitStmt.isUsable())
12828 return StmtError();
12829
12830 // For cond-expression: .floor.iv < NumIterations
12831 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12832 BO_LT, FloorIV, NumIterations);
12833 if (!CondExpr.isUsable())
12834 return StmtError();
12835
12836 // For incr-statement: .floor.iv += DimTileSize
12837 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12838 BO_AddAssign, FloorIV, DimTileSize);
12839 if (!IncrStmt.isUsable())
12840 return StmtError();
12841
12842 Inner = new (Context)
12843 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12844 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12845 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12846 }
12847
12848 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12849 AStmt, Inner,
12850 buildPreInits(Context, PreInits));
12851}
12852
12853StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
12854 Stmt *AStmt,
12855 SourceLocation StartLoc,
12856 SourceLocation EndLoc) {
12857 // Empty statement should only be possible if there already was an error.
12858 if (!AStmt)
12859 return StmtError();
12860
12861 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
12862 return StmtError();
12863
12864 const OMPFullClause *FullClause =
12865 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
12866 const OMPPartialClause *PartialClause =
12867 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
12868 assert(!(FullClause && PartialClause) &&(static_cast<void> (0))
12869 "mutual exclusivity must have been checked before")(static_cast<void> (0));
12870
12871 constexpr unsigned NumLoops = 1;
12872 Stmt *Body = nullptr;
12873 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
12874 NumLoops);
12875 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
12876 OriginalInits;
12877 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
12878 Body, OriginalInits))
12879 return StmtError();
12880
12881 // Delay unrolling to when template is completely instantiated.
12882 if (CurContext->isDependentContext())
12883 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12884 nullptr, nullptr);
12885
12886 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
12887
12888 if (FullClause) {
12889 if (!VerifyPositiveIntegerConstantInClause(
12890 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
12891 /*SuppressExprDigs=*/true)
12892 .isUsable()) {
12893 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
12894 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
12895 << "#pragma omp unroll full";
12896 return StmtError();
12897 }
12898 }
12899
12900 // The generated loop may only be passed to other loop-associated directive
12901 // when a partial clause is specified. Without the requirement it is
12902 // sufficient to generate loop unroll metadata at code-generation.
12903 if (!PartialClause)
12904 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12905 nullptr, nullptr);
12906
12907 // Otherwise, we need to provide a de-sugared/transformed AST that can be
12908 // associated with another loop directive.
12909 //
12910 // The canonical loop analysis return by checkTransformableLoopNest assumes
12911 // the following structure to be the same loop without transformations or
12912 // directives applied: \code OriginalInits; LoopHelper.PreInits;
12913 // LoopHelper.Counters;
12914 // for (; IV < LoopHelper.NumIterations; ++IV) {
12915 // LoopHelper.Updates;
12916 // Body;
12917 // }
12918 // \endcode
12919 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
12920 // and referenced by LoopHelper.IterationVarRef.
12921 //
12922 // The unrolling directive transforms this into the following loop:
12923 // \code
12924 // OriginalInits; \
12925 // LoopHelper.PreInits; > NewPreInits
12926 // LoopHelper.Counters; /
12927 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
12928 // #pragma clang loop unroll_count(Factor)
12929 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
12930 // {
12931 // LoopHelper.Updates;
12932 // Body;
12933 // }
12934 // }
12935 // \endcode
12936 // where UIV is a new logical iteration counter. IV must be the same VarDecl
12937 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
12938 // references it. If the partially unrolled loop is associated with another
12939 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
12940 // analyze this loop, i.e. the outer loop must fulfill the constraints of an
12941 // OpenMP canonical loop. The inner loop is not an associable canonical loop
12942 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
12943 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
12944 // property of the OMPLoopBasedDirective instead of statements in
12945 // CompoundStatement. This is to allow the loop to become a non-outermost loop
12946 // of a canonical loop nest where these PreInits are emitted before the
12947 // outermost directive.
12948
12949 // Determine the PreInit declarations.
12950 SmallVector<Decl *, 4> PreInits;
12951 assert(OriginalInits.size() == 1 &&(static_cast<void> (0))
12952 "Expecting a single-dimensional loop iteration space")(static_cast<void> (0));
12953 for (auto &P : OriginalInits[0]) {
12954 if (auto *D = P.dyn_cast<Decl *>())
12955 PreInits.push_back(D);
12956 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
12957 PreInits.append(PI->decl_begin(), PI->decl_end());
12958 }
12959 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12960 PreInits.append(PI->decl_begin(), PI->decl_end());
12961 // Gather declarations for the data members used as counters.
12962 for (Expr *CounterRef : LoopHelper.Counters) {
12963 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12964 if (isa<OMPCapturedExprDecl>(CounterDecl))
12965 PreInits.push_back(CounterDecl);
12966 }
12967
12968 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12969 QualType IVTy = IterationVarRef->getType();
12970 assert(LoopHelper.Counters.size() == 1 &&(static_cast<void> (0))
12971 "Expecting a single-dimensional loop iteration space")(static_cast<void> (0));
12972 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12973
12974 // Determine the unroll factor.
12975 uint64_t Factor;
12976 SourceLocation FactorLoc;
12977 if (Expr *FactorVal = PartialClause->getFactor()) {
12978 Factor =
12979 FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue();
12980 FactorLoc = FactorVal->getExprLoc();
12981 } else {
12982 // TODO: Use a better profitability model.
12983 Factor = 2;
12984 }
12985 assert(Factor > 0 && "Expected positive unroll factor")(static_cast<void> (0));
12986 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
12987 return IntegerLiteral::Create(
12988 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
12989 FactorLoc);
12990 };
12991
12992 // Iteration variable SourceLocations.
12993 SourceLocation OrigVarLoc = OrigVar->getExprLoc();
12994 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
12995 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
12996
12997 // Internal variable names.
12998 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
12999 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
13000 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
13001 std::string InnerTripCountName =
13002 (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
13003
13004 // Create the iteration variable for the unrolled loop.
13005 VarDecl *OuterIVDecl =
13006 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
13007 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
13008 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
13009 };
13010
13011 // Iteration variable for the inner loop: Reuse the iteration variable created
13012 // by checkOpenMPLoop.
13013 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
13014 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
13015 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
13016 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
13017 };
13018
13019 // Make a copy of the NumIterations expression for each use: By the AST
13020 // constraints, every expression object in a DeclContext must be unique.
13021 CaptureVars CopyTransformer(*this);
13022 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
13023 return AssertSuccess(
13024 CopyTransformer.TransformExpr(LoopHelper.NumIterations));
13025 };
13026
13027 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
13028 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
13029 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
13030 StmtResult InnerInit = new (Context)
13031 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13032 if (!InnerInit.isUsable())
13033 return StmtError();
13034
13035 // Inner For cond-expression:
13036 // \code
13037 // .unroll_inner.iv < .unrolled.iv + Factor &&
13038 // .unroll_inner.iv < NumIterations
13039 // \endcode
13040 // This conjunction of two conditions allows ScalarEvolution to derive the
13041 // maximum trip count of the inner loop.
13042 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13043 BO_Add, MakeOuterRef(), MakeFactorExpr());
13044 if (!EndOfTile.isUsable())
13045 return StmtError();
13046 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13047 BO_LE, MakeInnerRef(), EndOfTile.get());
13048 if (!InnerCond1.isUsable())
13049 return StmtError();
13050 ExprResult InnerCond2 =
13051 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
13052 MakeNumIterations());
13053 if (!InnerCond2.isUsable())
13054 return StmtError();
13055 ExprResult InnerCond =
13056 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
13057 InnerCond1.get(), InnerCond2.get());
13058 if (!InnerCond.isUsable())
13059 return StmtError();
13060
13061 // Inner For incr-statement: ++.unroll_inner.iv
13062 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
13063 UO_PreInc, MakeInnerRef());
13064 if (!InnerIncr.isUsable())
13065 return StmtError();
13066
13067 // Inner For statement.
13068 SmallVector<Stmt *> InnerBodyStmts;
13069 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
13070 InnerBodyStmts.push_back(Body);
13071 CompoundStmt *InnerBody = CompoundStmt::Create(
13072 Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
13073 ForStmt *InnerFor = new (Context)
13074 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
13075 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
13076 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13077
13078 // Unroll metadata for the inner loop.
13079 // This needs to take into account the remainder portion of the unrolled loop,
13080 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
13081 // supports multiple loop exits. Instead, unroll using a factor equivalent to
13082 // the maximum trip count, which will also generate a remainder loop. Just
13083 // `unroll(enable)` (which could have been useful if the user has not
13084 // specified a concrete factor; even though the outer loop cannot be
13085 // influenced anymore, would avoid more code bloat than necessary) will refuse
13086 // the loop because "Won't unroll; remainder loop could not be generated when
13087 // assuming runtime trip count". Even if it did work, it must not choose a
13088 // larger unroll factor than the maximum loop length, or it would always just
13089 // execute the remainder loop.
13090 LoopHintAttr *UnrollHintAttr =
13091 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
13092 LoopHintAttr::Numeric, MakeFactorExpr());
13093 AttributedStmt *InnerUnrolled =
13094 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
13095
13096 // Outer For init-statement: auto .unrolled.iv = 0
13097 AddInitializerToDecl(
13098 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
13099 /*DirectInit=*/false);
13100 StmtResult OuterInit = new (Context)
13101 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13102 if (!OuterInit.isUsable())
13103 return StmtError();
13104
13105 // Outer For cond-expression: .unrolled.iv < NumIterations
13106 ExprResult OuterConde =
13107 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
13108 MakeNumIterations());
13109 if (!OuterConde.isUsable())
13110 return StmtError();
13111
13112 // Outer For incr-statement: .unrolled.iv += Factor
13113 ExprResult OuterIncr =
13114 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
13115 MakeOuterRef(), MakeFactorExpr());
13116 if (!OuterIncr.isUsable())
13117 return StmtError();
13118
13119 // Outer For statement.
13120 ForStmt *OuterFor = new (Context)
13121 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
13122 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
13123 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13124
13125 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
13126 OuterFor, buildPreInits(Context, PreInits));
13127}
13128
13129OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
13130 SourceLocation StartLoc,
13131 SourceLocation LParenLoc,
13132 SourceLocation EndLoc) {
13133 OMPClause *Res = nullptr;
13134 switch (Kind) {
13135 case OMPC_final:
13136 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
13137 break;
13138 case OMPC_num_threads:
13139 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
13140 break;
13141 case OMPC_safelen:
13142 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
13143 break;
13144 case OMPC_simdlen:
13145 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
13146 break;
13147 case OMPC_allocator:
13148 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
13149 break;
13150 case OMPC_collapse:
13151 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
13152 break;
13153 case OMPC_ordered:
13154 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
13155 break;
13156 case OMPC_num_teams:
13157 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
13158 break;
13159 case OMPC_thread_limit:
13160 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
13161 break;
13162 case OMPC_priority:
13163 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
13164 break;
13165 case OMPC_grainsize:
13166 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
13167 break;
13168 case OMPC_num_tasks:
13169 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
13170 break;
13171 case OMPC_hint:
13172 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
13173 break;
13174 case OMPC_depobj:
13175 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
13176 break;
13177 case OMPC_detach:
13178 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
13179 break;
13180 case OMPC_novariants:
13181 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
13182 break;
13183 case OMPC_nocontext:
13184 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
13185 break;
13186 case OMPC_filter:
13187 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
13188 break;
13189 case OMPC_partial:
13190 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
13191 break;
13192 case OMPC_device:
13193 case OMPC_if:
13194 case OMPC_default:
13195 case OMPC_proc_bind:
13196 case OMPC_schedule:
13197 case OMPC_private:
13198 case OMPC_firstprivate:
13199 case OMPC_lastprivate:
13200 case OMPC_shared:
13201 case OMPC_reduction:
13202 case OMPC_task_reduction:
13203 case OMPC_in_reduction:
13204 case OMPC_linear:
13205 case OMPC_aligned:
13206 case OMPC_copyin:
13207 case OMPC_copyprivate:
13208 case OMPC_nowait:
13209 case OMPC_untied:
13210 case OMPC_mergeable:
13211 case OMPC_threadprivate:
13212 case OMPC_sizes:
13213 case OMPC_allocate:
13214 case OMPC_flush:
13215 case OMPC_read:
13216 case OMPC_write:
13217 case OMPC_update:
13218 case OMPC_capture:
13219 case OMPC_seq_cst:
13220 case OMPC_acq_rel:
13221 case OMPC_acquire:
13222 case OMPC_release:
13223 case OMPC_relaxed:
13224 case OMPC_depend:
13225 case OMPC_threads:
13226 case OMPC_simd:
13227 case OMPC_map:
13228 case OMPC_nogroup:
13229 case OMPC_dist_schedule:
13230 case OMPC_defaultmap:
13231 case OMPC_unknown:
13232 case OMPC_uniform:
13233 case OMPC_to:
13234 case OMPC_from:
13235 case OMPC_use_device_ptr:
13236 case OMPC_use_device_addr:
13237 case OMPC_is_device_ptr:
13238 case OMPC_unified_address:
13239 case OMPC_unified_shared_memory:
13240 case OMPC_reverse_offload:
13241 case OMPC_dynamic_allocators:
13242 case OMPC_atomic_default_mem_order:
13243 case OMPC_device_type:
13244 case OMPC_match:
13245 case OMPC_nontemporal:
13246 case OMPC_order:
13247 case OMPC_destroy:
13248 case OMPC_inclusive:
13249 case OMPC_exclusive:
13250 case OMPC_uses_allocators:
13251 case OMPC_affinity:
13252 default:
13253 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
13254 }
13255 return Res;
13256}
13257
13258// An OpenMP directive such as 'target parallel' has two captured regions:
13259// for the 'target' and 'parallel' respectively. This function returns
13260// the region in which to capture expressions associated with a clause.
13261// A return value of OMPD_unknown signifies that the expression should not
13262// be captured.
13263static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
13264 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
13265 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
13266 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13267 switch (CKind) {
13268 case OMPC_if:
13269 switch (DKind) {
13270 case OMPD_target_parallel_for_simd:
13271 if (OpenMPVersion >= 50 &&
13272 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13273 CaptureRegion = OMPD_parallel;
13274 break;
13275 }
13276 LLVM_FALLTHROUGH[[gnu::fallthrough]];
13277 case OMPD_target_parallel:
13278 case OMPD_target_parallel_for:
13279 // If this clause applies to the nested 'parallel' region, capture within
13280 // the 'target' region, otherwise do not capture.
13281 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13282 CaptureRegion = OMPD_target;
13283 break;
13284 case OMPD_target_teams_distribute_parallel_for_simd:
13285 if (OpenMPVersion >= 50 &&
13286 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13287 CaptureRegion = OMPD_parallel;
13288 break;
13289 }
13290 LLVM_FALLTHROUGH[[gnu::fallthrough]];
13291 case OMPD_target_teams_distribute_parallel_for:
13292 // If this clause applies to the nested 'parallel' region, capture within
13293 // the 'teams' region, otherwise do not capture.
13294 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13295 CaptureRegion = OMPD_teams;
13296 break;
13297 case OMPD_teams_distribute_parallel_for_simd:
13298 if (OpenMPVersion >= 50 &&
13299 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13300 CaptureRegion = OMPD_parallel;
13301 break;
13302 }
13303 LLVM_FALLTHROUGH[[gnu::fallthrough]];
13304 case OMPD_teams_distribute_parallel_for:
13305 CaptureRegion = OMPD_teams;
13306 break;
13307 case OMPD_target_update:
13308 case OMPD_target_enter_data:
13309 case OMPD_target_exit_data:
13310 CaptureRegion = OMPD_task;
13311 break;
13312 case OMPD_parallel_master_taskloop:
13313 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
13314 CaptureRegion = OMPD_parallel;
13315 break;
13316 case OMPD_parallel_master_taskloop_simd:
13317 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
13318 NameModifier == OMPD_taskloop) {
13319 CaptureRegion = OMPD_parallel;
13320 break;
13321 }
13322 if (OpenMPVersion <= 45)
13323 break;
13324 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13325 CaptureRegion = OMPD_taskloop;
13326 break;
13327 case OMPD_parallel_for_simd:
13328 if (OpenMPVersion <= 45)
13329 break;
13330 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13331 CaptureRegion = OMPD_parallel;
13332 break;
13333 case OMPD_taskloop_simd:
13334 case OMPD_master_taskloop_simd:
13335 if (OpenMPVersion <= 45)
13336 break;
13337 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13338 CaptureRegion = OMPD_taskloop;
13339 break;
13340 case OMPD_distribute_parallel_for_simd:
13341 if (OpenMPVersion <= 45)
13342 break;
13343 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13344 CaptureRegion = OMPD_parallel;
13345 break;
13346 case OMPD_target_simd:
13347 if (OpenMPVersion >= 50 &&
13348 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13349 CaptureRegion = OMPD_target;
13350 break;
13351 case OMPD_teams_distribute_simd:
13352 case OMPD_target_teams_distribute_simd:
13353 if (OpenMPVersion >= 50 &&
13354 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13355 CaptureRegion = OMPD_teams;
13356 break;
13357 case OMPD_cancel:
13358 case OMPD_parallel:
13359 case OMPD_parallel_master:
13360 case OMPD_parallel_sections:
13361 case OMPD_parallel_for:
13362 case OMPD_target:
13363 case OMPD_target_teams:
13364 case OMPD_target_teams_distribute:
13365 case OMPD_distribute_parallel_for:
13366 case OMPD_task:
13367 case OMPD_taskloop:
13368 case OMPD_master_taskloop:
13369 case OMPD_target_data:
13370 case OMPD_simd:
13371 case OMPD_for_simd:
13372 case OMPD_distribute_simd:
13373 // Do not capture if-clause expressions.
13374 break;
13375 case OMPD_threadprivate:
13376 case OMPD_allocate:
13377 case OMPD_taskyield:
13378 case OMPD_barrier:
13379 case OMPD_taskwait:
13380 case OMPD_cancellation_point:
13381 case OMPD_flush:
13382 case OMPD_depobj:
13383 case OMPD_scan:
13384 case OMPD_declare_reduction:
13385 case OMPD_declare_mapper:
13386 case OMPD_declare_simd:
13387 case OMPD_declare_variant:
13388 case OMPD_begin_declare_variant:
13389 case OMPD_end_declare_variant:
13390 case OMPD_declare_target:
13391 case OMPD_end_declare_target:
13392 case OMPD_teams:
13393 case OMPD_tile:
13394 case OMPD_unroll:
13395 case OMPD_for:
13396 case OMPD_sections:
13397 case OMPD_section:
13398 case OMPD_single:
13399 case OMPD_master:
13400 case OMPD_masked:
13401 case OMPD_critical:
13402 case OMPD_taskgroup:
13403 case OMPD_distribute:
13404 case OMPD_ordered:
13405 case OMPD_atomic:
13406 case OMPD_teams_distribute:
13407 case OMPD_requires:
13408 llvm_unreachable("Unexpected OpenMP directive with if-clause")__builtin_unreachable();
13409 case OMPD_unknown:
13410 default:
13411 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13412 }
13413 break;
13414 case OMPC_num_threads:
13415 switch (DKind) {
13416 case OMPD_target_parallel:
13417 case OMPD_target_parallel_for:
13418 case OMPD_target_parallel_for_simd:
13419 CaptureRegion = OMPD_target;
13420 break;
13421 case OMPD_teams_distribute_parallel_for:
13422 case OMPD_teams_distribute_parallel_for_simd:
13423 case OMPD_target_teams_distribute_parallel_for:
13424 case OMPD_target_teams_distribute_parallel_for_simd:
13425 CaptureRegion = OMPD_teams;
13426 break;
13427 case OMPD_parallel:
13428 case OMPD_parallel_master:
13429 case OMPD_parallel_sections:
13430 case OMPD_parallel_for:
13431 case OMPD_parallel_for_simd:
13432 case OMPD_distribute_parallel_for:
13433 case OMPD_distribute_parallel_for_simd:
13434 case OMPD_parallel_master_taskloop:
13435 case OMPD_parallel_master_taskloop_simd:
13436 // Do not capture num_threads-clause expressions.
13437 break;
13438 case OMPD_target_data:
13439 case OMPD_target_enter_data:
13440 case OMPD_target_exit_data:
13441 case OMPD_target_update:
13442 case OMPD_target:
13443 case OMPD_target_simd:
13444 case OMPD_target_teams:
13445 case OMPD_target_teams_distribute:
13446 case OMPD_target_teams_distribute_simd:
13447 case OMPD_cancel:
13448 case OMPD_task:
13449 case OMPD_taskloop:
13450 case OMPD_taskloop_simd:
13451 case OMPD_master_taskloop:
13452 case OMPD_master_taskloop_simd:
13453 case OMPD_threadprivate:
13454 case OMPD_allocate:
13455 case OMPD_taskyield:
13456 case OMPD_barrier:
13457 case OMPD_taskwait:
13458 case OMPD_cancellation_point:
13459 case OMPD_flush:
13460 case OMPD_depobj:
13461 case OMPD_scan:
13462 case OMPD_declare_reduction:
13463 case OMPD_declare_mapper:
13464 case OMPD_declare_simd:
13465 case OMPD_declare_variant:
13466 case OMPD_begin_declare_variant:
13467 case OMPD_end_declare_variant:
13468 case OMPD_declare_target:
13469 case OMPD_end_declare_target:
13470 case OMPD_teams:
13471 case OMPD_simd:
13472 case OMPD_tile:
13473 case OMPD_unroll:
13474 case OMPD_for:
13475 case OMPD_for_simd:
13476 case OMPD_sections:
13477 case OMPD_section:
13478 case OMPD_single:
13479 case OMPD_master:
13480 case OMPD_masked:
13481 case OMPD_critical:
13482 case OMPD_taskgroup:
13483 case OMPD_distribute:
13484 case OMPD_ordered:
13485 case OMPD_atomic:
13486 case OMPD_distribute_simd:
13487 case OMPD_teams_distribute:
13488 case OMPD_teams_distribute_simd:
13489 case OMPD_requires:
13490 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")__builtin_unreachable();
13491 case OMPD_unknown:
13492 default:
13493 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13494 }
13495 break;
13496 case OMPC_num_teams:
13497 switch (DKind) {
13498 case OMPD_target_teams:
13499 case OMPD_target_teams_distribute:
13500 case OMPD_target_teams_distribute_simd:
13501 case OMPD_target_teams_distribute_parallel_for:
13502 case OMPD_target_teams_distribute_parallel_for_simd:
13503 CaptureRegion = OMPD_target;
13504 break;
13505 case OMPD_teams_distribute_parallel_for:
13506 case OMPD_teams_distribute_parallel_for_simd:
13507 case OMPD_teams:
13508 case OMPD_teams_distribute:
13509 case OMPD_teams_distribute_simd:
13510 // Do not capture num_teams-clause expressions.
13511 break;
13512 case OMPD_distribute_parallel_for:
13513 case OMPD_distribute_parallel_for_simd:
13514 case OMPD_task:
13515 case OMPD_taskloop:
13516 case OMPD_taskloop_simd:
13517 case OMPD_master_taskloop:
13518 case OMPD_master_taskloop_simd:
13519 case OMPD_parallel_master_taskloop:
13520 case OMPD_parallel_master_taskloop_simd:
13521 case OMPD_target_data:
13522 case OMPD_target_enter_data:
13523 case OMPD_target_exit_data:
13524 case OMPD_target_update:
13525 case OMPD_cancel:
13526 case OMPD_parallel:
13527 case OMPD_parallel_master:
13528 case OMPD_parallel_sections:
13529 case OMPD_parallel_for:
13530 case OMPD_parallel_for_simd:
13531 case OMPD_target:
13532 case OMPD_target_simd:
13533 case OMPD_target_parallel:
13534 case OMPD_target_parallel_for:
13535 case OMPD_target_parallel_for_simd:
13536 case OMPD_threadprivate:
13537 case OMPD_allocate:
13538 case OMPD_taskyield:
13539 case OMPD_barrier:
13540 case OMPD_taskwait:
13541 case OMPD_cancellation_point:
13542 case OMPD_flush:
13543 case OMPD_depobj:
13544 case OMPD_scan:
13545 case OMPD_declare_reduction:
13546 case OMPD_declare_mapper:
13547 case OMPD_declare_simd:
13548 case OMPD_declare_variant:
13549 case OMPD_begin_declare_variant:
13550 case OMPD_end_declare_variant:
13551 case OMPD_declare_target:
13552 case OMPD_end_declare_target:
13553 case OMPD_simd:
13554 case OMPD_tile:
13555 case OMPD_unroll:
13556 case OMPD_for:
13557 case OMPD_for_simd:
13558 case OMPD_sections:
13559 case OMPD_section:
13560 case OMPD_single:
13561 case OMPD_master:
13562 case OMPD_masked:
13563 case OMPD_critical:
13564 case OMPD_taskgroup:
13565 case OMPD_distribute:
13566 case OMPD_ordered:
13567 case OMPD_atomic:
13568 case OMPD_distribute_simd:
13569 case OMPD_requires:
13570 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")__builtin_unreachable();
13571 case OMPD_unknown:
13572 default:
13573 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13574 }
13575 break;
13576 case OMPC_thread_limit:
13577 switch (DKind) {
13578 case OMPD_target_teams:
13579 case OMPD_target_teams_distribute:
13580 case OMPD_target_teams_distribute_simd:
13581 case OMPD_target_teams_distribute_parallel_for:
13582 case OMPD_target_teams_distribute_parallel_for_simd:
13583 CaptureRegion = OMPD_target;
13584 break;
13585 case OMPD_teams_distribute_parallel_for:
13586 case OMPD_teams_distribute_parallel_for_simd:
13587 case OMPD_teams:
13588 case OMPD_teams_distribute:
13589 case OMPD_teams_distribute_simd:
13590 // Do not capture thread_limit-clause expressions.
13591 break;
13592 case OMPD_distribute_parallel_for:
13593 case OMPD_distribute_parallel_for_simd:
13594 case OMPD_task:
13595 case OMPD_taskloop:
13596 case OMPD_taskloop_simd:
13597 case OMPD_master_taskloop:
13598 case OMPD_master_taskloop_simd:
13599 case OMPD_parallel_master_taskloop:
13600 case OMPD_parallel_master_taskloop_simd:
13601 case OMPD_target_data:
13602 case OMPD_target_enter_data:
13603 case OMPD_target_exit_data:
13604 case OMPD_target_update:
13605 case OMPD_cancel:
13606 case OMPD_parallel:
13607 case OMPD_parallel_master:
13608 case OMPD_parallel_sections:
13609 case OMPD_parallel_for:
13610 case OMPD_parallel_for_simd:
13611 case OMPD_target:
13612 case OMPD_target_simd:
13613 case OMPD_target_parallel:
13614 case OMPD_target_parallel_for:
13615 case OMPD_target_parallel_for_simd:
13616 case OMPD_threadprivate:
13617 case OMPD_allocate:
13618 case OMPD_taskyield:
13619 case OMPD_barrier:
13620 case OMPD_taskwait:
13621 case OMPD_cancellation_point:
13622 case OMPD_flush:
13623 case OMPD_depobj:
13624 case OMPD_scan:
13625 case OMPD_declare_reduction:
13626 case OMPD_declare_mapper:
13627 case OMPD_declare_simd:
13628 case OMPD_declare_variant:
13629 case OMPD_begin_declare_variant:
13630 case OMPD_end_declare_variant:
13631 case OMPD_declare_target:
13632 case OMPD_end_declare_target:
13633 case OMPD_simd:
13634 case OMPD_tile:
13635 case OMPD_unroll:
13636 case OMPD_for:
13637 case OMPD_for_simd:
13638 case OMPD_sections:
13639 case OMPD_section:
13640 case OMPD_single:
13641 case OMPD_master:
13642 case OMPD_masked:
13643 case OMPD_critical:
13644 case OMPD_taskgroup:
13645 case OMPD_distribute:
13646 case OMPD_ordered:
13647 case OMPD_atomic:
13648 case OMPD_distribute_simd:
13649 case OMPD_requires:
13650 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")__builtin_unreachable();
13651 case OMPD_unknown:
13652 default:
13653 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13654 }
13655 break;
13656 case OMPC_schedule:
13657 switch (DKind) {
13658 case OMPD_parallel_for:
13659 case OMPD_parallel_for_simd:
13660 case OMPD_distribute_parallel_for:
13661 case OMPD_distribute_parallel_for_simd:
13662 case OMPD_teams_distribute_parallel_for:
13663 case OMPD_teams_distribute_parallel_for_simd:
13664 case OMPD_target_parallel_for:
13665 case OMPD_target_parallel_for_simd:
13666 case OMPD_target_teams_distribute_parallel_for:
13667 case OMPD_target_teams_distribute_parallel_for_simd:
13668 CaptureRegion = OMPD_parallel;
13669 break;
13670 case OMPD_for:
13671 case OMPD_for_simd:
13672 // Do not capture schedule-clause expressions.
13673 break;
13674 case OMPD_task:
13675 case OMPD_taskloop:
13676 case OMPD_taskloop_simd:
13677 case OMPD_master_taskloop:
13678 case OMPD_master_taskloop_simd:
13679 case OMPD_parallel_master_taskloop:
13680 case OMPD_parallel_master_taskloop_simd:
13681 case OMPD_target_data:
13682 case OMPD_target_enter_data:
13683 case OMPD_target_exit_data:
13684 case OMPD_target_update:
13685 case OMPD_teams:
13686 case OMPD_teams_distribute:
13687 case OMPD_teams_distribute_simd:
13688 case OMPD_target_teams_distribute:
13689 case OMPD_target_teams_distribute_simd:
13690 case OMPD_target:
13691 case OMPD_target_simd:
13692 case OMPD_target_parallel:
13693 case OMPD_cancel:
13694 case OMPD_parallel:
13695 case OMPD_parallel_master:
13696 case OMPD_parallel_sections:
13697 case OMPD_threadprivate:
13698 case OMPD_allocate:
13699 case OMPD_taskyield:
13700 case OMPD_barrier:
13701 case OMPD_taskwait:
13702 case OMPD_cancellation_point:
13703 case OMPD_flush:
13704 case OMPD_depobj:
13705 case OMPD_scan:
13706 case OMPD_declare_reduction:
13707 case OMPD_declare_mapper:
13708 case OMPD_declare_simd:
13709 case OMPD_declare_variant:
13710 case OMPD_begin_declare_variant:
13711 case OMPD_end_declare_variant:
13712 case OMPD_declare_target:
13713 case OMPD_end_declare_target:
13714 case OMPD_simd:
13715 case OMPD_tile:
13716 case OMPD_unroll:
13717 case OMPD_sections:
13718 case OMPD_section:
13719 case OMPD_single:
13720 case OMPD_master:
13721 case OMPD_masked:
13722 case OMPD_critical:
13723 case OMPD_taskgroup:
13724 case OMPD_distribute:
13725 case OMPD_ordered:
13726 case OMPD_atomic:
13727 case OMPD_distribute_simd:
13728 case OMPD_target_teams:
13729 case OMPD_requires:
13730 llvm_unreachable("Unexpected OpenMP directive with schedule clause")__builtin_unreachable();
13731 case OMPD_unknown:
13732 default:
13733 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13734 }
13735 break;
13736 case OMPC_dist_schedule:
13737 switch (DKind) {
13738 case OMPD_teams_distribute_parallel_for:
13739 case OMPD_teams_distribute_parallel_for_simd:
13740 case OMPD_teams_distribute:
13741 case OMPD_teams_distribute_simd:
13742 case OMPD_target_teams_distribute_parallel_for:
13743 case OMPD_target_teams_distribute_parallel_for_simd:
13744 case OMPD_target_teams_distribute:
13745 case OMPD_target_teams_distribute_simd:
13746 CaptureRegion = OMPD_teams;
13747 break;
13748 case OMPD_distribute_parallel_for:
13749 case OMPD_distribute_parallel_for_simd:
13750 case OMPD_distribute:
13751 case OMPD_distribute_simd:
13752 // Do not capture dist_schedule-clause expressions.
13753 break;
13754 case OMPD_parallel_for:
13755 case OMPD_parallel_for_simd:
13756 case OMPD_target_parallel_for_simd:
13757 case OMPD_target_parallel_for:
13758 case OMPD_task:
13759 case OMPD_taskloop:
13760 case OMPD_taskloop_simd:
13761 case OMPD_master_taskloop:
13762 case OMPD_master_taskloop_simd:
13763 case OMPD_parallel_master_taskloop:
13764 case OMPD_parallel_master_taskloop_simd:
13765 case OMPD_target_data:
13766 case OMPD_target_enter_data:
13767 case OMPD_target_exit_data:
13768 case OMPD_target_update:
13769 case OMPD_teams:
13770 case OMPD_target:
13771 case OMPD_target_simd:
13772 case OMPD_target_parallel:
13773 case OMPD_cancel:
13774 case OMPD_parallel:
13775 case OMPD_parallel_master:
13776 case OMPD_parallel_sections:
13777 case OMPD_threadprivate:
13778 case OMPD_allocate:
13779 case OMPD_taskyield:
13780 case OMPD_barrier:
13781 case OMPD_taskwait:
13782 case OMPD_cancellation_point:
13783 case OMPD_flush:
13784 case OMPD_depobj:
13785 case OMPD_scan:
13786 case OMPD_declare_reduction:
13787 case OMPD_declare_mapper:
13788 case OMPD_declare_simd:
13789 case OMPD_declare_variant:
13790 case OMPD_begin_declare_variant:
13791 case OMPD_end_declare_variant:
13792 case OMPD_declare_target:
13793 case OMPD_end_declare_target:
13794 case OMPD_simd:
13795 case OMPD_tile:
13796 case OMPD_unroll:
13797 case OMPD_for:
13798 case OMPD_for_simd:
13799 case OMPD_sections:
13800 case OMPD_section:
13801 case OMPD_single:
13802 case OMPD_master:
13803 case OMPD_masked:
13804 case OMPD_critical:
13805 case OMPD_taskgroup:
13806 case OMPD_ordered:
13807 case OMPD_atomic:
13808 case OMPD_target_teams:
13809 case OMPD_requires:
13810 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause")__builtin_unreachable();
13811 case OMPD_unknown:
13812 default:
13813 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13814 }
13815 break;
13816 case OMPC_device:
13817 switch (DKind) {
13818 case OMPD_target_update:
13819 case OMPD_target_enter_data:
13820 case OMPD_target_exit_data:
13821 case OMPD_target:
13822 case OMPD_target_simd:
13823 case OMPD_target_teams:
13824 case OMPD_target_parallel:
13825 case OMPD_target_teams_distribute:
13826 case OMPD_target_teams_distribute_simd:
13827 case OMPD_target_parallel_for:
13828 case OMPD_target_parallel_for_simd:
13829 case OMPD_target_teams_distribute_parallel_for:
13830 case OMPD_target_teams_distribute_parallel_for_simd:
13831 case OMPD_dispatch:
13832 CaptureRegion = OMPD_task;
13833 break;
13834 case OMPD_target_data:
13835 case OMPD_interop:
13836 // Do not capture device-clause expressions.
13837 break;
13838 case OMPD_teams_distribute_parallel_for:
13839 case OMPD_teams_distribute_parallel_for_simd:
13840 case OMPD_teams:
13841 case OMPD_teams_distribute:
13842 case OMPD_teams_distribute_simd:
13843 case OMPD_distribute_parallel_for:
13844 case OMPD_distribute_parallel_for_simd:
13845 case OMPD_task:
13846 case OMPD_taskloop:
13847 case OMPD_taskloop_simd:
13848 case OMPD_master_taskloop:
13849 case OMPD_master_taskloop_simd:
13850 case OMPD_parallel_master_taskloop:
13851 case OMPD_parallel_master_taskloop_simd:
13852 case OMPD_cancel:
13853 case OMPD_parallel:
13854 case OMPD_parallel_master:
13855 case OMPD_parallel_sections:
13856 case OMPD_parallel_for:
13857 case OMPD_parallel_for_simd:
13858 case OMPD_threadprivate:
13859 case OMPD_allocate:
13860 case OMPD_taskyield:
13861 case OMPD_barrier:
13862 case OMPD_taskwait:
13863 case OMPD_cancellation_point:
13864 case OMPD_flush:
13865 case OMPD_depobj:
13866 case OMPD_scan:
13867 case OMPD_declare_reduction:
13868 case OMPD_declare_mapper:
13869 case OMPD_declare_simd:
13870 case OMPD_declare_variant:
13871 case OMPD_begin_declare_variant:
13872 case OMPD_end_declare_variant:
13873 case OMPD_declare_target:
13874 case OMPD_end_declare_target:
13875 case OMPD_simd:
13876 case OMPD_tile:
13877 case OMPD_unroll:
13878 case OMPD_for:
13879 case OMPD_for_simd:
13880 case OMPD_sections:
13881 case OMPD_section:
13882 case OMPD_single:
13883 case OMPD_master:
13884 case OMPD_masked:
13885 case OMPD_critical:
13886 case OMPD_taskgroup:
13887 case OMPD_distribute:
13888 case OMPD_ordered:
13889 case OMPD_atomic:
13890 case OMPD_distribute_simd:
13891 case OMPD_requires:
13892 llvm_unreachable("Unexpected OpenMP directive with device-clause")__builtin_unreachable();
13893 case OMPD_unknown:
13894 default:
13895 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13896 }
13897 break;
13898 case OMPC_grainsize:
13899 case OMPC_num_tasks:
13900 case OMPC_final:
13901 case OMPC_priority:
13902 switch (DKind) {
13903 case OMPD_task:
13904 case OMPD_taskloop:
13905 case OMPD_taskloop_simd:
13906 case OMPD_master_taskloop:
13907 case OMPD_master_taskloop_simd:
13908 break;
13909 case OMPD_parallel_master_taskloop:
13910 case OMPD_parallel_master_taskloop_simd:
13911 CaptureRegion = OMPD_parallel;
13912 break;
13913 case OMPD_target_update:
13914 case OMPD_target_enter_data:
13915 case OMPD_target_exit_data:
13916 case OMPD_target:
13917 case OMPD_target_simd:
13918 case OMPD_target_teams:
13919 case OMPD_target_parallel:
13920 case OMPD_target_teams_distribute:
13921 case OMPD_target_teams_distribute_simd:
13922 case OMPD_target_parallel_for:
13923 case OMPD_target_parallel_for_simd:
13924 case OMPD_target_teams_distribute_parallel_for:
13925 case OMPD_target_teams_distribute_parallel_for_simd:
13926 case OMPD_target_data:
13927 case OMPD_teams_distribute_parallel_for:
13928 case OMPD_teams_distribute_parallel_for_simd:
13929 case OMPD_teams:
13930 case OMPD_teams_distribute:
13931 case OMPD_teams_distribute_simd:
13932 case OMPD_distribute_parallel_for:
13933 case OMPD_distribute_parallel_for_simd:
13934 case OMPD_cancel:
13935 case OMPD_parallel:
13936 case OMPD_parallel_master:
13937 case OMPD_parallel_sections:
13938 case OMPD_parallel_for:
13939 case OMPD_parallel_for_simd:
13940 case OMPD_threadprivate:
13941 case OMPD_allocate:
13942 case OMPD_taskyield:
13943 case OMPD_barrier:
13944 case OMPD_taskwait:
13945 case OMPD_cancellation_point:
13946 case OMPD_flush:
13947 case OMPD_depobj:
13948 case OMPD_scan:
13949 case OMPD_declare_reduction:
13950 case OMPD_declare_mapper:
13951 case OMPD_declare_simd:
13952 case OMPD_declare_variant:
13953 case OMPD_begin_declare_variant:
13954 case OMPD_end_declare_variant:
13955 case OMPD_declare_target:
13956 case OMPD_end_declare_target:
13957 case OMPD_simd:
13958 case OMPD_tile:
13959 case OMPD_unroll:
13960 case OMPD_for:
13961 case OMPD_for_simd:
13962 case OMPD_sections:
13963 case OMPD_section:
13964 case OMPD_single:
13965 case OMPD_master:
13966 case OMPD_masked:
13967 case OMPD_critical:
13968 case OMPD_taskgroup:
13969 case OMPD_distribute:
13970 case OMPD_ordered:
13971 case OMPD_atomic:
13972 case OMPD_distribute_simd:
13973 case OMPD_requires:
13974 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")__builtin_unreachable();
13975 case OMPD_unknown:
13976 default:
13977 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13978 }
13979 break;
13980 case OMPC_novariants:
13981 case OMPC_nocontext:
13982 switch (DKind) {
13983 case OMPD_dispatch:
13984 CaptureRegion = OMPD_task;
13985 break;
13986 default:
13987 llvm_unreachable("Unexpected OpenMP directive")__builtin_unreachable();
13988 }
13989 break;
13990 case OMPC_filter:
13991 // Do not capture filter-clause expressions.
13992 break;
13993 case OMPC_firstprivate:
13994 case OMPC_lastprivate:
13995 case OMPC_reduction:
13996 case OMPC_task_reduction:
13997 case OMPC_in_reduction:
13998 case OMPC_linear:
13999 case OMPC_default:
14000 case OMPC_proc_bind:
14001 case OMPC_safelen:
14002 case OMPC_simdlen:
14003 case OMPC_sizes:
14004 case OMPC_allocator:
14005 case OMPC_collapse:
14006 case OMPC_private:
14007 case OMPC_shared:
14008 case OMPC_aligned:
14009 case OMPC_copyin:
14010 case OMPC_copyprivate:
14011 case OMPC_ordered:
14012 case OMPC_nowait:
14013 case OMPC_untied:
14014 case OMPC_mergeable:
14015 case OMPC_threadprivate:
14016 case OMPC_allocate:
14017 case OMPC_flush:
14018 case OMPC_depobj:
14019 case OMPC_read:
14020 case OMPC_write:
14021 case OMPC_update:
14022 case OMPC_capture:
14023 case OMPC_seq_cst:
14024 case OMPC_acq_rel:
14025 case OMPC_acquire:
14026 case OMPC_release:
14027 case OMPC_relaxed:
14028 case OMPC_depend:
14029 case OMPC_threads:
14030 case OMPC_simd:
14031 case OMPC_map:
14032 case OMPC_nogroup:
14033 case OMPC_hint:
14034 case OMPC_defaultmap:
14035 case OMPC_unknown:
14036 case OMPC_uniform:
14037 case OMPC_to:
14038 case OMPC_from:
14039 case OMPC_use_device_ptr:
14040 case OMPC_use_device_addr:
14041 case OMPC_is_device_ptr:
14042 case OMPC_unified_address:
14043 case OMPC_unified_shared_memory:
14044 case OMPC_reverse_offload:
14045 case OMPC_dynamic_allocators:
14046 case OMPC_atomic_default_mem_order:
14047 case OMPC_device_type:
14048 case OMPC_match:
14049 case OMPC_nontemporal:
14050 case OMPC_order:
14051 case OMPC_destroy:
14052 case OMPC_detach:
14053 case OMPC_inclusive:
14054 case OMPC_exclusive:
14055 case OMPC_uses_allocators:
14056 case OMPC_affinity:
14057 default:
14058 llvm_unreachable("Unexpected OpenMP clause.")__builtin_unreachable();
14059 }
14060 return CaptureRegion;
14061}
14062
14063OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
14064 Expr *Condition, SourceLocation StartLoc,
14065 SourceLocation LParenLoc,
14066 SourceLocation NameModifierLoc,
14067 SourceLocation ColonLoc,
14068 SourceLocation EndLoc) {
14069 Expr *ValExpr = Condition;
14070 Stmt *HelperValStmt = nullptr;
14071 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14072 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14073 !Condition->isInstantiationDependent() &&
14074 !Condition->containsUnexpandedParameterPack()) {
14075 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14076 if (Val.isInvalid())
14077 return nullptr;
14078
14079 ValExpr = Val.get();
14080
14081 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14082 CaptureRegion = getOpenMPCaptureRegionForClause(
14083 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
14084 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14085 ValExpr = MakeFullExpr(ValExpr).get();
14086 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14087 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14088 HelperValStmt = buildPreInits(Context, Captures);
14089 }
14090 }
14091
14092 return new (Context)
14093 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
14094 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
14095}
14096
14097OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
14098 SourceLocation StartLoc,
14099 SourceLocation LParenLoc,
14100 SourceLocation EndLoc) {
14101 Expr *ValExpr = Condition;
14102 Stmt *HelperValStmt = nullptr;
14103 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14104 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14105 !Condition->isInstantiationDependent() &&
14106 !Condition->containsUnexpandedParameterPack()) {
14107 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14108 if (Val.isInvalid())
14109 return nullptr;
14110
14111 ValExpr = MakeFullExpr(Val.get()).get();
14112
14113 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14114 CaptureRegion =
14115 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
14116 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14117 ValExpr = MakeFullExpr(ValExpr).get();
14118 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14119 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14120 HelperValStmt = buildPreInits(Context, Captures);
14121 }
14122 }
14123
14124 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
14125 StartLoc, LParenLoc, EndLoc);
14126}
14127
14128ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
14129 Expr *Op) {
14130 if (!Op)
14131 return ExprError();
14132
14133 class IntConvertDiagnoser : public ICEConvertDiagnoser {
14134 public:
14135 IntConvertDiagnoser()
14136 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
14137 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
14138 QualType T) override {
14139 return S.Diag(Loc, diag::err_omp_not_integral) << T;
14140 }
14141 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
14142 QualType T) override {
14143 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
14144 }
14145 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
14146 QualType T,
14147 QualType ConvTy) override {
14148 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
14149 }
14150 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
14151 QualType ConvTy) override {
14152 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14153 << ConvTy->isEnumeralType() << ConvTy;
14154 }
14155 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
14156 QualType T) override {
14157 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
14158 }
14159 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
14160 QualType ConvTy) override {
14161 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14162 << ConvTy->isEnumeralType() << ConvTy;
14163 }
14164 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
14165 QualType) override {
14166 llvm_unreachable("conversion functions are permitted")__builtin_unreachable();
14167 }
14168 } ConvertDiagnoser;
14169 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
14170}
14171
14172static bool
14173isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
14174 bool StrictlyPositive, bool BuildCapture = false,
14175 OpenMPDirectiveKind DKind = OMPD_unknown,
14176 OpenMPDirectiveKind *CaptureRegion = nullptr,
14177 Stmt **HelperValStmt = nullptr) {
14178 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
14179 !ValExpr->isInstantiationDependent()) {
14180 SourceLocation Loc = ValExpr->getExprLoc();
14181 ExprResult Value =
14182 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
14183 if (Value.isInvalid())
14184 return false;
14185
14186 ValExpr = Value.get();
14187 // The expression must evaluate to a non-negative integer value.
14188 if (Optional<llvm::APSInt> Result =
14189 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
14190 if (Result->isSigned() &&
14191 !((!StrictlyPositive && Result->isNonNegative()) ||
14192 (StrictlyPositive && Result->isStrictlyPositive()))) {
14193 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
14194 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14195 << ValExpr->getSourceRange();
14196 return false;
14197 }
14198 }
14199 if (!BuildCapture)
14200 return true;
14201 *CaptureRegion =
14202 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
14203 if (*CaptureRegion != OMPD_unknown &&
14204 !SemaRef.CurContext->isDependentContext()) {
14205 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
14206 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14207 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
14208 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
14209 }
14210 }
14211 return true;
14212}
14213
14214OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
14215 SourceLocation StartLoc,
14216 SourceLocation LParenLoc,
14217 SourceLocation EndLoc) {
14218 Expr *ValExpr = NumThreads;
14219 Stmt *HelperValStmt = nullptr;
14220
14221 // OpenMP [2.5, Restrictions]
14222 // The num_threads expression must evaluate to a positive integer value.
14223 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
14224 /*StrictlyPositive=*/true))
14225 return nullptr;
14226
14227 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14228 OpenMPDirectiveKind CaptureRegion =
14229 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
14230 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14231 ValExpr = MakeFullExpr(ValExpr).get();
14232 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14233 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14234 HelperValStmt = buildPreInits(Context, Captures);
14235 }
14236
14237 return new (Context) OMPNumThreadsClause(
14238 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14239}
14240
14241ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
14242 OpenMPClauseKind CKind,
14243 bool StrictlyPositive,
14244 bool SuppressExprDiags) {
14245 if (!E)
14246 return ExprError();
14247 if (E->isValueDependent() || E->isTypeDependent() ||
14248 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
14249 return E;
14250
14251 llvm::APSInt Result;
14252 ExprResult ICE;
14253 if (SuppressExprDiags) {
14254 // Use a custom diagnoser that suppresses 'note' diagnostics about the
14255 // expression.
14256 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
14257 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
14258 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
14259 SourceLocation Loc) override {
14260 llvm_unreachable("Diagnostic suppressed")__builtin_unreachable();
14261 }
14262 } Diagnoser;
14263 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
14264 } else {
14265 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
14266 }
14267 if (ICE.isInvalid())
14268 return ExprError();
14269
14270 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
14271 (!StrictlyPositive && !Result.isNonNegative())) {
14272 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
14273 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14274 << E->getSourceRange();
14275 return ExprError();
14276 }
14277 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
14278 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
14279 << E->getSourceRange();
14280 return ExprError();
14281 }
14282 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
14283 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
14284 else if (CKind == OMPC_ordered)
14285 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
14286 return ICE;
14287}
14288
14289OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
14290 SourceLocation LParenLoc,
14291 SourceLocation EndLoc) {
14292 // OpenMP [2.8.1, simd construct, Description]
14293 // The parameter of the safelen clause must be a constant
14294 // positive integer expression.
14295 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
14296 if (Safelen.isInvalid())
14297 return nullptr;
14298 return new (Context)
14299 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
14300}
14301
14302OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
14303 SourceLocation LParenLoc,
14304 SourceLocation EndLoc) {
14305 // OpenMP [2.8.1, simd construct, Description]
14306 // The parameter of the simdlen clause must be a constant
14307 // positive integer expression.
14308 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
14309 if (Simdlen.isInvalid())
14310 return nullptr;
14311 return new (Context)
14312 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
14313}
14314
14315/// Tries to find omp_allocator_handle_t type.
14316static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
14317 DSAStackTy *Stack) {
14318 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
14319 if (!OMPAllocatorHandleT.isNull())
14320 return true;
14321 // Build the predefined allocator expressions.
14322 bool ErrorFound = false;
14323 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
14324 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
14325 StringRef Allocator =
14326 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
14327 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
14328 auto *VD = dyn_cast_or_null<ValueDecl>(
14329 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
14330 if (!VD) {
14331 ErrorFound = true;
14332 break;
14333 }
14334 QualType AllocatorType =
14335 VD->getType().getNonLValueExprType(S.getASTContext());
14336 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
14337 if (!Res.isUsable()) {
14338 ErrorFound = true;
14339 break;
14340 }
14341 if (OMPAllocatorHandleT.isNull())
14342 OMPAllocatorHandleT = AllocatorType;
14343 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
14344 ErrorFound = true;
14345 break;
14346 }
14347 Stack->setAllocator(AllocatorKind, Res.get());
14348 }
14349 if (ErrorFound) {
14350 S.Diag(Loc, diag::err_omp_implied_type_not_found)
14351 << "omp_allocator_handle_t";
14352 return false;
14353 }
14354 OMPAllocatorHandleT.addConst();
14355 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
14356 return true;
14357}
14358
14359OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
14360 SourceLocation LParenLoc,
14361 SourceLocation EndLoc) {
14362 // OpenMP [2.11.3, allocate Directive, Description]
14363 // allocator is an expression of omp_allocator_handle_t type.
14364 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14365 return nullptr;
14366
14367 ExprResult Allocator = DefaultLvalueConversion(A);
14368 if (Allocator.isInvalid())
14369 return nullptr;
14370 Allocator = PerformImplicitConversion(Allocator.get(),
14371 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
14372 Sema::AA_Initializing,
14373 /*AllowExplicit=*/true);
14374 if (Allocator.isInvalid())
14375 return nullptr;
14376 return new (Context)
14377 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
14378}
14379
14380OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
14381 SourceLocation StartLoc,
14382 SourceLocation LParenLoc,
14383 SourceLocation EndLoc) {
14384 // OpenMP [2.7.1, loop construct, Description]
14385 // OpenMP [2.8.1, simd construct, Description]
14386 // OpenMP [2.9.6, distribute construct, Description]
14387 // The parameter of the collapse clause must be a constant
14388 // positive integer expression.
14389 ExprResult NumForLoopsResult =
14390 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
14391 if (NumForLoopsResult.isInvalid())
14392 return nullptr;
14393 return new (Context)
14394 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
14395}
14396
14397OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
14398 SourceLocation EndLoc,
14399 SourceLocation LParenLoc,
14400 Expr *NumForLoops) {
14401 // OpenMP [2.7.1, loop construct, Description]
14402 // OpenMP [2.8.1, simd construct, Description]
14403 // OpenMP [2.9.6, distribute construct, Description]
14404 // The parameter of the ordered clause must be a constant
14405 // positive integer expression if any.
14406 if (NumForLoops && LParenLoc.isValid()) {
14407 ExprResult NumForLoopsResult =
14408 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
14409 if (NumForLoopsResult.isInvalid())
14410 return nullptr;
14411 NumForLoops = NumForLoopsResult.get();
14412 } else {
14413 NumForLoops = nullptr;
14414 }
14415 auto *Clause = OMPOrderedClause::Create(
14416 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
14417 StartLoc, LParenLoc, EndLoc);
14418 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
14419 return Clause;
14420}
14421
14422OMPClause *Sema::ActOnOpenMPSimpleClause(
14423 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
14424 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14425 OMPClause *Res = nullptr;
14426 switch (Kind) {
14427 case OMPC_default:
14428 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
14429 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14430 break;
14431 case OMPC_proc_bind:
14432 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
14433 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14434 break;
14435 case OMPC_atomic_default_mem_order:
14436 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
14437 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
14438 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14439 break;
14440 case OMPC_order:
14441 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
14442 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14443 break;
14444 case OMPC_update:
14445 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
14446 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14447 break;
14448 case OMPC_if:
14449 case OMPC_final:
14450 case OMPC_num_threads:
14451 case OMPC_safelen:
14452 case OMPC_simdlen:
14453 case OMPC_sizes:
14454 case OMPC_allocator:
14455 case OMPC_collapse:
14456 case OMPC_schedule:
14457 case OMPC_private:
14458 case OMPC_firstprivate:
14459 case OMPC_lastprivate:
14460 case OMPC_shared:
14461 case OMPC_reduction:
14462 case OMPC_task_reduction:
14463 case OMPC_in_reduction:
14464 case OMPC_linear:
14465 case OMPC_aligned:
14466 case OMPC_copyin:
14467 case OMPC_copyprivate:
14468 case OMPC_ordered:
14469 case OMPC_nowait:
14470 case OMPC_untied:
14471 case OMPC_mergeable:
14472 case OMPC_threadprivate:
14473 case OMPC_allocate:
14474 case OMPC_flush:
14475 case OMPC_depobj:
14476 case OMPC_read:
14477 case OMPC_write:
14478 case OMPC_capture:
14479 case OMPC_seq_cst:
14480 case OMPC_acq_rel:
14481 case OMPC_acquire:
14482 case OMPC_release:
14483 case OMPC_relaxed:
14484 case OMPC_depend:
14485 case OMPC_device:
14486 case OMPC_threads:
14487 case OMPC_simd:
14488 case OMPC_map:
14489 case OMPC_num_teams:
14490 case OMPC_thread_limit:
14491 case OMPC_priority:
14492 case OMPC_grainsize:
14493 case OMPC_nogroup:
14494 case OMPC_num_tasks:
14495 case OMPC_hint:
14496 case OMPC_dist_schedule:
14497 case OMPC_defaultmap:
14498 case OMPC_unknown:
14499 case OMPC_uniform:
14500 case OMPC_to:
14501 case OMPC_from:
14502 case OMPC_use_device_ptr:
14503 case OMPC_use_device_addr:
14504 case OMPC_is_device_ptr:
14505 case OMPC_unified_address:
14506 case OMPC_unified_shared_memory:
14507 case OMPC_reverse_offload:
14508 case OMPC_dynamic_allocators:
14509 case OMPC_device_type:
14510 case OMPC_match:
14511 case OMPC_nontemporal:
14512 case OMPC_destroy:
14513 case OMPC_novariants:
14514 case OMPC_nocontext:
14515 case OMPC_detach:
14516 case OMPC_inclusive:
14517 case OMPC_exclusive:
14518 case OMPC_uses_allocators:
14519 case OMPC_affinity:
14520 default:
14521 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
14522 }
14523 return Res;
14524}
14525
14526static std::string
14527getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
14528 ArrayRef<unsigned> Exclude = llvm::None) {
14529 SmallString<256> Buffer;
14530 llvm::raw_svector_ostream Out(Buffer);
14531 unsigned Skipped = Exclude.size();
14532 auto S = Exclude.begin(), E = Exclude.end();
14533 for (unsigned I = First; I < Last; ++I) {
14534 if (std::find(S, E, I) != E) {
14535 --Skipped;
14536 continue;
14537 }
14538 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
14539 if (I + Skipped + 2 == Last)
14540 Out << " or ";
14541 else if (I + Skipped + 1 != Last)
14542 Out << ", ";
14543 }
14544 return std::string(Out.str());
14545}
14546
14547OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
14548 SourceLocation KindKwLoc,
14549 SourceLocation StartLoc,
14550 SourceLocation LParenLoc,
14551 SourceLocation EndLoc) {
14552 if (Kind == OMP_DEFAULT_unknown) {
14553 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14554 << getListOfPossibleValues(OMPC_default, /*First=*/0,
14555 /*Last=*/unsigned(OMP_DEFAULT_unknown))
14556 << getOpenMPClauseName(OMPC_default);
14557 return nullptr;
14558 }
14559
14560 switch (Kind) {
14561 case OMP_DEFAULT_none:
14562 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
14563 break;
14564 case OMP_DEFAULT_shared:
14565 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
14566 break;
14567 case OMP_DEFAULT_firstprivate:
14568 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
14569 break;
14570 default:
14571 llvm_unreachable("DSA unexpected in OpenMP default clause")__builtin_unreachable();
14572 }
14573
14574 return new (Context)
14575 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14576}
14577
14578OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
14579 SourceLocation KindKwLoc,
14580 SourceLocation StartLoc,
14581 SourceLocation LParenLoc,
14582 SourceLocation EndLoc) {
14583 if (Kind == OMP_PROC_BIND_unknown) {
14584 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14585 << getListOfPossibleValues(OMPC_proc_bind,
14586 /*First=*/unsigned(OMP_PROC_BIND_master),
14587 /*Last=*/
14588 unsigned(LangOpts.OpenMP > 50
14589 ? OMP_PROC_BIND_primary
14590 : OMP_PROC_BIND_spread) +
14591 1)
14592 << getOpenMPClauseName(OMPC_proc_bind);
14593 return nullptr;
14594 }
14595 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
14596 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14597 << getListOfPossibleValues(OMPC_proc_bind,
14598 /*First=*/unsigned(OMP_PROC_BIND_master),
14599 /*Last=*/
14600 unsigned(OMP_PROC_BIND_spread) + 1)
14601 << getOpenMPClauseName(OMPC_proc_bind);
14602 return new (Context)
14603 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14604}
14605
14606OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
14607 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
14608 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14609 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
14610 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14611 << getListOfPossibleValues(
14612 OMPC_atomic_default_mem_order, /*First=*/0,
14613 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
14614 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
14615 return nullptr;
14616 }
14617 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
14618 LParenLoc, EndLoc);
14619}
14620
14621OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
14622 SourceLocation KindKwLoc,
14623 SourceLocation StartLoc,
14624 SourceLocation LParenLoc,
14625 SourceLocation EndLoc) {
14626 if (Kind == OMPC_ORDER_unknown) {
14627 static_assert(OMPC_ORDER_unknown > 0,
14628 "OMPC_ORDER_unknown not greater than 0");
14629 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14630 << getListOfPossibleValues(OMPC_order, /*First=*/0,
14631 /*Last=*/OMPC_ORDER_unknown)
14632 << getOpenMPClauseName(OMPC_order);
14633 return nullptr;
14634 }
14635 return new (Context)
14636 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14637}
14638
14639OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
14640 SourceLocation KindKwLoc,
14641 SourceLocation StartLoc,
14642 SourceLocation LParenLoc,
14643 SourceLocation EndLoc) {
14644 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
14645 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
14646 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
14647 OMPC_DEPEND_depobj};
14648 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14649 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14650 /*Last=*/OMPC_DEPEND_unknown, Except)
14651 << getOpenMPClauseName(OMPC_update);
14652 return nullptr;
14653 }
14654 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
14655 EndLoc);
14656}
14657
14658OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
14659 SourceLocation StartLoc,
14660 SourceLocation LParenLoc,
14661 SourceLocation EndLoc) {
14662 for (Expr *SizeExpr : SizeExprs) {
14663 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
14664 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
14665 if (!NumForLoopsResult.isUsable())
14666 return nullptr;
14667 }
14668
14669 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(SizeExprs.size());
14670 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14671 SizeExprs);
14672}
14673
14674OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
14675 SourceLocation EndLoc) {
14676 return OMPFullClause::Create(Context, StartLoc, EndLoc);
14677}
14678
14679OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
14680 SourceLocation StartLoc,
14681 SourceLocation LParenLoc,
14682 SourceLocation EndLoc) {
14683 if (FactorExpr) {
14684 // If an argument is specified, it must be a constant (or an unevaluated
14685 // template expression).
14686 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
14687 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
14688 if (FactorResult.isInvalid())
14689 return nullptr;
14690 FactorExpr = FactorResult.get();
14691 }
14692
14693 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14694 FactorExpr);
14695}
14696
14697OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
14698 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
14699 SourceLocation StartLoc, SourceLocation LParenLoc,
14700 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
14701 SourceLocation EndLoc) {
14702 OMPClause *Res = nullptr;
14703 switch (Kind) {
14704 case OMPC_schedule:
14705 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
14706 assert(Argument.size() == NumberOfElements &&(static_cast<void> (0))
14707 ArgumentLoc.size() == NumberOfElements)(static_cast<void> (0));
14708 Res = ActOnOpenMPScheduleClause(
14709 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
14710 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
14711 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
14712 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
14713 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
14714 break;
14715 case OMPC_if:
14716 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)(static_cast<void> (0));
14717 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
14718 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
14719 DelimLoc, EndLoc);
14720 break;
14721 case OMPC_dist_schedule:
14722 Res = ActOnOpenMPDistScheduleClause(
14723 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
14724 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
14725 break;
14726 case OMPC_defaultmap:
14727 enum { Modifier, DefaultmapKind };
14728 Res = ActOnOpenMPDefaultmapClause(
14729 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
14730 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
14731 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
14732 EndLoc);
14733 break;
14734 case OMPC_device:
14735 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)(static_cast<void> (0));
14736 Res = ActOnOpenMPDeviceClause(
14737 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
14738 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
14739 break;
14740 case OMPC_final:
14741 case OMPC_num_threads:
14742 case OMPC_safelen:
14743 case OMPC_simdlen:
14744 case OMPC_sizes:
14745 case OMPC_allocator:
14746 case OMPC_collapse:
14747 case OMPC_default:
14748 case OMPC_proc_bind:
14749 case OMPC_private:
14750 case OMPC_firstprivate:
14751 case OMPC_lastprivate:
14752 case OMPC_shared:
14753 case OMPC_reduction:
14754 case OMPC_task_reduction:
14755 case OMPC_in_reduction:
14756 case OMPC_linear:
14757 case OMPC_aligned:
14758 case OMPC_copyin:
14759 case OMPC_copyprivate:
14760 case OMPC_ordered:
14761 case OMPC_nowait:
14762 case OMPC_untied:
14763 case OMPC_mergeable:
14764 case OMPC_threadprivate:
14765 case OMPC_allocate:
14766 case OMPC_flush:
14767 case OMPC_depobj:
14768 case OMPC_read:
14769 case OMPC_write:
14770 case OMPC_update:
14771 case OMPC_capture:
14772 case OMPC_seq_cst:
14773 case OMPC_acq_rel:
14774 case OMPC_acquire:
14775 case OMPC_release:
14776 case OMPC_relaxed:
14777 case OMPC_depend:
14778 case OMPC_threads:
14779 case OMPC_simd:
14780 case OMPC_map:
14781 case OMPC_num_teams:
14782 case OMPC_thread_limit:
14783 case OMPC_priority:
14784 case OMPC_grainsize:
14785 case OMPC_nogroup:
14786 case OMPC_num_tasks:
14787 case OMPC_hint:
14788 case OMPC_unknown:
14789 case OMPC_uniform:
14790 case OMPC_to:
14791 case OMPC_from:
14792 case OMPC_use_device_ptr:
14793 case OMPC_use_device_addr:
14794 case OMPC_is_device_ptr:
14795 case OMPC_unified_address:
14796 case OMPC_unified_shared_memory:
14797 case OMPC_reverse_offload:
14798 case OMPC_dynamic_allocators:
14799 case OMPC_atomic_default_mem_order:
14800 case OMPC_device_type:
14801 case OMPC_match:
14802 case OMPC_nontemporal:
14803 case OMPC_order:
14804 case OMPC_destroy:
14805 case OMPC_novariants:
14806 case OMPC_nocontext:
14807 case OMPC_detach:
14808 case OMPC_inclusive:
14809 case OMPC_exclusive:
14810 case OMPC_uses_allocators:
14811 case OMPC_affinity:
14812 default:
14813 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
14814 }
14815 return Res;
14816}
14817
14818static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
14819 OpenMPScheduleClauseModifier M2,
14820 SourceLocation M1Loc, SourceLocation M2Loc) {
14821 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
14822 SmallVector<unsigned, 2> Excluded;
14823 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
14824 Excluded.push_back(M2);
14825 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
14826 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
14827 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
14828 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
14829 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
14830 << getListOfPossibleValues(OMPC_schedule,
14831 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
14832 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14833 Excluded)
14834 << getOpenMPClauseName(OMPC_schedule);
14835 return true;
14836 }
14837 return false;
14838}
14839
14840OMPClause *Sema::ActOnOpenMPScheduleClause(
14841 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
14842 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14843 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
14844 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
14845 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
14846 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
14847 return nullptr;
14848 // OpenMP, 2.7.1, Loop Construct, Restrictions
14849 // Either the monotonic modifier or the nonmonotonic modifier can be specified
14850 // but not both.
14851 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
14852 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
14853 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
14854 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
14855 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
14856 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
14857 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
14858 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
14859 return nullptr;
14860 }
14861 if (Kind == OMPC_SCHEDULE_unknown) {
14862 std::string Values;
14863 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
14864 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
14865 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14866 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14867 Exclude);
14868 } else {
14869 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14870 /*Last=*/OMPC_SCHEDULE_unknown);
14871 }
14872 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14873 << Values << getOpenMPClauseName(OMPC_schedule);
14874 return nullptr;
14875 }
14876 // OpenMP, 2.7.1, Loop Construct, Restrictions
14877 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
14878 // schedule(guided).
14879 // OpenMP 5.0 does not have this restriction.
14880 if (LangOpts.OpenMP < 50 &&
14881 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
14882 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
14883 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
14884 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
14885 diag::err_omp_schedule_nonmonotonic_static);
14886 return nullptr;
14887 }
14888 Expr *ValExpr = ChunkSize;
14889 Stmt *HelperValStmt = nullptr;
14890 if (ChunkSize) {
14891 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14892 !ChunkSize->isInstantiationDependent() &&
14893 !ChunkSize->containsUnexpandedParameterPack()) {
14894 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14895 ExprResult Val =
14896 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14897 if (Val.isInvalid())
14898 return nullptr;
14899
14900 ValExpr = Val.get();
14901
14902 // OpenMP [2.7.1, Restrictions]
14903 // chunk_size must be a loop invariant integer expression with a positive
14904 // value.
14905 if (Optional<llvm::APSInt> Result =
14906 ValExpr->getIntegerConstantExpr(Context)) {
14907 if (Result->isSigned() && !Result->isStrictlyPositive()) {
14908 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14909 << "schedule" << 1 << ChunkSize->getSourceRange();
14910 return nullptr;
14911 }
14912 } else if (getOpenMPCaptureRegionForClause(
14913 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
14914 LangOpts.OpenMP) != OMPD_unknown &&
14915 !CurContext->isDependentContext()) {
14916 ValExpr = MakeFullExpr(ValExpr).get();
14917 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14918 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14919 HelperValStmt = buildPreInits(Context, Captures);
14920 }
14921 }
14922 }
14923
14924 return new (Context)
14925 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
14926 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
14927}
14928
14929OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
14930 SourceLocation StartLoc,
14931 SourceLocation EndLoc) {
14932 OMPClause *Res = nullptr;
14933 switch (Kind) {
14934 case OMPC_ordered:
14935 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
14936 break;
14937 case OMPC_nowait:
14938 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
14939 break;
14940 case OMPC_untied:
14941 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
14942 break;
14943 case OMPC_mergeable:
14944 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
14945 break;
14946 case OMPC_read:
14947 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
14948 break;
14949 case OMPC_write:
14950 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
14951 break;
14952 case OMPC_update:
14953 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
14954 break;
14955 case OMPC_capture:
14956 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
14957 break;
14958 case OMPC_seq_cst:
14959 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
14960 break;
14961 case OMPC_acq_rel:
14962 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
14963 break;
14964 case OMPC_acquire:
14965 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
14966 break;
14967 case OMPC_release:
14968 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
14969 break;
14970 case OMPC_relaxed:
14971 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
14972 break;
14973 case OMPC_threads:
14974 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
14975 break;
14976 case OMPC_simd:
14977 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
14978 break;
14979 case OMPC_nogroup:
14980 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
14981 break;
14982 case OMPC_unified_address:
14983 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
14984 break;
14985 case OMPC_unified_shared_memory:
14986 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14987 break;
14988 case OMPC_reverse_offload:
14989 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
14990 break;
14991 case OMPC_dynamic_allocators:
14992 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
14993 break;
14994 case OMPC_destroy:
14995 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
14996 /*LParenLoc=*/SourceLocation(),
14997 /*VarLoc=*/SourceLocation(), EndLoc);
14998 break;
14999 case OMPC_full:
15000 Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
15001 break;
15002 case OMPC_partial:
15003 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
15004 break;
15005 case OMPC_if:
15006 case OMPC_final:
15007 case OMPC_num_threads:
15008 case OMPC_safelen:
15009 case OMPC_simdlen:
15010 case OMPC_sizes:
15011 case OMPC_allocator:
15012 case OMPC_collapse:
15013 case OMPC_schedule:
15014 case OMPC_private:
15015 case OMPC_firstprivate:
15016 case OMPC_lastprivate:
15017 case OMPC_shared:
15018 case OMPC_reduction:
15019 case OMPC_task_reduction:
15020 case OMPC_in_reduction:
15021 case OMPC_linear:
15022 case OMPC_aligned:
15023 case OMPC_copyin:
15024 case OMPC_copyprivate:
15025 case OMPC_default:
15026 case OMPC_proc_bind:
15027 case OMPC_threadprivate:
15028 case OMPC_allocate:
15029 case OMPC_flush:
15030 case OMPC_depobj:
15031 case OMPC_depend:
15032 case OMPC_device:
15033 case OMPC_map:
15034 case OMPC_num_teams:
15035 case OMPC_thread_limit:
15036 case OMPC_priority:
15037 case OMPC_grainsize:
15038 case OMPC_num_tasks:
15039 case OMPC_hint:
15040 case OMPC_dist_schedule:
15041 case OMPC_defaultmap:
15042 case OMPC_unknown:
15043 case OMPC_uniform:
15044 case OMPC_to:
15045 case OMPC_from:
15046 case OMPC_use_device_ptr:
15047 case OMPC_use_device_addr:
15048 case OMPC_is_device_ptr:
15049 case OMPC_atomic_default_mem_order:
15050 case OMPC_device_type:
15051 case OMPC_match:
15052 case OMPC_nontemporal:
15053 case OMPC_order:
15054 case OMPC_novariants:
15055 case OMPC_nocontext:
15056 case OMPC_detach:
15057 case OMPC_inclusive:
15058 case OMPC_exclusive:
15059 case OMPC_uses_allocators:
15060 case OMPC_affinity:
15061 default:
15062 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
15063 }
15064 return Res;
15065}
15066
15067OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
15068 SourceLocation EndLoc) {
15069 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
15070 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
15071}
15072
15073OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
15074 SourceLocation EndLoc) {
15075 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
15076}
15077
15078OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
15079 SourceLocation EndLoc) {
15080 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
15081}
15082
15083OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
15084 SourceLocation EndLoc) {
15085 return new (Context) OMPReadClause(StartLoc, EndLoc);
15086}
15087
15088OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
15089 SourceLocation EndLoc) {
15090 return new (Context) OMPWriteClause(StartLoc, EndLoc);
15091}
15092
15093OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
15094 SourceLocation EndLoc) {
15095 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
15096}
15097
15098OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
15099 SourceLocation EndLoc) {
15100 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
15101}
15102
15103OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
15104 SourceLocation EndLoc) {
15105 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
15106}
15107
15108OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
15109 SourceLocation EndLoc) {
15110 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
15111}
15112
15113OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
15114 SourceLocation EndLoc) {
15115 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
15116}
15117
15118OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
15119 SourceLocation EndLoc) {
15120 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
15121}
15122
15123OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
15124 SourceLocation EndLoc) {
15125 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
15126}
15127
15128OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
15129 SourceLocation EndLoc) {
15130 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
15131}
15132
15133OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
15134 SourceLocation EndLoc) {
15135 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
15136}
15137
15138OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
15139 SourceLocation EndLoc) {
15140 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
15141}
15142
15143OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
15144 SourceLocation EndLoc) {
15145 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
15146}
15147
15148OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
15149 SourceLocation EndLoc) {
15150 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
15151}
15152
15153OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
15154 SourceLocation EndLoc) {
15155 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
15156}
15157
15158OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
15159 SourceLocation EndLoc) {
15160 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
15161}
15162
15163StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
15164 SourceLocation StartLoc,
15165 SourceLocation EndLoc) {
15166
15167 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15168 // At least one action-clause must appear on a directive.
15169 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
15170 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
15171 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
15172 << Expected << getOpenMPDirectiveName(OMPD_interop);
15173 return StmtError();
15174 }
15175
15176 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15177 // A depend clause can only appear on the directive if a targetsync
15178 // interop-type is present or the interop-var was initialized with
15179 // the targetsync interop-type.
15180
15181 // If there is any 'init' clause diagnose if there is no 'init' clause with
15182 // interop-type of 'targetsync'. Cases involving other directives cannot be
15183 // diagnosed.
15184 const OMPDependClause *DependClause = nullptr;
15185 bool HasInitClause = false;
15186 bool IsTargetSync = false;
15187 for (const OMPClause *C : Clauses) {
15188 if (IsTargetSync)
15189 break;
15190 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
15191 HasInitClause = true;
15192 if (InitClause->getIsTargetSync())
15193 IsTargetSync = true;
15194 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
15195 DependClause = DC;
15196 }
15197 }
15198 if (DependClause && HasInitClause && !IsTargetSync) {
15199 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
15200 return StmtError();
15201 }
15202
15203 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15204 // Each interop-var may be specified for at most one action-clause of each
15205 // interop construct.
15206 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
15207 for (const OMPClause *C : Clauses) {
15208 OpenMPClauseKind ClauseKind = C->getClauseKind();
15209 const DeclRefExpr *DRE = nullptr;
15210 SourceLocation VarLoc;
15211
15212 if (ClauseKind == OMPC_init) {
15213 const auto *IC = cast<OMPInitClause>(C);
15214 VarLoc = IC->getVarLoc();
15215 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
15216 } else if (ClauseKind == OMPC_use) {
15217 const auto *UC = cast<OMPUseClause>(C);
15218 VarLoc = UC->getVarLoc();
15219 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
15220 } else if (ClauseKind == OMPC_destroy) {
15221 const auto *DC = cast<OMPDestroyClause>(C);
15222 VarLoc = DC->getVarLoc();
15223 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
15224 }
15225
15226 if (!DRE)
15227 continue;
15228
15229 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
15230 if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
15231 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
15232 return StmtError();
15233 }
15234 }
15235 }
15236
15237 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
15238}
15239
15240static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
15241 SourceLocation VarLoc,
15242 OpenMPClauseKind Kind) {
15243 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
15244 InteropVarExpr->isInstantiationDependent() ||
15245 InteropVarExpr->containsUnexpandedParameterPack())
15246 return true;
15247
15248 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
15249 if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
15250 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
15251 return false;
15252 }
15253
15254 // Interop variable should be of type omp_interop_t.
15255 bool HasError = false;
15256 QualType InteropType;
15257 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
15258 VarLoc, Sema::LookupOrdinaryName);
15259 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
15260 NamedDecl *ND = Result.getFoundDecl();
15261 if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
15262 InteropType = QualType(TD->getTypeForDecl(), 0);
15263 } else {
15264 HasError = true;
15265 }
15266 } else {
15267 HasError = true;
15268 }
15269
15270 if (HasError) {
15271 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
15272 << "omp_interop_t";
15273 return false;
15274 }
15275
15276 QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
15277 if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
15278 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
15279 return false;
15280 }
15281
15282 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15283 // The interop-var passed to init or destroy must be non-const.
15284 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
15285 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
15286 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
15287 << /*non-const*/ 1;
15288 return false;
15289 }
15290 return true;
15291}
15292
15293OMPClause *
15294Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
15295 bool IsTarget, bool IsTargetSync,
15296 SourceLocation StartLoc, SourceLocation LParenLoc,
15297 SourceLocation VarLoc, SourceLocation EndLoc) {
15298
15299 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
15300 return nullptr;
15301
15302 // Check prefer_type values. These foreign-runtime-id values are either
15303 // string literals or constant integral expressions.
15304 for (const Expr *E : PrefExprs) {
15305 if (E->isValueDependent() || E->isTypeDependent() ||
15306 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
15307 continue;
15308 if (E->isIntegerConstantExpr(Context))
15309 continue;
15310 if (isa<StringLiteral>(E))
15311 continue;
15312 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
15313 return nullptr;
15314 }
15315
15316 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
15317 IsTargetSync, StartLoc, LParenLoc, VarLoc,
15318 EndLoc);
15319}
15320
15321OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
15322 SourceLocation LParenLoc,
15323 SourceLocation VarLoc,
15324 SourceLocation EndLoc) {
15325
15326 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
15327 return nullptr;
15328
15329 return new (Context)
15330 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15331}
15332
15333OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
15334 SourceLocation StartLoc,
15335 SourceLocation LParenLoc,
15336 SourceLocation VarLoc,
15337 SourceLocation EndLoc) {
15338 if (InteropVar &&
15339 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
15340 return nullptr;
15341
15342 return new (Context)
15343 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15344}
15345
15346OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
15347 SourceLocation StartLoc,
15348 SourceLocation LParenLoc,
15349 SourceLocation EndLoc) {
15350 Expr *ValExpr = Condition;
15351 Stmt *HelperValStmt = nullptr;
15352 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15353 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15354 !Condition->isInstantiationDependent() &&
15355 !Condition->containsUnexpandedParameterPack()) {
15356 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15357 if (Val.isInvalid())
15358 return nullptr;
15359
15360 ValExpr = MakeFullExpr(Val.get()).get();
15361
15362 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15363 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
15364 LangOpts.OpenMP);
15365 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15366 ValExpr = MakeFullExpr(ValExpr).get();
15367 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15368 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15369 HelperValStmt = buildPreInits(Context, Captures);
15370 }
15371 }
15372
15373 return new (Context) OMPNovariantsClause(
15374 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15375}
15376
15377OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
15378 SourceLocation StartLoc,
15379 SourceLocation LParenLoc,
15380 SourceLocation EndLoc) {
15381 Expr *ValExpr = Condition;
15382 Stmt *HelperValStmt = nullptr;
15383 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15384 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15385 !Condition->isInstantiationDependent() &&
15386 !Condition->containsUnexpandedParameterPack()) {
15387 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15388 if (Val.isInvalid())
15389 return nullptr;
15390
15391 ValExpr = MakeFullExpr(Val.get()).get();
15392
15393 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15394 CaptureRegion =
15395 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
15396 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15397 ValExpr = MakeFullExpr(ValExpr).get();
15398 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15399 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15400 HelperValStmt = buildPreInits(Context, Captures);
15401 }
15402 }
15403
15404 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
15405 StartLoc, LParenLoc, EndLoc);
15406}
15407
15408OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
15409 SourceLocation StartLoc,
15410 SourceLocation LParenLoc,
15411 SourceLocation EndLoc) {
15412 Expr *ValExpr = ThreadID;
15413 Stmt *HelperValStmt = nullptr;
15414
15415 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15416 OpenMPDirectiveKind CaptureRegion =
15417 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
15418 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15419 ValExpr = MakeFullExpr(ValExpr).get();
15420 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15421 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15422 HelperValStmt = buildPreInits(Context, Captures);
15423 }
15424
15425 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
15426 StartLoc, LParenLoc, EndLoc);
15427}
15428
15429OMPClause *Sema::ActOnOpenMPVarListClause(
15430 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
15431 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
15432 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
15433 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
15434 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15435 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
15436 SourceLocation ExtraModifierLoc,
15437 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
15438 ArrayRef<SourceLocation> MotionModifiersLoc) {
15439 SourceLocation StartLoc = Locs.StartLoc;
15440 SourceLocation LParenLoc = Locs.LParenLoc;
15441 SourceLocation EndLoc = Locs.EndLoc;
15442 OMPClause *Res = nullptr;
15443 switch (Kind) {
15444 case OMPC_private:
15445 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15446 break;
15447 case OMPC_firstprivate:
15448 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15449 break;
15450 case OMPC_lastprivate:
15451 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&(static_cast<void> (0))
15452 "Unexpected lastprivate modifier.")(static_cast<void> (0));
15453 Res = ActOnOpenMPLastprivateClause(
15454 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
15455 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
15456 break;
15457 case OMPC_shared:
15458 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
15459 break;
15460 case OMPC_reduction:
15461 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&(static_cast<void> (0))
15462 "Unexpected lastprivate modifier.")(static_cast<void> (0));
15463 Res = ActOnOpenMPReductionClause(
15464 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
15465 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
15466 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
15467 break;
15468 case OMPC_task_reduction:
15469 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15470 EndLoc, ReductionOrMapperIdScopeSpec,
15471 ReductionOrMapperId);
15472 break;
15473 case OMPC_in_reduction:
15474 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15475 EndLoc, ReductionOrMapperIdScopeSpec,
15476 ReductionOrMapperId);
15477 break;
15478 case OMPC_linear:
15479 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&(static_cast<void> (0))
15480 "Unexpected linear modifier.")(static_cast<void> (0));
15481 Res = ActOnOpenMPLinearClause(
15482 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
15483 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
15484 ColonLoc, EndLoc);
15485 break;
15486 case OMPC_aligned:
15487 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
15488 LParenLoc, ColonLoc, EndLoc);
15489 break;
15490 case OMPC_copyin:
15491 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
15492 break;
15493 case OMPC_copyprivate:
15494 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15495 break;
15496 case OMPC_flush:
15497 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
15498 break;
15499 case OMPC_depend:
15500 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&(static_cast<void> (0))
15501 "Unexpected depend modifier.")(static_cast<void> (0));
15502 Res = ActOnOpenMPDependClause(
15503 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
15504 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
15505 break;
15506 case OMPC_map:
15507 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&(static_cast<void> (0))
15508 "Unexpected map modifier.")(static_cast<void> (0));
15509 Res = ActOnOpenMPMapClause(
15510 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
15511 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
15512 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
15513 break;
15514 case OMPC_to:
15515 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
15516 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
15517 ColonLoc, VarList, Locs);
15518 break;
15519 case OMPC_from:
15520 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
15521 ReductionOrMapperIdScopeSpec,
15522 ReductionOrMapperId, ColonLoc, VarList, Locs);
15523 break;
15524 case OMPC_use_device_ptr:
15525 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
15526 break;
15527 case OMPC_use_device_addr:
15528 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
15529 break;
15530 case OMPC_is_device_ptr:
15531 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
15532 break;
15533 case OMPC_allocate:
15534 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
15535 LParenLoc, ColonLoc, EndLoc);
15536 break;
15537 case OMPC_nontemporal:
15538 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
15539 break;
15540 case OMPC_inclusive:
15541 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15542 break;
15543 case OMPC_exclusive:
15544 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15545 break;
15546 case OMPC_affinity:
15547 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
15548 DepModOrTailExpr, VarList);
15549 break;
15550 case OMPC_if:
15551 case OMPC_depobj:
15552 case OMPC_final:
15553 case OMPC_num_threads:
15554 case OMPC_safelen:
15555 case OMPC_simdlen:
15556 case OMPC_sizes:
15557 case OMPC_allocator:
15558 case OMPC_collapse:
15559 case OMPC_default:
15560 case OMPC_proc_bind:
15561 case OMPC_schedule:
15562 case OMPC_ordered:
15563 case OMPC_nowait:
15564 case OMPC_untied:
15565 case OMPC_mergeable:
15566 case OMPC_threadprivate:
15567 case OMPC_read:
15568 case OMPC_write:
15569 case OMPC_update:
15570 case OMPC_capture:
15571 case OMPC_seq_cst:
15572 case OMPC_acq_rel:
15573 case OMPC_acquire:
15574 case OMPC_release:
15575 case OMPC_relaxed:
15576 case OMPC_device:
15577 case OMPC_threads:
15578 case OMPC_simd:
15579 case OMPC_num_teams:
15580 case OMPC_thread_limit:
15581 case OMPC_priority:
15582 case OMPC_grainsize:
15583 case OMPC_nogroup:
15584 case OMPC_num_tasks:
15585 case OMPC_hint:
15586 case OMPC_dist_schedule:
15587 case OMPC_defaultmap:
15588 case OMPC_unknown:
15589 case OMPC_uniform:
15590 case OMPC_unified_address:
15591 case OMPC_unified_shared_memory:
15592 case OMPC_reverse_offload:
15593 case OMPC_dynamic_allocators:
15594 case OMPC_atomic_default_mem_order:
15595 case OMPC_device_type:
15596 case OMPC_match:
15597 case OMPC_order:
15598 case OMPC_destroy:
15599 case OMPC_novariants:
15600 case OMPC_nocontext:
15601 case OMPC_detach:
15602 case OMPC_uses_allocators:
15603 default:
15604 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
15605 }
15606 return Res;
15607}
15608
15609ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
15610 ExprObjectKind OK, SourceLocation Loc) {
15611 ExprResult Res = BuildDeclRefExpr(
15612 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
15613 if (!Res.isUsable())
15614 return ExprError();
15615 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
15616 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
15617 if (!Res.isUsable())
15618 return ExprError();
15619 }
15620 if (VK != VK_LValue && Res.get()->isGLValue()) {
15621 Res = DefaultLvalueConversion(Res.get());
15622 if (!Res.isUsable())
15623 return ExprError();
15624 }
15625 return Res;
15626}
15627
15628OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
15629 SourceLocation StartLoc,
15630 SourceLocation LParenLoc,
15631 SourceLocation EndLoc) {
15632 SmallVector<Expr *, 8> Vars;
15633 SmallVector<Expr *, 8> PrivateCopies;
15634 for (Expr *RefExpr : VarList) {
15635 assert(RefExpr && "NULL expr in OpenMP private clause.")(static_cast<void> (0));
15636 SourceLocation ELoc;
15637 SourceRange ERange;
15638 Expr *SimpleRefExpr = RefExpr;
15639 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15640 if (Res.second) {
15641 // It will be analyzed later.
15642 Vars.push_back(RefExpr);
15643 PrivateCopies.push_back(nullptr);
15644 }
15645 ValueDecl *D = Res.first;
15646 if (!D)
15647 continue;
15648
15649 QualType Type = D->getType();
15650 auto *VD = dyn_cast<VarDecl>(D);
15651
15652 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15653 // A variable that appears in a private clause must not have an incomplete
15654 // type or a reference type.
15655 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
15656 continue;
15657 Type = Type.getNonReferenceType();
15658
15659 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15660 // A variable that is privatized must not have a const-qualified type
15661 // unless it is of class type with a mutable member. This restriction does
15662 // not apply to the firstprivate clause.
15663 //
15664 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
15665 // A variable that appears in a private clause must not have a
15666 // const-qualified type unless it is of class type with a mutable member.
15667 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
15668 continue;
15669
15670 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15671 // in a Construct]
15672 // Variables with the predetermined data-sharing attributes may not be
15673 // listed in data-sharing attributes clauses, except for the cases
15674 // listed below. For these exceptions only, listing a predetermined
15675 // variable in a data-sharing attribute clause is allowed and overrides
15676 // the variable's predetermined data-sharing attributes.
15677 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15678 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
15679 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15680 << getOpenMPClauseName(OMPC_private);
15681 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15682 continue;
15683 }
15684
15685 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15686 // Variably modified types are not supported for tasks.
15687 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15688 isOpenMPTaskingDirective(CurrDir)) {
15689 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15690 << getOpenMPClauseName(OMPC_private) << Type
15691 << getOpenMPDirectiveName(CurrDir);
15692 bool IsDecl =
15693 !VD ||
15694 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15695 Diag(D->getLocation(),
15696 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15697 << D;
15698 continue;
15699 }
15700
15701 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15702 // A list item cannot appear in both a map clause and a data-sharing
15703 // attribute clause on the same construct
15704 //
15705 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15706 // A list item cannot appear in both a map clause and a data-sharing
15707 // attribute clause on the same construct unless the construct is a
15708 // combined construct.
15709 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
15710 CurrDir == OMPD_target) {
15711 OpenMPClauseKind ConflictKind;
15712 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
15713 VD, /*CurrentRegionOnly=*/true,
15714 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
15715 OpenMPClauseKind WhereFoundClauseKind) -> bool {
15716 ConflictKind = WhereFoundClauseKind;
15717 return true;
15718 })) {
15719 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15720 << getOpenMPClauseName(OMPC_private)
15721 << getOpenMPClauseName(ConflictKind)
15722 << getOpenMPDirectiveName(CurrDir);
15723 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15724 continue;
15725 }
15726 }
15727
15728 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
15729 // A variable of class type (or array thereof) that appears in a private
15730 // clause requires an accessible, unambiguous default constructor for the
15731 // class type.
15732 // Generate helper private variable and initialize it with the default
15733 // value. The address of the original variable is replaced by the address of
15734 // the new private variable in CodeGen. This new variable is not added to
15735 // IdResolver, so the code in the OpenMP region uses original variable for
15736 // proper diagnostics.
15737 Type = Type.getUnqualifiedType();
15738 VarDecl *VDPrivate =
15739 buildVarDecl(*this, ELoc, Type, D->getName(),
15740 D->hasAttrs() ? &D->getAttrs() : nullptr,
15741 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15742 ActOnUninitializedDecl(VDPrivate);
15743 if (VDPrivate->isInvalidDecl())
15744 continue;
15745 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15746 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15747
15748 DeclRefExpr *Ref = nullptr;
15749 if (!VD && !CurContext->isDependentContext())
15750 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15751 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
15752 Vars.push_back((VD || CurContext->isDependentContext())
15753 ? RefExpr->IgnoreParens()
15754 : Ref);
15755 PrivateCopies.push_back(VDPrivateRefExpr);
15756 }
15757
15758 if (Vars.empty())
15759 return nullptr;
15760
15761 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15762 PrivateCopies);
15763}
15764
15765namespace {
15766class DiagsUninitializedSeveretyRAII {
15767private:
15768 DiagnosticsEngine &Diags;
15769 SourceLocation SavedLoc;
15770 bool IsIgnored = false;
15771
15772public:
15773 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
15774 bool IsIgnored)
15775 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
15776 if (!IsIgnored) {
15777 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
15778 /*Map*/ diag::Severity::Ignored, Loc);
15779 }
15780 }
15781 ~DiagsUninitializedSeveretyRAII() {
15782 if (!IsIgnored)
15783 Diags.popMappings(SavedLoc);
15784 }
15785};
15786}
15787
15788OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
15789 SourceLocation StartLoc,
15790 SourceLocation LParenLoc,
15791 SourceLocation EndLoc) {
15792 SmallVector<Expr *, 8> Vars;
15793 SmallVector<Expr *, 8> PrivateCopies;
15794 SmallVector<Expr *, 8> Inits;
15795 SmallVector<Decl *, 4> ExprCaptures;
15796 bool IsImplicitClause =
15797 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
15798 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
15799
15800 for (Expr *RefExpr : VarList) {
15801 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")(static_cast<void> (0));
15802 SourceLocation ELoc;
15803 SourceRange ERange;
15804 Expr *SimpleRefExpr = RefExpr;
15805 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15806 if (Res.second) {
15807 // It will be analyzed later.
15808 Vars.push_back(RefExpr);
15809 PrivateCopies.push_back(nullptr);
15810 Inits.push_back(nullptr);
15811 }
15812 ValueDecl *D = Res.first;
15813 if (!D)
15814 continue;
15815
15816 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
15817 QualType Type = D->getType();
15818 auto *VD = dyn_cast<VarDecl>(D);
15819
15820 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15821 // A variable that appears in a private clause must not have an incomplete
15822 // type or a reference type.
15823 if (RequireCompleteType(ELoc, Type,
15824 diag::err_omp_firstprivate_incomplete_type))
15825 continue;
15826 Type = Type.getNonReferenceType();
15827
15828 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
15829 // A variable of class type (or array thereof) that appears in a private
15830 // clause requires an accessible, unambiguous copy constructor for the
15831 // class type.
15832 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15833
15834 // If an implicit firstprivate variable found it was checked already.
15835 DSAStackTy::DSAVarData TopDVar;
15836 if (!IsImplicitClause) {
15837 DSAStackTy::DSAVarData DVar =
15838 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15839 TopDVar = DVar;
15840 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15841 bool IsConstant = ElemType.isConstant(Context);
15842 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
15843 // A list item that specifies a given variable may not appear in more
15844 // than one clause on the same directive, except that a variable may be
15845 // specified in both firstprivate and lastprivate clauses.
15846 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15847 // A list item may appear in a firstprivate or lastprivate clause but not
15848 // both.
15849 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
15850 (isOpenMPDistributeDirective(CurrDir) ||
15851 DVar.CKind != OMPC_lastprivate) &&
15852 DVar.RefExpr) {
15853 Diag(ELoc, diag::err_omp_wrong_dsa)
15854 << getOpenMPClauseName(DVar.CKind)
15855 << getOpenMPClauseName(OMPC_firstprivate);
15856 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15857 continue;
15858 }
15859
15860 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15861 // in a Construct]
15862 // Variables with the predetermined data-sharing attributes may not be
15863 // listed in data-sharing attributes clauses, except for the cases
15864 // listed below. For these exceptions only, listing a predetermined
15865 // variable in a data-sharing attribute clause is allowed and overrides
15866 // the variable's predetermined data-sharing attributes.
15867 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15868 // in a Construct, C/C++, p.2]
15869 // Variables with const-qualified type having no mutable member may be
15870 // listed in a firstprivate clause, even if they are static data members.
15871 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
15872 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
15873 Diag(ELoc, diag::err_omp_wrong_dsa)
15874 << getOpenMPClauseName(DVar.CKind)
15875 << getOpenMPClauseName(OMPC_firstprivate);
15876 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15877 continue;
15878 }
15879
15880 // OpenMP [2.9.3.4, Restrictions, p.2]
15881 // A list item that is private within a parallel region must not appear
15882 // in a firstprivate clause on a worksharing construct if any of the
15883 // worksharing regions arising from the worksharing construct ever bind
15884 // to any of the parallel regions arising from the parallel construct.
15885 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15886 // A list item that is private within a teams region must not appear in a
15887 // firstprivate clause on a distribute construct if any of the distribute
15888 // regions arising from the distribute construct ever bind to any of the
15889 // teams regions arising from the teams construct.
15890 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15891 // A list item that appears in a reduction clause of a teams construct
15892 // must not appear in a firstprivate clause on a distribute construct if
15893 // any of the distribute regions arising from the distribute construct
15894 // ever bind to any of the teams regions arising from the teams construct.
15895 if ((isOpenMPWorksharingDirective(CurrDir) ||
15896 isOpenMPDistributeDirective(CurrDir)) &&
15897 !isOpenMPParallelDirective(CurrDir) &&
15898 !isOpenMPTeamsDirective(CurrDir)) {
15899 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
15900 if (DVar.CKind != OMPC_shared &&
15901 (isOpenMPParallelDirective(DVar.DKind) ||
15902 isOpenMPTeamsDirective(DVar.DKind) ||
15903 DVar.DKind == OMPD_unknown)) {
15904 Diag(ELoc, diag::err_omp_required_access)
15905 << getOpenMPClauseName(OMPC_firstprivate)
15906 << getOpenMPClauseName(OMPC_shared);
15907 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15908 continue;
15909 }
15910 }
15911 // OpenMP [2.9.3.4, Restrictions, p.3]
15912 // A list item that appears in a reduction clause of a parallel construct
15913 // must not appear in a firstprivate clause on a worksharing or task
15914 // construct if any of the worksharing or task regions arising from the
15915 // worksharing or task construct ever bind to any of the parallel regions
15916 // arising from the parallel construct.
15917 // OpenMP [2.9.3.4, Restrictions, p.4]
15918 // A list item that appears in a reduction clause in worksharing
15919 // construct must not appear in a firstprivate clause in a task construct
15920 // encountered during execution of any of the worksharing regions arising
15921 // from the worksharing construct.
15922 if (isOpenMPTaskingDirective(CurrDir)) {
15923 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
15924 D,
15925 [](OpenMPClauseKind C, bool AppliedToPointee) {
15926 return C == OMPC_reduction && !AppliedToPointee;
15927 },
15928 [](OpenMPDirectiveKind K) {
15929 return isOpenMPParallelDirective(K) ||
15930 isOpenMPWorksharingDirective(K) ||
15931 isOpenMPTeamsDirective(K);
15932 },
15933 /*FromParent=*/true);
15934 if (DVar.CKind == OMPC_reduction &&
15935 (isOpenMPParallelDirective(DVar.DKind) ||
15936 isOpenMPWorksharingDirective(DVar.DKind) ||
15937 isOpenMPTeamsDirective(DVar.DKind))) {
15938 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
15939 << getOpenMPDirectiveName(DVar.DKind);
15940 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15941 continue;
15942 }
15943 }
15944
15945 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15946 // A list item cannot appear in both a map clause and a data-sharing
15947 // attribute clause on the same construct
15948 //
15949 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15950 // A list item cannot appear in both a map clause and a data-sharing
15951 // attribute clause on the same construct unless the construct is a
15952 // combined construct.
15953 if ((LangOpts.OpenMP <= 45 &&
15954 isOpenMPTargetExecutionDirective(CurrDir)) ||
15955 CurrDir == OMPD_target) {
15956 OpenMPClauseKind ConflictKind;
15957 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
15958 VD, /*CurrentRegionOnly=*/true,
15959 [&ConflictKind](
15960 OMPClauseMappableExprCommon::MappableExprComponentListRef,
15961 OpenMPClauseKind WhereFoundClauseKind) {
15962 ConflictKind = WhereFoundClauseKind;
15963 return true;
15964 })) {
15965 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15966 << getOpenMPClauseName(OMPC_firstprivate)
15967 << getOpenMPClauseName(ConflictKind)
15968 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
15969 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15970 continue;
15971 }
15972 }
15973 }
15974
15975 // Variably modified types are not supported for tasks.
15976 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15977 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
15978 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15979 << getOpenMPClauseName(OMPC_firstprivate) << Type
15980 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
15981 bool IsDecl =
15982 !VD ||
15983 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15984 Diag(D->getLocation(),
15985 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15986 << D;
15987 continue;
15988 }
15989
15990 Type = Type.getUnqualifiedType();
15991 VarDecl *VDPrivate =
15992 buildVarDecl(*this, ELoc, Type, D->getName(),
15993 D->hasAttrs() ? &D->getAttrs() : nullptr,
15994 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15995 // Generate helper private variable and initialize it with the value of the
15996 // original variable. The address of the original variable is replaced by
15997 // the address of the new private variable in the CodeGen. This new variable
15998 // is not added to IdResolver, so the code in the OpenMP region uses
15999 // original variable for proper diagnostics and variable capturing.
16000 Expr *VDInitRefExpr = nullptr;
16001 // For arrays generate initializer for single element and replace it by the
16002 // original array element in CodeGen.
16003 if (Type->isArrayType()) {
16004 VarDecl *VDInit =
16005 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
16006 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
16007 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
16008 ElemType = ElemType.getUnqualifiedType();
16009 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
16010 ".firstprivate.temp");
16011 InitializedEntity Entity =
16012 InitializedEntity::InitializeVariable(VDInitTemp);
16013 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
16014
16015 InitializationSequence InitSeq(*this, Entity, Kind, Init);
16016 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
16017 if (Result.isInvalid())
16018 VDPrivate->setInvalidDecl();
16019 else
16020 VDPrivate->setInit(Result.getAs<Expr>());
16021 // Remove temp variable declaration.
16022 Context.Deallocate(VDInitTemp);
16023 } else {
16024 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
16025 ".firstprivate.temp");
16026 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
16027 RefExpr->getExprLoc());
16028 AddInitializerToDecl(VDPrivate,
16029 DefaultLvalueConversion(VDInitRefExpr).get(),
16030 /*DirectInit=*/false);
16031 }
16032 if (VDPrivate->isInvalidDecl()) {
16033 if (IsImplicitClause) {
16034 Diag(RefExpr->getExprLoc(),
16035 diag::note_omp_task_predetermined_firstprivate_here);
16036 }
16037 continue;
16038 }
16039 CurContext->addDecl(VDPrivate);
16040 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
16041 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
16042 RefExpr->getExprLoc());
16043 DeclRefExpr *Ref = nullptr;
16044 if (!VD && !CurContext->isDependentContext()) {
16045 if (TopDVar.CKind == OMPC_lastprivate) {
16046 Ref = TopDVar.PrivateCopy;
16047 } else {
16048 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16049 if (!isOpenMPCapturedDecl(D))
16050 ExprCaptures.push_back(Ref->getDecl());
16051 }
16052 }
16053 if (!IsImplicitClause)
16054 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
16055 Vars.push_back((VD || CurContext->isDependentContext())
16056 ? RefExpr->IgnoreParens()
16057 : Ref);
16058 PrivateCopies.push_back(VDPrivateRefExpr);
16059 Inits.push_back(VDInitRefExpr);
16060 }
16061
16062 if (Vars.empty())
16063 return nullptr;
16064
16065 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16066 Vars, PrivateCopies, Inits,
16067 buildPreInits(Context, ExprCaptures));
16068}
16069
16070OMPClause *Sema::ActOnOpenMPLastprivateClause(
16071 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
16072 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
16073 SourceLocation LParenLoc, SourceLocation EndLoc) {
16074 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
16075 assert(ColonLoc.isValid() && "Colon location must be valid.")(static_cast<void> (0));
16076 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
16077 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
16078 /*Last=*/OMPC_LASTPRIVATE_unknown)
16079 << getOpenMPClauseName(OMPC_lastprivate);
16080 return nullptr;
16081 }
16082
16083 SmallVector<Expr *, 8> Vars;
16084 SmallVector<Expr *, 8> SrcExprs;
16085 SmallVector<Expr *, 8> DstExprs;
16086 SmallVector<Expr *, 8> AssignmentOps;
16087 SmallVector<Decl *, 4> ExprCaptures;
16088 SmallVector<Expr *, 4> ExprPostUpdates;
16089 for (Expr *RefExpr : VarList) {
16090 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")(static_cast<void> (0));
16091 SourceLocation ELoc;
16092 SourceRange ERange;
16093 Expr *SimpleRefExpr = RefExpr;
16094 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16095 if (Res.second) {
16096 // It will be analyzed later.
16097 Vars.push_back(RefExpr);
16098 SrcExprs.push_back(nullptr);
16099 DstExprs.push_back(nullptr);
16100 AssignmentOps.push_back(nullptr);
16101 }
16102 ValueDecl *D = Res.first;
16103 if (!D)
16104 continue;
16105
16106 QualType Type = D->getType();
16107 auto *VD = dyn_cast<VarDecl>(D);
16108
16109 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
16110 // A variable that appears in a lastprivate clause must not have an
16111 // incomplete type or a reference type.
16112 if (RequireCompleteType(ELoc, Type,
16113 diag::err_omp_lastprivate_incomplete_type))
16114 continue;
16115 Type = Type.getNonReferenceType();
16116
16117 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
16118 // A variable that is privatized must not have a const-qualified type
16119 // unless it is of class type with a mutable member. This restriction does
16120 // not apply to the firstprivate clause.
16121 //
16122 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
16123 // A variable that appears in a lastprivate clause must not have a
16124 // const-qualified type unless it is of class type with a mutable member.
16125 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
16126 continue;
16127
16128 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
16129 // A list item that appears in a lastprivate clause with the conditional
16130 // modifier must be a scalar variable.
16131 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
16132 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
16133 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16134 VarDecl::DeclarationOnly;
16135 Diag(D->getLocation(),
16136 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16137 << D;
16138 continue;
16139 }
16140
16141 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16142 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16143 // in a Construct]
16144 // Variables with the predetermined data-sharing attributes may not be
16145 // listed in data-sharing attributes clauses, except for the cases
16146 // listed below.
16147 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
16148 // A list item may appear in a firstprivate or lastprivate clause but not
16149 // both.
16150 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16151 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
16152 (isOpenMPDistributeDirective(CurrDir) ||
16153 DVar.CKind != OMPC_firstprivate) &&
16154 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
16155 Diag(ELoc, diag::err_omp_wrong_dsa)
16156 << getOpenMPClauseName(DVar.CKind)
16157 << getOpenMPClauseName(OMPC_lastprivate);
16158 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16159 continue;
16160 }
16161
16162 // OpenMP [2.14.3.5, Restrictions, p.2]
16163 // A list item that is private within a parallel region, or that appears in
16164 // the reduction clause of a parallel construct, must not appear in a
16165 // lastprivate clause on a worksharing construct if any of the corresponding
16166 // worksharing regions ever binds to any of the corresponding parallel
16167 // regions.
16168 DSAStackTy::DSAVarData TopDVar = DVar;
16169 if (isOpenMPWorksharingDirective(CurrDir) &&
16170 !isOpenMPParallelDirective(CurrDir) &&
16171 !isOpenMPTeamsDirective(CurrDir)) {
16172 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
16173 if (DVar.CKind != OMPC_shared) {
16174 Diag(ELoc, diag::err_omp_required_access)
16175 << getOpenMPClauseName(OMPC_lastprivate)
16176 << getOpenMPClauseName(OMPC_shared);
16177 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16178 continue;
16179 }
16180 }
16181
16182 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
16183 // A variable of class type (or array thereof) that appears in a
16184 // lastprivate clause requires an accessible, unambiguous default
16185 // constructor for the class type, unless the list item is also specified
16186 // in a firstprivate clause.
16187 // A variable of class type (or array thereof) that appears in a
16188 // lastprivate clause requires an accessible, unambiguous copy assignment
16189 // operator for the class type.
16190 Type = Context.getBaseElementType(Type).getNonReferenceType();
16191 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
16192 Type.getUnqualifiedType(), ".lastprivate.src",
16193 D->hasAttrs() ? &D->getAttrs() : nullptr);
16194 DeclRefExpr *PseudoSrcExpr =
16195 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
16196 VarDecl *DstVD =
16197 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
16198 D->hasAttrs() ? &D->getAttrs() : nullptr);
16199 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16200 // For arrays generate assignment operation for single element and replace
16201 // it by the original array element in CodeGen.
16202 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
16203 PseudoDstExpr, PseudoSrcExpr);
16204 if (AssignmentOp.isInvalid())
16205 continue;
16206 AssignmentOp =
16207 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16208 if (AssignmentOp.isInvalid())
16209 continue;
16210
16211 DeclRefExpr *Ref = nullptr;
16212 if (!VD && !CurContext->isDependentContext()) {
16213 if (TopDVar.CKind == OMPC_firstprivate) {
16214 Ref = TopDVar.PrivateCopy;
16215 } else {
16216 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16217 if (!isOpenMPCapturedDecl(D))
16218 ExprCaptures.push_back(Ref->getDecl());
16219 }
16220 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
16221 (!isOpenMPCapturedDecl(D) &&
16222 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
16223 ExprResult RefRes = DefaultLvalueConversion(Ref);
16224 if (!RefRes.isUsable())
16225 continue;
16226 ExprResult PostUpdateRes =
16227 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
16228 RefRes.get());
16229 if (!PostUpdateRes.isUsable())
16230 continue;
16231 ExprPostUpdates.push_back(
16232 IgnoredValueConversions(PostUpdateRes.get()).get());
16233 }
16234 }
16235 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
16236 Vars.push_back((VD || CurContext->isDependentContext())
16237 ? RefExpr->IgnoreParens()
16238 : Ref);
16239 SrcExprs.push_back(PseudoSrcExpr);
16240 DstExprs.push_back(PseudoDstExpr);
16241 AssignmentOps.push_back(AssignmentOp.get());
16242 }
16243
16244 if (Vars.empty())
16245 return nullptr;
16246
16247 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16248 Vars, SrcExprs, DstExprs, AssignmentOps,
16249 LPKind, LPKindLoc, ColonLoc,
16250 buildPreInits(Context, ExprCaptures),
16251 buildPostUpdate(*this, ExprPostUpdates));
16252}
16253
16254OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
16255 SourceLocation StartLoc,
16256 SourceLocation LParenLoc,
16257 SourceLocation EndLoc) {
16258 SmallVector<Expr *, 8> Vars;
16259 for (Expr *RefExpr : VarList) {
16260 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")(static_cast<void> (0));
16261 SourceLocation ELoc;
16262 SourceRange ERange;
16263 Expr *SimpleRefExpr = RefExpr;
16264 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16265 if (Res.second) {
16266 // It will be analyzed later.
16267 Vars.push_back(RefExpr);
16268 }
16269 ValueDecl *D = Res.first;
16270 if (!D)
16271 continue;
16272
16273 auto *VD = dyn_cast<VarDecl>(D);
16274 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
16275 // in a Construct]
16276 // Variables with the predetermined data-sharing attributes may not be
16277 // listed in data-sharing attributes clauses, except for the cases
16278 // listed below. For these exceptions only, listing a predetermined
16279 // variable in a data-sharing attribute clause is allowed and overrides
16280 // the variable's predetermined data-sharing attributes.
16281 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16282 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
16283 DVar.RefExpr) {
16284 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
16285 << getOpenMPClauseName(OMPC_shared);
16286 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16287 continue;
16288 }
16289
16290 DeclRefExpr *Ref = nullptr;
16291 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
16292 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16293 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
16294 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
16295 ? RefExpr->IgnoreParens()
16296 : Ref);
16297 }
16298
16299 if (Vars.empty())
16300 return nullptr;
16301
16302 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
16303}
16304
16305namespace {
16306class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
16307 DSAStackTy *Stack;
16308
16309public:
16310 bool VisitDeclRefExpr(DeclRefExpr *E) {
16311 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
16312 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
16313 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
16314 return false;
16315 if (DVar.CKind != OMPC_unknown)
16316 return true;
16317 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
16318 VD,
16319 [](OpenMPClauseKind C, bool AppliedToPointee) {
16320 return isOpenMPPrivate(C) && !AppliedToPointee;
16321 },
16322 [](OpenMPDirectiveKind) { return true; },
16323 /*FromParent=*/true);
16324 return DVarPrivate.CKind != OMPC_unknown;
16325 }
16326 return false;
16327 }
16328 bool VisitStmt(Stmt *S) {
16329 for (Stmt *Child : S->children()) {
16330 if (Child && Visit(Child))
16331 return true;
16332 }
16333 return false;
16334 }
16335 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
16336};
16337} // namespace
16338
16339namespace {
16340// Transform MemberExpression for specified FieldDecl of current class to
16341// DeclRefExpr to specified OMPCapturedExprDecl.
16342class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
16343 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
16344 ValueDecl *Field = nullptr;
16345 DeclRefExpr *CapturedExpr = nullptr;
16346
16347public:
16348 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
16349 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
16350
16351 ExprResult TransformMemberExpr(MemberExpr *E) {
16352 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
16353 E->getMemberDecl() == Field) {
16354 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
16355 return CapturedExpr;
16356 }
16357 return BaseTransform::TransformMemberExpr(E);
16358 }
16359 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
16360};
16361} // namespace
16362
16363template <typename T, typename U>
16364static T filterLookupForUDReductionAndMapper(
16365 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
16366 for (U &Set : Lookups) {
16367 for (auto *D : Set) {
16368 if (T Res = Gen(cast<ValueDecl>(D)))
16369 return Res;
16370 }
16371 }
16372 return T();
16373}
16374
16375static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
16376 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")(static_cast<void> (0));
16377
16378 for (auto RD : D->redecls()) {
16379 // Don't bother with extra checks if we already know this one isn't visible.
16380 if (RD == D)
16381 continue;
16382
16383 auto ND = cast<NamedDecl>(RD);
16384 if (LookupResult::isVisible(SemaRef, ND))
16385 return ND;
16386 }
16387
16388 return nullptr;
16389}
16390
16391static void
16392argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
16393 SourceLocation Loc, QualType Ty,
16394 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
16395 // Find all of the associated namespaces and classes based on the
16396 // arguments we have.
16397 Sema::AssociatedNamespaceSet AssociatedNamespaces;
16398 Sema::AssociatedClassSet AssociatedClasses;
16399 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
16400 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
16401 AssociatedClasses);
16402
16403 // C++ [basic.lookup.argdep]p3:
16404 // Let X be the lookup set produced by unqualified lookup (3.4.1)
16405 // and let Y be the lookup set produced by argument dependent
16406 // lookup (defined as follows). If X contains [...] then Y is
16407 // empty. Otherwise Y is the set of declarations found in the
16408 // namespaces associated with the argument types as described
16409 // below. The set of declarations found by the lookup of the name
16410 // is the union of X and Y.
16411 //
16412 // Here, we compute Y and add its members to the overloaded
16413 // candidate set.
16414 for (auto *NS : AssociatedNamespaces) {
16415 // When considering an associated namespace, the lookup is the
16416 // same as the lookup performed when the associated namespace is
16417 // used as a qualifier (3.4.3.2) except that:
16418 //
16419 // -- Any using-directives in the associated namespace are
16420 // ignored.
16421 //
16422 // -- Any namespace-scope friend functions declared in
16423 // associated classes are visible within their respective
16424 // namespaces even if they are not visible during an ordinary
16425 // lookup (11.4).
16426 DeclContext::lookup_result R = NS->lookup(Id.getName());
16427 for (auto *D : R) {
16428 auto *Underlying = D;
16429 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16430 Underlying = USD->getTargetDecl();
16431
16432 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
16433 !isa<OMPDeclareMapperDecl>(Underlying))
16434 continue;
16435
16436 if (!SemaRef.isVisible(D)) {
16437 D = findAcceptableDecl(SemaRef, D);
16438 if (!D)
16439 continue;
16440 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16441 Underlying = USD->getTargetDecl();
16442 }
16443 Lookups.emplace_back();
16444 Lookups.back().addDecl(Underlying);
16445 }
16446 }
16447}
16448
16449static ExprResult
16450buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
16451 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
16452 const DeclarationNameInfo &ReductionId, QualType Ty,
16453 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
16454 if (ReductionIdScopeSpec.isInvalid())
16455 return ExprError();
16456 SmallVector<UnresolvedSet<8>, 4> Lookups;
16457 if (S) {
16458 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16459 Lookup.suppressDiagnostics();
16460 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
16461 NamedDecl *D = Lookup.getRepresentativeDecl();
16462 do {
16463 S = S->getParent();
16464 } while (S && !S->isDeclScope(D));
16465 if (S)
16466 S = S->getParent();
16467 Lookups.emplace_back();
16468 Lookups.back().append(Lookup.begin(), Lookup.end());
16469 Lookup.clear();
16470 }
16471 } else if (auto *ULE =
16472 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
16473 Lookups.push_back(UnresolvedSet<8>());
16474 Decl *PrevD = nullptr;
16475 for (NamedDecl *D : ULE->decls()) {
16476 if (D == PrevD)
16477 Lookups.push_back(UnresolvedSet<8>());
16478 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
16479 Lookups.back().addDecl(DRD);
16480 PrevD = D;
16481 }
16482 }
16483 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
16484 Ty->isInstantiationDependentType() ||
16485 Ty->containsUnexpandedParameterPack() ||
16486 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
16487 return !D->isInvalidDecl() &&
16488 (D->getType()->isDependentType() ||
16489 D->getType()->isInstantiationDependentType() ||
16490 D->getType()->containsUnexpandedParameterPack());
16491 })) {
16492 UnresolvedSet<8> ResSet;
16493 for (const UnresolvedSet<8> &Set : Lookups) {
16494 if (Set.empty())
16495 continue;
16496 ResSet.append(Set.begin(), Set.end());
16497 // The last item marks the end of all declarations at the specified scope.
16498 ResSet.addDecl(Set[Set.size() - 1]);
16499 }
16500 return UnresolvedLookupExpr::Create(
16501 SemaRef.Context, /*NamingClass=*/nullptr,
16502 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
16503 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
16504 }
16505 // Lookup inside the classes.
16506 // C++ [over.match.oper]p3:
16507 // For a unary operator @ with an operand of a type whose
16508 // cv-unqualified version is T1, and for a binary operator @ with
16509 // a left operand of a type whose cv-unqualified version is T1 and
16510 // a right operand of a type whose cv-unqualified version is T2,
16511 // three sets of candidate functions, designated member
16512 // candidates, non-member candidates and built-in candidates, are
16513 // constructed as follows:
16514 // -- If T1 is a complete class type or a class currently being
16515 // defined, the set of member candidates is the result of the
16516 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
16517 // the set of member candidates is empty.
16518 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16519 Lookup.suppressDiagnostics();
16520 if (const auto *TyRec = Ty->getAs<RecordType>()) {
16521 // Complete the type if it can be completed.
16522 // If the type is neither complete nor being defined, bail out now.
16523 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
16524 TyRec->getDecl()->getDefinition()) {
16525 Lookup.clear();
16526 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
16527 if (Lookup.empty()) {
16528 Lookups.emplace_back();
16529 Lookups.back().append(Lookup.begin(), Lookup.end());
16530 }
16531 }
16532 }
16533 // Perform ADL.
16534 if (SemaRef.getLangOpts().CPlusPlus)
16535 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
16536 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16537 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
16538 if (!D->isInvalidDecl() &&
16539 SemaRef.Context.hasSameType(D->getType(), Ty))
16540 return D;
16541 return nullptr;
16542 }))
16543 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
16544 VK_LValue, Loc);
16545 if (SemaRef.getLangOpts().CPlusPlus) {
16546 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16547 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
16548 if (!D->isInvalidDecl() &&
16549 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
16550 !Ty.isMoreQualifiedThan(D->getType()))
16551 return D;
16552 return nullptr;
16553 })) {
16554 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16555 /*DetectVirtual=*/false);
16556 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
16557 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16558 VD->getType().getUnqualifiedType()))) {
16559 if (SemaRef.CheckBaseClassAccess(
16560 Loc, VD->getType(), Ty, Paths.front(),
16561 /*DiagID=*/0) != Sema::AR_inaccessible) {
16562 SemaRef.BuildBasePathArray(Paths, BasePath);
16563 return SemaRef.BuildDeclRefExpr(
16564 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
16565 }
16566 }
16567 }
16568 }
16569 }
16570 if (ReductionIdScopeSpec.isSet()) {
16571 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
16572 << Ty << Range;
16573 return ExprError();
16574 }
16575 return ExprEmpty();
16576}
16577
16578namespace {
16579/// Data for the reduction-based clauses.
16580struct ReductionData {
16581 /// List of original reduction items.
16582 SmallVector<Expr *, 8> Vars;
16583 /// List of private copies of the reduction items.
16584 SmallVector<Expr *, 8> Privates;
16585 /// LHS expressions for the reduction_op expressions.
16586 SmallVector<Expr *, 8> LHSs;
16587 /// RHS expressions for the reduction_op expressions.
16588 SmallVector<Expr *, 8> RHSs;
16589 /// Reduction operation expression.
16590 SmallVector<Expr *, 8> ReductionOps;
16591 /// inscan copy operation expressions.
16592 SmallVector<Expr *, 8> InscanCopyOps;
16593 /// inscan copy temp array expressions for prefix sums.
16594 SmallVector<Expr *, 8> InscanCopyArrayTemps;
16595 /// inscan copy temp array element expressions for prefix sums.
16596 SmallVector<Expr *, 8> InscanCopyArrayElems;
16597 /// Taskgroup descriptors for the corresponding reduction items in
16598 /// in_reduction clauses.
16599 SmallVector<Expr *, 8> TaskgroupDescriptors;
16600 /// List of captures for clause.
16601 SmallVector<Decl *, 4> ExprCaptures;
16602 /// List of postupdate expressions.
16603 SmallVector<Expr *, 4> ExprPostUpdates;
16604 /// Reduction modifier.
16605 unsigned RedModifier = 0;
16606 ReductionData() = delete;
16607 /// Reserves required memory for the reduction data.
16608 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
16609 Vars.reserve(Size);
16610 Privates.reserve(Size);
16611 LHSs.reserve(Size);
16612 RHSs.reserve(Size);
16613 ReductionOps.reserve(Size);
16614 if (RedModifier == OMPC_REDUCTION_inscan) {
16615 InscanCopyOps.reserve(Size);
16616 InscanCopyArrayTemps.reserve(Size);
16617 InscanCopyArrayElems.reserve(Size);
16618 }
16619 TaskgroupDescriptors.reserve(Size);
16620 ExprCaptures.reserve(Size);
16621 ExprPostUpdates.reserve(Size);
16622 }
16623 /// Stores reduction item and reduction operation only (required for dependent
16624 /// reduction item).
16625 void push(Expr *Item, Expr *ReductionOp) {
16626 Vars.emplace_back(Item);
16627 Privates.emplace_back(nullptr);
16628 LHSs.emplace_back(nullptr);
16629 RHSs.emplace_back(nullptr);
16630 ReductionOps.emplace_back(ReductionOp);
16631 TaskgroupDescriptors.emplace_back(nullptr);
16632 if (RedModifier == OMPC_REDUCTION_inscan) {
16633 InscanCopyOps.push_back(nullptr);
16634 InscanCopyArrayTemps.push_back(nullptr);
16635 InscanCopyArrayElems.push_back(nullptr);
16636 }
16637 }
16638 /// Stores reduction data.
16639 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
16640 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
16641 Expr *CopyArrayElem) {
16642 Vars.emplace_back(Item);
16643 Privates.emplace_back(Private);
16644 LHSs.emplace_back(LHS);
16645 RHSs.emplace_back(RHS);
16646 ReductionOps.emplace_back(ReductionOp);
16647 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
16648 if (RedModifier == OMPC_REDUCTION_inscan) {
16649 InscanCopyOps.push_back(CopyOp);
16650 InscanCopyArrayTemps.push_back(CopyArrayTemp);
16651 InscanCopyArrayElems.push_back(CopyArrayElem);
16652 } else {
16653 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&(static_cast<void> (0))
16654 CopyArrayElem == nullptr &&(static_cast<void> (0))
16655 "Copy operation must be used for inscan reductions only.")(static_cast<void> (0));
16656 }
16657 }
16658};
16659} // namespace
16660
16661static bool checkOMPArraySectionConstantForReduction(
16662 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
16663 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
16664 const Expr *Length = OASE->getLength();
16665 if (Length == nullptr) {
16666 // For array sections of the form [1:] or [:], we would need to analyze
16667 // the lower bound...
16668 if (OASE->getColonLocFirst().isValid())
16669 return false;
16670
16671 // This is an array subscript which has implicit length 1!
16672 SingleElement = true;
16673 ArraySizes.push_back(llvm::APSInt::get(1));
16674 } else {
16675 Expr::EvalResult Result;
16676 if (!Length->EvaluateAsInt(Result, Context))
16677 return false;
16678
16679 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16680 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
16681 ArraySizes.push_back(ConstantLengthValue);
16682 }
16683
16684 // Get the base of this array section and walk up from there.
16685 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
16686
16687 // We require length = 1 for all array sections except the right-most to
16688 // guarantee that the memory region is contiguous and has no holes in it.
16689 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
16690 Length = TempOASE->getLength();
16691 if (Length == nullptr) {
16692 // For array sections of the form [1:] or [:], we would need to analyze
16693 // the lower bound...
16694 if (OASE->getColonLocFirst().isValid())
16695 return false;
16696
16697 // This is an array subscript which has implicit length 1!
16698 ArraySizes.push_back(llvm::APSInt::get(1));
16699 } else {
16700 Expr::EvalResult Result;
16701 if (!Length->EvaluateAsInt(Result, Context))
16702 return false;
16703
16704 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16705 if (ConstantLengthValue.getSExtValue() != 1)
16706 return false;
16707
16708 ArraySizes.push_back(ConstantLengthValue);
16709 }
16710 Base = TempOASE->getBase()->IgnoreParenImpCasts();
16711 }
16712
16713 // If we have a single element, we don't need to add the implicit lengths.
16714 if (!SingleElement) {
16715 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
16716 // Has implicit length 1!
16717 ArraySizes.push_back(llvm::APSInt::get(1));
16718 Base = TempASE->getBase()->IgnoreParenImpCasts();
16719 }
16720 }
16721
16722 // This array section can be privatized as a single value or as a constant
16723 // sized array.
16724 return true;
16725}
16726
16727static BinaryOperatorKind
16728getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
16729 if (BOK == BO_Add)
16730 return BO_AddAssign;
16731 if (BOK == BO_Mul)
16732 return BO_MulAssign;
16733 if (BOK == BO_And)
16734 return BO_AndAssign;
16735 if (BOK == BO_Or)
16736 return BO_OrAssign;
16737 if (BOK == BO_Xor)
16738 return BO_XorAssign;
16739 return BOK;
16740}
16741
16742static bool actOnOMPReductionKindClause(
16743 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
16744 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16745 SourceLocation ColonLoc, SourceLocation EndLoc,
16746 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16747 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
16748 DeclarationName DN = ReductionId.getName();
16749 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
16750 BinaryOperatorKind BOK = BO_Comma;
16751
16752 ASTContext &Context = S.Context;
16753 // OpenMP [2.14.3.6, reduction clause]
16754 // C
16755 // reduction-identifier is either an identifier or one of the following
16756 // operators: +, -, *, &, |, ^, && and ||
16757 // C++
16758 // reduction-identifier is either an id-expression or one of the following
16759 // operators: +, -, *, &, |, ^, && and ||
16760 switch (OOK) {
16761 case OO_Plus:
16762 case OO_Minus:
16763 BOK = BO_Add;
16764 break;
16765 case OO_Star:
16766 BOK = BO_Mul;
16767 break;
16768 case OO_Amp:
16769 BOK = BO_And;
16770 break;
16771 case OO_Pipe:
16772 BOK = BO_Or;
16773 break;
16774 case OO_Caret:
16775 BOK = BO_Xor;
16776 break;
16777 case OO_AmpAmp:
16778 BOK = BO_LAnd;
16779 break;
16780 case OO_PipePipe:
16781 BOK = BO_LOr;
16782 break;
16783 case OO_New:
16784 case OO_Delete:
16785 case OO_Array_New:
16786 case OO_Array_Delete:
16787 case OO_Slash:
16788 case OO_Percent:
16789 case OO_Tilde:
16790 case OO_Exclaim:
16791 case OO_Equal:
16792 case OO_Less:
16793 case OO_Greater:
16794 case OO_LessEqual:
16795 case OO_GreaterEqual:
16796 case OO_PlusEqual:
16797 case OO_MinusEqual:
16798 case OO_StarEqual:
16799 case OO_SlashEqual:
16800 case OO_PercentEqual:
16801 case OO_CaretEqual:
16802 case OO_AmpEqual:
16803 case OO_PipeEqual:
16804 case OO_LessLess:
16805 case OO_GreaterGreater:
16806 case OO_LessLessEqual:
16807 case OO_GreaterGreaterEqual:
16808 case OO_EqualEqual:
16809 case OO_ExclaimEqual:
16810 case OO_Spaceship:
16811 case OO_PlusPlus:
16812 case OO_MinusMinus:
16813 case OO_Comma:
16814 case OO_ArrowStar:
16815 case OO_Arrow:
16816 case OO_Call:
16817 case OO_Subscript:
16818 case OO_Conditional:
16819 case OO_Coawait:
16820 case NUM_OVERLOADED_OPERATORS:
16821 llvm_unreachable("Unexpected reduction identifier")__builtin_unreachable();
16822 case OO_None:
16823 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
16824 if (II->isStr("max"))
16825 BOK = BO_GT;
16826 else if (II->isStr("min"))
16827 BOK = BO_LT;
16828 }
16829 break;
16830 }
16831 SourceRange ReductionIdRange;
16832 if (ReductionIdScopeSpec.isValid())
16833 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
16834 else
16835 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
16836 ReductionIdRange.setEnd(ReductionId.getEndLoc());
16837
16838 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
16839 bool FirstIter = true;
16840 for (Expr *RefExpr : VarList) {
16841 assert(RefExpr && "nullptr expr in OpenMP reduction clause.")(static_cast<void> (0));
16842 // OpenMP [2.1, C/C++]
16843 // A list item is a variable or array section, subject to the restrictions
16844 // specified in Section 2.4 on page 42 and in each of the sections
16845 // describing clauses and directives for which a list appears.
16846 // OpenMP [2.14.3.3, Restrictions, p.1]
16847 // A variable that is part of another variable (as an array or
16848 // structure element) cannot appear in a private clause.
16849 if (!FirstIter && IR != ER)
16850 ++IR;
16851 FirstIter = false;
16852 SourceLocation ELoc;
16853 SourceRange ERange;
16854 Expr *SimpleRefExpr = RefExpr;
16855 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
16856 /*AllowArraySection=*/true);
16857 if (Res.second) {
16858 // Try to find 'declare reduction' corresponding construct before using
16859 // builtin/overloaded operators.
16860 QualType Type = Context.DependentTy;
16861 CXXCastPath BasePath;
16862 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16863 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16864 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16865 Expr *ReductionOp = nullptr;
16866 if (S.CurContext->isDependentContext() &&
16867 (DeclareReductionRef.isUnset() ||
16868 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
16869 ReductionOp = DeclareReductionRef.get();
16870 // It will be analyzed later.
16871 RD.push(RefExpr, ReductionOp);
16872 }
16873 ValueDecl *D = Res.first;
16874 if (!D)
16875 continue;
16876
16877 Expr *TaskgroupDescriptor = nullptr;
16878 QualType Type;
16879 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
16880 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
16881 if (ASE) {
16882 Type = ASE->getType().getNonReferenceType();
16883 } else if (OASE) {
16884 QualType BaseType =
16885 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16886 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16887 Type = ATy->getElementType();
16888 else
16889 Type = BaseType->getPointeeType();
16890 Type = Type.getNonReferenceType();
16891 } else {
16892 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
16893 }
16894 auto *VD = dyn_cast<VarDecl>(D);
16895
16896 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16897 // A variable that appears in a private clause must not have an incomplete
16898 // type or a reference type.
16899 if (S.RequireCompleteType(ELoc, D->getType(),
16900 diag::err_omp_reduction_incomplete_type))
16901 continue;
16902 // OpenMP [2.14.3.6, reduction clause, Restrictions]
16903 // A list item that appears in a reduction clause must not be
16904 // const-qualified.
16905 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
16906 /*AcceptIfMutable*/ false, ASE || OASE))
16907 continue;
16908
16909 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
16910 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
16911 // If a list-item is a reference type then it must bind to the same object
16912 // for all threads of the team.
16913 if (!ASE && !OASE) {
16914 if (VD) {
16915 VarDecl *VDDef = VD->getDefinition();
16916 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
16917 DSARefChecker Check(Stack);
16918 if (Check.Visit(VDDef->getInit())) {
16919 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
16920 << getOpenMPClauseName(ClauseKind) << ERange;
16921 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
16922 continue;
16923 }
16924 }
16925 }
16926
16927 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16928 // in a Construct]
16929 // Variables with the predetermined data-sharing attributes may not be
16930 // listed in data-sharing attributes clauses, except for the cases
16931 // listed below. For these exceptions only, listing a predetermined
16932 // variable in a data-sharing attribute clause is allowed and overrides
16933 // the variable's predetermined data-sharing attributes.
16934 // OpenMP [2.14.3.6, Restrictions, p.3]
16935 // Any number of reduction clauses can be specified on the directive,
16936 // but a list item can appear only once in the reduction clauses for that
16937 // directive.
16938 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16939 if (DVar.CKind == OMPC_reduction) {
16940 S.Diag(ELoc, diag::err_omp_once_referenced)
16941 << getOpenMPClauseName(ClauseKind);
16942 if (DVar.RefExpr)
16943 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
16944 continue;
16945 }
16946 if (DVar.CKind != OMPC_unknown) {
16947 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16948 << getOpenMPClauseName(DVar.CKind)
16949 << getOpenMPClauseName(OMPC_reduction);
16950 reportOriginalDsa(S, Stack, D, DVar);
16951 continue;
16952 }
16953
16954 // OpenMP [2.14.3.6, Restrictions, p.1]
16955 // A list item that appears in a reduction clause of a worksharing
16956 // construct must be shared in the parallel regions to which any of the
16957 // worksharing regions arising from the worksharing construct bind.
16958 if (isOpenMPWorksharingDirective(CurrDir) &&
16959 !isOpenMPParallelDirective(CurrDir) &&
16960 !isOpenMPTeamsDirective(CurrDir)) {
16961 DVar = Stack->getImplicitDSA(D, true);
16962 if (DVar.CKind != OMPC_shared) {
16963 S.Diag(ELoc, diag::err_omp_required_access)
16964 << getOpenMPClauseName(OMPC_reduction)
16965 << getOpenMPClauseName(OMPC_shared);
16966 reportOriginalDsa(S, Stack, D, DVar);
16967 continue;
16968 }
16969 }
16970 } else {
16971 // Threadprivates cannot be shared between threads, so dignose if the base
16972 // is a threadprivate variable.
16973 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16974 if (DVar.CKind == OMPC_threadprivate) {
16975 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16976 << getOpenMPClauseName(DVar.CKind)
16977 << getOpenMPClauseName(OMPC_reduction);
16978 reportOriginalDsa(S, Stack, D, DVar);
16979 continue;
16980 }
16981 }
16982
16983 // Try to find 'declare reduction' corresponding construct before using
16984 // builtin/overloaded operators.
16985 CXXCastPath BasePath;
16986 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16987 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16988 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16989 if (DeclareReductionRef.isInvalid())
16990 continue;
16991 if (S.CurContext->isDependentContext() &&
16992 (DeclareReductionRef.isUnset() ||
16993 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
16994 RD.push(RefExpr, DeclareReductionRef.get());
16995 continue;
16996 }
16997 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
16998 // Not allowed reduction identifier is found.
16999 S.Diag(ReductionId.getBeginLoc(),
17000 diag::err_omp_unknown_reduction_identifier)
17001 << Type << ReductionIdRange;
17002 continue;
17003 }
17004
17005 // OpenMP [2.14.3.6, reduction clause, Restrictions]
17006 // The type of a list item that appears in a reduction clause must be valid
17007 // for the reduction-identifier. For a max or min reduction in C, the type
17008 // of the list item must be an allowed arithmetic data type: char, int,
17009 // float, double, or _Bool, possibly modified with long, short, signed, or
17010 // unsigned. For a max or min reduction in C++, the type of the list item
17011 // must be an allowed arithmetic data type: char, wchar_t, int, float,
17012 // double, or bool, possibly modified with long, short, signed, or unsigned.
17013 if (DeclareReductionRef.isUnset()) {
17014 if ((BOK == BO_GT || BOK == BO_LT) &&
17015 !(Type->isScalarType() ||
17016 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
17017 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
17018 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
17019 if (!ASE && !OASE) {
17020 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17021 VarDecl::DeclarationOnly;
17022 S.Diag(D->getLocation(),
17023 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17024 << D;
17025 }
17026 continue;
17027 }
17028 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
17029 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
17030 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
17031 << getOpenMPClauseName(ClauseKind);
17032 if (!ASE && !OASE) {
17033 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17034 VarDecl::DeclarationOnly;
17035 S.Diag(D->getLocation(),
17036 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17037 << D;
17038 }
17039 continue;
17040 }
17041 }
17042
17043 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
17044 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
17045 D->hasAttrs() ? &D->getAttrs() : nullptr);
17046 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
17047 D->hasAttrs() ? &D->getAttrs() : nullptr);
17048 QualType PrivateTy = Type;
17049
17050 // Try if we can determine constant lengths for all array sections and avoid
17051 // the VLA.
17052 bool ConstantLengthOASE = false;
17053 if (OASE) {
17054 bool SingleElement;
17055 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
17056 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
17057 Context, OASE, SingleElement, ArraySizes);
17058
17059 // If we don't have a single element, we must emit a constant array type.
17060 if (ConstantLengthOASE && !SingleElement) {
17061 for (llvm::APSInt &Size : ArraySizes)
17062 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
17063 ArrayType::Normal,
17064 /*IndexTypeQuals=*/0);
17065 }
17066 }
17067
17068 if ((OASE && !ConstantLengthOASE) ||
17069 (!OASE && !ASE &&
17070 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
17071 if (!Context.getTargetInfo().isVLASupported()) {
17072 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
17073 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17074 S.Diag(ELoc, diag::note_vla_unsupported);
17075 continue;
17076 } else {
17077 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17078 S.targetDiag(ELoc, diag::note_vla_unsupported);
17079 }
17080 }
17081 // For arrays/array sections only:
17082 // Create pseudo array type for private copy. The size for this array will
17083 // be generated during codegen.
17084 // For array subscripts or single variables Private Ty is the same as Type
17085 // (type of the variable or single array element).
17086 PrivateTy = Context.getVariableArrayType(
17087 Type,
17088 new (Context)
17089 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
17090 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
17091 } else if (!ASE && !OASE &&
17092 Context.getAsArrayType(D->getType().getNonReferenceType())) {
17093 PrivateTy = D->getType().getNonReferenceType();
17094 }
17095 // Private copy.
17096 VarDecl *PrivateVD =
17097 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17098 D->hasAttrs() ? &D->getAttrs() : nullptr,
17099 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17100 // Add initializer for private variable.
17101 Expr *Init = nullptr;
17102 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
17103 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
17104 if (DeclareReductionRef.isUsable()) {
17105 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
17106 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
17107 if (DRD->getInitializer()) {
17108 Init = DRDRef;
17109 RHSVD->setInit(DRDRef);
17110 RHSVD->setInitStyle(VarDecl::CallInit);
17111 }
17112 } else {
17113 switch (BOK) {
17114 case BO_Add:
17115 case BO_Xor:
17116 case BO_Or:
17117 case BO_LOr:
17118 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
17119 if (Type->isScalarType() || Type->isAnyComplexType())
17120 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
17121 break;
17122 case BO_Mul:
17123 case BO_LAnd:
17124 if (Type->isScalarType() || Type->isAnyComplexType()) {
17125 // '*' and '&&' reduction ops - initializer is '1'.
17126 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
17127 }
17128 break;
17129 case BO_And: {
17130 // '&' reduction op - initializer is '~0'.
17131 QualType OrigType = Type;
17132 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
17133 Type = ComplexTy->getElementType();
17134 if (Type->isRealFloatingType()) {
17135 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
17136 Context.getFloatTypeSemantics(Type),
17137 Context.getTypeSize(Type));
17138 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17139 Type, ELoc);
17140 } else if (Type->isScalarType()) {
17141 uint64_t Size = Context.getTypeSize(Type);
17142 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
17143 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
17144 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17145 }
17146 if (Init && OrigType->isAnyComplexType()) {
17147 // Init = 0xFFFF + 0xFFFFi;
17148 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
17149 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
17150 }
17151 Type = OrigType;
17152 break;
17153 }
17154 case BO_LT:
17155 case BO_GT: {
17156 // 'min' reduction op - initializer is 'Largest representable number in
17157 // the reduction list item type'.
17158 // 'max' reduction op - initializer is 'Least representable number in
17159 // the reduction list item type'.
17160 if (Type->isIntegerType() || Type->isPointerType()) {
17161 bool IsSigned = Type->hasSignedIntegerRepresentation();
17162 uint64_t Size = Context.getTypeSize(Type);
17163 QualType IntTy =
17164 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
17165 llvm::APInt InitValue =
17166 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
17167 : llvm::APInt::getMinValue(Size)
17168 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
17169 : llvm::APInt::getMaxValue(Size);
17170 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17171 if (Type->isPointerType()) {
17172 // Cast to pointer type.
17173 ExprResult CastExpr = S.BuildCStyleCastExpr(
17174 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
17175 if (CastExpr.isInvalid())
17176 continue;
17177 Init = CastExpr.get();
17178 }
17179 } else if (Type->isRealFloatingType()) {
17180 llvm::APFloat InitValue = llvm::APFloat::getLargest(
17181 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
17182 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17183 Type, ELoc);
17184 }
17185 break;
17186 }
17187 case BO_PtrMemD:
17188 case BO_PtrMemI:
17189 case BO_MulAssign:
17190 case BO_Div:
17191 case BO_Rem:
17192 case BO_Sub:
17193 case BO_Shl:
17194 case BO_Shr:
17195 case BO_LE:
17196 case BO_GE:
17197 case BO_EQ:
17198 case BO_NE:
17199 case BO_Cmp:
17200 case BO_AndAssign:
17201 case BO_XorAssign:
17202 case BO_OrAssign:
17203 case BO_Assign:
17204 case BO_AddAssign:
17205 case BO_SubAssign:
17206 case BO_DivAssign:
17207 case BO_RemAssign:
17208 case BO_ShlAssign:
17209 case BO_ShrAssign:
17210 case BO_Comma:
17211 llvm_unreachable("Unexpected reduction operation")__builtin_unreachable();
17212 }
17213 }
17214 if (Init && DeclareReductionRef.isUnset()) {
17215 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
17216 // Store initializer for single element in private copy. Will be used
17217 // during codegen.
17218 PrivateVD->setInit(RHSVD->getInit());
17219 PrivateVD->setInitStyle(RHSVD->getInitStyle());
17220 } else if (!Init) {
17221 S.ActOnUninitializedDecl(RHSVD);
17222 // Store initializer for single element in private copy. Will be used
17223 // during codegen.
17224 PrivateVD->setInit(RHSVD->getInit());
17225 PrivateVD->setInitStyle(RHSVD->getInitStyle());
17226 }
17227 if (RHSVD->isInvalidDecl())
17228 continue;
17229 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
17230 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
17231 << Type << ReductionIdRange;
17232 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17233 VarDecl::DeclarationOnly;
17234 S.Diag(D->getLocation(),
17235 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17236 << D;
17237 continue;
17238 }
17239 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
17240 ExprResult ReductionOp;
17241 if (DeclareReductionRef.isUsable()) {
17242 QualType RedTy = DeclareReductionRef.get()->getType();
17243 QualType PtrRedTy = Context.getPointerType(RedTy);
17244 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
17245 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
17246 if (!BasePath.empty()) {
17247 LHS = S.DefaultLvalueConversion(LHS.get());
17248 RHS = S.DefaultLvalueConversion(RHS.get());
17249 LHS = ImplicitCastExpr::Create(
17250 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
17251 LHS.get()->getValueKind(), FPOptionsOverride());
17252 RHS = ImplicitCastExpr::Create(
17253 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
17254 RHS.get()->getValueKind(), FPOptionsOverride());
17255 }
17256 FunctionProtoType::ExtProtoInfo EPI;
17257 QualType Params[] = {PtrRedTy, PtrRedTy};
17258 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
17259 auto *OVE = new (Context) OpaqueValueExpr(
17260 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
17261 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
17262 Expr *Args[] = {LHS.get(), RHS.get()};
17263 ReductionOp =
17264 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
17265 S.CurFPFeatureOverrides());
17266 } else {
17267 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
17268 if (Type->isRecordType() && CombBOK != BOK) {
17269 Sema::TentativeAnalysisScope Trap(S);
17270 ReductionOp =
17271 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17272 CombBOK, LHSDRE, RHSDRE);
17273 }
17274 if (!ReductionOp.isUsable()) {
17275 ReductionOp =
17276 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
17277 LHSDRE, RHSDRE);
17278 if (ReductionOp.isUsable()) {
17279 if (BOK != BO_LT && BOK != BO_GT) {
17280 ReductionOp =
17281 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17282 BO_Assign, LHSDRE, ReductionOp.get());
17283 } else {
17284 auto *ConditionalOp = new (Context)
17285 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
17286 RHSDRE, Type, VK_LValue, OK_Ordinary);
17287 ReductionOp =
17288 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17289 BO_Assign, LHSDRE, ConditionalOp);
17290 }
17291 }
17292 }
17293 if (ReductionOp.isUsable())
17294 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
17295 /*DiscardedValue*/ false);
17296 if (!ReductionOp.isUsable())
17297 continue;
17298 }
17299
17300 // Add copy operations for inscan reductions.
17301 // LHS = RHS;
17302 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
17303 if (ClauseKind == OMPC_reduction &&
17304 RD.RedModifier == OMPC_REDUCTION_inscan) {
17305 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
17306 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
17307 RHS.get());
17308 if (!CopyOpRes.isUsable())
17309 continue;
17310 CopyOpRes =
17311 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
17312 if (!CopyOpRes.isUsable())
17313 continue;
17314 // For simd directive and simd-based directives in simd mode no need to
17315 // construct temp array, need just a single temp element.
17316 if (Stack->getCurrentDirective() == OMPD_simd ||
17317 (S.getLangOpts().OpenMPSimd &&
17318 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
17319 VarDecl *TempArrayVD =
17320 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17321 D->hasAttrs() ? &D->getAttrs() : nullptr);
17322 // Add a constructor to the temp decl.
17323 S.ActOnUninitializedDecl(TempArrayVD);
17324 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
17325 } else {
17326 // Build temp array for prefix sum.
17327 auto *Dim = new (S.Context)
17328 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17329 QualType ArrayTy =
17330 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
17331 /*IndexTypeQuals=*/0, {ELoc, ELoc});
17332 VarDecl *TempArrayVD =
17333 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
17334 D->hasAttrs() ? &D->getAttrs() : nullptr);
17335 // Add a constructor to the temp decl.
17336 S.ActOnUninitializedDecl(TempArrayVD);
17337 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
17338 TempArrayElem =
17339 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
17340 auto *Idx = new (S.Context)
17341 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17342 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
17343 ELoc, Idx, ELoc);
17344 }
17345 }
17346
17347 // OpenMP [2.15.4.6, Restrictions, p.2]
17348 // A list item that appears in an in_reduction clause of a task construct
17349 // must appear in a task_reduction clause of a construct associated with a
17350 // taskgroup region that includes the participating task in its taskgroup
17351 // set. The construct associated with the innermost region that meets this
17352 // condition must specify the same reduction-identifier as the in_reduction
17353 // clause.
17354 if (ClauseKind == OMPC_in_reduction) {
17355 SourceRange ParentSR;
17356 BinaryOperatorKind ParentBOK;
17357 const Expr *ParentReductionOp = nullptr;
17358 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
17359 DSAStackTy::DSAVarData ParentBOKDSA =
17360 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
17361 ParentBOKTD);
17362 DSAStackTy::DSAVarData ParentReductionOpDSA =
17363 Stack->getTopMostTaskgroupReductionData(
17364 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
17365 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
17366 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
17367 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
17368 (DeclareReductionRef.isUsable() && IsParentBOK) ||
17369 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
17370 bool EmitError = true;
17371 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
17372 llvm::FoldingSetNodeID RedId, ParentRedId;
17373 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
17374 DeclareReductionRef.get()->Profile(RedId, Context,
17375 /*Canonical=*/true);
17376 EmitError = RedId != ParentRedId;
17377 }
17378 if (EmitError) {
17379 S.Diag(ReductionId.getBeginLoc(),
17380 diag::err_omp_reduction_identifier_mismatch)
17381 << ReductionIdRange << RefExpr->getSourceRange();
17382 S.Diag(ParentSR.getBegin(),
17383 diag::note_omp_previous_reduction_identifier)
17384 << ParentSR
17385 << (IsParentBOK ? ParentBOKDSA.RefExpr
17386 : ParentReductionOpDSA.RefExpr)
17387 ->getSourceRange();
17388 continue;
17389 }
17390 }
17391 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
17392 }
17393
17394 DeclRefExpr *Ref = nullptr;
17395 Expr *VarsExpr = RefExpr->IgnoreParens();
17396 if (!VD && !S.CurContext->isDependentContext()) {
17397 if (ASE || OASE) {
17398 TransformExprToCaptures RebuildToCapture(S, D);
17399 VarsExpr =
17400 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
17401 Ref = RebuildToCapture.getCapturedExpr();
17402 } else {
17403 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
17404 }
17405 if (!S.isOpenMPCapturedDecl(D)) {
17406 RD.ExprCaptures.emplace_back(Ref->getDecl());
17407 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17408 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
17409 if (!RefRes.isUsable())
17410 continue;
17411 ExprResult PostUpdateRes =
17412 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17413 RefRes.get());
17414 if (!PostUpdateRes.isUsable())
17415 continue;
17416 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
17417 Stack->getCurrentDirective() == OMPD_taskgroup) {
17418 S.Diag(RefExpr->getExprLoc(),
17419 diag::err_omp_reduction_non_addressable_expression)
17420 << RefExpr->getSourceRange();
17421 continue;
17422 }
17423 RD.ExprPostUpdates.emplace_back(
17424 S.IgnoredValueConversions(PostUpdateRes.get()).get());
17425 }
17426 }
17427 }
17428 // All reduction items are still marked as reduction (to do not increase
17429 // code base size).
17430 unsigned Modifier = RD.RedModifier;
17431 // Consider task_reductions as reductions with task modifier. Required for
17432 // correct analysis of in_reduction clauses.
17433 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
17434 Modifier = OMPC_REDUCTION_task;
17435 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
17436 ASE || OASE);
17437 if (Modifier == OMPC_REDUCTION_task &&
17438 (CurrDir == OMPD_taskgroup ||
17439 ((isOpenMPParallelDirective(CurrDir) ||
17440 isOpenMPWorksharingDirective(CurrDir)) &&
17441 !isOpenMPSimdDirective(CurrDir)))) {
17442 if (DeclareReductionRef.isUsable())
17443 Stack->addTaskgroupReductionData(D, ReductionIdRange,
17444 DeclareReductionRef.get());
17445 else
17446 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
17447 }
17448 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
17449 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
17450 TempArrayElem.get());
17451 }
17452 return RD.Vars.empty();
17453}
17454
17455OMPClause *Sema::ActOnOpenMPReductionClause(
17456 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
17457 SourceLocation StartLoc, SourceLocation LParenLoc,
17458 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
17459 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17460 ArrayRef<Expr *> UnresolvedReductions) {
17461 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
17462 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
17463 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
17464 /*Last=*/OMPC_REDUCTION_unknown)
17465 << getOpenMPClauseName(OMPC_reduction);
17466 return nullptr;
17467 }
17468 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
17469 // A reduction clause with the inscan reduction-modifier may only appear on a
17470 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
17471 // construct, a parallel worksharing-loop construct or a parallel
17472 // worksharing-loop SIMD construct.
17473 if (Modifier == OMPC_REDUCTION_inscan &&
17474 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
17475 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
17476 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
17477 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
17478 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
17479 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
17480 return nullptr;
17481 }
17482
17483 ReductionData RD(VarList.size(), Modifier);
17484 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
17485 StartLoc, LParenLoc, ColonLoc, EndLoc,
17486 ReductionIdScopeSpec, ReductionId,
17487 UnresolvedReductions, RD))
17488 return nullptr;
17489
17490 return OMPReductionClause::Create(
17491 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
17492 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17493 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
17494 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
17495 buildPreInits(Context, RD.ExprCaptures),
17496 buildPostUpdate(*this, RD.ExprPostUpdates));
17497}
17498
17499OMPClause *Sema::ActOnOpenMPTaskReductionClause(
17500 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17501 SourceLocation ColonLoc, SourceLocation EndLoc,
17502 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17503 ArrayRef<Expr *> UnresolvedReductions) {
17504 ReductionData RD(VarList.size());
17505 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
17506 StartLoc, LParenLoc, ColonLoc, EndLoc,
17507 ReductionIdScopeSpec, ReductionId,
17508 UnresolvedReductions, RD))
17509 return nullptr;
17510
17511 return OMPTaskReductionClause::Create(
17512 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17513 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17514 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
17515 buildPreInits(Context, RD.ExprCaptures),
17516 buildPostUpdate(*this, RD.ExprPostUpdates));
17517}
17518
17519OMPClause *Sema::ActOnOpenMPInReductionClause(
17520 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17521 SourceLocation ColonLoc, SourceLocation EndLoc,
17522 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17523 ArrayRef<Expr *> UnresolvedReductions) {
17524 ReductionData RD(VarList.size());
17525 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
17526 StartLoc, LParenLoc, ColonLoc, EndLoc,
17527 ReductionIdScopeSpec, ReductionId,
17528 UnresolvedReductions, RD))
17529 return nullptr;
17530
17531 return OMPInReductionClause::Create(
17532 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17533 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17534 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
17535 buildPreInits(Context, RD.ExprCaptures),
17536 buildPostUpdate(*this, RD.ExprPostUpdates));
17537}
17538
17539bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
17540 SourceLocation LinLoc) {
17541 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
17542 LinKind == OMPC_LINEAR_unknown) {
17543 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
17544 return true;
17545 }
17546 return false;
17547}
17548
17549bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
17550 OpenMPLinearClauseKind LinKind, QualType Type,
17551 bool IsDeclareSimd) {
17552 const auto *VD = dyn_cast_or_null<VarDecl>(D);
17553 // A variable must not have an incomplete type or a reference type.
17554 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
17555 return true;
17556 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
17557 !Type->isReferenceType()) {
17558 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
17559 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
17560 return true;
17561 }
17562 Type = Type.getNonReferenceType();
17563
17564 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17565 // A variable that is privatized must not have a const-qualified type
17566 // unless it is of class type with a mutable member. This restriction does
17567 // not apply to the firstprivate clause, nor to the linear clause on
17568 // declarative directives (like declare simd).
17569 if (!IsDeclareSimd &&
17570 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
17571 return true;
17572
17573 // A list item must be of integral or pointer type.
17574 Type = Type.getUnqualifiedType().getCanonicalType();
17575 const auto *Ty = Type.getTypePtrOrNull();
17576 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
17577 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
17578 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
17579 if (D) {
17580 bool IsDecl =
17581 !VD ||
17582 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17583 Diag(D->getLocation(),
17584 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17585 << D;
17586 }
17587 return true;
17588 }
17589 return false;
17590}
17591
17592OMPClause *Sema::ActOnOpenMPLinearClause(
17593 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
17594 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
17595 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17596 SmallVector<Expr *, 8> Vars;
17597 SmallVector<Expr *, 8> Privates;
17598 SmallVector<Expr *, 8> Inits;
17599 SmallVector<Decl *, 4> ExprCaptures;
17600 SmallVector<Expr *, 4> ExprPostUpdates;
17601 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
17602 LinKind = OMPC_LINEAR_val;
17603 for (Expr *RefExpr : VarList) {
17604 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast<void> (0));
17605 SourceLocation ELoc;
17606 SourceRange ERange;
17607 Expr *SimpleRefExpr = RefExpr;
17608 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17609 if (Res.second) {
17610 // It will be analyzed later.
17611 Vars.push_back(RefExpr);
17612 Privates.push_back(nullptr);
17613 Inits.push_back(nullptr);
17614 }
17615 ValueDecl *D = Res.first;
17616 if (!D)
17617 continue;
17618
17619 QualType Type = D->getType();
17620 auto *VD = dyn_cast<VarDecl>(D);
17621
17622 // OpenMP [2.14.3.7, linear clause]
17623 // A list-item cannot appear in more than one linear clause.
17624 // A list-item that appears in a linear clause cannot appear in any
17625 // other data-sharing attribute clause.
17626 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17627 if (DVar.RefExpr) {
17628 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17629 << getOpenMPClauseName(OMPC_linear);
17630 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17631 continue;
17632 }
17633
17634 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
17635 continue;
17636 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17637
17638 // Build private copy of original var.
17639 VarDecl *Private =
17640 buildVarDecl(*this, ELoc, Type, D->getName(),
17641 D->hasAttrs() ? &D->getAttrs() : nullptr,
17642 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17643 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
17644 // Build var to save initial value.
17645 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
17646 Expr *InitExpr;
17647 DeclRefExpr *Ref = nullptr;
17648 if (!VD && !CurContext->isDependentContext()) {
17649 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17650 if (!isOpenMPCapturedDecl(D)) {
17651 ExprCaptures.push_back(Ref->getDecl());
17652 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17653 ExprResult RefRes = DefaultLvalueConversion(Ref);
17654 if (!RefRes.isUsable())
17655 continue;
17656 ExprResult PostUpdateRes =
17657 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
17658 SimpleRefExpr, RefRes.get());
17659 if (!PostUpdateRes.isUsable())
17660 continue;
17661 ExprPostUpdates.push_back(
17662 IgnoredValueConversions(PostUpdateRes.get()).get());
17663 }
17664 }
17665 }
17666 if (LinKind == OMPC_LINEAR_uval)
17667 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
17668 else
17669 InitExpr = VD ? SimpleRefExpr : Ref;
17670 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
17671 /*DirectInit=*/false);
17672 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
17673
17674 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
17675 Vars.push_back((VD || CurContext->isDependentContext())
17676 ? RefExpr->IgnoreParens()
17677 : Ref);
17678 Privates.push_back(PrivateRef);
17679 Inits.push_back(InitRef);
17680 }
17681
17682 if (Vars.empty())
17683 return nullptr;
17684
17685 Expr *StepExpr = Step;
17686 Expr *CalcStepExpr = nullptr;
17687 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
17688 !Step->isInstantiationDependent() &&
17689 !Step->containsUnexpandedParameterPack()) {
17690 SourceLocation StepLoc = Step->getBeginLoc();
17691 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
17692 if (Val.isInvalid())
17693 return nullptr;
17694 StepExpr = Val.get();
17695
17696 // Build var to save the step value.
17697 VarDecl *SaveVar =
17698 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
17699 ExprResult SaveRef =
17700 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
17701 ExprResult CalcStep =
17702 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
17703 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
17704
17705 // Warn about zero linear step (it would be probably better specified as
17706 // making corresponding variables 'const').
17707 if (Optional<llvm::APSInt> Result =
17708 StepExpr->getIntegerConstantExpr(Context)) {
17709 if (!Result->isNegative() && !Result->isStrictlyPositive())
17710 Diag(StepLoc, diag::warn_omp_linear_step_zero)
17711 << Vars[0] << (Vars.size() > 1);
17712 } else if (CalcStep.isUsable()) {
17713 // Calculate the step beforehand instead of doing this on each iteration.
17714 // (This is not used if the number of iterations may be kfold-ed).
17715 CalcStepExpr = CalcStep.get();
17716 }
17717 }
17718
17719 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
17720 ColonLoc, EndLoc, Vars, Privates, Inits,
17721 StepExpr, CalcStepExpr,
17722 buildPreInits(Context, ExprCaptures),
17723 buildPostUpdate(*this, ExprPostUpdates));
17724}
17725
17726static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
17727 Expr *NumIterations, Sema &SemaRef,
17728 Scope *S, DSAStackTy *Stack) {
17729 // Walk the vars and build update/final expressions for the CodeGen.
17730 SmallVector<Expr *, 8> Updates;
17731 SmallVector<Expr *, 8> Finals;
17732 SmallVector<Expr *, 8> UsedExprs;
17733 Expr *Step = Clause.getStep();
17734 Expr *CalcStep = Clause.getCalcStep();
17735 // OpenMP [2.14.3.7, linear clause]
17736 // If linear-step is not specified it is assumed to be 1.
17737 if (!Step)
17738 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
17739 else if (CalcStep)
17740 Step = cast<BinaryOperator>(CalcStep)->getLHS();
17741 bool HasErrors = false;
17742 auto CurInit = Clause.inits().begin();
17743 auto CurPrivate = Clause.privates().begin();
17744 OpenMPLinearClauseKind LinKind = Clause.getModifier();
17745 for (Expr *RefExpr : Clause.varlists()) {
17746 SourceLocation ELoc;
17747 SourceRange ERange;
17748 Expr *SimpleRefExpr = RefExpr;
17749 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17750 ValueDecl *D = Res.first;
17751 if (Res.second || !D) {
17752 Updates.push_back(nullptr);
17753 Finals.push_back(nullptr);
17754 HasErrors = true;
17755 continue;
17756 }
17757 auto &&Info = Stack->isLoopControlVariable(D);
17758 // OpenMP [2.15.11, distribute simd Construct]
17759 // A list item may not appear in a linear clause, unless it is the loop
17760 // iteration variable.
17761 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
17762 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
17763 SemaRef.Diag(ELoc,
17764 diag::err_omp_linear_distribute_var_non_loop_iteration);
17765 Updates.push_back(nullptr);
17766 Finals.push_back(nullptr);
17767 HasErrors = true;
17768 continue;
17769 }
17770 Expr *InitExpr = *CurInit;
17771
17772 // Build privatized reference to the current linear var.
17773 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
17774 Expr *CapturedRef;
17775 if (LinKind == OMPC_LINEAR_uval)
17776 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
17777 else
17778 CapturedRef =
17779 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
17780 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
17781 /*RefersToCapture=*/true);
17782
17783 // Build update: Var = InitExpr + IV * Step
17784 ExprResult Update;
17785 if (!Info.first)
17786 Update = buildCounterUpdate(
17787 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
17788 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
17789 else
17790 Update = *CurPrivate;
17791 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
17792 /*DiscardedValue*/ false);
17793
17794 // Build final: Var = InitExpr + NumIterations * Step
17795 ExprResult Final;
17796 if (!Info.first)
17797 Final =
17798 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
17799 InitExpr, NumIterations, Step, /*Subtract=*/false,
17800 /*IsNonRectangularLB=*/false);
17801 else
17802 Final = *CurPrivate;
17803 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
17804 /*DiscardedValue*/ false);
17805
17806 if (!Update.isUsable() || !Final.isUsable()) {
17807 Updates.push_back(nullptr);
17808 Finals.push_back(nullptr);
17809 UsedExprs.push_back(nullptr);
17810 HasErrors = true;
17811 } else {
17812 Updates.push_back(Update.get());
17813 Finals.push_back(Final.get());
17814 if (!Info.first)
17815 UsedExprs.push_back(SimpleRefExpr);
17816 }
17817 ++CurInit;
17818 ++CurPrivate;
17819 }
17820 if (Expr *S = Clause.getStep())
17821 UsedExprs.push_back(S);
17822 // Fill the remaining part with the nullptr.
17823 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
17824 Clause.setUpdates(Updates);
17825 Clause.setFinals(Finals);
17826 Clause.setUsedExprs(UsedExprs);
17827 return HasErrors;
17828}
17829
17830OMPClause *Sema::ActOnOpenMPAlignedClause(
17831 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
17832 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17833 SmallVector<Expr *, 8> Vars;
17834 for (Expr *RefExpr : VarList) {
17835 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast<void> (0));
17836 SourceLocation ELoc;
17837 SourceRange ERange;
17838 Expr *SimpleRefExpr = RefExpr;
17839 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17840 if (Res.second) {
17841 // It will be analyzed later.
17842 Vars.push_back(RefExpr);
17843 }
17844 ValueDecl *D = Res.first;
17845 if (!D)
17846 continue;
17847
17848 QualType QType = D->getType();
17849 auto *VD = dyn_cast<VarDecl>(D);
17850
17851 // OpenMP [2.8.1, simd construct, Restrictions]
17852 // The type of list items appearing in the aligned clause must be
17853 // array, pointer, reference to array, or reference to pointer.
17854 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17855 const Type *Ty = QType.getTypePtrOrNull();
17856 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
17857 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
17858 << QType << getLangOpts().CPlusPlus << ERange;
17859 bool IsDecl =
17860 !VD ||
17861 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17862 Diag(D->getLocation(),
17863 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17864 << D;
17865 continue;
17866 }
17867
17868 // OpenMP [2.8.1, simd construct, Restrictions]
17869 // A list-item cannot appear in more than one aligned clause.
17870 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
17871 Diag(ELoc, diag::err_omp_used_in_clause_twice)
17872 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
17873 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17874 << getOpenMPClauseName(OMPC_aligned);
17875 continue;
17876 }
17877
17878 DeclRefExpr *Ref = nullptr;
17879 if (!VD && isOpenMPCapturedDecl(D))
17880 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17881 Vars.push_back(DefaultFunctionArrayConversion(
17882 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
17883 .get());
17884 }
17885
17886 // OpenMP [2.8.1, simd construct, Description]
17887 // The parameter of the aligned clause, alignment, must be a constant
17888 // positive integer expression.
17889 // If no optional parameter is specified, implementation-defined default
17890 // alignments for SIMD instructions on the target platforms are assumed.
17891 if (Alignment != nullptr) {
17892 ExprResult AlignResult =
17893 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
17894 if (AlignResult.isInvalid())
17895 return nullptr;
17896 Alignment = AlignResult.get();
17897 }
17898 if (Vars.empty())
17899 return nullptr;
17900
17901 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
17902 EndLoc, Vars, Alignment);
17903}
17904
17905OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
17906 SourceLocation StartLoc,
17907 SourceLocation LParenLoc,
17908 SourceLocation EndLoc) {
17909 SmallVector<Expr *, 8> Vars;
17910 SmallVector<Expr *, 8> SrcExprs;
17911 SmallVector<Expr *, 8> DstExprs;
17912 SmallVector<Expr *, 8> AssignmentOps;
17913 for (Expr *RefExpr : VarList) {
17914 assert(RefExpr && "NULL expr in OpenMP copyin clause.")(static_cast<void> (0));
17915 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17916 // It will be analyzed later.
17917 Vars.push_back(RefExpr);
17918 SrcExprs.push_back(nullptr);
17919 DstExprs.push_back(nullptr);
17920 AssignmentOps.push_back(nullptr);
17921 continue;
17922 }
17923
17924 SourceLocation ELoc = RefExpr->getExprLoc();
17925 // OpenMP [2.1, C/C++]
17926 // A list item is a variable name.
17927 // OpenMP [2.14.4.1, Restrictions, p.1]
17928 // A list item that appears in a copyin clause must be threadprivate.
17929 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
17930 if (!DE || !isa<VarDecl>(DE->getDecl())) {
17931 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
17932 << 0 << RefExpr->getSourceRange();
17933 continue;
17934 }
17935
17936 Decl *D = DE->getDecl();
17937 auto *VD = cast<VarDecl>(D);
17938
17939 QualType Type = VD->getType();
17940 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
17941 // It will be analyzed later.
17942 Vars.push_back(DE);
17943 SrcExprs.push_back(nullptr);
17944 DstExprs.push_back(nullptr);
17945 AssignmentOps.push_back(nullptr);
17946 continue;
17947 }
17948
17949 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
17950 // A list item that appears in a copyin clause must be threadprivate.
17951 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
17952 Diag(ELoc, diag::err_omp_required_access)
17953 << getOpenMPClauseName(OMPC_copyin)
17954 << getOpenMPDirectiveName(OMPD_threadprivate);
17955 continue;
17956 }
17957
17958 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17959 // A variable of class type (or array thereof) that appears in a
17960 // copyin clause requires an accessible, unambiguous copy assignment
17961 // operator for the class type.
17962 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17963 VarDecl *SrcVD =
17964 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
17965 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17966 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
17967 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
17968 VarDecl *DstVD =
17969 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
17970 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17971 DeclRefExpr *PseudoDstExpr =
17972 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
17973 // For arrays generate assignment operation for single element and replace
17974 // it by the original array element in CodeGen.
17975 ExprResult AssignmentOp =
17976 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
17977 PseudoSrcExpr);
17978 if (AssignmentOp.isInvalid())
17979 continue;
17980 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
17981 /*DiscardedValue*/ false);
17982 if (AssignmentOp.isInvalid())
17983 continue;
17984
17985 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
17986 Vars.push_back(DE);
17987 SrcExprs.push_back(PseudoSrcExpr);
17988 DstExprs.push_back(PseudoDstExpr);
17989 AssignmentOps.push_back(AssignmentOp.get());
17990 }
17991
17992 if (Vars.empty())
17993 return nullptr;
17994
17995 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17996 SrcExprs, DstExprs, AssignmentOps);
17997}
17998
17999OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
18000 SourceLocation StartLoc,
18001 SourceLocation LParenLoc,
18002 SourceLocation EndLoc) {
18003 SmallVector<Expr *, 8> Vars;
18004 SmallVector<Expr *, 8> SrcExprs;
18005 SmallVector<Expr *, 8> DstExprs;
18006 SmallVector<Expr *, 8> AssignmentOps;
18007 for (Expr *RefExpr : VarList) {
18008 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast<void> (0));
18009 SourceLocation ELoc;
18010 SourceRange ERange;
18011 Expr *SimpleRefExpr = RefExpr;
18012 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18013 if (Res.second) {
18014 // It will be analyzed later.
18015 Vars.push_back(RefExpr);
18016 SrcExprs.push_back(nullptr);
18017 DstExprs.push_back(nullptr);
18018 AssignmentOps.push_back(nullptr);
18019 }
18020 ValueDecl *D = Res.first;
18021 if (!D)
18022 continue;
18023
18024 QualType Type = D->getType();
18025 auto *VD = dyn_cast<VarDecl>(D);
18026
18027 // OpenMP [2.14.4.2, Restrictions, p.2]
18028 // A list item that appears in a copyprivate clause may not appear in a
18029 // private or firstprivate clause on the single construct.
18030 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
18031 DSAStackTy::DSAVarData DVar =
18032 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
18033 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
18034 DVar.RefExpr) {
18035 Diag(ELoc, diag::err_omp_wrong_dsa)
18036 << getOpenMPClauseName(DVar.CKind)
18037 << getOpenMPClauseName(OMPC_copyprivate);
18038 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18039 continue;
18040 }
18041
18042 // OpenMP [2.11.4.2, Restrictions, p.1]
18043 // All list items that appear in a copyprivate clause must be either
18044 // threadprivate or private in the enclosing context.
18045 if (DVar.CKind == OMPC_unknown) {
18046 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
18047 if (DVar.CKind == OMPC_shared) {
18048 Diag(ELoc, diag::err_omp_required_access)
18049 << getOpenMPClauseName(OMPC_copyprivate)
18050 << "threadprivate or private in the enclosing context";
18051 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18052 continue;
18053 }
18054 }
18055 }
18056
18057 // Variably modified types are not supported.
18058 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
18059 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18060 << getOpenMPClauseName(OMPC_copyprivate) << Type
18061 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
18062 bool IsDecl =
18063 !VD ||
18064 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
18065 Diag(D->getLocation(),
18066 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18067 << D;
18068 continue;
18069 }
18070
18071 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
18072 // A variable of class type (or array thereof) that appears in a
18073 // copyin clause requires an accessible, unambiguous copy assignment
18074 // operator for the class type.
18075 Type = Context.getBaseElementType(Type.getNonReferenceType())
18076 .getUnqualifiedType();
18077 VarDecl *SrcVD =
18078 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
18079 D->hasAttrs() ? &D->getAttrs() : nullptr);
18080 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
18081 VarDecl *DstVD =
18082 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
18083 D->hasAttrs() ? &D->getAttrs() : nullptr);
18084 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18085 ExprResult AssignmentOp = BuildBinOp(
18086 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
18087 if (AssignmentOp.isInvalid())
18088 continue;
18089 AssignmentOp =
18090 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18091 if (AssignmentOp.isInvalid())
18092 continue;
18093
18094 // No need to mark vars as copyprivate, they are already threadprivate or
18095 // implicitly private.
18096 assert(VD || isOpenMPCapturedDecl(D))(static_cast<void> (0));
18097 Vars.push_back(
18098 VD ? RefExpr->IgnoreParens()
18099 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
18100 SrcExprs.push_back(PseudoSrcExpr);
18101 DstExprs.push_back(PseudoDstExpr);
18102 AssignmentOps.push_back(AssignmentOp.get());
18103 }
18104
18105 if (Vars.empty())
18106 return nullptr;
18107
18108 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18109 Vars, SrcExprs, DstExprs, AssignmentOps);
18110}
18111
18112OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
18113 SourceLocation StartLoc,
18114 SourceLocation LParenLoc,
18115 SourceLocation EndLoc) {
18116 if (VarList.empty())
18117 return nullptr;
18118
18119 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
18120}
18121
18122/// Tries to find omp_depend_t. type.
18123static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
18124 bool Diagnose = true) {
18125 QualType OMPDependT = Stack->getOMPDependT();
18126 if (!OMPDependT.isNull())
18127 return true;
18128 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
18129 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18130 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18131 if (Diagnose)
18132 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
18133 return false;
18134 }
18135 Stack->setOMPDependT(PT.get());
18136 return true;
18137}
18138
18139OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
18140 SourceLocation LParenLoc,
18141 SourceLocation EndLoc) {
18142 if (!Depobj)
18143 return nullptr;
18144
18145 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
18146
18147 // OpenMP 5.0, 2.17.10.1 depobj Construct
18148 // depobj is an lvalue expression of type omp_depend_t.
18149 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
18150 !Depobj->isInstantiationDependent() &&
18151 !Depobj->containsUnexpandedParameterPack() &&
18152 (OMPDependTFound &&
18153 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
18154 /*CompareUnqualified=*/true))) {
18155 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18156 << 0 << Depobj->getType() << Depobj->getSourceRange();
18157 }
18158
18159 if (!Depobj->isLValue()) {
18160 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18161 << 1 << Depobj->getSourceRange();
18162 }
18163
18164 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
18165}
18166
18167OMPClause *
18168Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
18169 SourceLocation DepLoc, SourceLocation ColonLoc,
18170 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
18171 SourceLocation LParenLoc, SourceLocation EndLoc) {
18172 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
18173 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
18174 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18175 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
18176 return nullptr;
18177 }
18178 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
18179 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
18180 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
18181 DepKind == OMPC_DEPEND_sink ||
18182 ((LangOpts.OpenMP < 50 ||
18183 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
18184 DepKind == OMPC_DEPEND_depobj))) {
18185 SmallVector<unsigned, 3> Except;
18186 Except.push_back(OMPC_DEPEND_source);
18187 Except.push_back(OMPC_DEPEND_sink);
18188 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
18189 Except.push_back(OMPC_DEPEND_depobj);
18190 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
18191 ? "depend modifier(iterator) or "
18192 : "";
18193 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18194 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
18195 /*Last=*/OMPC_DEPEND_unknown,
18196 Except)
18197 << getOpenMPClauseName(OMPC_depend);
18198 return nullptr;
18199 }
18200 if (DepModifier &&
18201 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
18202 Diag(DepModifier->getExprLoc(),
18203 diag::err_omp_depend_sink_source_with_modifier);
18204 return nullptr;
18205 }
18206 if (DepModifier &&
18207 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
18208 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
18209
18210 SmallVector<Expr *, 8> Vars;
18211 DSAStackTy::OperatorOffsetTy OpsOffs;
18212 llvm::APSInt DepCounter(/*BitWidth=*/32);
18213 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
18214 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
18215 if (const Expr *OrderedCountExpr =
18216 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
18217 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
18218 TotalDepCount.setIsUnsigned(/*Val=*/true);
18219 }
18220 }
18221 for (Expr *RefExpr : VarList) {
18222 assert(RefExpr && "NULL expr in OpenMP shared clause.")(static_cast<void> (0));
18223 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
18224 // It will be analyzed later.
18225 Vars.push_back(RefExpr);
18226 continue;
18227 }
18228
18229 SourceLocation ELoc = RefExpr->getExprLoc();
18230 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
18231 if (DepKind == OMPC_DEPEND_sink) {
18232 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
18233 DepCounter >= TotalDepCount) {
18234 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
18235 continue;
18236 }
18237 ++DepCounter;
18238 // OpenMP [2.13.9, Summary]
18239 // depend(dependence-type : vec), where dependence-type is:
18240 // 'sink' and where vec is the iteration vector, which has the form:
18241 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
18242 // where n is the value specified by the ordered clause in the loop
18243 // directive, xi denotes the loop iteration variable of the i-th nested
18244 // loop associated with the loop directive, and di is a constant
18245 // non-negative integer.
18246 if (CurContext->isDependentContext()) {
18247 // It will be analyzed later.
18248 Vars.push_back(RefExpr);
18249 continue;
18250 }
18251 SimpleExpr = SimpleExpr->IgnoreImplicit();
18252 OverloadedOperatorKind OOK = OO_None;
18253 SourceLocation OOLoc;
18254 Expr *LHS = SimpleExpr;
18255 Expr *RHS = nullptr;
18256 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
18257 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
18258 OOLoc = BO->getOperatorLoc();
18259 LHS = BO->getLHS()->IgnoreParenImpCasts();
18260 RHS = BO->getRHS()->IgnoreParenImpCasts();
18261 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
18262 OOK = OCE->getOperator();
18263 OOLoc = OCE->getOperatorLoc();
18264 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18265 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
18266 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
18267 OOK = MCE->getMethodDecl()
18268 ->getNameInfo()
18269 .getName()
18270 .getCXXOverloadedOperator();
18271 OOLoc = MCE->getCallee()->getExprLoc();
18272 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
18273 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18274 }
18275 SourceLocation ELoc;
18276 SourceRange ERange;
18277 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
18278 if (Res.second) {
18279 // It will be analyzed later.
18280 Vars.push_back(RefExpr);
18281 }
18282 ValueDecl *D = Res.first;
18283 if (!D)
18284 continue;
18285
18286 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
18287 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
18288 continue;
18289 }
18290 if (RHS) {
18291 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
18292 RHS, OMPC_depend, /*StrictlyPositive=*/false);
18293 if (RHSRes.isInvalid())
18294 continue;
18295 }
18296 if (!CurContext->isDependentContext() &&
18297 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
18298 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
18299 const ValueDecl *VD =
18300 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
18301 if (VD)
18302 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
18303 << 1 << VD;
18304 else
18305 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
18306 continue;
18307 }
18308 OpsOffs.emplace_back(RHS, OOK);
18309 } else {
18310 bool OMPDependTFound = LangOpts.OpenMP >= 50;
18311 if (OMPDependTFound)
18312 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
18313 DepKind == OMPC_DEPEND_depobj);
18314 if (DepKind == OMPC_DEPEND_depobj) {
18315 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18316 // List items used in depend clauses with the depobj dependence type
18317 // must be expressions of the omp_depend_t type.
18318 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18319 !RefExpr->isInstantiationDependent() &&
18320 !RefExpr->containsUnexpandedParameterPack() &&
18321 (OMPDependTFound &&
18322 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
18323 RefExpr->getType()))) {
18324 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18325 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
18326 continue;
18327 }
18328 if (!RefExpr->isLValue()) {
18329 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18330 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
18331 continue;
18332 }
18333 } else {
18334 // OpenMP 5.0 [2.17.11, Restrictions]
18335 // List items used in depend clauses cannot be zero-length array
18336 // sections.
18337 QualType ExprTy = RefExpr->getType().getNonReferenceType();
18338 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
18339 if (OASE) {
18340 QualType BaseType =
18341 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18342 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18343 ExprTy = ATy->getElementType();
18344 else
18345 ExprTy = BaseType->getPointeeType();
18346 ExprTy = ExprTy.getNonReferenceType();
18347 const Expr *Length = OASE->getLength();
18348 Expr::EvalResult Result;
18349 if (Length && !Length->isValueDependent() &&
18350 Length->EvaluateAsInt(Result, Context) &&
18351 Result.Val.getInt().isNullValue()) {
18352 Diag(ELoc,
18353 diag::err_omp_depend_zero_length_array_section_not_allowed)
18354 << SimpleExpr->getSourceRange();
18355 continue;
18356 }
18357 }
18358
18359 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18360 // List items used in depend clauses with the in, out, inout or
18361 // mutexinoutset dependence types cannot be expressions of the
18362 // omp_depend_t type.
18363 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18364 !RefExpr->isInstantiationDependent() &&
18365 !RefExpr->containsUnexpandedParameterPack() &&
18366 (OMPDependTFound &&
18367 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
18368 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18369 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
18370 << RefExpr->getSourceRange();
18371 continue;
18372 }
18373
18374 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
18375 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
18376 (ASE && !ASE->getBase()->isTypeDependent() &&
18377 !ASE->getBase()
18378 ->getType()
18379 .getNonReferenceType()
18380 ->isPointerType() &&
18381 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
18382 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18383 << (LangOpts.OpenMP >= 50 ? 1 : 0)
18384 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18385 continue;
18386 }
18387
18388 ExprResult Res;
18389 {
18390 Sema::TentativeAnalysisScope Trap(*this);
18391 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
18392 RefExpr->IgnoreParenImpCasts());
18393 }
18394 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
18395 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
18396 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18397 << (LangOpts.OpenMP >= 50 ? 1 : 0)
18398 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18399 continue;
18400 }
18401 }
18402 }
18403 Vars.push_back(RefExpr->IgnoreParenImpCasts());
18404 }
18405
18406 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
18407 TotalDepCount > VarList.size() &&
18408 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
18409 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
18410 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
18411 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
18412 }
18413 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
18414 Vars.empty())
18415 return nullptr;
18416
18417 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18418 DepModifier, DepKind, DepLoc, ColonLoc,
18419 Vars, TotalDepCount.getZExtValue());
18420 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
18421 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
18422 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
18423 return C;
18424}
18425
18426OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
18427 Expr *Device, SourceLocation StartLoc,
18428 SourceLocation LParenLoc,
18429 SourceLocation ModifierLoc,
18430 SourceLocation EndLoc) {
18431 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&(static_cast<void> (0))
18432 "Unexpected device modifier in OpenMP < 50.")(static_cast<void> (0));
18433
18434 bool ErrorFound = false;
18435 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
18436 std::string Values =
18437 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
18438 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
18439 << Values << getOpenMPClauseName(OMPC_device);
18440 ErrorFound = true;
18441 }
18442
18443 Expr *ValExpr = Device;
18444 Stmt *HelperValStmt = nullptr;
18445
18446 // OpenMP [2.9.1, Restrictions]
18447 // The device expression must evaluate to a non-negative integer value.
18448 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
18449 /*StrictlyPositive=*/false) ||
18450 ErrorFound;
18451 if (ErrorFound)
18452 return nullptr;
18453
18454 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18455 OpenMPDirectiveKind CaptureRegion =
18456 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
18457 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18458 ValExpr = MakeFullExpr(ValExpr).get();
18459 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18460 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18461 HelperValStmt = buildPreInits(Context, Captures);
18462 }
18463
18464 return new (Context)
18465 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
18466 LParenLoc, ModifierLoc, EndLoc);
18467}
18468
18469static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
18470 DSAStackTy *Stack, QualType QTy,
18471 bool FullCheck = true) {
18472 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
18473 return false;
18474 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
18475 !QTy.isTriviallyCopyableType(SemaRef.Context))
18476 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
18477 return true;
18478}
18479
18480/// Return true if it can be proven that the provided array expression
18481/// (array section or array subscript) does NOT specify the whole size of the
18482/// array whose base type is \a BaseQTy.
18483static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
18484 const Expr *E,
18485 QualType BaseQTy) {
18486 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
3
Assuming 'E' is not a 'OMPArraySectionExpr'
4
'OASE' initialized to a null pointer value
18487
18488 // If this is an array subscript, it refers to the whole size if the size of
18489 // the dimension is constant and equals 1. Also, an array section assumes the
18490 // format of an array subscript if no colon is used.
18491 if (isa<ArraySubscriptExpr>(E) ||
5
Assuming 'E' is not a 'ArraySubscriptExpr'
6
Taking false branch
18492 (OASE
5.1
'OASE' is null
&& OASE->getColonLocFirst().isInvalid())) {
18493 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18494 return ATy->getSize().getSExtValue() != 1;
18495 // Size can't be evaluated statically.
18496 return false;
18497 }
18498
18499 assert(OASE && "Expecting array section if not an array subscript.")(static_cast<void> (0));
18500 const Expr *LowerBound = OASE->getLowerBound();
7
Called C++ object pointer is null
18501 const Expr *Length = OASE->getLength();
18502
18503 // If there is a lower bound that does not evaluates to zero, we are not
18504 // covering the whole dimension.
18505 if (LowerBound) {
18506 Expr::EvalResult Result;
18507 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
18508 return false; // Can't get the integer value as a constant.
18509
18510 llvm::APSInt ConstLowerBound = Result.Val.getInt();
18511 if (ConstLowerBound.getSExtValue())
18512 return true;
18513 }
18514
18515 // If we don't have a length we covering the whole dimension.
18516 if (!Length)
18517 return false;
18518
18519 // If the base is a pointer, we don't have a way to get the size of the
18520 // pointee.
18521 if (BaseQTy->isPointerType())
18522 return false;
18523
18524 // We can only check if the length is the same as the size of the dimension
18525 // if we have a constant array.
18526 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
18527 if (!CATy)
18528 return false;
18529
18530 Expr::EvalResult Result;
18531 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18532 return false; // Can't get the integer value as a constant.
18533
18534 llvm::APSInt ConstLength = Result.Val.getInt();
18535 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
18536}
18537
18538// Return true if it can be proven that the provided array expression (array
18539// section or array subscript) does NOT specify a single element of the array
18540// whose base type is \a BaseQTy.
18541static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
18542 const Expr *E,
18543 QualType BaseQTy) {
18544 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18545
18546 // An array subscript always refer to a single element. Also, an array section
18547 // assumes the format of an array subscript if no colon is used.
18548 if (isa<ArraySubscriptExpr>(E) ||
18549 (OASE && OASE->getColonLocFirst().isInvalid()))
18550 return false;
18551
18552 assert(OASE && "Expecting array section if not an array subscript.")(static_cast<void> (0));
18553 const Expr *Length = OASE->getLength();
18554
18555 // If we don't have a length we have to check if the array has unitary size
18556 // for this dimension. Also, we should always expect a length if the base type
18557 // is pointer.
18558 if (!Length) {
18559 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18560 return ATy->getSize().getSExtValue() != 1;
18561 // We cannot assume anything.
18562 return false;
18563 }
18564
18565 // Check if the length evaluates to 1.
18566 Expr::EvalResult Result;
18567 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18568 return false; // Can't get the integer value as a constant.
18569
18570 llvm::APSInt ConstLength = Result.Val.getInt();
18571 return ConstLength.getSExtValue() != 1;
18572}
18573
18574// The base of elements of list in a map clause have to be either:
18575// - a reference to variable or field.
18576// - a member expression.
18577// - an array expression.
18578//
18579// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
18580// reference to 'r'.
18581//
18582// If we have:
18583//
18584// struct SS {
18585// Bla S;
18586// foo() {
18587// #pragma omp target map (S.Arr[:12]);
18588// }
18589// }
18590//
18591// We want to retrieve the member expression 'this->S';
18592
18593// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
18594// If a list item is an array section, it must specify contiguous storage.
18595//
18596// For this restriction it is sufficient that we make sure only references
18597// to variables or fields and array expressions, and that no array sections
18598// exist except in the rightmost expression (unless they cover the whole
18599// dimension of the array). E.g. these would be invalid:
18600//
18601// r.ArrS[3:5].Arr[6:7]
18602//
18603// r.ArrS[3:5].x
18604//
18605// but these would be valid:
18606// r.ArrS[3].Arr[6:7]
18607//
18608// r.ArrS[3].x
18609namespace {
18610class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
18611 Sema &SemaRef;
18612 OpenMPClauseKind CKind = OMPC_unknown;
18613 OpenMPDirectiveKind DKind = OMPD_unknown;
18614 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
18615 bool IsNonContiguous = false;
18616 bool NoDiagnose = false;
18617 const Expr *RelevantExpr = nullptr;
18618 bool AllowUnitySizeArraySection = true;
18619 bool AllowWholeSizeArraySection = true;
18620 bool AllowAnotherPtr = true;
18621 SourceLocation ELoc;
18622 SourceRange ERange;
18623
18624 void emitErrorMsg() {
18625 // If nothing else worked, this is not a valid map clause expression.
18626 if (SemaRef.getLangOpts().OpenMP < 50) {
18627 SemaRef.Diag(ELoc,
18628 diag::err_omp_expected_named_var_member_or_array_expression)
18629 << ERange;
18630 } else {
18631 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18632 << getOpenMPClauseName(CKind) << ERange;
18633 }
18634 }
18635
18636public:
18637 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
18638 if (!isa<VarDecl>(DRE->getDecl())) {
18639 emitErrorMsg();
18640 return false;
18641 }
18642 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast<void> (0));
18643 RelevantExpr = DRE;
18644 // Record the component.
18645 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
18646 return true;
18647 }
18648
18649 bool VisitMemberExpr(MemberExpr *ME) {
18650 Expr *E = ME;
18651 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
18652
18653 if (isa<CXXThisExpr>(BaseE)) {
18654 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast<void> (0));
18655 // We found a base expression: this->Val.
18656 RelevantExpr = ME;
18657 } else {
18658 E = BaseE;
18659 }
18660
18661 if (!isa<FieldDecl>(ME->getMemberDecl())) {
18662 if (!NoDiagnose) {
18663 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
18664 << ME->getSourceRange();
18665 return false;
18666 }
18667 if (RelevantExpr)
18668 return false;
18669 return Visit(E);
18670 }
18671
18672 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
18673
18674 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
18675 // A bit-field cannot appear in a map clause.
18676 //
18677 if (FD->isBitField()) {
18678 if (!NoDiagnose) {
18679 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
18680 << ME->getSourceRange() << getOpenMPClauseName(CKind);
18681 return false;
18682 }
18683 if (RelevantExpr)
18684 return false;
18685 return Visit(E);
18686 }
18687
18688 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18689 // If the type of a list item is a reference to a type T then the type
18690 // will be considered to be T for all purposes of this clause.
18691 QualType CurType = BaseE->getType().getNonReferenceType();
18692
18693 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
18694 // A list item cannot be a variable that is a member of a structure with
18695 // a union type.
18696 //
18697 if (CurType->isUnionType()) {
18698 if (!NoDiagnose) {
18699 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
18700 << ME->getSourceRange();
18701 return false;
18702 }
18703 return RelevantExpr || Visit(E);
18704 }
18705
18706 // If we got a member expression, we should not expect any array section
18707 // before that:
18708 //
18709 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
18710 // If a list item is an element of a structure, only the rightmost symbol
18711 // of the variable reference can be an array section.
18712 //
18713 AllowUnitySizeArraySection = false;
18714 AllowWholeSizeArraySection = false;
18715
18716 // Record the component.
18717 Components.emplace_back(ME, FD, IsNonContiguous);
18718 return RelevantExpr || Visit(E);
18719 }
18720
18721 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
18722 Expr *E = AE->getBase()->IgnoreParenImpCasts();
18723
18724 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
1
Taking false branch
18725 if (!NoDiagnose) {
18726 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18727 << 0 << AE->getSourceRange();
18728 return false;
18729 }
18730 return RelevantExpr || Visit(E);
18731 }
18732
18733 // If we got an array subscript that express the whole dimension we
18734 // can have any array expressions before. If it only expressing part of
18735 // the dimension, we can only have unitary-size array expressions.
18736 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
2
Calling 'checkArrayExpressionDoesNotReferToWholeSize'
18737 E->getType()))
18738 AllowWholeSizeArraySection = false;
18739
18740 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
18741 Expr::EvalResult Result;
18742 if (!AE->getIdx()->isValueDependent() &&
18743 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
18744 !Result.Val.getInt().isNullValue()) {
18745 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18746 diag::err_omp_invalid_map_this_expr);
18747 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18748 diag::note_omp_invalid_subscript_on_this_ptr_map);
18749 }
18750 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast<void> (0));
18751 RelevantExpr = TE;
18752 }
18753
18754 // Record the component - we don't have any declaration associated.
18755 Components.emplace_back(AE, nullptr, IsNonContiguous);
18756
18757 return RelevantExpr || Visit(E);
18758 }
18759
18760 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
18761 // After OMP 5.0 Array section in reduction clause will be implicitly
18762 // mapped
18763 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&(static_cast<void> (0))
18764 "Array sections cannot be implicitly mapped.")(static_cast<void> (0));
18765 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18766 QualType CurType =
18767 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18768
18769 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18770 // If the type of a list item is a reference to a type T then the type
18771 // will be considered to be T for all purposes of this clause.
18772 if (CurType->isReferenceType())
18773 CurType = CurType->getPointeeType();
18774
18775 bool IsPointer = CurType->isAnyPointerType();
18776
18777 if (!IsPointer && !CurType->isArrayType()) {
18778 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18779 << 0 << OASE->getSourceRange();
18780 return false;
18781 }
18782
18783 bool NotWhole =
18784 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
18785 bool NotUnity =
18786 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
18787
18788 if (AllowWholeSizeArraySection) {
18789 // Any array section is currently allowed. Allowing a whole size array
18790 // section implies allowing a unity array section as well.
18791 //
18792 // If this array section refers to the whole dimension we can still
18793 // accept other array sections before this one, except if the base is a
18794 // pointer. Otherwise, only unitary sections are accepted.
18795 if (NotWhole || IsPointer)
18796 AllowWholeSizeArraySection = false;
18797 } else if (DKind == OMPD_target_update &&
18798 SemaRef.getLangOpts().OpenMP >= 50) {
18799 if (IsPointer && !AllowAnotherPtr)
18800 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
18801 << /*array of unknown bound */ 1;
18802 else
18803 IsNonContiguous = true;
18804 } else if (AllowUnitySizeArraySection && NotUnity) {
18805 // A unity or whole array section is not allowed and that is not
18806 // compatible with the properties of the current array section.
18807 if (NoDiagnose)
18808 return false;
18809 SemaRef.Diag(
18810 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
18811 << OASE->getSourceRange();
18812 return false;
18813 }
18814
18815 if (IsPointer)
18816 AllowAnotherPtr = false;
18817
18818 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
18819 Expr::EvalResult ResultR;
18820 Expr::EvalResult ResultL;
18821 if (!OASE->getLength()->isValueDependent() &&
18822 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
18823 !ResultR.Val.getInt().isOneValue()) {
18824 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18825 diag::err_omp_invalid_map_this_expr);
18826 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18827 diag::note_omp_invalid_length_on_this_ptr_mapping);
18828 }
18829 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
18830 OASE->getLowerBound()->EvaluateAsInt(ResultL,
18831 SemaRef.getASTContext()) &&
18832 !ResultL.Val.getInt().isNullValue()) {
18833 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18834 diag::err_omp_invalid_map_this_expr);
18835 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18836 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
18837 }
18838 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast<void> (0));
18839 RelevantExpr = TE;
18840 }
18841
18842 // Record the component - we don't have any declaration associated.
18843 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
18844 return RelevantExpr || Visit(E);
18845 }
18846 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
18847 Expr *Base = E->getBase();
18848
18849 // Record the component - we don't have any declaration associated.
18850 Components.emplace_back(E, nullptr, IsNonContiguous);
18851
18852 return Visit(Base->IgnoreParenImpCasts());
18853 }
18854
18855 bool VisitUnaryOperator(UnaryOperator *UO) {
18856 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
18857 UO->getOpcode() != UO_Deref) {
18858 emitErrorMsg();
18859 return false;
18860 }
18861 if (!RelevantExpr) {
18862 // Record the component if haven't found base decl.
18863 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
18864 }
18865 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
18866 }
18867 bool VisitBinaryOperator(BinaryOperator *BO) {
18868 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
18869 emitErrorMsg();
18870 return false;
18871 }
18872
18873 // Pointer arithmetic is the only thing we expect to happen here so after we
18874 // make sure the binary operator is a pointer type, the we only thing need
18875 // to to is to visit the subtree that has the same type as root (so that we
18876 // know the other subtree is just an offset)
18877 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
18878 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
18879 Components.emplace_back(BO, nullptr, false);
18880 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||(static_cast<void> (0))
18881 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&(static_cast<void> (0))
18882 "Either LHS or RHS have base decl inside")(static_cast<void> (0));
18883 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
18884 return RelevantExpr || Visit(LE);
18885 return RelevantExpr || Visit(RE);
18886 }
18887 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
18888 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast<void> (0));
18889 RelevantExpr = CTE;
18890 Components.emplace_back(CTE, nullptr, IsNonContiguous);
18891 return true;
18892 }
18893 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
18894 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast<void> (0));
18895 Components.emplace_back(COCE, nullptr, IsNonContiguous);
18896 return true;
18897 }
18898 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
18899 Expr *Source = E->getSourceExpr();
18900 if (!Source) {
18901 emitErrorMsg();
18902 return false;
18903 }
18904 return Visit(Source);
18905 }
18906 bool VisitStmt(Stmt *) {
18907 emitErrorMsg();
18908 return false;
18909 }
18910 const Expr *getFoundBase() const {
18911 return RelevantExpr;
18912 }
18913 explicit MapBaseChecker(
18914 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
18915 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
18916 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
18917 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
18918 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
18919};
18920} // namespace
18921
18922/// Return the expression of the base of the mappable expression or null if it
18923/// cannot be determined and do all the necessary checks to see if the expression
18924/// is valid as a standalone mappable expression. In the process, record all the
18925/// components of the expression.
18926static const Expr *checkMapClauseExpressionBase(
18927 Sema &SemaRef, Expr *E,
18928 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
18929 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
18930 SourceLocation ELoc = E->getExprLoc();
18931 SourceRange ERange = E->getSourceRange();
18932 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
18933 ERange);
18934 if (Checker.Visit(E->IgnoreParens())) {
18935 // Check if the highest dimension array section has length specified
18936 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
18937 (CKind == OMPC_to || CKind == OMPC_from)) {
18938 auto CI = CurComponents.rbegin();
18939 auto CE = CurComponents.rend();
18940 for (; CI != CE; ++CI) {
18941 const auto *OASE =
18942 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
18943 if (!OASE)
18944 continue;
18945 if (OASE && OASE->getLength())
18946 break;
18947 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
18948 << ERange;
18949 }
18950 }
18951 return Checker.getFoundBase();
18952 }
18953 return nullptr;
18954}
18955
18956// Return true if expression E associated with value VD has conflicts with other
18957// map information.
18958static bool checkMapConflicts(
18959 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
18960 bool CurrentRegionOnly,
18961 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
18962 OpenMPClauseKind CKind) {
18963 assert(VD && E)(static_cast<void> (0));
18964 SourceLocation ELoc = E->getExprLoc();
18965 SourceRange ERange = E->getSourceRange();
18966
18967 // In order to easily check the conflicts we need to match each component of
18968 // the expression under test with the components of the expressions that are
18969 // already in the stack.
18970
18971 assert(!CurComponents.empty() && "Map clause expression with no components!")(static_cast<void> (0));
18972 assert(CurComponents.back().getAssociatedDeclaration() == VD &&(static_cast<void> (0))
18973 "Map clause expression with unexpected base!")(static_cast<void> (0));
18974
18975 // Variables to help detecting enclosing problems in data environment nests.
18976 bool IsEnclosedByDataEnvironmentExpr = false;
18977 const Expr *EnclosingExpr = nullptr;
18978
18979 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
18980 VD, CurrentRegionOnly,
18981 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
18982 ERange, CKind, &EnclosingExpr,
18983 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
18984 StackComponents,
18985 OpenMPClauseKind Kind) {
18986 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
18987 return false;
18988 assert(!StackComponents.empty() &&(static_cast<void> (0))
18989 "Map clause expression with no components!")(static_cast<void> (0));
18990 assert(StackComponents.back().getAssociatedDeclaration() == VD &&(static_cast<void> (0))
18991 "Map clause expression with unexpected base!")(static_cast<void> (0));
18992 (void)VD;
18993
18994 // The whole expression in the stack.
18995 const Expr *RE = StackComponents.front().getAssociatedExpression();
18996
18997 // Expressions must start from the same base. Here we detect at which
18998 // point both expressions diverge from each other and see if we can
18999 // detect if the memory referred to both expressions is contiguous and
19000 // do not overlap.
19001 auto CI = CurComponents.rbegin();
19002 auto CE = CurComponents.rend();
19003 auto SI = StackComponents.rbegin();
19004 auto SE = StackComponents.rend();
19005 for (; CI != CE && SI != SE; ++CI, ++SI) {
19006
19007 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
19008 // At most one list item can be an array item derived from a given
19009 // variable in map clauses of the same construct.
19010 if (CurrentRegionOnly &&
19011 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
19012 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
19013 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
19014 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
19015 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
19016 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
19017 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
19018 diag::err_omp_multiple_array_items_in_map_clause)
19019 << CI->getAssociatedExpression()->getSourceRange();
19020 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
19021 diag::note_used_here)
19022 << SI->getAssociatedExpression()->getSourceRange();
19023 return true;
19024 }
19025
19026 // Do both expressions have the same kind?
19027 if (CI->getAssociatedExpression()->getStmtClass() !=
19028 SI->getAssociatedExpression()->getStmtClass())
19029 break;
19030
19031 // Are we dealing with different variables/fields?
19032 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
19033 break;
19034 }
19035 // Check if the extra components of the expressions in the enclosing
19036 // data environment are redundant for the current base declaration.
19037 // If they are, the maps completely overlap, which is legal.
19038 for (; SI != SE; ++SI) {
19039 QualType Type;
19040 if (const auto *ASE =
19041 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
19042 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
19043 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
19044 SI->getAssociatedExpression())) {
19045 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
19046 Type =
19047 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
19048 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
19049 SI->getAssociatedExpression())) {
19050 Type = OASE->getBase()->getType()->getPointeeType();
19051 }
19052 if (Type.isNull() || Type->isAnyPointerType() ||
19053 checkArrayExpressionDoesNotReferToWholeSize(
19054 SemaRef, SI->getAssociatedExpression(), Type))
19055 break;
19056 }
19057
19058 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19059 // List items of map clauses in the same construct must not share
19060 // original storage.
19061 //
19062 // If the expressions are exactly the same or one is a subset of the
19063 // other, it means they are sharing storage.
19064 if (CI == CE && SI == SE) {
19065 if (CurrentRegionOnly) {
19066 if (CKind == OMPC_map) {
19067 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19068 } else {
19069 assert(CKind == OMPC_to || CKind == OMPC_from)(static_cast<void> (0));
19070 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19071 << ERange;
19072 }
19073 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19074 << RE->getSourceRange();
19075 return true;
19076 }
19077 // If we find the same expression in the enclosing data environment,
19078 // that is legal.
19079 IsEnclosedByDataEnvironmentExpr = true;
19080 return false;
19081 }
19082
19083 QualType DerivedType =
19084 std::prev(CI)->getAssociatedDeclaration()->getType();
19085 SourceLocation DerivedLoc =
19086 std::prev(CI)->getAssociatedExpression()->getExprLoc();
19087
19088 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19089 // If the type of a list item is a reference to a type T then the type
19090 // will be considered to be T for all purposes of this clause.
19091 DerivedType = DerivedType.getNonReferenceType();
19092
19093 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
19094 // A variable for which the type is pointer and an array section
19095 // derived from that variable must not appear as list items of map
19096 // clauses of the same construct.
19097 //
19098 // Also, cover one of the cases in:
19099 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19100 // If any part of the original storage of a list item has corresponding
19101 // storage in the device data environment, all of the original storage
19102 // must have corresponding storage in the device data environment.
19103 //
19104 if (DerivedType->isAnyPointerType()) {
19105 if (CI == CE || SI == SE) {
19106 SemaRef.Diag(
19107 DerivedLoc,
19108 diag::err_omp_pointer_mapped_along_with_derived_section)
19109 << DerivedLoc;
19110 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19111 << RE->getSourceRange();
19112 return true;
19113 }
19114 if (CI->getAssociatedExpression()->getStmtClass() !=
19115 SI->getAssociatedExpression()->getStmtClass() ||
19116 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
19117 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
19118 assert(CI != CE && SI != SE)(static_cast<void> (0));
19119 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
19120 << DerivedLoc;
19121 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19122 << RE->getSourceRange();
19123 return true;
19124 }
19125 }
19126
19127 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19128 // List items of map clauses in the same construct must not share
19129 // original storage.
19130 //
19131 // An expression is a subset of the other.
19132 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
19133 if (CKind == OMPC_map) {
19134 if (CI != CE || SI != SE) {
19135 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
19136 // a pointer.
19137 auto Begin =
19138 CI != CE ? CurComponents.begin() : StackComponents.begin();
19139 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
19140 auto It = Begin;
19141 while (It != End && !It->getAssociatedDeclaration())
19142 std::advance(It, 1);
19143 assert(It != End &&(static_cast<void> (0))
19144 "Expected at least one component with the declaration.")(static_cast<void> (0));
19145 if (It != Begin && It->getAssociatedDeclaration()
19146 ->getType()
19147 .getCanonicalType()
19148 ->isAnyPointerType()) {
19149 IsEnclosedByDataEnvironmentExpr = false;
19150 EnclosingExpr = nullptr;
19151 return false;
19152 }
19153 }
19154 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19155 } else {
19156 assert(CKind == OMPC_to || CKind == OMPC_from)(static_cast<void> (0));
19157 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19158 << ERange;
19159 }
19160 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19161 << RE->getSourceRange();
19162 return true;
19163 }
19164
19165 // The current expression uses the same base as other expression in the
19166 // data environment but does not contain it completely.
19167 if (!CurrentRegionOnly && SI != SE)
19168 EnclosingExpr = RE;
19169
19170 // The current expression is a subset of the expression in the data
19171 // environment.
19172 IsEnclosedByDataEnvironmentExpr |=
19173 (!CurrentRegionOnly && CI != CE && SI == SE);
19174
19175 return false;
19176 });
19177
19178 if (CurrentRegionOnly)
19179 return FoundError;
19180
19181 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19182 // If any part of the original storage of a list item has corresponding
19183 // storage in the device data environment, all of the original storage must
19184 // have corresponding storage in the device data environment.
19185 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
19186 // If a list item is an element of a structure, and a different element of
19187 // the structure has a corresponding list item in the device data environment
19188 // prior to a task encountering the construct associated with the map clause,
19189 // then the list item must also have a corresponding list item in the device
19190 // data environment prior to the task encountering the construct.
19191 //
19192 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
19193 SemaRef.Diag(ELoc,
19194 diag::err_omp_original_storage_is_shared_and_does_not_contain)
19195 << ERange;
19196 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
19197 << EnclosingExpr->getSourceRange();
19198 return true;
19199 }
19200
19201 return FoundError;
19202}
19203
19204// Look up the user-defined mapper given the mapper name and mapped type, and
19205// build a reference to it.
19206static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
19207 CXXScopeSpec &MapperIdScopeSpec,
19208 const DeclarationNameInfo &MapperId,
19209 QualType Type,
19210 Expr *UnresolvedMapper) {
19211 if (MapperIdScopeSpec.isInvalid())
19212 return ExprError();
19213 // Get the actual type for the array type.
19214 if (Type->isArrayType()) {
19215 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")(static_cast<void> (0));
19216 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
19217 }
19218 // Find all user-defined mappers with the given MapperId.
19219 SmallVector<UnresolvedSet<8>, 4> Lookups;
19220 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
19221 Lookup.suppressDiagnostics();
19222 if (S) {
19223 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
19224 NamedDecl *D = Lookup.getRepresentativeDecl();
19225 while (S && !S->isDeclScope(D))
19226 S = S->getParent();
19227 if (S)
19228 S = S->getParent();
19229 Lookups.emplace_back();
19230 Lookups.back().append(Lookup.begin(), Lookup.end());
19231 Lookup.clear();
19232 }
19233 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
19234 // Extract the user-defined mappers with the given MapperId.
19235 Lookups.push_back(UnresolvedSet<8>());
19236 for (NamedDecl *D : ULE->decls()) {
19237 auto *DMD = cast<OMPDeclareMapperDecl>(D);
19238 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")(static_cast<void> (0));
19239 Lookups.back().addDecl(DMD);
19240 }
19241 }
19242 // Defer the lookup for dependent types. The results will be passed through
19243 // UnresolvedMapper on instantiation.
19244 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
19245 Type->isInstantiationDependentType() ||
19246 Type->containsUnexpandedParameterPack() ||
19247 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
19248 return !D->isInvalidDecl() &&
19249 (D->getType()->isDependentType() ||
19250 D->getType()->isInstantiationDependentType() ||
19251 D->getType()->containsUnexpandedParameterPack());
19252 })) {
19253 UnresolvedSet<8> URS;
19254 for (const UnresolvedSet<8> &Set : Lookups) {
19255 if (Set.empty())
19256 continue;
19257 URS.append(Set.begin(), Set.end());
19258 }
19259 return UnresolvedLookupExpr::Create(
19260 SemaRef.Context, /*NamingClass=*/nullptr,
19261 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
19262 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
19263 }
19264 SourceLocation Loc = MapperId.getLoc();
19265 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19266 // The type must be of struct, union or class type in C and C++
19267 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
19268 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
19269 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
19270 return ExprError();
19271 }
19272 // Perform argument dependent lookup.
19273 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
19274 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
19275 // Return the first user-defined mapper with the desired type.
19276 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19277 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
19278 if (!D->isInvalidDecl() &&
19279 SemaRef.Context.hasSameType(D->getType(), Type))
19280 return D;
19281 return nullptr;
19282 }))
19283 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19284 // Find the first user-defined mapper with a type derived from the desired
19285 // type.
19286 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19287 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
19288 if (!D->isInvalidDecl() &&
19289 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
19290 !Type.isMoreQualifiedThan(D->getType()))
19291 return D;
19292 return nullptr;
19293 })) {
19294 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19295 /*DetectVirtual=*/false);
19296 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
19297 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19298 VD->getType().getUnqualifiedType()))) {
19299 if (SemaRef.CheckBaseClassAccess(
19300 Loc, VD->getType(), Type, Paths.front(),
19301 /*DiagID=*/0) != Sema::AR_inaccessible) {
19302 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19303 }
19304 }
19305 }
19306 }
19307 // Report error if a mapper is specified, but cannot be found.
19308 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
19309 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
19310 << Type << MapperId.getName();
19311 return ExprError();
19312 }
19313 return ExprEmpty();
19314}
19315
19316namespace {
19317// Utility struct that gathers all the related lists associated with a mappable
19318// expression.
19319struct MappableVarListInfo {
19320 // The list of expressions.
19321 ArrayRef<Expr *> VarList;
19322 // The list of processed expressions.
19323 SmallVector<Expr *, 16> ProcessedVarList;
19324 // The mappble components for each expression.
19325 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
19326 // The base declaration of the variable.
19327 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
19328 // The reference to the user-defined mapper associated with every expression.
19329 SmallVector<Expr *, 16> UDMapperList;
19330
19331 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
19332 // We have a list of components and base declarations for each entry in the
19333 // variable list.
19334 VarComponents.reserve(VarList.size());
19335 VarBaseDeclarations.reserve(VarList.size());
19336 }
19337};
19338}
19339
19340// Check the validity of the provided variable list for the provided clause kind
19341// \a CKind. In the check process the valid expressions, mappable expression
19342// components, variables, and user-defined mappers are extracted and used to
19343// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
19344// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
19345// and \a MapperId are expected to be valid if the clause kind is 'map'.
19346static void checkMappableExpressionList(
19347 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
19348 MappableVarListInfo &MVLI, SourceLocation StartLoc,
19349 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
19350 ArrayRef<Expr *> UnresolvedMappers,
19351 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
19352 ArrayRef<OpenMPMapModifierKind> Modifiers = None,
19353 bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
19354 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
19355 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(static_cast<void> (0))
19356 "Unexpected clause kind with mappable expressions!")(static_cast<void> (0));
19357
19358 // If the identifier of user-defined mapper is not specified, it is "default".
19359 // We do not change the actual name in this clause to distinguish whether a
19360 // mapper is specified explicitly, i.e., it is not explicitly specified when
19361 // MapperId.getName() is empty.
19362 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
19363 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
19364 MapperId.setName(DeclNames.getIdentifier(
19365 &SemaRef.getASTContext().Idents.get("default")));
19366 MapperId.setLoc(StartLoc);
19367 }
19368
19369 // Iterators to find the current unresolved mapper expression.
19370 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
19371 bool UpdateUMIt = false;
19372 Expr *UnresolvedMapper = nullptr;
19373
19374 bool HasHoldModifier =
19375 Modifiers.end() != std::find(Modifiers.begin(), Modifiers.end(),
19376 OMPC_MAP_MODIFIER_ompx_hold);
19377
19378 // Keep track of the mappable components and base declarations in this clause.
19379 // Each entry in the list is going to have a list of components associated. We
19380 // record each set of the components so that we can build the clause later on.
19381 // In the end we should have the same amount of declarations and component
19382 // lists.
19383
19384 for (Expr *RE : MVLI.VarList) {
19385 assert(RE && "Null expr in omp to/from/map clause")(static_cast<void> (0));
19386 SourceLocation ELoc = RE->getExprLoc();
19387
19388 // Find the current unresolved mapper expression.
19389 if (UpdateUMIt && UMIt != UMEnd) {
19390 UMIt++;
19391 assert((static_cast<void> (0))
19392 UMIt != UMEnd &&(static_cast<void> (0))
19393 "Expect the size of UnresolvedMappers to match with that of VarList")(static_cast<void> (0));
19394 }
19395 UpdateUMIt = true;
19396 if (UMIt != UMEnd)
19397 UnresolvedMapper = *UMIt;
19398
19399 const Expr *VE = RE->IgnoreParenLValueCasts();
19400
19401 if (VE->isValueDependent() || VE->isTypeDependent() ||
19402 VE->isInstantiationDependent() ||
19403 VE->containsUnexpandedParameterPack()) {
19404 // Try to find the associated user-defined mapper.
19405 ExprResult ER = buildUserDefinedMapperRef(
19406 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19407 VE->getType().getCanonicalType(), UnresolvedMapper);
19408 if (ER.isInvalid())
19409 continue;
19410 MVLI.UDMapperList.push_back(ER.get());
19411 // We can only analyze this information once the missing information is
19412 // resolved.
19413 MVLI.ProcessedVarList.push_back(RE);
19414 continue;
19415 }
19416
19417 Expr *SimpleExpr = RE->IgnoreParenCasts();
19418
19419 if (!RE->isLValue()) {
19420 if (SemaRef.getLangOpts().OpenMP < 50) {
19421 SemaRef.Diag(
19422 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
19423 << RE->getSourceRange();
19424 } else {
19425 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
19426 << getOpenMPClauseName(CKind) << RE->getSourceRange();
19427 }
19428 continue;
19429 }
19430
19431 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
19432 ValueDecl *CurDeclaration = nullptr;
19433
19434 // Obtain the array or member expression bases if required. Also, fill the
19435 // components array with all the components identified in the process.
19436 const Expr *BE =
19437 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
19438 DSAS->getCurrentDirective(), NoDiagnose);
19439 if (!BE)
19440 continue;
19441
19442 assert(!CurComponents.empty() &&(static_cast<void> (0))
19443 "Invalid mappable expression information.")(static_cast<void> (0));
19444
19445 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
19446 // Add store "this" pointer to class in DSAStackTy for future checking
19447 DSAS->addMappedClassesQualTypes(TE->getType());
19448 // Try to find the associated user-defined mapper.
19449 ExprResult ER = buildUserDefinedMapperRef(
19450 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19451 VE->getType().getCanonicalType(), UnresolvedMapper);
19452 if (ER.isInvalid())
19453 continue;
19454 MVLI.UDMapperList.push_back(ER.get());
19455 // Skip restriction checking for variable or field declarations
19456 MVLI.ProcessedVarList.push_back(RE);
19457 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19458 MVLI.VarComponents.back().append(CurComponents.begin(),
19459 CurComponents.end());
19460 MVLI.VarBaseDeclarations.push_back(nullptr);
19461 continue;
19462 }
19463
19464 // For the following checks, we rely on the base declaration which is
19465 // expected to be associated with the last component. The declaration is
19466 // expected to be a variable or a field (if 'this' is being mapped).
19467 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
19468 assert(CurDeclaration && "Null decl on map clause.")(static_cast<void> (0));
19469 assert((static_cast<void> (0))
19470 CurDeclaration->isCanonicalDecl() &&(static_cast<void> (0))
19471 "Expecting components to have associated only canonical declarations.")(static_cast<void> (0));
19472
19473 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
19474 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
19475
19476 assert((VD || FD) && "Only variables or fields are expected here!")(static_cast<void> (0));
19477 (void)FD;
19478
19479 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
19480 // threadprivate variables cannot appear in a map clause.
19481 // OpenMP 4.5 [2.10.5, target update Construct]
19482 // threadprivate variables cannot appear in a from clause.
19483 if (VD && DSAS->isThreadPrivate(VD)) {
19484 if (NoDiagnose)
19485 continue;
19486 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19487 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
19488 << getOpenMPClauseName(CKind);
19489 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
19490 continue;
19491 }
19492
19493 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19494 // A list item cannot appear in both a map clause and a data-sharing
19495 // attribute clause on the same construct.
19496
19497 // Check conflicts with other map clause expressions. We check the conflicts
19498 // with the current construct separately from the enclosing data
19499 // environment, because the restrictions are different. We only have to
19500 // check conflicts across regions for the map clauses.
19501 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19502 /*CurrentRegionOnly=*/true, CurComponents, CKind))
19503 break;
19504 if (CKind == OMPC_map &&
19505 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
19506 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19507 /*CurrentRegionOnly=*/false, CurComponents, CKind))
19508 break;
19509
19510 // OpenMP 4.5 [2.10.5, target update Construct]
19511 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19512 // If the type of a list item is a reference to a type T then the type will
19513 // be considered to be T for all purposes of this clause.
19514 auto I = llvm::find_if(
19515 CurComponents,
19516 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
19517 return MC.getAssociatedDeclaration();
19518 });
19519 assert(I != CurComponents.end() && "Null decl on map clause.")(static_cast<void> (0));
19520 (void)I;
19521 QualType Type;
19522 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
19523 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
19524 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
19525 if (ASE) {
19526 Type = ASE->getType().getNonReferenceType();
19527 } else if (OASE) {
19528 QualType BaseType =
19529 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19530 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19531 Type = ATy->getElementType();
19532 else
19533 Type = BaseType->getPointeeType();
19534 Type = Type.getNonReferenceType();
19535 } else if (OAShE) {
19536 Type = OAShE->getBase()->getType()->getPointeeType();
19537 } else {
19538 Type = VE->getType();
19539 }
19540
19541 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
19542 // A list item in a to or from clause must have a mappable type.
19543 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19544 // A list item must have a mappable type.
19545 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
19546 DSAS, Type, /*FullCheck=*/true))
19547 continue;
19548
19549 if (CKind == OMPC_map) {
19550 // target enter data
19551 // OpenMP [2.10.2, Restrictions, p. 99]
19552 // A map-type must be specified in all map clauses and must be either
19553 // to or alloc.
19554 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
19555 if (DKind == OMPD_target_enter_data &&
19556 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
19557 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19558 << (IsMapTypeImplicit ? 1 : 0)
19559 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19560 << getOpenMPDirectiveName(DKind);
19561 continue;
19562 }
19563
19564 // target exit_data
19565 // OpenMP [2.10.3, Restrictions, p. 102]
19566 // A map-type must be specified in all map clauses and must be either
19567 // from, release, or delete.
19568 if (DKind == OMPD_target_exit_data &&
19569 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
19570 MapType == OMPC_MAP_delete)) {
19571 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19572 << (IsMapTypeImplicit ? 1 : 0)
19573 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19574 << getOpenMPDirectiveName(DKind);
19575 continue;
19576 }
19577
19578 // The 'ompx_hold' modifier is specifically intended to be used on a
19579 // 'target' or 'target data' directive to prevent data from being unmapped
19580 // during the associated statement. It is not permitted on a 'target
19581 // enter data' or 'target exit data' directive, which have no associated
19582 // statement.
19583 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
19584 HasHoldModifier) {
19585 SemaRef.Diag(StartLoc,
19586 diag::err_omp_invalid_map_type_modifier_for_directive)
19587 << getOpenMPSimpleClauseTypeName(OMPC_map,
19588 OMPC_MAP_MODIFIER_ompx_hold)
19589 << getOpenMPDirectiveName(DKind);
19590 continue;
19591 }
19592
19593 // target, target data
19594 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
19595 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
19596 // A map-type in a map clause must be to, from, tofrom or alloc
19597 if ((DKind == OMPD_target_data ||
19598 isOpenMPTargetExecutionDirective(DKind)) &&
19599 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
19600 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
19601 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19602 << (IsMapTypeImplicit ? 1 : 0)
19603 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19604 << getOpenMPDirectiveName(DKind);
19605 continue;
19606 }
19607
19608 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
19609 // A list item cannot appear in both a map clause and a data-sharing
19610 // attribute clause on the same construct
19611 //
19612 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
19613 // A list item cannot appear in both a map clause and a data-sharing
19614 // attribute clause on the same construct unless the construct is a
19615 // combined construct.
19616 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
19617 isOpenMPTargetExecutionDirective(DKind)) ||
19618 DKind == OMPD_target)) {
19619 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19620 if (isOpenMPPrivate(DVar.CKind)) {
19621 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19622 << getOpenMPClauseName(DVar.CKind)
19623 << getOpenMPClauseName(OMPC_map)
19624 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
19625 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
19626 continue;
19627 }
19628 }
19629 }
19630
19631 // Try to find the associated user-defined mapper.
19632 ExprResult ER = buildUserDefinedMapperRef(
19633 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19634 Type.getCanonicalType(), UnresolvedMapper);
19635 if (ER.isInvalid())
19636 continue;
19637 MVLI.UDMapperList.push_back(ER.get());
19638
19639 // Save the current expression.
19640 MVLI.ProcessedVarList.push_back(RE);
19641
19642 // Store the components in the stack so that they can be used to check
19643 // against other clauses later on.
19644 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
19645 /*WhereFoundClauseKind=*/OMPC_map);
19646
19647 // Save the components and declaration to create the clause. For purposes of
19648 // the clause creation, any component list that has has base 'this' uses
19649 // null as base declaration.
19650 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19651 MVLI.VarComponents.back().append(CurComponents.begin(),
19652 CurComponents.end());
19653 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
19654 : CurDeclaration);
19655 }
19656}
19657
19658OMPClause *Sema::ActOnOpenMPMapClause(
19659 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
19660 ArrayRef<SourceLocation> MapTypeModifiersLoc,
19661 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19662 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
19663 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19664 const OMPVarListLocTy &Locs, bool NoDiagnose,
19665 ArrayRef<Expr *> UnresolvedMappers) {
19666 OpenMPMapModifierKind Modifiers[] = {
19667 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19668 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19669 OMPC_MAP_MODIFIER_unknown};
19670 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
19671
19672 // Process map-type-modifiers, flag errors for duplicate modifiers.
19673 unsigned Count = 0;
19674 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
19675 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
19676 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
19677 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
19678 continue;
19679 }
19680 assert(Count < NumberOfOMPMapClauseModifiers &&(static_cast<void> (0))
19681 "Modifiers exceed the allowed number of map type modifiers")(static_cast<void> (0));
19682 Modifiers[Count] = MapTypeModifiers[I];
19683 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
19684 ++Count;
19685 }
19686
19687 MappableVarListInfo MVLI(VarList);
19688 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
19689 MapperIdScopeSpec, MapperId, UnresolvedMappers,
19690 MapType, Modifiers, IsMapTypeImplicit,
19691 NoDiagnose);
19692
19693 // We need to produce a map clause even if we don't have variables so that
19694 // other diagnostics related with non-existing map clauses are accurate.
19695 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
19696 MVLI.VarBaseDeclarations, MVLI.VarComponents,
19697 MVLI.UDMapperList, Modifiers, ModifiersLoc,
19698 MapperIdScopeSpec.getWithLocInContext(Context),
19699 MapperId, MapType, IsMapTypeImplicit, MapLoc);
19700}
19701
19702QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
19703 TypeResult ParsedType) {
19704 assert(ParsedType.isUsable())(static_cast<void> (0));
19705
19706 QualType ReductionType = GetTypeFromParser(ParsedType.get());
19707 if (ReductionType.isNull())
19708 return QualType();
19709
19710 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
19711 // A type name in a declare reduction directive cannot be a function type, an
19712 // array type, a reference type, or a type qualified with const, volatile or
19713 // restrict.
19714 if (ReductionType.hasQualifiers()) {
19715 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
19716 return QualType();
19717 }
19718
19719 if (ReductionType->isFunctionType()) {
19720 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
19721 return QualType();
19722 }
19723 if (ReductionType->isReferenceType()) {
19724 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
19725 return QualType();
19726 }
19727 if (ReductionType->isArrayType()) {
19728 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
19729 return QualType();
19730 }
19731 return ReductionType;
19732}
19733
19734Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
19735 Scope *S, DeclContext *DC, DeclarationName Name,
19736 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
19737 AccessSpecifier AS, Decl *PrevDeclInScope) {
19738 SmallVector<Decl *, 8> Decls;
19739 Decls.reserve(ReductionTypes.size());
19740
19741 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
19742 forRedeclarationInCurContext());
19743 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
19744 // A reduction-identifier may not be re-declared in the current scope for the
19745 // same type or for a type that is compatible according to the base language
19746 // rules.
19747 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19748 OMPDeclareReductionDecl *PrevDRD = nullptr;
19749 bool InCompoundScope = true;
19750 if (S != nullptr) {
19751 // Find previous declaration with the same name not referenced in other
19752 // declarations.
19753 FunctionScopeInfo *ParentFn = getEnclosingFunction();
19754 InCompoundScope =
19755 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19756 LookupName(Lookup, S);
19757 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19758 /*AllowInlineNamespace=*/false);
19759 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
19760 LookupResult::Filter Filter = Lookup.makeFilter();
19761 while (Filter.hasNext()) {
19762 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
19763 if (InCompoundScope) {
19764 auto I = UsedAsPrevious.find(PrevDecl);
19765 if (I == UsedAsPrevious.end())
19766 UsedAsPrevious[PrevDecl] = false;
19767 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
19768 UsedAsPrevious[D] = true;
19769 }
19770 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19771 PrevDecl->getLocation();
19772 }
19773 Filter.done();
19774 if (InCompoundScope) {
19775 for (const auto &PrevData : UsedAsPrevious) {
19776 if (!PrevData.second) {
19777 PrevDRD = PrevData.first;
19778 break;
19779 }
19780 }
19781 }
19782 } else if (PrevDeclInScope != nullptr) {
19783 auto *PrevDRDInScope = PrevDRD =
19784 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
19785 do {
19786 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
19787 PrevDRDInScope->getLocation();
19788 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
19789 } while (PrevDRDInScope != nullptr);
19790 }
19791 for (const auto &TyData : ReductionTypes) {
19792 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
19793 bool Invalid = false;
19794 if (I != PreviousRedeclTypes.end()) {
19795 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
19796 << TyData.first;
19797 Diag(I->second, diag::note_previous_definition);
19798 Invalid = true;
19799 }
19800 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
19801 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
19802 Name, TyData.first, PrevDRD);
19803 DC->addDecl(DRD);
19804 DRD->setAccess(AS);
19805 Decls.push_back(DRD);
19806 if (Invalid)
19807 DRD->setInvalidDecl();
19808 else
19809 PrevDRD = DRD;
19810 }
19811
19812 return DeclGroupPtrTy::make(
19813 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
19814}
19815
19816void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
19817 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19818
19819 // Enter new function scope.
19820 PushFunctionScope();
19821 setFunctionHasBranchProtectedScope();
19822 getCurFunction()->setHasOMPDeclareReductionCombiner();
19823
19824 if (S != nullptr)
19825 PushDeclContext(S, DRD);
19826 else
19827 CurContext = DRD;
19828
19829 PushExpressionEvaluationContext(
19830 ExpressionEvaluationContext::PotentiallyEvaluated);
19831
19832 QualType ReductionType = DRD->getType();
19833 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
19834 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
19835 // uses semantics of argument handles by value, but it should be passed by
19836 // reference. C lang does not support references, so pass all parameters as
19837 // pointers.
19838 // Create 'T omp_in;' variable.
19839 VarDecl *OmpInParm =
19840 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
19841 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
19842 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
19843 // uses semantics of argument handles by value, but it should be passed by
19844 // reference. C lang does not support references, so pass all parameters as
19845 // pointers.
19846 // Create 'T omp_out;' variable.
19847 VarDecl *OmpOutParm =
19848 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
19849 if (S != nullptr) {
19850 PushOnScopeChains(OmpInParm, S);
19851 PushOnScopeChains(OmpOutParm, S);
19852 } else {
19853 DRD->addDecl(OmpInParm);
19854 DRD->addDecl(OmpOutParm);
19855 }
19856 Expr *InE =
19857 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
19858 Expr *OutE =
19859 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
19860 DRD->setCombinerData(InE, OutE);
19861}
19862
19863void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
19864 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19865 DiscardCleanupsInEvaluationContext();
19866 PopExpressionEvaluationContext();
19867
19868 PopDeclContext();
19869 PopFunctionScopeInfo();
19870
19871 if (Combiner != nullptr)
19872 DRD->setCombiner(Combiner);
19873 else
19874 DRD->setInvalidDecl();
19875}
19876
19877VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
19878 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19879
19880 // Enter new function scope.
19881 PushFunctionScope();
19882 setFunctionHasBranchProtectedScope();
19883
19884 if (S != nullptr)
19885 PushDeclContext(S, DRD);
19886 else
19887 CurContext = DRD;
19888
19889 PushExpressionEvaluationContext(
19890 ExpressionEvaluationContext::PotentiallyEvaluated);
19891
19892 QualType ReductionType = DRD->getType();
19893 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
19894 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
19895 // uses semantics of argument handles by value, but it should be passed by
19896 // reference. C lang does not support references, so pass all parameters as
19897 // pointers.
19898 // Create 'T omp_priv;' variable.
19899 VarDecl *OmpPrivParm =
19900 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
19901 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
19902 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
19903 // uses semantics of argument handles by value, but it should be passed by
19904 // reference. C lang does not support references, so pass all parameters as
19905 // pointers.
19906 // Create 'T omp_orig;' variable.
19907 VarDecl *OmpOrigParm =
19908 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
19909 if (S != nullptr) {
19910 PushOnScopeChains(OmpPrivParm, S);
19911 PushOnScopeChains(OmpOrigParm, S);
19912 } else {
19913 DRD->addDecl(OmpPrivParm);
19914 DRD->addDecl(OmpOrigParm);
19915 }
19916 Expr *OrigE =
19917 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
19918 Expr *PrivE =
19919 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
19920 DRD->setInitializerData(OrigE, PrivE);
19921 return OmpPrivParm;
19922}
19923
19924void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
19925 VarDecl *OmpPrivParm) {
19926 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19927 DiscardCleanupsInEvaluationContext();
19928 PopExpressionEvaluationContext();
19929
19930 PopDeclContext();
19931 PopFunctionScopeInfo();
19932
19933 if (Initializer != nullptr) {
19934 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
19935 } else if (OmpPrivParm->hasInit()) {
19936 DRD->setInitializer(OmpPrivParm->getInit(),
19937 OmpPrivParm->isDirectInit()
19938 ? OMPDeclareReductionDecl::DirectInit
19939 : OMPDeclareReductionDecl::CopyInit);
19940 } else {
19941 DRD->setInvalidDecl();
19942 }
19943}
19944
19945Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
19946 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
19947 for (Decl *D : DeclReductions.get()) {
19948 if (IsValid) {
19949 if (S)
19950 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
19951 /*AddToContext=*/false);
19952 } else {
19953 D->setInvalidDecl();
19954 }
19955 }
19956 return DeclReductions;
19957}
19958
19959TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
19960 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
19961 QualType T = TInfo->getType();
19962 if (D.isInvalidType())
19963 return true;
19964
19965 if (getLangOpts().CPlusPlus) {
19966 // Check that there are no default arguments (C++ only).
19967 CheckExtraCXXDefaultArguments(D);
19968 }
19969
19970 return CreateParsedType(T, TInfo);
19971}
19972
19973QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
19974 TypeResult ParsedType) {
19975 assert(ParsedType.isUsable() && "Expect usable parsed mapper type")(static_cast<void> (0));
19976
19977 QualType MapperType = GetTypeFromParser(ParsedType.get());
19978 assert(!MapperType.isNull() && "Expect valid mapper type")(static_cast<void> (0));
19979
19980 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19981 // The type must be of struct, union or class type in C and C++
19982 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
19983 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
19984 return QualType();
19985 }
19986 return MapperType;
19987}
19988
19989Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
19990 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
19991 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
19992 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
19993 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
19994 forRedeclarationInCurContext());
19995 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19996 // A mapper-identifier may not be redeclared in the current scope for the
19997 // same type or for a type that is compatible according to the base language
19998 // rules.
19999 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
20000 OMPDeclareMapperDecl *PrevDMD = nullptr;
20001 bool InCompoundScope = true;
20002 if (S != nullptr) {
20003 // Find previous declaration with the same name not referenced in other
20004 // declarations.
20005 FunctionScopeInfo *ParentFn = getEnclosingFunction();
20006 InCompoundScope =
20007 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
20008 LookupName(Lookup, S);
20009 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
20010 /*AllowInlineNamespace=*/false);
20011 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
20012 LookupResult::Filter Filter = Lookup.makeFilter();
20013 while (Filter.hasNext()) {
20014 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
20015 if (InCompoundScope) {
20016 auto I = UsedAsPrevious.find(PrevDecl);
20017 if (I == UsedAsPrevious.end())
20018 UsedAsPrevious[PrevDecl] = false;
20019 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
20020 UsedAsPrevious[D] = true;
20021 }
20022 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
20023 PrevDecl->getLocation();
20024 }
20025 Filter.done();
20026 if (InCompoundScope) {
20027 for (const auto &PrevData : UsedAsPrevious) {
20028 if (!PrevData.second) {
20029 PrevDMD = PrevData.first;
20030 break;
20031 }
20032 }
20033 }
20034 } else if (PrevDeclInScope) {
20035 auto *PrevDMDInScope = PrevDMD =
20036 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
20037 do {
20038 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
20039 PrevDMDInScope->getLocation();
20040 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
20041 } while (PrevDMDInScope != nullptr);
20042 }
20043 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
20044 bool Invalid = false;
20045 if (I != PreviousRedeclTypes.end()) {
20046 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
20047 << MapperType << Name;
20048 Diag(I->second, diag::note_previous_definition);
20049 Invalid = true;
20050 }
20051 // Build expressions for implicit maps of data members with 'default'
20052 // mappers.
20053 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
20054 Clauses.end());
20055 if (LangOpts.OpenMP >= 50)
20056 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ClausesWithImplicit);
20057 auto *DMD =
20058 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
20059 ClausesWithImplicit, PrevDMD);
20060 if (S)
20061 PushOnScopeChains(DMD, S);
20062 else
20063 DC->addDecl(DMD);
20064 DMD->setAccess(AS);
20065 if (Invalid)
20066 DMD->setInvalidDecl();
20067
20068 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
20069 VD->setDeclContext(DMD);
20070 VD->setLexicalDeclContext(DMD);
20071 DMD->addDecl(VD);
20072 DMD->setMapperVarRef(MapperVarRef);
20073
20074 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
20075}
20076
20077ExprResult
20078Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
20079 SourceLocation StartLoc,
20080 DeclarationName VN) {
20081 TypeSourceInfo *TInfo =
20082 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
20083 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
20084 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
20085 MapperType, TInfo, SC_None);
20086 if (S)
20087 PushOnScopeChains(VD, S, /*AddToContext=*/false);
20088 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
20089 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
20090 return E;
20091}
20092
20093bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
20094 assert(LangOpts.OpenMP && "Expected OpenMP mode.")(static_cast<void> (0));
20095 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
20096 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
20097 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
20098 return true;
20099 if (VD->isUsableInConstantExpressions(Context))
20100 return true;
20101 return false;
20102 }
20103 return true;
20104}
20105
20106const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
20107 assert(LangOpts.OpenMP && "Expected OpenMP mode.")(static_cast<void> (0));
20108 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
20109}
20110
20111OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
20112 SourceLocation StartLoc,
20113 SourceLocation LParenLoc,
20114 SourceLocation EndLoc) {
20115 Expr *ValExpr = NumTeams;
20116 Stmt *HelperValStmt = nullptr;
20117
20118 // OpenMP [teams Constrcut, Restrictions]
20119 // The num_teams expression must evaluate to a positive integer value.
20120 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
20121 /*StrictlyPositive=*/true))
20122 return nullptr;
20123
20124 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
20125 OpenMPDirectiveKind CaptureRegion =
20126 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
20127 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20128 ValExpr = MakeFullExpr(ValExpr).get();
20129 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20130 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20131 HelperValStmt = buildPreInits(Context, Captures);
20132 }
20133
20134 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
20135 StartLoc, LParenLoc, EndLoc);
20136}
20137
20138OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
20139 SourceLocation StartLoc,
20140 SourceLocation LParenLoc,
20141 SourceLocation EndLoc) {
20142 Expr *ValExpr = ThreadLimit;
20143 Stmt *HelperValStmt = nullptr;
20144
20145 // OpenMP [teams Constrcut, Restrictions]
20146 // The thread_limit expression must evaluate to a positive integer value.
20147 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
20148 /*StrictlyPositive=*/true))
20149 return nullptr;
20150
20151 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
20152 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
20153 DKind, OMPC_thread_limit, LangOpts.OpenMP);
20154 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20155 ValExpr = MakeFullExpr(ValExpr).get();
20156 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20157 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20158 HelperValStmt = buildPreInits(Context, Captures);
20159 }
20160
20161 return new (Context) OMPThreadLimitClause(
20162 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
20163}
20164
20165OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
20166 SourceLocation StartLoc,
20167 SourceLocation LParenLoc,
20168 SourceLocation EndLoc) {
20169 Expr *ValExpr = Priority;
20170 Stmt *HelperValStmt = nullptr;
20171 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20172
20173 // OpenMP [2.9.1, task Constrcut]
20174 // The priority-value is a non-negative numerical scalar expression.
20175 if (!isNonNegativeIntegerValue(
20176 ValExpr, *this, OMPC_priority,
20177 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
20178 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20179 return nullptr;
20180
20181 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
20182 StartLoc, LParenLoc, EndLoc);
20183}
20184
20185OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
20186 SourceLocation StartLoc,
20187 SourceLocation LParenLoc,
20188 SourceLocation EndLoc) {
20189 Expr *ValExpr = Grainsize;
20190 Stmt *HelperValStmt = nullptr;
20191 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20192
20193 // OpenMP [2.9.2, taskloop Constrcut]
20194 // The parameter of the grainsize clause must be a positive integer
20195 // expression.
20196 if (!isNonNegativeIntegerValue(
20197 ValExpr, *this, OMPC_grainsize,
20198 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20199 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20200 return nullptr;
20201
20202 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
20203 StartLoc, LParenLoc, EndLoc);
20204}
20205
20206OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
20207 SourceLocation StartLoc,
20208 SourceLocation LParenLoc,
20209 SourceLocation EndLoc) {
20210 Expr *ValExpr = NumTasks;
20211 Stmt *HelperValStmt = nullptr;
20212 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20213
20214 // OpenMP [2.9.2, taskloop Constrcut]
20215 // The parameter of the num_tasks clause must be a positive integer
20216 // expression.
20217 if (!isNonNegativeIntegerValue(
20218 ValExpr, *this, OMPC_num_tasks,
20219 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20220 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20221 return nullptr;
20222
20223 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
20224 StartLoc, LParenLoc, EndLoc);
20225}
20226
20227OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
20228 SourceLocation LParenLoc,
20229 SourceLocation EndLoc) {
20230 // OpenMP [2.13.2, critical construct, Description]
20231 // ... where hint-expression is an integer constant expression that evaluates
20232 // to a valid lock hint.
20233 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
20234 if (HintExpr.isInvalid())
20235 return nullptr;
20236 return new (Context)
20237 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
20238}
20239
20240/// Tries to find omp_event_handle_t type.
20241static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
20242 DSAStackTy *Stack) {
20243 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
20244 if (!OMPEventHandleT.isNull())
20245 return true;
20246 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
20247 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20248 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20249 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
20250 return false;
20251 }
20252 Stack->setOMPEventHandleT(PT.get());
20253 return true;
20254}
20255
20256OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
20257 SourceLocation LParenLoc,
20258 SourceLocation EndLoc) {
20259 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
20260 !Evt->isInstantiationDependent() &&
20261 !Evt->containsUnexpandedParameterPack()) {
20262 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
20263 return nullptr;
20264 // OpenMP 5.0, 2.10.1 task Construct.
20265 // event-handle is a variable of the omp_event_handle_t type.
20266 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
20267 if (!Ref) {
20268 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20269 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20270 return nullptr;
20271 }
20272 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
20273 if (!VD) {
20274 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20275 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20276 return nullptr;
20277 }
20278 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
20279 VD->getType()) ||
20280 VD->getType().isConstant(Context)) {
20281 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20282 << "omp_event_handle_t" << 1 << VD->getType()
20283 << Evt->getSourceRange();
20284 return nullptr;
20285 }
20286 // OpenMP 5.0, 2.10.1 task Construct
20287 // [detach clause]... The event-handle will be considered as if it was
20288 // specified on a firstprivate clause.
20289 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
20290 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
20291 DVar.RefExpr) {
20292 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
20293 << getOpenMPClauseName(DVar.CKind)
20294 << getOpenMPClauseName(OMPC_firstprivate);
20295 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
20296 return nullptr;
20297 }
20298 }
20299
20300 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
20301}
20302
20303OMPClause *Sema::ActOnOpenMPDistScheduleClause(
20304 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
20305 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
20306 SourceLocation EndLoc) {
20307 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
20308 std::string Values;
20309 Values += "'";
20310 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
20311 Values += "'";
20312 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20313 << Values << getOpenMPClauseName(OMPC_dist_schedule);
20314 return nullptr;
20315 }
20316 Expr *ValExpr = ChunkSize;
20317 Stmt *HelperValStmt = nullptr;
20318 if (ChunkSize) {
20319 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
20320 !ChunkSize->isInstantiationDependent() &&
20321 !ChunkSize->containsUnexpandedParameterPack()) {
20322 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
20323 ExprResult Val =
20324 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
20325 if (Val.isInvalid())
20326 return nullptr;
20327
20328 ValExpr = Val.get();
20329
20330 // OpenMP [2.7.1, Restrictions]
20331 // chunk_size must be a loop invariant integer expression with a positive
20332 // value.
20333 if (Optional<llvm::APSInt> Result =
20334 ValExpr->getIntegerConstantExpr(Context)) {
20335 if (Result->isSigned() && !Result->isStrictlyPositive()) {
20336 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
20337 << "dist_schedule" << ChunkSize->getSourceRange();
20338 return nullptr;
20339 }
20340 } else if (getOpenMPCaptureRegionForClause(
20341 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
20342 LangOpts.OpenMP) != OMPD_unknown &&
20343 !CurContext->isDependentContext()) {
20344 ValExpr = MakeFullExpr(ValExpr).get();
20345 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20346 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20347 HelperValStmt = buildPreInits(Context, Captures);
20348 }
20349 }
20350 }
20351
20352 return new (Context)
20353 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
20354 Kind, ValExpr, HelperValStmt);
20355}
20356
20357OMPClause *Sema::ActOnOpenMPDefaultmapClause(
20358 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
20359 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
20360 SourceLocation KindLoc, SourceLocation EndLoc) {
20361 if (getLangOpts().OpenMP < 50) {
20362 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
20363 Kind != OMPC_DEFAULTMAP_scalar) {
20364 std::string Value;
20365 SourceLocation Loc;
20366 Value += "'";
20367 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
20368 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20369 OMPC_DEFAULTMAP_MODIFIER_tofrom);
20370 Loc = MLoc;
20371 } else {
20372 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20373 OMPC_DEFAULTMAP_scalar);
20374 Loc = KindLoc;
20375 }
20376 Value += "'";
20377 Diag(Loc, diag::err_omp_unexpected_clause_value)
20378 << Value << getOpenMPClauseName(OMPC_defaultmap);
20379 return nullptr;
20380 }
20381 } else {
20382 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
20383 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
20384 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
20385 if (!isDefaultmapKind || !isDefaultmapModifier) {
20386 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
20387 if (LangOpts.OpenMP == 50) {
20388 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
20389 "'firstprivate', 'none', 'default'";
20390 if (!isDefaultmapKind && isDefaultmapModifier) {
20391 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20392 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20393 } else if (isDefaultmapKind && !isDefaultmapModifier) {
20394 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20395 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20396 } else {
20397 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20398 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20399 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20400 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20401 }
20402 } else {
20403 StringRef ModifierValue =
20404 "'alloc', 'from', 'to', 'tofrom', "
20405 "'firstprivate', 'none', 'default', 'present'";
20406 if (!isDefaultmapKind && isDefaultmapModifier) {
20407 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20408 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20409 } else if (isDefaultmapKind && !isDefaultmapModifier) {
20410 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20411 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20412 } else {
20413 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20414 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20415 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20416 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20417 }
20418 }
20419 return nullptr;
20420 }
20421
20422 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
20423 // At most one defaultmap clause for each category can appear on the
20424 // directive.
20425 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
20426 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
20427 return nullptr;
20428 }
20429 }
20430 if (Kind == OMPC_DEFAULTMAP_unknown) {
20431 // Variable category is not specified - mark all categories.
20432 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
20433 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
20434 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
20435 } else {
20436 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
20437 }
20438
20439 return new (Context)
20440 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
20441}
20442
20443bool Sema::ActOnStartOpenMPDeclareTargetContext(
20444 DeclareTargetContextInfo &DTCI) {
20445 DeclContext *CurLexicalContext = getCurLexicalContext();
20446 if (!CurLexicalContext->isFileContext() &&
20447 !CurLexicalContext->isExternCContext() &&
20448 !CurLexicalContext->isExternCXXContext() &&
20449 !isa<CXXRecordDecl>(CurLexicalContext) &&
20450 !isa<ClassTemplateDecl>(CurLexicalContext) &&
20451 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
20452 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
20453 Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
20454 return false;
20455 }
20456 DeclareTargetNesting.push_back(DTCI);
20457 return true;
20458}
20459
20460const Sema::DeclareTargetContextInfo
20461Sema::ActOnOpenMPEndDeclareTargetDirective() {
20462 assert(!DeclareTargetNesting.empty() &&(static_cast<void> (0))
20463 "check isInOpenMPDeclareTargetContext() first!")(static_cast<void> (0));
20464 return DeclareTargetNesting.pop_back_val();
20465}
20466
20467void Sema::ActOnFinishedOpenMPDeclareTargetContext(
20468 DeclareTargetContextInfo &DTCI) {
20469 for (auto &It : DTCI.ExplicitlyMapped)
20470 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT,
20471 DTCI.DT);
20472}
20473
20474NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
20475 CXXScopeSpec &ScopeSpec,
20476 const DeclarationNameInfo &Id) {
20477 LookupResult Lookup(*this, Id, LookupOrdinaryName);
20478 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
20479
20480 if (Lookup.isAmbiguous())
20481 return nullptr;
20482 Lookup.suppressDiagnostics();
20483
20484 if (!Lookup.isSingleResult()) {
20485 VarOrFuncDeclFilterCCC CCC(*this);
20486 if (TypoCorrection Corrected =
20487 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
20488 CTK_ErrorRecovery)) {
20489 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
20490 << Id.getName());
20491 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
20492 return nullptr;
20493 }
20494
20495 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
20496 return nullptr;
20497 }
20498
20499 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
20500 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
20501 !isa<FunctionTemplateDecl>(ND)) {
20502 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
20503 return nullptr;
20504 }
20505 return ND;
20506}
20507
20508void Sema::ActOnOpenMPDeclareTargetName(
20509 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
20510 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
20511 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||(static_cast<void> (0))
20512 isa<FunctionTemplateDecl>(ND)) &&(static_cast<void> (0))
20513 "Expected variable, function or function template.")(static_cast<void> (0));
20514
20515 // Diagnose marking after use as it may lead to incorrect diagnosis and
20516 // codegen.
20517 if (LangOpts.OpenMP >= 50 &&
20518 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
20519 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
20520
20521 // Explicit declare target lists have precedence.
20522 const unsigned Level = -1;
20523
20524 auto *VD = cast<ValueDecl>(ND);
20525 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20526 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20527 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DT &&
20528 ActiveAttr.getValue()->getLevel() == Level) {
20529 Diag(Loc, diag::err_omp_device_type_mismatch)
20530 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
20531 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
20532 ActiveAttr.getValue()->getDevType());
20533 return;
20534 }
20535 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
20536 ActiveAttr.getValue()->getLevel() == Level) {
20537 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
20538 return;
20539 }
20540
20541 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
20542 return;
20543
20544 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, Level,
20545 SourceRange(Loc, Loc));
20546 ND->addAttr(A);
20547 if (ASTMutationListener *ML = Context.getASTMutationListener())
20548 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
20549 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
20550}
20551
20552static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
20553 Sema &SemaRef, Decl *D) {
20554 if (!D || !isa<VarDecl>(D))
20555 return;
20556 auto *VD = cast<VarDecl>(D);
20557 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
20558 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
20559 if (SemaRef.LangOpts.OpenMP >= 50 &&
20560 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
20561 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
20562 VD->hasGlobalStorage()) {
20563 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
20564 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
20565 // If a lambda declaration and definition appears between a
20566 // declare target directive and the matching end declare target
20567 // directive, all variables that are captured by the lambda
20568 // expression must also appear in a to clause.
20569 SemaRef.Diag(VD->getLocation(),
20570 diag::err_omp_lambda_capture_in_declare_target_not_to);
20571 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
20572 << VD << 0 << SR;
20573 return;
20574 }
20575 }
20576 if (MapTy.hasValue())
20577 return;
20578 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
20579 SemaRef.Diag(SL, diag::note_used_here) << SR;
20580}
20581
20582static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
20583 Sema &SemaRef, DSAStackTy *Stack,
20584 ValueDecl *VD) {
20585 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
20586 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
20587 /*FullCheck=*/false);
20588}
20589
20590void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
20591 SourceLocation IdLoc) {
20592 if (!D || D->isInvalidDecl())
20593 return;
20594 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
20595 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
20596 if (auto *VD = dyn_cast<VarDecl>(D)) {
20597 // Only global variables can be marked as declare target.
20598 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
20599 !VD->isStaticDataMember())
20600 return;
20601 // 2.10.6: threadprivate variable cannot appear in a declare target
20602 // directive.
20603 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
20604 Diag(SL, diag::err_omp_threadprivate_in_target);
20605 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
20606 return;
20607 }
20608 }
20609 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
20610 D = FTD->getTemplatedDecl();
20611 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
20612 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
20613 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
20614 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
20615 Diag(IdLoc, diag::err_omp_function_in_link_clause);
20616 Diag(FD->getLocation(), diag::note_defined_here) << FD;
20617 return;
20618 }
20619 }
20620 if (auto *VD = dyn_cast<ValueDecl>(D)) {
20621 // Problem if any with var declared with incomplete type will be reported
20622 // as normal, so no need to check it here.
20623 if ((E || !VD->getType()->isIncompleteType()) &&
20624 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
20625 return;
20626 if (!E && isInOpenMPDeclareTargetContext()) {
20627 // Checking declaration inside declare target region.
20628 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
20629 isa<FunctionTemplateDecl>(D)) {
20630 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20631 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20632 unsigned Level = DeclareTargetNesting.size();
20633 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
20634 return;
20635 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
20636 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
20637 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, Level,
20638 SourceRange(DTCI.Loc, DTCI.Loc));
20639 D->addAttr(A);
20640 if (ASTMutationListener *ML = Context.getASTMutationListener())
20641 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
20642 }
20643 return;
20644 }
20645 }
20646 if (!E)
20647 return;
20648 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
20649}
20650
20651OMPClause *Sema::ActOnOpenMPToClause(
20652 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20653 ArrayRef<SourceLocation> MotionModifiersLoc,
20654 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20655 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20656 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20657 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20658 OMPC_MOTION_MODIFIER_unknown};
20659 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20660
20661 // Process motion-modifiers, flag errors for duplicate modifiers.
20662 unsigned Count = 0;
20663 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20664 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20665 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20666 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20667 continue;
20668 }
20669 assert(Count < NumberOfOMPMotionModifiers &&(static_cast<void> (0))
20670 "Modifiers exceed the allowed number of motion modifiers")(static_cast<void> (0));
20671 Modifiers[Count] = MotionModifiers[I];
20672 ModifiersLoc[Count] = MotionModifiersLoc[I];
20673 ++Count;
20674 }
20675
20676 MappableVarListInfo MVLI(VarList);
20677 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
20678 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20679 if (MVLI.ProcessedVarList.empty())
20680 return nullptr;
20681
20682 return OMPToClause::Create(
20683 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20684 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20685 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20686}
20687
20688OMPClause *Sema::ActOnOpenMPFromClause(
20689 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20690 ArrayRef<SourceLocation> MotionModifiersLoc,
20691 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20692 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20693 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20694 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20695 OMPC_MOTION_MODIFIER_unknown};
20696 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20697
20698 // Process motion-modifiers, flag errors for duplicate modifiers.
20699 unsigned Count = 0;
20700 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20701 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20702 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20703 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20704 continue;
20705 }
20706 assert(Count < NumberOfOMPMotionModifiers &&(static_cast<void> (0))
20707 "Modifiers exceed the allowed number of motion modifiers")(static_cast<void> (0));
20708 Modifiers[Count] = MotionModifiers[I];
20709 ModifiersLoc[Count] = MotionModifiersLoc[I];
20710 ++Count;
20711 }
20712
20713 MappableVarListInfo MVLI(VarList);
20714 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
20715 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20716 if (MVLI.ProcessedVarList.empty())
20717 return nullptr;
20718
20719 return OMPFromClause::Create(
20720 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20721 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20722 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20723}
20724
20725OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
20726 const OMPVarListLocTy &Locs) {
20727 MappableVarListInfo MVLI(VarList);
20728 SmallVector<Expr *, 8> PrivateCopies;
20729 SmallVector<Expr *, 8> Inits;
20730
20731 for (Expr *RefExpr : VarList) {
20732 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")(static_cast<void> (0));
20733 SourceLocation ELoc;
20734 SourceRange ERange;
20735 Expr *SimpleRefExpr = RefExpr;
20736 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20737 if (Res.second) {
20738 // It will be analyzed later.
20739 MVLI.ProcessedVarList.push_back(RefExpr);
20740 PrivateCopies.push_back(nullptr);
20741 Inits.push_back(nullptr);
20742 }
20743 ValueDecl *D = Res.first;
20744 if (!D)
20745 continue;
20746
20747 QualType Type = D->getType();
20748 Type = Type.getNonReferenceType().getUnqualifiedType();
20749
20750 auto *VD = dyn_cast<VarDecl>(D);
20751
20752 // Item should be a pointer or reference to pointer.
20753 if (!Type->isPointerType()) {
20754 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
20755 << 0 << RefExpr->getSourceRange();
20756 continue;
20757 }
20758
20759 // Build the private variable and the expression that refers to it.
20760 auto VDPrivate =
20761 buildVarDecl(*this, ELoc, Type, D->getName(),
20762 D->hasAttrs() ? &D->getAttrs() : nullptr,
20763 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20764 if (VDPrivate->isInvalidDecl())
20765 continue;
20766
20767 CurContext->addDecl(VDPrivate);
20768 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
20769 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
20770
20771 // Add temporary variable to initialize the private copy of the pointer.
20772 VarDecl *VDInit =
20773 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
20774 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
20775 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
20776 AddInitializerToDecl(VDPrivate,
20777 DefaultLvalueConversion(VDInitRefExpr).get(),
20778 /*DirectInit=*/false);
20779
20780 // If required, build a capture to implement the privatization initialized
20781 // with the current list item value.
20782 DeclRefExpr *Ref = nullptr;
20783 if (!VD)
20784 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20785 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20786 PrivateCopies.push_back(VDPrivateRefExpr);
20787 Inits.push_back(VDInitRefExpr);
20788
20789 // We need to add a data sharing attribute for this variable to make sure it
20790 // is correctly captured. A variable that shows up in a use_device_ptr has
20791 // similar properties of a first private variable.
20792 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20793
20794 // Create a mappable component for the list item. List items in this clause
20795 // only need a component.
20796 MVLI.VarBaseDeclarations.push_back(D);
20797 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20798 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
20799 /*IsNonContiguous=*/false);
20800 }
20801
20802 if (MVLI.ProcessedVarList.empty())
20803 return nullptr;
20804
20805 return OMPUseDevicePtrClause::Create(
20806 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
20807 MVLI.VarBaseDeclarations, MVLI.VarComponents);
20808}
20809
20810OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
20811 const OMPVarListLocTy &Locs) {
20812 MappableVarListInfo MVLI(VarList);
20813
20814 for (Expr *RefExpr : VarList) {
20815 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")(static_cast<void> (0));
20816 SourceLocation ELoc;
20817 SourceRange ERange;
20818 Expr *SimpleRefExpr = RefExpr;
20819 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20820 /*AllowArraySection=*/true);
20821 if (Res.second) {
20822 // It will be analyzed later.
20823 MVLI.ProcessedVarList.push_back(RefExpr);
20824 }
20825 ValueDecl *D = Res.first;
20826 if (!D)
20827 continue;
20828 auto *VD = dyn_cast<VarDecl>(D);
20829
20830 // If required, build a capture to implement the privatization initialized
20831 // with the current list item value.
20832 DeclRefExpr *Ref = nullptr;
20833 if (!VD)
20834 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20835 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20836
20837 // We need to add a data sharing attribute for this variable to make sure it
20838 // is correctly captured. A variable that shows up in a use_device_addr has
20839 // similar properties of a first private variable.
20840 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20841
20842 // Create a mappable component for the list item. List items in this clause
20843 // only need a component.
20844 MVLI.VarBaseDeclarations.push_back(D);
20845 MVLI.VarComponents.emplace_back();
20846 Expr *Component = SimpleRefExpr;
20847 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
20848 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
20849 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
20850 MVLI.VarComponents.back().emplace_back(Component, D,
20851 /*IsNonContiguous=*/false);
20852 }
20853
20854 if (MVLI.ProcessedVarList.empty())
20855 return nullptr;
20856
20857 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20858 MVLI.VarBaseDeclarations,
20859 MVLI.VarComponents);
20860}
20861
20862OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
20863 const OMPVarListLocTy &Locs) {
20864 MappableVarListInfo MVLI(VarList);
20865 for (Expr *RefExpr : VarList) {
20866 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")(static_cast<void> (0));
20867 SourceLocation ELoc;
20868 SourceRange ERange;
20869 Expr *SimpleRefExpr = RefExpr;
20870 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20871 if (Res.second) {
20872 // It will be analyzed later.
20873 MVLI.ProcessedVarList.push_back(RefExpr);
20874 }
20875 ValueDecl *D = Res.first;
20876 if (!D)
20877 continue;
20878
20879 QualType Type = D->getType();
20880 // item should be a pointer or array or reference to pointer or array
20881 if (!Type.getNonReferenceType()->isPointerType() &&
20882 !Type.getNonReferenceType()->isArrayType()) {
20883 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
20884 << 0 << RefExpr->getSourceRange();
20885 continue;
20886 }
20887
20888 // Check if the declaration in the clause does not show up in any data
20889 // sharing attribute.
20890 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
20891 if (isOpenMPPrivate(DVar.CKind)) {
20892 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20893 << getOpenMPClauseName(DVar.CKind)
20894 << getOpenMPClauseName(OMPC_is_device_ptr)
20895 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
20896 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
20897 continue;
20898 }
20899
20900 const Expr *ConflictExpr;
20901 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
20902 D, /*CurrentRegionOnly=*/true,
20903 [&ConflictExpr](
20904 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
20905 OpenMPClauseKind) -> bool {
20906 ConflictExpr = R.front().getAssociatedExpression();
20907 return true;
20908 })) {
20909 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
20910 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
20911 << ConflictExpr->getSourceRange();
20912 continue;
20913 }
20914
20915 // Store the components in the stack so that they can be used to check
20916 // against other clauses later on.
20917 OMPClauseMappableExprCommon::MappableComponent MC(
20918 SimpleRefExpr, D, /*IsNonContiguous=*/false);
20919 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
20920 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
20921
20922 // Record the expression we've just processed.
20923 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
20924
20925 // Create a mappable component for the list item. List items in this clause
20926 // only need a component. We use a null declaration to signal fields in
20927 // 'this'.
20928 assert((isa<DeclRefExpr>(SimpleRefExpr) ||(static_cast<void> (0))
20929 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(static_cast<void> (0))
20930 "Unexpected device pointer expression!")(static_cast<void> (0));
20931 MVLI.VarBaseDeclarations.push_back(
20932 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
20933 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20934 MVLI.VarComponents.back().push_back(MC);
20935 }
20936
20937 if (MVLI.ProcessedVarList.empty())
20938 return nullptr;
20939
20940 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20941 MVLI.VarBaseDeclarations,
20942 MVLI.VarComponents);
20943}
20944
20945OMPClause *Sema::ActOnOpenMPAllocateClause(
20946 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
20947 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
20948 if (Allocator) {
20949 // OpenMP [2.11.4 allocate Clause, Description]
20950 // allocator is an expression of omp_allocator_handle_t type.
20951 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
20952 return nullptr;
20953
20954 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
20955 if (AllocatorRes.isInvalid())
20956 return nullptr;
20957 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
20958 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
20959 Sema::AA_Initializing,
20960 /*AllowExplicit=*/true);
20961 if (AllocatorRes.isInvalid())
20962 return nullptr;
20963 Allocator = AllocatorRes.get();
20964 } else {
20965 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
20966 // allocate clauses that appear on a target construct or on constructs in a
20967 // target region must specify an allocator expression unless a requires
20968 // directive with the dynamic_allocators clause is present in the same
20969 // compilation unit.
20970 if (LangOpts.OpenMPIsDevice &&
20971 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
20972 targetDiag(StartLoc, diag::err_expected_allocator_expression);
20973 }
20974 // Analyze and build list of variables.
20975 SmallVector<Expr *, 8> Vars;
20976 for (Expr *RefExpr : VarList) {
20977 assert(RefExpr && "NULL expr in OpenMP private clause.")(static_cast<void> (0));
20978 SourceLocation ELoc;
20979 SourceRange ERange;
20980 Expr *SimpleRefExpr = RefExpr;
20981 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20982 if (Res.second) {
20983 // It will be analyzed later.
20984 Vars.push_back(RefExpr);
20985 }
20986 ValueDecl *D = Res.first;
20987 if (!D)
20988 continue;
20989
20990 auto *VD = dyn_cast<VarDecl>(D);
20991 DeclRefExpr *Ref = nullptr;
20992 if (!VD && !CurContext->isDependentContext())
20993 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20994 Vars.push_back((VD || CurContext->isDependentContext())
20995 ? RefExpr->IgnoreParens()
20996 : Ref);
20997 }
20998
20999 if (Vars.empty())
21000 return nullptr;
21001
21002 if (Allocator)
21003 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
21004 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
21005 ColonLoc, EndLoc, Vars);
21006}
21007
21008OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
21009 SourceLocation StartLoc,
21010 SourceLocation LParenLoc,
21011 SourceLocation EndLoc) {
21012 SmallVector<Expr *, 8> Vars;
21013 for (Expr *RefExpr : VarList) {
21014 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast<void> (0));
21015 SourceLocation ELoc;
21016 SourceRange ERange;
21017 Expr *SimpleRefExpr = RefExpr;
21018 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
21019 if (Res.second)
21020 // It will be analyzed later.
21021 Vars.push_back(RefExpr);
21022 ValueDecl *D = Res.first;
21023 if (!D)
21024 continue;
21025
21026 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
21027 // A list-item cannot appear in more than one nontemporal clause.
21028 if (const Expr *PrevRef =
21029 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
21030 Diag(ELoc, diag::err_omp_used_in_clause_twice)
21031 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
21032 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
21033 << getOpenMPClauseName(OMPC_nontemporal);
21034 continue;
21035 }
21036
21037 Vars.push_back(RefExpr);
21038 }
21039
21040 if (Vars.empty())
21041 return nullptr;
21042
21043 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
21044 Vars);
21045}
21046
21047OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
21048 SourceLocation StartLoc,
21049 SourceLocation LParenLoc,
21050 SourceLocation EndLoc) {
21051 SmallVector<Expr *, 8> Vars;
21052 for (Expr *RefExpr : VarList) {
21053 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast<void> (0));
21054 SourceLocation ELoc;
21055 SourceRange ERange;
21056 Expr *SimpleRefExpr = RefExpr;
21057 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21058 /*AllowArraySection=*/true);
21059 if (Res.second)
21060 // It will be analyzed later.
21061 Vars.push_back(RefExpr);
21062 ValueDecl *D = Res.first;
21063 if (!D)
21064 continue;
21065
21066 const DSAStackTy::DSAVarData DVar =
21067 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
21068 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21069 // A list item that appears in the inclusive or exclusive clause must appear
21070 // in a reduction clause with the inscan modifier on the enclosing
21071 // worksharing-loop, worksharing-loop SIMD, or simd construct.
21072 if (DVar.CKind != OMPC_reduction ||
21073 DVar.Modifier != OMPC_REDUCTION_inscan)
21074 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21075 << RefExpr->getSourceRange();
21076
21077 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
21078 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
21079 Vars.push_back(RefExpr);
21080 }
21081
21082 if (Vars.empty())
21083 return nullptr;
21084
21085 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21086}
21087
21088OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
21089 SourceLocation StartLoc,
21090 SourceLocation LParenLoc,
21091 SourceLocation EndLoc) {
21092 SmallVector<Expr *, 8> Vars;
21093 for (Expr *RefExpr : VarList) {
21094 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast<void> (0));
21095 SourceLocation ELoc;
21096 SourceRange ERange;
21097 Expr *SimpleRefExpr = RefExpr;
21098 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21099 /*AllowArraySection=*/true);
21100 if (Res.second)
21101 // It will be analyzed later.
21102 Vars.push_back(RefExpr);
21103 ValueDecl *D = Res.first;
21104 if (!D)
21105 continue;
21106
21107 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
21108 DSAStackTy::DSAVarData DVar;
21109 if (ParentDirective != OMPD_unknown)
21110 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
21111 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21112 // A list item that appears in the inclusive or exclusive clause must appear
21113 // in a reduction clause with the inscan modifier on the enclosing
21114 // worksharing-loop, worksharing-loop SIMD, or simd construct.
21115 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
21116 DVar.Modifier != OMPC_REDUCTION_inscan) {
21117 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21118 << RefExpr->getSourceRange();
21119 } else {
21120 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
21121 }
21122 Vars.push_back(RefExpr);
21123 }
21124
21125 if (Vars.empty())
21126 return nullptr;
21127
21128 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21129}
21130
21131/// Tries to find omp_alloctrait_t type.
21132static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
21133 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
21134 if (!OMPAlloctraitT.isNull())
21135 return true;
21136 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
21137 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
21138 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
21139 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
21140 return false;
21141 }
21142 Stack->setOMPAlloctraitT(PT.get());
21143 return true;
21144}
21145
21146OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
21147 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
21148 ArrayRef<UsesAllocatorsData> Data) {
21149 // OpenMP [2.12.5, target Construct]
21150 // allocator is an identifier of omp_allocator_handle_t type.
21151 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
21152 return nullptr;
21153 // OpenMP [2.12.5, target Construct]
21154 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
21155 if (llvm::any_of(
21156 Data,
21157 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
21158 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
21159 return nullptr;
21160 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
21161 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
21162 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
21163 StringRef Allocator =
21164 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
21165 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
21166 PredefinedAllocators.insert(LookupSingleName(
21167 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
21168 }
21169
21170 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
21171 for (const UsesAllocatorsData &D : Data) {
21172 Expr *AllocatorExpr = nullptr;
21173 // Check allocator expression.
21174 if (D.Allocator->isTypeDependent()) {
21175 AllocatorExpr = D.Allocator;
21176 } else {
21177 // Traits were specified - need to assign new allocator to the specified
21178 // allocator, so it must be an lvalue.
21179 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
21180 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
21181 bool IsPredefinedAllocator = false;
21182 if (DRE)
21183 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
21184 if (!DRE ||
21185 !(Context.hasSameUnqualifiedType(
21186 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
21187 Context.typesAreCompatible(AllocatorExpr->getType(),
21188 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
21189 /*CompareUnqualified=*/true)) ||
21190 (!IsPredefinedAllocator &&
21191 (AllocatorExpr->getType().isConstant(Context) ||
21192 !AllocatorExpr->isLValue()))) {
21193 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
21194 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
21195 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
21196 continue;
21197 }
21198 // OpenMP [2.12.5, target Construct]
21199 // Predefined allocators appearing in a uses_allocators clause cannot have
21200 // traits specified.
21201 if (IsPredefinedAllocator && D.AllocatorTraits) {
21202 Diag(D.AllocatorTraits->getExprLoc(),
21203 diag::err_omp_predefined_allocator_with_traits)
21204 << D.AllocatorTraits->getSourceRange();
21205 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
21206 << cast<NamedDecl>(DRE->getDecl())->getName()
21207 << D.Allocator->getSourceRange();
21208 continue;
21209 }
21210 // OpenMP [2.12.5, target Construct]
21211 // Non-predefined allocators appearing in a uses_allocators clause must
21212 // have traits specified.
21213 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
21214 Diag(D.Allocator->getExprLoc(),
21215 diag::err_omp_nonpredefined_allocator_without_traits);
21216 continue;
21217 }
21218 // No allocator traits - just convert it to rvalue.
21219 if (!D.AllocatorTraits)
21220 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
21221 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
21222 DRE->getDecl(),
21223 IsPredefinedAllocator
21224 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
21225 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
21226 }
21227 Expr *AllocatorTraitsExpr = nullptr;
21228 if (D.AllocatorTraits) {
21229 if (D.AllocatorTraits->isTypeDependent()) {
21230 AllocatorTraitsExpr = D.AllocatorTraits;
21231 } else {
21232 // OpenMP [2.12.5, target Construct]
21233 // Arrays that contain allocator traits that appear in a uses_allocators
21234 // clause must be constant arrays, have constant values and be defined
21235 // in the same scope as the construct in which the clause appears.
21236 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
21237 // Check that traits expr is a constant array.
21238 QualType TraitTy;
21239 if (const ArrayType *Ty =
21240 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
21241 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
21242 TraitTy = ConstArrayTy->getElementType();
21243 if (TraitTy.isNull() ||
21244 !(Context.hasSameUnqualifiedType(TraitTy,
21245 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
21246 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
21247 /*CompareUnqualified=*/true))) {
21248 Diag(D.AllocatorTraits->getExprLoc(),
21249 diag::err_omp_expected_array_alloctraits)
21250 << AllocatorTraitsExpr->getType();
21251 continue;
21252 }
21253 // Do not map by default allocator traits if it is a standalone
21254 // variable.
21255 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
21256 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
21257 DRE->getDecl(),
21258 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
21259 }
21260 }
21261 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
21262 NewD.Allocator = AllocatorExpr;
21263 NewD.AllocatorTraits = AllocatorTraitsExpr;
21264 NewD.LParenLoc = D.LParenLoc;
21265 NewD.RParenLoc = D.RParenLoc;
21266 }
21267 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
21268 NewData);
21269}
21270
21271OMPClause *Sema::ActOnOpenMPAffinityClause(
21272 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
21273 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
21274 SmallVector<Expr *, 8> Vars;
21275 for (Expr *RefExpr : Locators) {
21276 assert(RefExpr && "NULL expr in OpenMP shared clause.")(static_cast<void> (0));
21277 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
21278 // It will be analyzed later.
21279 Vars.push_back(RefExpr);
21280 continue;
21281 }
21282
21283 SourceLocation ELoc = RefExpr->getExprLoc();
21284 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
21285
21286 if (!SimpleExpr->isLValue()) {
21287 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21288 << 1 << 0 << RefExpr->getSourceRange();
21289 continue;
21290 }
21291
21292 ExprResult Res;
21293 {
21294 Sema::TentativeAnalysisScope Trap(*this);
21295 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
21296 }
21297 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21298 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21299 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21300 << 1 << 0 << RefExpr->getSourceRange();
21301 continue;
21302 }
21303 Vars.push_back(SimpleExpr);
21304 }
21305
21306 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
21307 EndLoc, Modifier, Vars);
21308}