Bug Summary

File:src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/lib/Sema/SemaOpenMP.cpp
Warning:line 1216, column 9
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -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 -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangSema/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libclangSema/obj/../include/clang/Sema -I /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libclangSema/../include -I /usr/src/gnu/usr.bin/clang/libclangSema/obj -I /usr/src/gnu/usr.bin/clang/libclangSema/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangSema/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/lib/Sema/SemaOpenMP.cpp

/usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/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")((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")((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.")((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 &&((void)0)
372 "cannot change stack while ignoring elements")((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 &&((void)0)
382 "cannot change stack while ignoring elements")((void)0);
383 assert(!Stack.back().first.empty() &&((void)0)
384 "Data-sharing attributes stack is empty!")((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()) &&((void)0)
417 "Expected loop-based directive.")((void)0);
418 getTopOfStack().LoopStart = true;
419 }
420 /// Start capturing of the variables in the loop context.
421 void loopStart() {
422 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((void)0)
423 "Expected loop-based directive.")((void)0);
424 getTopOfStack().LoopStart = false;
425 }
426 /// true, if variables are captured, false otherwise.
427 bool isLoopStarted() const {
428 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((void)0)
429 "Expected loop-based directive.")((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 &&((void)0)
444 "cannot change stack while ignoring elements")((void)0);
445 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
446 assert(!isa<CapturingScopeInfo>(CurFnScope))((void)0);
447 CurrentNonCapturingFunctionScope = CurFnScope;
448 }
449 /// Pop region stack for non-capturing function.
450 void popFunction(const FunctionScopeInfo *OldFSI) {
451 assert(!IgnoredStackElements &&((void)0)
452 "cannot change stack while ignoring elements")((void)0);
453 if (!Stack.empty() && Stack.back().second == OldFSI) {
454 assert(Stack.back().first.empty())((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 ||((void)0)
549 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((void)0)
550 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((void)0)
551 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((void)0)
552 "taskgroup reference expression requested for non taskgroup or "((void)0)
553 "parallel/worksharing directive.")((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.")((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())((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))((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(((void)0)
1031 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&((void)0)
1032 "Expected declare target link global.")((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()) &&((void)0)
1045 "Expected target executable directive.")((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)((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);
11
Assuming 'D' is not a 'VarDecl'
12
'VD' initialized to a null pointer value
1155 const auto *FD = dyn_cast<FieldDecl>(D);
13
Assuming 'D' is not a 'FieldDecl'
1156 DSAVarData DVar;
1157 if (Iter == end()) {
14
Calling 'operator==<const (anonymous namespace)::DSAStackTy::SharingMapTy *, const (anonymous namespace)::DSAStackTy::SharingMapTy *>'
17
Returning from 'operator==<const (anonymous namespace)::DSAStackTy::SharingMapTy *, const (anonymous namespace)::DSAStackTy::SharingMapTy *>'
18
Taking false branch
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
18.1
'VD' is null
18.1
'VD' is null
&& 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)) {
19
Assuming the condition is false
20
Taking false branch
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) {
21
Control jumps to 'case DSA_firstprivate:' at line 1215
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 &&
22
Called C++ object pointer is null
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")((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")((void)0);
1280 StackElem.AlignedMap[D] = NewDE;
1281 return nullptr;
1282 }
1283 assert(It->second && "Unexpected nullptr expr in the aligned map")((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")((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")((void)0);
1295 StackElem.NontemporalMap[D] = NewDE;
1296 return nullptr;
1297 }
1298 assert(It->second && "Unexpected nullptr expr in the aligned map")((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")((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")((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")((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")((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")((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) ||((void)0)
1369 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||((void)0)
1370 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||((void)0)
1371 (isLoopControlVariable(D).first && A == OMPC_private))((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")((void)0);
1430 assert(((void)0)
1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((void)0)
1432 "Additional reduction info may be specified only for reduction items.")((void)0);
1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434 assert(ReductionData.ReductionRange.isInvalid() &&((void)0)
1435 (getTopOfStack().Directive == OMPD_taskgroup ||((void)0)
1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((void)0)
1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((void)0)
1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((void)0)
1439 "Additional reduction info may be specified only once for reduction "((void)0)
1440 "items.")((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")((void)0);
1456 assert(((void)0)
1457 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((void)0)
1458 "Additional reduction info may be specified only for reduction items.")((void)0);
1459 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1460 assert(ReductionData.ReductionRange.isInvalid() &&((void)0)
1461 (getTopOfStack().Directive == OMPD_taskgroup ||((void)0)
1462 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((void)0)
1463 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((void)0)
1464 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((void)0)
1465 "Additional reduction info may be specified only once for reduction "((void)0)
1466 "items.")((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.")((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 "((void)0)
1495 "expression for the descriptor is not "((void)0)
1496 "set.")((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.")((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 "((void)0)
1522 "expression for the descriptor is not "((void)0)
1523 "set.")((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)
8
Assuming the condition is false
9
Taking false branch
1776 return DSAVarData();
1777 D = getCanonicalDecl(D);
1778 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1779 return getDSA(StartI, D);
10
Calling 'DSAStackTy::getDSA'
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 &&((void)0)
1886 "Expected OpenMP device compilation.")((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 &&((void)0)
1903 "Expected OpenMP device compilation.")((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 &&((void)0)
1941 "Expected OpenMP host compilation.")((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")((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!")((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)((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")((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")((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.")((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.")((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")((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")((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")((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")((void)0);
2440 // Return true if the current level is no longer enclosed in a target region.
2441
2442 if (const auto *VD
1.1
'VD' is non-null
1.1
'VD' is non-null
= dyn_cast<VarDecl>(D)) {
1
Assuming 'D' is a 'VarDecl'
2
Taking true branch
2443 if (!VD->hasLocalStorage()) {
3
Taking true branch
2444 if (isInOpenMPTargetExecutionDirective())
4
Taking false branch
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)
5
Assuming 'Level' is not equal to 0
6
Taking false branch
2451 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2452 do {
2453 --Level;
2454 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level)
;
7
Calling 'DSAStackTy::getImplicitDSA'
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() &&((void)0)
2472 "Not in OpenMP declare variant scope!")((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.")((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.")((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.")((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.")((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 &&((void)0)
3234 "Unexpected omp assumption directive!")((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!")((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")((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)((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() &&((void)0)
4512 "No captured regions in loop transformation directives.")((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() &&((void)0)
5073 "Expected non-dependent context.")((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) &&((void)0)
5299 "Expected one of these relational operators")((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 =
5324 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_PreInc, Range));
5325 }
5326
5327 // Divide by the absolute step amount.
5328 Expr *Divisor = BuildVarRef(NewStep);
5329 if (Rel == BO_GE || Rel == BO_GT)
5330 Divisor =
5331 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5332 Dist = AssertSuccess(
5333 Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
5334
5335 // If there is not at least one iteration, the range contains garbage. Fix
5336 // to zero in this case.
5337 Dist = AssertSuccess(
5338 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5339 }
5340
5341 // Assign the result to the out-parameter.
5342 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5343 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5344 BodyStmts.push_back(ResultAssign);
5345
5346 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5347 }
5348
5349 return cast<CapturedStmt>(
5350 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5351}
5352
5353/// Create a closure that computes the loop variable from the logical iteration
5354/// number.
5355///
5356/// \param Actions The Sema object.
5357/// \param LoopVarTy Type for the loop variable used for result value.
5358/// \param LogicalTy Type for the logical iteration number.
5359/// \param StartExpr Value of the loop counter at the first iteration.
5360/// \param Step Amount of increment after each iteration.
5361/// \param Deref Whether the loop variable is a dereference of the loop
5362/// counter variable.
5363///
5364/// \return Closure (CapturedStmt) of the loop value calculation.
5365static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5366 QualType LogicalTy,
5367 DeclRefExpr *StartExpr, Expr *Step,
5368 bool Deref) {
5369 ASTContext &Ctx = Actions.getASTContext();
5370
5371 // Pass the result as an out-parameter. Passing as return value would require
5372 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5373 // invoke a copy constructor.
5374 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5375 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5376 {"Logical", LogicalTy},
5377 {StringRef(), QualType()}};
5378 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5379
5380 // Capture the initial iterator which represents the LoopVar value at the
5381 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5382 // it in every iteration, capture it by value before it is modified.
5383 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5384 bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5385 Sema::TryCapture_ExplicitByVal, {});
5386 (void)Invalid;
5387 assert(!Invalid && "Expecting capture-by-value to work.")((void)0);
5388
5389 Expr *Body;
5390 {
5391 Sema::CompoundScopeRAII CompoundScope(Actions);
5392 auto *CS = cast<CapturedDecl>(Actions.CurContext);
5393
5394 ImplicitParamDecl *TargetParam = CS->getParam(0);
5395 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5396 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5397 ImplicitParamDecl *IndvarParam = CS->getParam(1);
5398 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5399 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5400
5401 // Capture the Start expression.
5402 CaptureVars Recap(Actions);
5403 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5404 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5405
5406 Expr *Skip = AssertSuccess(
5407 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5408 // TODO: Explicitly cast to the iterator's difference_type instead of
5409 // relying on implicit conversion.
5410 Expr *Advanced =
5411 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5412
5413 if (Deref) {
5414 // For range-based for-loops convert the loop counter value to a concrete
5415 // loop variable value by dereferencing the iterator.
5416 Advanced =
5417 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5418 }
5419
5420 // Assign the result to the output parameter.
5421 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5422 BO_Assign, TargetRef, Advanced));
5423 }
5424 return cast<CapturedStmt>(
5425 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5426}
5427
5428StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5429 ASTContext &Ctx = getASTContext();
5430
5431 // Extract the common elements of ForStmt and CXXForRangeStmt:
5432 // Loop variable, repeat condition, increment
5433 Expr *Cond, *Inc;
5434 VarDecl *LIVDecl, *LUVDecl;
5435 if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5436 Stmt *Init = For->getInit();
5437 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5438 // For statement declares loop variable.
5439 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5440 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5441 // For statement reuses variable.
5442 assert(LCAssign->getOpcode() == BO_Assign &&((void)0)
5443 "init part must be a loop variable assignment")((void)0);
5444 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5445 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5446 } else
5447 llvm_unreachable("Cannot determine loop variable")__builtin_unreachable();
5448 LUVDecl = LIVDecl;
5449
5450 Cond = For->getCond();
5451 Inc = For->getInc();
5452 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5453 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5454 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5455 LUVDecl = RangeFor->getLoopVariable();
5456
5457 Cond = RangeFor->getCond();
5458 Inc = RangeFor->getInc();
5459 } else
5460 llvm_unreachable("unhandled kind of loop")__builtin_unreachable();
5461
5462 QualType CounterTy = LIVDecl->getType();
5463 QualType LVTy = LUVDecl->getType();
5464
5465 // Analyze the loop condition.
5466 Expr *LHS, *RHS;
5467 BinaryOperator::Opcode CondRel;
5468 Cond = Cond->IgnoreImplicit();
5469 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5470 LHS = CondBinExpr->getLHS();
5471 RHS = CondBinExpr->getRHS();
5472 CondRel = CondBinExpr->getOpcode();
5473 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5474 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands")((void)0);
5475 LHS = CondCXXOp->getArg(0);
5476 RHS = CondCXXOp->getArg(1);
5477 switch (CondCXXOp->getOperator()) {
5478 case OO_ExclaimEqual:
5479 CondRel = BO_NE;
5480 break;
5481 case OO_Less:
5482 CondRel = BO_LT;
5483 break;
5484 case OO_LessEqual:
5485 CondRel = BO_LE;
5486 break;
5487 case OO_Greater:
5488 CondRel = BO_GT;
5489 break;
5490 case OO_GreaterEqual:
5491 CondRel = BO_GE;
5492 break;
5493 default:
5494 llvm_unreachable("unexpected iterator operator")__builtin_unreachable();
5495 }
5496 } else
5497 llvm_unreachable("unexpected loop condition")__builtin_unreachable();
5498
5499 // Normalize such that the loop counter is on the LHS.
5500 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5501 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5502 std::swap(LHS, RHS);
5503 CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5504 }
5505 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5506
5507 // Decide the bit width for the logical iteration counter. By default use the
5508 // unsigned ptrdiff_t integer size (for iterators and pointers).
5509 // TODO: For iterators, use iterator::difference_type,
5510 // std::iterator_traits<>::difference_type or decltype(it - end).
5511 QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5512 if (CounterTy->isIntegerType()) {
5513 unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5514 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5515 }
5516
5517 // Analyze the loop increment.
5518 Expr *Step;
5519 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5520 int Direction;
5521 switch (IncUn->getOpcode()) {
5522 case UO_PreInc:
5523 case UO_PostInc:
5524 Direction = 1;
5525 break;
5526 case UO_PreDec:
5527 case UO_PostDec:
5528 Direction = -1;
5529 break;
5530 default:
5531 llvm_unreachable("unhandled unary increment operator")__builtin_unreachable();
5532 }
5533 Step = IntegerLiteral::Create(
5534 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5535 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5536 if (IncBin->getOpcode() == BO_AddAssign) {
5537 Step = IncBin->getRHS();
5538 } else if (IncBin->getOpcode() == BO_SubAssign) {
5539 Step =
5540 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5541 } else
5542 llvm_unreachable("unhandled binary increment operator")__builtin_unreachable();
5543 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5544 switch (CondCXXOp->getOperator()) {
5545 case OO_PlusPlus:
5546 Step = IntegerLiteral::Create(
5547 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5548 break;
5549 case OO_MinusMinus:
5550 Step = IntegerLiteral::Create(
5551 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5552 break;
5553 case OO_PlusEqual:
5554 Step = CondCXXOp->getArg(1);
5555 break;
5556 case OO_MinusEqual:
5557 Step = AssertSuccess(
5558 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5559 break;
5560 default:
5561 llvm_unreachable("unhandled overloaded increment operator")__builtin_unreachable();
5562 }
5563 } else
5564 llvm_unreachable("unknown increment expression")__builtin_unreachable();
5565
5566 CapturedStmt *DistanceFunc =
5567 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5568 CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5569 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5570 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5571 {}, nullptr, nullptr, {}, nullptr);
5572 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5573 LoopVarFunc, LVRef);
5574}
5575
5576static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5577 CXXScopeSpec &MapperIdScopeSpec,
5578 const DeclarationNameInfo &MapperId,
5579 QualType Type,
5580 Expr *UnresolvedMapper);
5581
5582/// Perform DFS through the structure/class data members trying to find
5583/// member(s) with user-defined 'default' mapper and generate implicit map
5584/// clauses for such members with the found 'default' mapper.
5585static void
5586processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5587 SmallVectorImpl<OMPClause *> &Clauses) {
5588 // Check for the deault mapper for data members.
5589 if (S.getLangOpts().OpenMP < 50)
5590 return;
5591 SmallVector<OMPClause *, 4> ImplicitMaps;
5592 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5593 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5594 if (!C)
5595 continue;
5596 SmallVector<Expr *, 4> SubExprs;
5597 auto *MI = C->mapperlist_begin();
5598 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5599 ++I, ++MI) {
5600 // Expression is mapped using mapper - skip it.
5601 if (*MI)
5602 continue;
5603 Expr *E = *I;
5604 // Expression is dependent - skip it, build the mapper when it gets
5605 // instantiated.
5606 if (E->isTypeDependent() || E->isValueDependent() ||
5607 E->containsUnexpandedParameterPack())
5608 continue;
5609 // Array section - need to check for the mapping of the array section
5610 // element.
5611 QualType CanonType = E->getType().getCanonicalType();
5612 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5613 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5614 QualType BaseType =
5615 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5616 QualType ElemType;
5617 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5618 ElemType = ATy->getElementType();
5619 else
5620 ElemType = BaseType->getPointeeType();
5621 CanonType = ElemType;
5622 }
5623
5624 // DFS over data members in structures/classes.
5625 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5626 1, {CanonType, nullptr});
5627 llvm::DenseMap<const Type *, Expr *> Visited;
5628 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5629 1, {nullptr, 1});
5630 while (!Types.empty()) {
5631 QualType BaseType;
5632 FieldDecl *CurFD;
5633 std::tie(BaseType, CurFD) = Types.pop_back_val();
5634 while (ParentChain.back().second == 0)
5635 ParentChain.pop_back();
5636 --ParentChain.back().second;
5637 if (BaseType.isNull())
5638 continue;
5639 // Only structs/classes are allowed to have mappers.
5640 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5641 if (!RD)
5642 continue;
5643 auto It = Visited.find(BaseType.getTypePtr());
5644 if (It == Visited.end()) {
5645 // Try to find the associated user-defined mapper.
5646 CXXScopeSpec MapperIdScopeSpec;
5647 DeclarationNameInfo DefaultMapperId;
5648 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5649 &S.Context.Idents.get("default")));
5650 DefaultMapperId.setLoc(E->getExprLoc());
5651 ExprResult ER = buildUserDefinedMapperRef(
5652 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5653 BaseType, /*UnresolvedMapper=*/nullptr);
5654 if (ER.isInvalid())
5655 continue;
5656 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5657 }
5658 // Found default mapper.
5659 if (It->second) {
5660 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5661 VK_LValue, OK_Ordinary, E);
5662 OE->setIsUnique(/*V=*/true);
5663 Expr *BaseExpr = OE;
5664 for (const auto &P : ParentChain) {
5665 if (P.first) {
5666 BaseExpr = S.BuildMemberExpr(
5667 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5668 NestedNameSpecifierLoc(), SourceLocation(), P.first,
5669 DeclAccessPair::make(P.first, P.first->getAccess()),
5670 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5671 P.first->getType(), VK_LValue, OK_Ordinary);
5672 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5673 }
5674 }
5675 if (CurFD)
5676 BaseExpr = S.BuildMemberExpr(
5677 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5678 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5679 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5680 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5681 CurFD->getType(), VK_LValue, OK_Ordinary);
5682 SubExprs.push_back(BaseExpr);
5683 continue;
5684 }
5685 // Check for the "default" mapper for data memebers.
5686 bool FirstIter = true;
5687 for (FieldDecl *FD : RD->fields()) {
5688 if (!FD)
5689 continue;
5690 QualType FieldTy = FD->getType();
5691 if (FieldTy.isNull() ||
5692 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5693 continue;
5694 if (FirstIter) {
5695 FirstIter = false;
5696 ParentChain.emplace_back(CurFD, 1);
5697 } else {
5698 ++ParentChain.back().second;
5699 }
5700 Types.emplace_back(FieldTy, FD);
5701 }
5702 }
5703 }
5704 if (SubExprs.empty())
5705 continue;
5706 CXXScopeSpec MapperIdScopeSpec;
5707 DeclarationNameInfo MapperId;
5708 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5709 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5710 MapperIdScopeSpec, MapperId, C->getMapType(),
5711 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5712 SubExprs, OMPVarListLocTy()))
5713 Clauses.push_back(NewClause);
5714 }
5715}
5716
5717StmtResult Sema::ActOnOpenMPExecutableDirective(
5718 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5719 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5720 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5721 StmtResult Res = StmtError();
5722 // First check CancelRegion which is then used in checkNestingOfRegions.
5723 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5724 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5725 StartLoc))
5726 return StmtError();
5727
5728 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5729 VarsWithInheritedDSAType VarsWithInheritedDSA;
5730 bool ErrorFound = false;
5731 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5732 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5733 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5734 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5735 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
5736
5737 // Check default data sharing attributes for referenced variables.
5738 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5739 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5740 Stmt *S = AStmt;
5741 while (--ThisCaptureLevel >= 0)
5742 S = cast<CapturedStmt>(S)->getCapturedStmt();
5743 DSAChecker.Visit(S);
5744 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5745 !isOpenMPTaskingDirective(Kind)) {
5746 // Visit subcaptures to generate implicit clauses for captured vars.
5747 auto *CS = cast<CapturedStmt>(AStmt);
5748 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5749 getOpenMPCaptureRegions(CaptureRegions, Kind);
5750 // Ignore outer tasking regions for target directives.
5751 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5752 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5753 DSAChecker.visitSubCaptures(CS);
5754 }
5755 if (DSAChecker.isErrorFound())
5756 return StmtError();
5757 // Generate list of implicitly defined firstprivate variables.
5758 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5759
5760 SmallVector<Expr *, 4> ImplicitFirstprivates(
5761 DSAChecker.getImplicitFirstprivate().begin(),
5762 DSAChecker.getImplicitFirstprivate().end());
5763 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5764 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5765 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5766 ImplicitMapModifiers[DefaultmapKindNum];
5767 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5768 ImplicitMapModifiersLoc[DefaultmapKindNum];
5769 // Get the original location of present modifier from Defaultmap clause.
5770 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5771 for (OMPClause *C : Clauses) {
5772 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5773 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5774 PresentModifierLocs[DMC->getDefaultmapKind()] =
5775 DMC->getDefaultmapModifierLoc();
5776 }
5777 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5778 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5779 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5780 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5781 Kind, static_cast<OpenMPMapClauseKind>(I));
5782 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5783 }
5784 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5785 DSAChecker.getImplicitMapModifier(Kind);
5786 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5787 ImplicitModifier.end());
5788 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5789 ImplicitModifier.size(), PresentModifierLocs[VC]);
5790 }
5791 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5792 for (OMPClause *C : Clauses) {
5793 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5794 for (Expr *E : IRC->taskgroup_descriptors())
5795 if (E)
5796 ImplicitFirstprivates.emplace_back(E);
5797 }
5798 // OpenMP 5.0, 2.10.1 task Construct
5799 // [detach clause]... The event-handle will be considered as if it was
5800 // specified on a firstprivate clause.
5801 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5802 ImplicitFirstprivates.push_back(DC->getEventHandler());
5803 }
5804 if (!ImplicitFirstprivates.empty()) {
5805 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5806 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5807 SourceLocation())) {
5808 ClausesWithImplicit.push_back(Implicit);
5809 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5810 ImplicitFirstprivates.size();
5811 } else {
5812 ErrorFound = true;
5813 }
5814 }
5815 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5816 int ClauseKindCnt = -1;
5817 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5818 ++ClauseKindCnt;
5819 if (ImplicitMap.empty())
5820 continue;
5821 CXXScopeSpec MapperIdScopeSpec;
5822 DeclarationNameInfo MapperId;
5823 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5824 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5825 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5826 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5827 SourceLocation(), SourceLocation(), ImplicitMap,
5828 OMPVarListLocTy())) {
5829 ClausesWithImplicit.emplace_back(Implicit);
5830 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5831 ImplicitMap.size();
5832 } else {
5833 ErrorFound = true;
5834 }
5835 }
5836 }
5837 // Build expressions for implicit maps of data members with 'default'
5838 // mappers.
5839 if (LangOpts.OpenMP >= 50)
5840 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5841 ClausesWithImplicit);
5842 }
5843
5844 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5845 switch (Kind) {
5846 case OMPD_parallel:
5847 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5848 EndLoc);
5849 AllowedNameModifiers.push_back(OMPD_parallel);
5850 break;
5851 case OMPD_simd:
5852 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5853 VarsWithInheritedDSA);
5854 if (LangOpts.OpenMP >= 50)
5855 AllowedNameModifiers.push_back(OMPD_simd);
5856 break;
5857 case OMPD_tile:
5858 Res =
5859 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5860 break;
5861 case OMPD_unroll:
5862 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
5863 EndLoc);
5864 break;
5865 case OMPD_for:
5866 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5867 VarsWithInheritedDSA);
5868 break;
5869 case OMPD_for_simd:
5870 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5871 EndLoc, VarsWithInheritedDSA);
5872 if (LangOpts.OpenMP >= 50)
5873 AllowedNameModifiers.push_back(OMPD_simd);
5874 break;
5875 case OMPD_sections:
5876 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5877 EndLoc);
5878 break;
5879 case OMPD_section:
5880 assert(ClausesWithImplicit.empty() &&((void)0)
5881 "No clauses are allowed for 'omp section' directive")((void)0);
5882 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5883 break;
5884 case OMPD_single:
5885 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5886 EndLoc);
5887 break;
5888 case OMPD_master:
5889 assert(ClausesWithImplicit.empty() &&((void)0)
5890 "No clauses are allowed for 'omp master' directive")((void)0);
5891 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5892 break;
5893 case OMPD_masked:
5894 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
5895 EndLoc);
5896 break;
5897 case OMPD_critical:
5898 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5899 StartLoc, EndLoc);
5900 break;
5901 case OMPD_parallel_for:
5902 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5903 EndLoc, VarsWithInheritedDSA);
5904 AllowedNameModifiers.push_back(OMPD_parallel);
5905 break;
5906 case OMPD_parallel_for_simd:
5907 Res = ActOnOpenMPParallelForSimdDirective(
5908 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5909 AllowedNameModifiers.push_back(OMPD_parallel);
5910 if (LangOpts.OpenMP >= 50)
5911 AllowedNameModifiers.push_back(OMPD_simd);
5912 break;
5913 case OMPD_parallel_master:
5914 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5915 StartLoc, EndLoc);
5916 AllowedNameModifiers.push_back(OMPD_parallel);
5917 break;
5918 case OMPD_parallel_sections:
5919 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5920 StartLoc, EndLoc);
5921 AllowedNameModifiers.push_back(OMPD_parallel);
5922 break;
5923 case OMPD_task:
5924 Res =
5925 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5926 AllowedNameModifiers.push_back(OMPD_task);
5927 break;
5928 case OMPD_taskyield:
5929 assert(ClausesWithImplicit.empty() &&((void)0)
5930 "No clauses are allowed for 'omp taskyield' directive")((void)0);
5931 assert(AStmt == nullptr &&((void)0)
5932 "No associated statement allowed for 'omp taskyield' directive")((void)0);
5933 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5934 break;
5935 case OMPD_barrier:
5936 assert(ClausesWithImplicit.empty() &&((void)0)
5937 "No clauses are allowed for 'omp barrier' directive")((void)0);
5938 assert(AStmt == nullptr &&((void)0)
5939 "No associated statement allowed for 'omp barrier' directive")((void)0);
5940 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5941 break;
5942 case OMPD_taskwait:
5943 assert(ClausesWithImplicit.empty() &&((void)0)
5944 "No clauses are allowed for 'omp taskwait' directive")((void)0);
5945 assert(AStmt == nullptr &&((void)0)
5946 "No associated statement allowed for 'omp taskwait' directive")((void)0);
5947 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5948 break;
5949 case OMPD_taskgroup:
5950 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5951 EndLoc);
5952 break;
5953 case OMPD_flush:
5954 assert(AStmt == nullptr &&((void)0)
5955 "No associated statement allowed for 'omp flush' directive")((void)0);
5956 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5957 break;
5958 case OMPD_depobj:
5959 assert(AStmt == nullptr &&((void)0)
5960 "No associated statement allowed for 'omp depobj' directive")((void)0);
5961 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5962 break;
5963 case OMPD_scan:
5964 assert(AStmt == nullptr &&((void)0)
5965 "No associated statement allowed for 'omp scan' directive")((void)0);
5966 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5967 break;
5968 case OMPD_ordered:
5969 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5970 EndLoc);
5971 break;
5972 case OMPD_atomic:
5973 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5974 EndLoc);
5975 break;
5976 case OMPD_teams:
5977 Res =
5978 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5979 break;
5980 case OMPD_target:
5981 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5982 EndLoc);
5983 AllowedNameModifiers.push_back(OMPD_target);
5984 break;
5985 case OMPD_target_parallel:
5986 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5987 StartLoc, EndLoc);
5988 AllowedNameModifiers.push_back(OMPD_target);
5989 AllowedNameModifiers.push_back(OMPD_parallel);
5990 break;
5991 case OMPD_target_parallel_for:
5992 Res = ActOnOpenMPTargetParallelForDirective(
5993 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5994 AllowedNameModifiers.push_back(OMPD_target);
5995 AllowedNameModifiers.push_back(OMPD_parallel);
5996 break;
5997 case OMPD_cancellation_point:
5998 assert(ClausesWithImplicit.empty() &&((void)0)
5999 "No clauses are allowed for 'omp cancellation point' directive")((void)0);
6000 assert(AStmt == nullptr && "No associated statement allowed for 'omp "((void)0)
6001 "cancellation point' directive")((void)0);
6002 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6003 break;
6004 case OMPD_cancel:
6005 assert(AStmt == nullptr &&((void)0)
6006 "No associated statement allowed for 'omp cancel' directive")((void)0);
6007 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6008 CancelRegion);
6009 AllowedNameModifiers.push_back(OMPD_cancel);
6010 break;
6011 case OMPD_target_data:
6012 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6013 EndLoc);
6014 AllowedNameModifiers.push_back(OMPD_target_data);
6015 break;
6016 case OMPD_target_enter_data:
6017 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6018 EndLoc, AStmt);
6019 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6020 break;
6021 case OMPD_target_exit_data:
6022 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6023 EndLoc, AStmt);
6024 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6025 break;
6026 case OMPD_taskloop:
6027 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6028 EndLoc, VarsWithInheritedDSA);
6029 AllowedNameModifiers.push_back(OMPD_taskloop);
6030 break;
6031 case OMPD_taskloop_simd:
6032 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6033 EndLoc, VarsWithInheritedDSA);
6034 AllowedNameModifiers.push_back(OMPD_taskloop);
6035 if (LangOpts.OpenMP >= 50)
6036 AllowedNameModifiers.push_back(OMPD_simd);
6037 break;
6038 case OMPD_master_taskloop:
6039 Res = ActOnOpenMPMasterTaskLoopDirective(
6040 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6041 AllowedNameModifiers.push_back(OMPD_taskloop);
6042 break;
6043 case OMPD_master_taskloop_simd:
6044 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6045 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6046 AllowedNameModifiers.push_back(OMPD_taskloop);
6047 if (LangOpts.OpenMP >= 50)
6048 AllowedNameModifiers.push_back(OMPD_simd);
6049 break;
6050 case OMPD_parallel_master_taskloop:
6051 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6052 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6053 AllowedNameModifiers.push_back(OMPD_taskloop);
6054 AllowedNameModifiers.push_back(OMPD_parallel);
6055 break;
6056 case OMPD_parallel_master_taskloop_simd:
6057 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6058 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6059 AllowedNameModifiers.push_back(OMPD_taskloop);
6060 AllowedNameModifiers.push_back(OMPD_parallel);
6061 if (LangOpts.OpenMP >= 50)
6062 AllowedNameModifiers.push_back(OMPD_simd);
6063 break;
6064 case OMPD_distribute:
6065 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6066 EndLoc, VarsWithInheritedDSA);
6067 break;
6068 case OMPD_target_update:
6069 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6070 EndLoc, AStmt);
6071 AllowedNameModifiers.push_back(OMPD_target_update);
6072 break;
6073 case OMPD_distribute_parallel_for:
6074 Res = ActOnOpenMPDistributeParallelForDirective(
6075 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6076 AllowedNameModifiers.push_back(OMPD_parallel);
6077 break;
6078 case OMPD_distribute_parallel_for_simd:
6079 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6080 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6081 AllowedNameModifiers.push_back(OMPD_parallel);
6082 if (LangOpts.OpenMP >= 50)
6083 AllowedNameModifiers.push_back(OMPD_simd);
6084 break;
6085 case OMPD_distribute_simd:
6086 Res = ActOnOpenMPDistributeSimdDirective(
6087 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6088 if (LangOpts.OpenMP >= 50)
6089 AllowedNameModifiers.push_back(OMPD_simd);
6090 break;
6091 case OMPD_target_parallel_for_simd:
6092 Res = ActOnOpenMPTargetParallelForSimdDirective(
6093 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6094 AllowedNameModifiers.push_back(OMPD_target);
6095 AllowedNameModifiers.push_back(OMPD_parallel);
6096 if (LangOpts.OpenMP >= 50)
6097 AllowedNameModifiers.push_back(OMPD_simd);
6098 break;
6099 case OMPD_target_simd:
6100 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6101 EndLoc, VarsWithInheritedDSA);
6102 AllowedNameModifiers.push_back(OMPD_target);
6103 if (LangOpts.OpenMP >= 50)
6104 AllowedNameModifiers.push_back(OMPD_simd);
6105 break;
6106 case OMPD_teams_distribute:
6107 Res = ActOnOpenMPTeamsDistributeDirective(
6108 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6109 break;
6110 case OMPD_teams_distribute_simd:
6111 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6112 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6113 if (LangOpts.OpenMP >= 50)
6114 AllowedNameModifiers.push_back(OMPD_simd);
6115 break;
6116 case OMPD_teams_distribute_parallel_for_simd:
6117 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6118 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6119 AllowedNameModifiers.push_back(OMPD_parallel);
6120 if (LangOpts.OpenMP >= 50)
6121 AllowedNameModifiers.push_back(OMPD_simd);
6122 break;
6123 case OMPD_teams_distribute_parallel_for:
6124 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6125 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6126 AllowedNameModifiers.push_back(OMPD_parallel);
6127 break;
6128 case OMPD_target_teams:
6129 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6130 EndLoc);
6131 AllowedNameModifiers.push_back(OMPD_target);
6132 break;
6133 case OMPD_target_teams_distribute:
6134 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6135 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6136 AllowedNameModifiers.push_back(OMPD_target);
6137 break;
6138 case OMPD_target_teams_distribute_parallel_for:
6139 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6140 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6141 AllowedNameModifiers.push_back(OMPD_target);
6142 AllowedNameModifiers.push_back(OMPD_parallel);
6143 break;
6144 case OMPD_target_teams_distribute_parallel_for_simd:
6145 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6146 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6147 AllowedNameModifiers.push_back(OMPD_target);
6148 AllowedNameModifiers.push_back(OMPD_parallel);
6149 if (LangOpts.OpenMP >= 50)
6150 AllowedNameModifiers.push_back(OMPD_simd);
6151 break;
6152 case OMPD_target_teams_distribute_simd:
6153 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6154 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6155 AllowedNameModifiers.push_back(OMPD_target);
6156 if (LangOpts.OpenMP >= 50)
6157 AllowedNameModifiers.push_back(OMPD_simd);
6158 break;
6159 case OMPD_interop:
6160 assert(AStmt == nullptr &&((void)0)
6161 "No associated statement allowed for 'omp interop' directive")((void)0);
6162 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6163 break;
6164 case OMPD_dispatch:
6165 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6166 EndLoc);
6167 break;
6168 case OMPD_declare_target:
6169 case OMPD_end_declare_target:
6170 case OMPD_threadprivate:
6171 case OMPD_allocate:
6172 case OMPD_declare_reduction:
6173 case OMPD_declare_mapper:
6174 case OMPD_declare_simd:
6175 case OMPD_requires:
6176 case OMPD_declare_variant:
6177 case OMPD_begin_declare_variant:
6178 case OMPD_end_declare_variant:
6179 llvm_unreachable("OpenMP Directive is not allowed")__builtin_unreachable();
6180 case OMPD_unknown:
6181 default:
6182 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
6183 }
6184
6185 ErrorFound = Res.isInvalid() || ErrorFound;
6186
6187 // Check variables in the clauses if default(none) or
6188 // default(firstprivate) was specified.
6189 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6190 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6191 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
6192 for (OMPClause *C : Clauses) {
6193 switch (C->getClauseKind()) {
6194 case OMPC_num_threads:
6195 case OMPC_dist_schedule:
6196 // Do not analyse if no parent teams directive.
6197 if (isOpenMPTeamsDirective(Kind))
6198 break;
6199 continue;
6200 case OMPC_if:
6201 if (isOpenMPTeamsDirective(Kind) &&
6202 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6203 break;
6204 if (isOpenMPParallelDirective(Kind) &&
6205 isOpenMPTaskLoopDirective(Kind) &&
6206 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6207 break;
6208 continue;
6209 case OMPC_schedule:
6210 case OMPC_detach:
6211 break;
6212 case OMPC_grainsize:
6213 case OMPC_num_tasks:
6214 case OMPC_final:
6215 case OMPC_priority:
6216 case OMPC_novariants:
6217 case OMPC_nocontext:
6218 // Do not analyze if no parent parallel directive.
6219 if (isOpenMPParallelDirective(Kind))
6220 break;
6221 continue;
6222 case OMPC_ordered:
6223 case OMPC_device:
6224 case OMPC_num_teams:
6225 case OMPC_thread_limit:
6226 case OMPC_hint:
6227 case OMPC_collapse:
6228 case OMPC_safelen:
6229 case OMPC_simdlen:
6230 case OMPC_sizes:
6231 case OMPC_default:
6232 case OMPC_proc_bind:
6233 case OMPC_private:
6234 case OMPC_firstprivate:
6235 case OMPC_lastprivate:
6236 case OMPC_shared:
6237 case OMPC_reduction:
6238 case OMPC_task_reduction:
6239 case OMPC_in_reduction:
6240 case OMPC_linear:
6241 case OMPC_aligned:
6242 case OMPC_copyin:
6243 case OMPC_copyprivate:
6244 case OMPC_nowait:
6245 case OMPC_untied:
6246 case OMPC_mergeable:
6247 case OMPC_allocate:
6248 case OMPC_read:
6249 case OMPC_write:
6250 case OMPC_update:
6251 case OMPC_capture:
6252 case OMPC_seq_cst:
6253 case OMPC_acq_rel:
6254 case OMPC_acquire:
6255 case OMPC_release:
6256 case OMPC_relaxed:
6257 case OMPC_depend:
6258 case OMPC_threads:
6259 case OMPC_simd:
6260 case OMPC_map:
6261 case OMPC_nogroup:
6262 case OMPC_defaultmap:
6263 case OMPC_to:
6264 case OMPC_from:
6265 case OMPC_use_device_ptr:
6266 case OMPC_use_device_addr:
6267 case OMPC_is_device_ptr:
6268 case OMPC_nontemporal:
6269 case OMPC_order:
6270 case OMPC_destroy:
6271 case OMPC_inclusive:
6272 case OMPC_exclusive:
6273 case OMPC_uses_allocators:
6274 case OMPC_affinity:
6275 continue;
6276 case OMPC_allocator:
6277 case OMPC_flush:
6278 case OMPC_depobj:
6279 case OMPC_threadprivate:
6280 case OMPC_uniform:
6281 case OMPC_unknown:
6282 case OMPC_unified_address:
6283 case OMPC_unified_shared_memory:
6284 case OMPC_reverse_offload:
6285 case OMPC_dynamic_allocators:
6286 case OMPC_atomic_default_mem_order:
6287 case OMPC_device_type:
6288 case OMPC_match:
6289 default:
6290 llvm_unreachable("Unexpected clause")__builtin_unreachable();
6291 }
6292 for (Stmt *CC : C->children()) {
6293 if (CC)
6294 DSAChecker.Visit(CC);
6295 }
6296 }
6297 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6298 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6299 }
6300 for (const auto &P : VarsWithInheritedDSA) {
6301 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6302 continue;
6303 ErrorFound = true;
6304 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6305 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6306 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6307 << P.first << P.second->getSourceRange();
6308 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6309 } else if (getLangOpts().OpenMP >= 50) {
6310 Diag(P.second->getExprLoc(),
6311 diag::err_omp_defaultmap_no_attr_for_variable)
6312 << P.first << P.second->getSourceRange();
6313 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
6314 diag::note_omp_defaultmap_attr_none);
6315 }
6316 }
6317
6318 if (!AllowedNameModifiers.empty())
6319 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6320 ErrorFound;
6321
6322 if (ErrorFound)
6323 return StmtError();
6324
6325 if (!CurContext->isDependentContext() &&
6326 isOpenMPTargetExecutionDirective(Kind) &&
6327 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6328 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6329 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6330 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6331 // Register target to DSA Stack.
6332 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
6333 }
6334
6335 return Res;
6336}
6337
6338Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6339 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6340 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6341 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6342 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6343 assert(Aligneds.size() == Alignments.size())((void)0);
6344 assert(Linears.size() == LinModifiers.size())((void)0);
6345 assert(Linears.size() == Steps.size())((void)0);
6346 if (!DG || DG.get().isNull())
6347 return DeclGroupPtrTy();
6348
6349 const int SimdId = 0;
6350 if (!DG.get().isSingleDecl()) {
6351 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6352 << SimdId;
6353 return DG;
6354 }
6355 Decl *ADecl = DG.get().getSingleDecl();
6356 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6357 ADecl = FTD->getTemplatedDecl();
6358
6359 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6360 if (!FD) {
6361 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6362 return DeclGroupPtrTy();
6363 }
6364
6365 // OpenMP [2.8.2, declare simd construct, Description]
6366 // The parameter of the simdlen clause must be a constant positive integer
6367 // expression.
6368 ExprResult SL;
6369 if (Simdlen)
6370 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6371 // OpenMP [2.8.2, declare simd construct, Description]
6372 // The special this pointer can be used as if was one of the arguments to the
6373 // function in any of the linear, aligned, or uniform clauses.
6374 // The uniform clause declares one or more arguments to have an invariant
6375 // value for all concurrent invocations of the function in the execution of a
6376 // single SIMD loop.
6377 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6378 const Expr *UniformedLinearThis = nullptr;
6379 for (const Expr *E : Uniforms) {
6380 E = E->IgnoreParenImpCasts();
6381 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6382 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6383 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6384 FD->getParamDecl(PVD->getFunctionScopeIndex())
6385 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6386 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6387 continue;
6388 }
6389 if (isa<CXXThisExpr>(E)) {
6390 UniformedLinearThis = E;
6391 continue;
6392 }
6393 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6394 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6395 }
6396 // OpenMP [2.8.2, declare simd construct, Description]
6397 // The aligned clause declares that the object to which each list item points
6398 // is aligned to the number of bytes expressed in the optional parameter of
6399 // the aligned clause.
6400 // The special this pointer can be used as if was one of the arguments to the
6401 // function in any of the linear, aligned, or uniform clauses.
6402 // The type of list items appearing in the aligned clause must be array,
6403 // pointer, reference to array, or reference to pointer.
6404 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6405 const Expr *AlignedThis = nullptr;
6406 for (const Expr *E : Aligneds) {
6407 E = E->IgnoreParenImpCasts();
6408 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6409 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6410 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6411 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6412 FD->getParamDecl(PVD->getFunctionScopeIndex())
6413 ->getCanonicalDecl() == CanonPVD) {
6414 // OpenMP [2.8.1, simd construct, Restrictions]
6415 // A list-item cannot appear in more than one aligned clause.
6416 if (AlignedArgs.count(CanonPVD) > 0) {
6417 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6418 << 1 << getOpenMPClauseName(OMPC_aligned)
6419 << E->getSourceRange();
6420 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6421 diag::note_omp_explicit_dsa)
6422 << getOpenMPClauseName(OMPC_aligned);
6423 continue;
6424 }
6425 AlignedArgs[CanonPVD] = E;
6426 QualType QTy = PVD->getType()
6427 .getNonReferenceType()
6428 .getUnqualifiedType()
6429 .getCanonicalType();
6430 const Type *Ty = QTy.getTypePtrOrNull();
6431 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6432 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6433 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6434 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6435 }
6436 continue;
6437 }
6438 }
6439 if (isa<CXXThisExpr>(E)) {
6440 if (AlignedThis) {
6441 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6442 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6443 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6444 << getOpenMPClauseName(OMPC_aligned);
6445 }
6446 AlignedThis = E;
6447 continue;
6448 }
6449 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6450 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6451 }
6452 // The optional parameter of the aligned clause, alignment, must be a constant
6453 // positive integer expression. If no optional parameter is specified,
6454 // implementation-defined default alignments for SIMD instructions on the
6455 // target platforms are assumed.
6456 SmallVector<const Expr *, 4> NewAligns;
6457 for (Expr *E : Alignments) {
6458 ExprResult Align;
6459 if (E)
6460 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6461 NewAligns.push_back(Align.get());
6462 }
6463 // OpenMP [2.8.2, declare simd construct, Description]
6464 // The linear clause declares one or more list items to be private to a SIMD
6465 // lane and to have a linear relationship with respect to the iteration space
6466 // of a loop.
6467 // The special this pointer can be used as if was one of the arguments to the
6468 // function in any of the linear, aligned, or uniform clauses.
6469 // When a linear-step expression is specified in a linear clause it must be
6470 // either a constant integer expression or an integer-typed parameter that is
6471 // specified in a uniform clause on the directive.
6472 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6473 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6474 auto MI = LinModifiers.begin();
6475 for (const Expr *E : Linears) {
6476 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6477 ++MI;
6478 E = E->IgnoreParenImpCasts();
6479 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6480 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6481 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6482 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6483 FD->getParamDecl(PVD->getFunctionScopeIndex())
6484 ->getCanonicalDecl() == CanonPVD) {
6485 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6486 // A list-item cannot appear in more than one linear clause.
6487 if (LinearArgs.count(CanonPVD) > 0) {
6488 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6489 << getOpenMPClauseName(OMPC_linear)
6490 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6491 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6492 diag::note_omp_explicit_dsa)
6493 << getOpenMPClauseName(OMPC_linear);
6494 continue;
6495 }
6496 // Each argument can appear in at most one uniform or linear clause.
6497 if (UniformedArgs.count(CanonPVD) > 0) {
6498 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6499 << getOpenMPClauseName(OMPC_linear)
6500 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6501 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6502 diag::note_omp_explicit_dsa)
6503 << getOpenMPClauseName(OMPC_uniform);
6504 continue;
6505 }
6506 LinearArgs[CanonPVD] = E;
6507 if (E->isValueDependent() || E->isTypeDependent() ||
6508 E->isInstantiationDependent() ||
6509 E->containsUnexpandedParameterPack())
6510 continue;
6511 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6512 PVD->getOriginalType(),
6513 /*IsDeclareSimd=*/true);
6514 continue;
6515 }
6516 }
6517 if (isa<CXXThisExpr>(E)) {
6518 if (UniformedLinearThis) {
6519 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6520 << getOpenMPClauseName(OMPC_linear)
6521 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6522 << E->getSourceRange();
6523 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6524 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6525 : OMPC_linear);
6526 continue;
6527 }
6528 UniformedLinearThis = E;
6529 if (E->isValueDependent() || E->isTypeDependent() ||
6530 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6531 continue;
6532 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6533 E->getType(), /*IsDeclareSimd=*/true);
6534 continue;
6535 }
6536 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6537 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6538 }
6539 Expr *Step = nullptr;
6540 Expr *NewStep = nullptr;
6541 SmallVector<Expr *, 4> NewSteps;
6542 for (Expr *E : Steps) {
6543 // Skip the same step expression, it was checked already.
6544 if (Step == E || !E) {
6545 NewSteps.push_back(E ? NewStep : nullptr);
6546 continue;
6547 }
6548 Step = E;
6549 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6550 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6551 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6552 if (UniformedArgs.count(CanonPVD) == 0) {
6553 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6554 << Step->getSourceRange();
6555 } else if (E->isValueDependent() || E->isTypeDependent() ||
6556 E->isInstantiationDependent() ||
6557 E->containsUnexpandedParameterPack() ||
6558 CanonPVD->getType()->hasIntegerRepresentation()) {
6559 NewSteps.push_back(Step);
6560 } else {
6561 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6562 << Step->getSourceRange();
6563 }
6564 continue;
6565 }
6566 NewStep = Step;
6567 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6568 !Step->isInstantiationDependent() &&
6569 !Step->containsUnexpandedParameterPack()) {
6570 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6571 .get();
6572 if (NewStep)
6573 NewStep =
6574 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6575 }
6576 NewSteps.push_back(NewStep);
6577 }
6578 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6579 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6580 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6581 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6582 const_cast<Expr **>(Linears.data()), Linears.size(),
6583 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6584 NewSteps.data(), NewSteps.size(), SR);
6585 ADecl->addAttr(NewAttr);
6586 return DG;
6587}
6588
6589static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6590 QualType NewType) {
6591 assert(NewType->isFunctionProtoType() &&((void)0)
6592 "Expected function type with prototype.")((void)0);
6593 assert(FD->getType()->isFunctionNoProtoType() &&((void)0)
6594 "Expected function with type with no prototype.")((void)0);
6595 assert(FDWithProto->getType()->isFunctionProtoType() &&((void)0)
6596 "Expected function with prototype.")((void)0);
6597 // Synthesize parameters with the same types.
6598 FD->setType(NewType);
6599 SmallVector<ParmVarDecl *, 16> Params;
6600 for (const ParmVarDecl *P : FDWithProto->parameters()) {
6601 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6602 SourceLocation(), nullptr, P->getType(),
6603 /*TInfo=*/nullptr, SC_None, nullptr);
6604 Param->setScopeInfo(0, Params.size());
6605 Param->setImplicit();
6606 Params.push_back(Param);
6607 }
6608
6609 FD->setParams(Params);
6610}
6611
6612void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6613 if (D->isInvalidDecl())
6614 return;
6615 FunctionDecl *FD = nullptr;
6616 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6617 FD = UTemplDecl->getTemplatedDecl();
6618 else
6619 FD = cast<FunctionDecl>(D);
6620 assert(FD && "Expected a function declaration!")((void)0);
6621
6622 // If we are intantiating templates we do *not* apply scoped assumptions but
6623 // only global ones. We apply scoped assumption to the template definition
6624 // though.
6625 if (!inTemplateInstantiation()) {
6626 for (AssumptionAttr *AA : OMPAssumeScoped)
6627 FD->addAttr(AA);
6628 }
6629 for (AssumptionAttr *AA : OMPAssumeGlobal)
6630 FD->addAttr(AA);
6631}
6632
6633Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6634 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6635
6636void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6637 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6638 SmallVectorImpl<FunctionDecl *> &Bases) {
6639 if (!D.getIdentifier())
6640 return;
6641
6642 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6643
6644 // Template specialization is an extension, check if we do it.
6645 bool IsTemplated = !TemplateParamLists.empty();
6646 if (IsTemplated &
6647 !DVScope.TI->isExtensionActive(
6648 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6649 return;
6650
6651 IdentifierInfo *BaseII = D.getIdentifier();
6652 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6653 LookupOrdinaryName);
6654 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6655
6656 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6657 QualType FType = TInfo->getType();
6658
6659 bool IsConstexpr =
6660 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6661 bool IsConsteval =
6662 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6663
6664 for (auto *Candidate : Lookup) {
6665 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6666 FunctionDecl *UDecl = nullptr;
6667 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6668 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6669 else if (!IsTemplated)
6670 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6671 if (!UDecl)
6672 continue;
6673
6674 // Don't specialize constexpr/consteval functions with
6675 // non-constexpr/consteval functions.
6676 if (UDecl->isConstexpr() && !IsConstexpr)
6677 continue;
6678 if (UDecl->isConsteval() && !IsConsteval)
6679 continue;
6680
6681 QualType UDeclTy = UDecl->getType();
6682 if (!UDeclTy->isDependentType()) {
6683 QualType NewType = Context.mergeFunctionTypes(
6684 FType, UDeclTy, /* OfBlockPointer */ false,
6685 /* Unqualified */ false, /* AllowCXX */ true);
6686 if (NewType.isNull())
6687 continue;
6688 }
6689
6690 // Found a base!
6691 Bases.push_back(UDecl);
6692 }
6693
6694 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6695 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6696 // If no base was found we create a declaration that we use as base.
6697 if (Bases.empty() && UseImplicitBase) {
6698 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6699 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6700 BaseD->setImplicit(true);
6701 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6702 Bases.push_back(BaseTemplD->getTemplatedDecl());
6703 else
6704 Bases.push_back(cast<FunctionDecl>(BaseD));
6705 }
6706
6707 std::string MangledName;
6708 MangledName += D.getIdentifier()->getName();
6709 MangledName += getOpenMPVariantManglingSeparatorStr();
6710 MangledName += DVScope.NameSuffix;
6711 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6712
6713 VariantII.setMangledOpenMPVariantName(true);
6714 D.SetIdentifier(&VariantII, D.getBeginLoc());
6715}
6716
6717void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6718 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6719 // Do not mark function as is used to prevent its emission if this is the
6720 // only place where it is used.
6721 EnterExpressionEvaluationContext Unevaluated(
6722 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6723
6724 FunctionDecl *FD = nullptr;
6725 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6726 FD = UTemplDecl->getTemplatedDecl();
6727 else
6728 FD = cast<FunctionDecl>(D);
6729 auto *VariantFuncRef = DeclRefExpr::Create(
6730 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6731 /* RefersToEnclosingVariableOrCapture */ false,
6732 /* NameLoc */ FD->getLocation(), FD->getType(),
6733 ExprValueKind::VK_PRValue);
6734
6735 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6736 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6737 Context, VariantFuncRef, DVScope.TI);
6738 for (FunctionDecl *BaseFD : Bases)
6739 BaseFD->addAttr(OMPDeclareVariantA);
6740}
6741
6742ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6743 SourceLocation LParenLoc,
6744 MultiExprArg ArgExprs,
6745 SourceLocation RParenLoc, Expr *ExecConfig) {
6746 // The common case is a regular call we do not want to specialize at all. Try
6747 // to make that case fast by bailing early.
6748 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6749 if (!CE)
6750 return Call;
6751
6752 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6753 if (!CalleeFnDecl)
6754 return Call;
6755
6756 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6757 return Call;
6758
6759 ASTContext &Context = getASTContext();
6760 std::function<void(StringRef)> DiagUnknownTrait = [this,
6761 CE](StringRef ISATrait) {
6762 // TODO Track the selector locations in a way that is accessible here to
6763 // improve the diagnostic location.
6764 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6765 << ISATrait;
6766 };
6767 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6768 getCurFunctionDecl());
6769
6770 QualType CalleeFnType = CalleeFnDecl->getType();
6771
6772 SmallVector<Expr *, 4> Exprs;
6773 SmallVector<VariantMatchInfo, 4> VMIs;
6774 while (CalleeFnDecl) {
6775 for (OMPDeclareVariantAttr *A :
6776 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6777 Expr *VariantRef = A->getVariantFuncRef();
6778
6779 VariantMatchInfo VMI;
6780 OMPTraitInfo &TI = A->getTraitInfo();
6781 TI.getAsVariantMatchInfo(Context, VMI);
6782 if (!isVariantApplicableInContext(VMI, OMPCtx,
6783 /* DeviceSetOnly */ false))
6784 continue;
6785
6786 VMIs.push_back(VMI);
6787 Exprs.push_back(VariantRef);
6788 }
6789
6790 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6791 }
6792
6793 ExprResult NewCall;
6794 do {
6795 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6796 if (BestIdx < 0)
6797 return Call;
6798 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6799 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6800
6801 {
6802 // Try to build a (member) call expression for the current best applicable
6803 // variant expression. We allow this to fail in which case we continue
6804 // with the next best variant expression. The fail case is part of the
6805 // implementation defined behavior in the OpenMP standard when it talks
6806 // about what differences in the function prototypes: "Any differences
6807 // that the specific OpenMP context requires in the prototype of the
6808 // variant from the base function prototype are implementation defined."
6809 // This wording is there to allow the specialized variant to have a
6810 // different type than the base function. This is intended and OK but if
6811 // we cannot create a call the difference is not in the "implementation
6812 // defined range" we allow.
6813 Sema::TentativeAnalysisScope Trap(*this);
6814
6815 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6816 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6817 BestExpr = MemberExpr::CreateImplicit(
6818 Context, MemberCall->getImplicitObjectArgument(),
6819 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6820 MemberCall->getValueKind(), MemberCall->getObjectKind());
6821 }
6822 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6823 ExecConfig);
6824 if (NewCall.isUsable()) {
6825 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6826 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6827 QualType NewType = Context.mergeFunctionTypes(
6828 CalleeFnType, NewCalleeFnDecl->getType(),
6829 /* OfBlockPointer */ false,
6830 /* Unqualified */ false, /* AllowCXX */ true);
6831 if (!NewType.isNull())
6832 break;
6833 // Don't use the call if the function type was not compatible.
6834 NewCall = nullptr;
6835 }
6836 }
6837 }
6838
6839 VMIs.erase(VMIs.begin() + BestIdx);
6840 Exprs.erase(Exprs.begin() + BestIdx);
6841 } while (!VMIs.empty());
6842
6843 if (!NewCall.isUsable())
6844 return Call;
6845 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6846}
6847
6848Optional<std::pair<FunctionDecl *, Expr *>>
6849Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6850 Expr *VariantRef, OMPTraitInfo &TI,
6851 SourceRange SR) {
6852 if (!DG || DG.get().isNull())
6853 return None;
6854
6855 const int VariantId = 1;
6856 // Must be applied only to single decl.
6857 if (!DG.get().isSingleDecl()) {
6858 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6859 << VariantId << SR;
6860 return None;
6861 }
6862 Decl *ADecl = DG.get().getSingleDecl();
6863 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6864 ADecl = FTD->getTemplatedDecl();
6865
6866 // Decl must be a function.
6867 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6868 if (!FD) {
6869 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6870 << VariantId << SR;
6871 return None;
6872 }
6873
6874 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6875 return FD->hasAttrs() &&
6876 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6877 FD->hasAttr<TargetAttr>());
6878 };
6879 // OpenMP is not compatible with CPU-specific attributes.
6880 if (HasMultiVersionAttributes(FD)) {
6881 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6882 << SR;
6883 return None;
6884 }
6885
6886 // Allow #pragma omp declare variant only if the function is not used.
6887 if (FD->isUsed(false))
6888 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6889 << FD->getLocation();
6890
6891 // Check if the function was emitted already.
6892 const FunctionDecl *Definition;
6893 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6894 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6895 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6896 << FD->getLocation();
6897
6898 // The VariantRef must point to function.
6899 if (!VariantRef) {
6900 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6901 return None;
6902 }
6903
6904 auto ShouldDelayChecks = [](Expr *&E, bool) {
6905 return E && (E->isTypeDependent() || E->isValueDependent() ||
6906 E->containsUnexpandedParameterPack() ||
6907 E->isInstantiationDependent());
6908 };
6909 // Do not check templates, wait until instantiation.
6910 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6911 TI.anyScoreOrCondition(ShouldDelayChecks))
6912 return std::make_pair(FD, VariantRef);
6913
6914 // Deal with non-constant score and user condition expressions.
6915 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6916 bool IsScore) -> bool {
6917 if (!E || E->isIntegerConstantExpr(Context))
6918 return false;
6919
6920 if (IsScore) {
6921 // We warn on non-constant scores and pretend they were not present.
6922 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6923 << E;
6924 E = nullptr;
6925 } else {
6926 // We could replace a non-constant user condition with "false" but we
6927 // will soon need to handle these anyway for the dynamic version of
6928 // OpenMP context selectors.
6929 Diag(E->getExprLoc(),
6930 diag::err_omp_declare_variant_user_condition_not_constant)
6931 << E;
6932 }
6933 return true;
6934 };
6935 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6936 return None;
6937
6938 // Convert VariantRef expression to the type of the original function to
6939 // resolve possible conflicts.
6940 ExprResult VariantRefCast = VariantRef;
6941 if (LangOpts.CPlusPlus) {
6942 QualType FnPtrType;
6943 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6944 if (Method && !Method->isStatic()) {
6945 const Type *ClassType =
6946 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6947 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6948 ExprResult ER;
6949 {
6950 // Build adrr_of unary op to correctly handle type checks for member
6951 // functions.
6952 Sema::TentativeAnalysisScope Trap(*this);
6953 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6954 VariantRef);
6955 }
6956 if (!ER.isUsable()) {
6957 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6958 << VariantId << VariantRef->getSourceRange();
6959 return None;
6960 }
6961 VariantRef = ER.get();
6962 } else {
6963 FnPtrType = Context.getPointerType(FD->getType());
6964 }
6965 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6966 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6967 ImplicitConversionSequence ICS = TryImplicitConversion(
6968 VariantRef, FnPtrType.getUnqualifiedType(),
6969 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6970 /*InOverloadResolution=*/false,
6971 /*CStyle=*/false,
6972 /*AllowObjCWritebackConversion=*/false);
6973 if (ICS.isFailure()) {
6974 Diag(VariantRef->getExprLoc(),
6975 diag::err_omp_declare_variant_incompat_types)
6976 << VariantRef->getType()
6977 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6978 << VariantRef->getSourceRange();
6979 return None;
6980 }
6981 VariantRefCast = PerformImplicitConversion(
6982 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6983 if (!VariantRefCast.isUsable())
6984 return None;
6985 }
6986 // Drop previously built artificial addr_of unary op for member functions.
6987 if (Method && !Method->isStatic()) {
6988 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6989 if (auto *UO = dyn_cast<UnaryOperator>(
6990 PossibleAddrOfVariantRef->IgnoreImplicit()))
6991 VariantRefCast = UO->getSubExpr();
6992 }
6993 }
6994
6995 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6996 if (!ER.isUsable() ||
6997 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6998 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6999 << VariantId << VariantRef->getSourceRange();
7000 return None;
7001 }
7002
7003 // The VariantRef must point to function.
7004 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7005 if (!DRE) {
7006 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7007 << VariantId << VariantRef->getSourceRange();
7008 return None;
7009 }
7010 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7011 if (!NewFD) {
7012 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7013 << VariantId << VariantRef->getSourceRange();
7014 return None;
7015 }
7016
7017 // Check if function types are compatible in C.
7018 if (!LangOpts.CPlusPlus) {
7019 QualType NewType =
7020 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
7021 if (NewType.isNull()) {
7022 Diag(VariantRef->getExprLoc(),
7023 diag::err_omp_declare_variant_incompat_types)
7024 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
7025 return None;
7026 }
7027 if (NewType->isFunctionProtoType()) {
7028 if (FD->getType()->isFunctionNoProtoType())
7029 setPrototype(*this, FD, NewFD, NewType);
7030 else if (NewFD->getType()->isFunctionNoProtoType())
7031 setPrototype(*this, NewFD, FD, NewType);
7032 }
7033 }
7034
7035 // Check if variant function is not marked with declare variant directive.
7036 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7037 Diag(VariantRef->getExprLoc(),
7038 diag::warn_omp_declare_variant_marked_as_declare_variant)
7039 << VariantRef->getSourceRange();
7040 SourceRange SR =
7041 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7042 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7043 return None;
7044 }
7045
7046 enum DoesntSupport {
7047 VirtFuncs = 1,
7048 Constructors = 3,
7049 Destructors = 4,
7050 DeletedFuncs = 5,
7051 DefaultedFuncs = 6,
7052 ConstexprFuncs = 7,
7053 ConstevalFuncs = 8,
7054 };
7055 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7056 if (CXXFD->isVirtual()) {
7057 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7058 << VirtFuncs;
7059 return None;
7060 }
7061
7062 if (isa<CXXConstructorDecl>(FD)) {
7063 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7064 << Constructors;
7065 return None;
7066 }
7067
7068 if (isa<CXXDestructorDecl>(FD)) {
7069 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7070 << Destructors;
7071 return None;
7072 }
7073 }
7074
7075 if (FD->isDeleted()) {
7076 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7077 << DeletedFuncs;
7078 return None;
7079 }
7080
7081 if (FD->isDefaulted()) {
7082 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7083 << DefaultedFuncs;
7084 return None;
7085 }
7086
7087 if (FD->isConstexpr()) {
7088 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7089 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7090 return None;
7091 }
7092
7093 // Check general compatibility.
7094 if (areMultiversionVariantFunctionsCompatible(
7095 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7096 PartialDiagnosticAt(SourceLocation(),
7097 PartialDiagnostic::NullDiagnostic()),
7098 PartialDiagnosticAt(
7099 VariantRef->getExprLoc(),
7100 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7101 PartialDiagnosticAt(VariantRef->getExprLoc(),
7102 PDiag(diag::err_omp_declare_variant_diff)
7103 << FD->getLocation()),
7104 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7105 /*CLinkageMayDiffer=*/true))
7106 return None;
7107 return std::make_pair(FD, cast<Expr>(DRE));
7108}
7109
7110void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
7111 Expr *VariantRef,
7112 OMPTraitInfo &TI,
7113 SourceRange SR) {
7114 auto *NewAttr =
7115 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
7116 FD->addAttr(NewAttr);
7117}
7118
7119StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7120 Stmt *AStmt,
7121 SourceLocation StartLoc,
7122 SourceLocation EndLoc) {
7123 if (!AStmt)
7124 return StmtError();
7125
7126 auto *CS = cast<CapturedStmt>(AStmt);
7127 // 1.2.2 OpenMP Language Terminology
7128 // Structured block - An executable statement with a single entry at the
7129 // top and a single exit at the bottom.
7130 // The point of exit cannot be a branch out of the structured block.
7131 // longjmp() and throw() must not violate the entry/exit criteria.
7132 CS->getCapturedDecl()->setNothrow();
7133
7134 setFunctionHasBranchProtectedScope();
7135
7136 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7137 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
7138 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7139}
7140
7141namespace {
7142/// Iteration space of a single for loop.
7143struct LoopIterationSpace final {
7144 /// True if the condition operator is the strict compare operator (<, > or
7145 /// !=).
7146 bool IsStrictCompare = false;
7147 /// Condition of the loop.
7148 Expr *PreCond = nullptr;
7149 /// This expression calculates the number of iterations in the loop.
7150 /// It is always possible to calculate it before starting the loop.
7151 Expr *NumIterations = nullptr;
7152 /// The loop counter variable.
7153 Expr *CounterVar = nullptr;
7154 /// Private loop counter variable.
7155 Expr *PrivateCounterVar = nullptr;
7156 /// This is initializer for the initial value of #CounterVar.
7157 Expr *CounterInit = nullptr;
7158 /// This is step for the #CounterVar used to generate its update:
7159 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7160 Expr *CounterStep = nullptr;
7161 /// Should step be subtracted?
7162 bool Subtract = false;
7163 /// Source range of the loop init.
7164 SourceRange InitSrcRange;
7165 /// Source range of the loop condition.
7166 SourceRange CondSrcRange;
7167 /// Source range of the loop increment.
7168 SourceRange IncSrcRange;
7169 /// Minimum value that can have the loop control variable. Used to support
7170 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7171 /// since only such variables can be used in non-loop invariant expressions.
7172 Expr *MinValue = nullptr;
7173 /// Maximum value that can have the loop control variable. Used to support
7174 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7175 /// since only such variables can be used in non-loop invariant expressions.
7176 Expr *MaxValue = nullptr;
7177 /// true, if the lower bound depends on the outer loop control var.
7178 bool IsNonRectangularLB = false;
7179 /// true, if the upper bound depends on the outer loop control var.
7180 bool IsNonRectangularUB = false;
7181 /// Index of the loop this loop depends on and forms non-rectangular loop
7182 /// nest.
7183 unsigned LoopDependentIdx = 0;
7184 /// Final condition for the non-rectangular loop nest support. It is used to
7185 /// check that the number of iterations for this particular counter must be
7186 /// finished.
7187 Expr *FinalCondition = nullptr;
7188};
7189
7190/// Helper class for checking canonical form of the OpenMP loops and
7191/// extracting iteration space of each loop in the loop nest, that will be used
7192/// for IR generation.
7193class OpenMPIterationSpaceChecker {
7194 /// Reference to Sema.
7195 Sema &SemaRef;
7196 /// Does the loop associated directive support non-rectangular loops?
7197 bool SupportsNonRectangular;
7198 /// Data-sharing stack.
7199 DSAStackTy &Stack;
7200 /// A location for diagnostics (when there is no some better location).
7201 SourceLocation DefaultLoc;
7202 /// A location for diagnostics (when increment is not compatible).
7203 SourceLocation ConditionLoc;
7204 /// A source location for referring to loop init later.
7205 SourceRange InitSrcRange;
7206 /// A source location for referring to condition later.
7207 SourceRange ConditionSrcRange;
7208 /// A source location for referring to increment later.
7209 SourceRange IncrementSrcRange;
7210 /// Loop variable.
7211 ValueDecl *LCDecl = nullptr;
7212 /// Reference to loop variable.
7213 Expr *LCRef = nullptr;
7214 /// Lower bound (initializer for the var).
7215 Expr *LB = nullptr;
7216 /// Upper bound.
7217 Expr *UB = nullptr;
7218 /// Loop step (increment).
7219 Expr *Step = nullptr;
7220 /// This flag is true when condition is one of:
7221 /// Var < UB
7222 /// Var <= UB
7223 /// UB > Var
7224 /// UB >= Var
7225 /// This will have no value when the condition is !=
7226 llvm::Optional<bool> TestIsLessOp;
7227 /// This flag is true when condition is strict ( < or > ).
7228 bool TestIsStrictOp = false;
7229 /// This flag is true when step is subtracted on each iteration.
7230 bool SubtractStep = false;
7231 /// The outer loop counter this loop depends on (if any).
7232 const ValueDecl *DepDecl = nullptr;
7233 /// Contains number of loop (starts from 1) on which loop counter init
7234 /// expression of this loop depends on.
7235 Optional<unsigned> InitDependOnLC;
7236 /// Contains number of loop (starts from 1) on which loop counter condition
7237 /// expression of this loop depends on.
7238 Optional<unsigned> CondDependOnLC;
7239 /// Checks if the provide statement depends on the loop counter.
7240 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7241 /// Original condition required for checking of the exit condition for
7242 /// non-rectangular loop.
7243 Expr *Condition = nullptr;
7244
7245public:
7246 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7247 DSAStackTy &Stack, SourceLocation DefaultLoc)
7248 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7249 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7250 /// Check init-expr for canonical loop form and save loop counter
7251 /// variable - #Var and its initialization value - #LB.
7252 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7253 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7254 /// for less/greater and for strict/non-strict comparison.
7255 bool checkAndSetCond(Expr *S);
7256 /// Check incr-expr for canonical loop form and return true if it
7257 /// does not conform, otherwise save loop step (#Step).
7258 bool checkAndSetInc(Expr *S);
7259 /// Return the loop counter variable.
7260 ValueDecl *getLoopDecl() const { return LCDecl; }
7261 /// Return the reference expression to loop counter variable.
7262 Expr *getLoopDeclRefExpr() const { return LCRef; }
7263 /// Source range of the loop init.
7264 SourceRange getInitSrcRange() const { return InitSrcRange; }
7265 /// Source range of the loop condition.
7266 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7267 /// Source range of the loop increment.
7268 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7269 /// True if the step should be subtracted.
7270 bool shouldSubtractStep() const { return SubtractStep; }
7271 /// True, if the compare operator is strict (<, > or !=).
7272 bool isStrictTestOp() const { return TestIsStrictOp; }
7273 /// Build the expression to calculate the number of iterations.
7274 Expr *buildNumIterations(
7275 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7276 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7277 /// Build the precondition expression for the loops.
7278 Expr *
7279 buildPreCond(Scope *S, Expr *Cond,
7280 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7281 /// Build reference expression to the counter be used for codegen.
7282 DeclRefExpr *
7283 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7284 DSAStackTy &DSA) const;
7285 /// Build reference expression to the private counter be used for
7286 /// codegen.
7287 Expr *buildPrivateCounterVar() const;
7288 /// Build initialization of the counter be used for codegen.
7289 Expr *buildCounterInit() const;
7290 /// Build step of the counter be used for codegen.
7291 Expr *buildCounterStep() const;
7292 /// Build loop data with counter value for depend clauses in ordered
7293 /// directives.
7294 Expr *
7295 buildOrderedLoopData(Scope *S, Expr *Counter,
7296 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7297 SourceLocation Loc, Expr *Inc = nullptr,
7298 OverloadedOperatorKind OOK = OO_Amp);
7299 /// Builds the minimum value for the loop counter.
7300 std::pair<Expr *, Expr *> buildMinMaxValues(
7301 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7302 /// Builds final condition for the non-rectangular loops.
7303 Expr *buildFinalCondition(Scope *S) const;
7304 /// Return true if any expression is dependent.
7305 bool dependent() const;
7306 /// Returns true if the initializer forms non-rectangular loop.
7307 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7308 /// Returns true if the condition forms non-rectangular loop.
7309 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7310 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7311 unsigned getLoopDependentIdx() const {
7312 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7313 }
7314
7315private:
7316 /// Check the right-hand side of an assignment in the increment
7317 /// expression.
7318 bool checkAndSetIncRHS(Expr *RHS);
7319 /// Helper to set loop counter variable and its initializer.
7320 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7321 bool EmitDiags);
7322 /// Helper to set upper bound.
7323 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7324 SourceRange SR, SourceLocation SL);
7325 /// Helper to set loop increment.
7326 bool setStep(Expr *NewStep, bool Subtract);
7327};
7328
7329bool OpenMPIterationSpaceChecker::dependent() const {
7330 if (!LCDecl) {
7331 assert(!LB && !UB && !Step)((void)0);
7332 return false;
7333 }
7334 return LCDecl->getType()->isDependentType() ||
7335 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7336 (Step && Step->isValueDependent());
7337}
7338
7339bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7340 Expr *NewLCRefExpr,
7341 Expr *NewLB, bool EmitDiags) {
7342 // State consistency checking to ensure correct usage.
7343 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&((void)0)
7344 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((void)0);
7345 if (!NewLCDecl || !NewLB)
7346 return true;
7347 LCDecl = getCanonicalDecl(NewLCDecl);
7348 LCRef = NewLCRefExpr;
7349 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7350 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7351 if ((Ctor->isCopyOrMoveConstructor() ||
7352 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7353 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7354 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7355 LB = NewLB;
7356 if (EmitDiags)
7357 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7358 return false;
7359}
7360
7361bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7362 llvm::Optional<bool> LessOp,
7363 bool StrictOp, SourceRange SR,
7364 SourceLocation SL) {
7365 // State consistency checking to ensure correct usage.
7366 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&((void)0)
7367 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((void)0);
7368 if (!NewUB)
7369 return true;
7370 UB = NewUB;
7371 if (LessOp)
7372 TestIsLessOp = LessOp;
7373 TestIsStrictOp = StrictOp;
7374 ConditionSrcRange = SR;
7375 ConditionLoc = SL;
7376 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7377 return false;
7378}
7379
7380bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7381 // State consistency checking to ensure correct usage.
7382 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)((void)0);
7383 if (!NewStep)
7384 return true;
7385 if (!NewStep->isValueDependent()) {
7386 // Check that the step is integer expression.
7387 SourceLocation StepLoc = NewStep->getBeginLoc();
7388 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7389 StepLoc, getExprAsWritten(NewStep));
7390 if (Val.isInvalid())
7391 return true;
7392 NewStep = Val.get();
7393
7394 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7395 // If test-expr is of form var relational-op b and relational-op is < or
7396 // <= then incr-expr must cause var to increase on each iteration of the
7397 // loop. If test-expr is of form var relational-op b and relational-op is
7398 // > or >= then incr-expr must cause var to decrease on each iteration of
7399 // the loop.
7400 // If test-expr is of form b relational-op var and relational-op is < or
7401 // <= then incr-expr must cause var to decrease on each iteration of the
7402 // loop. If test-expr is of form b relational-op var and relational-op is
7403 // > or >= then incr-expr must cause var to increase on each iteration of
7404 // the loop.
7405 Optional<llvm::APSInt> Result =
7406 NewStep->getIntegerConstantExpr(SemaRef.Context);
7407 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7408 bool IsConstNeg =
7409 Result && Result->isSigned() && (Subtract != Result->isNegative());
7410 bool IsConstPos =
7411 Result && Result->isSigned() && (Subtract == Result->isNegative());
7412 bool IsConstZero = Result && !Result->getBoolValue();
7413
7414 // != with increment is treated as <; != with decrement is treated as >
7415 if (!TestIsLessOp.hasValue())
7416 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7417 if (UB && (IsConstZero ||
7418 (TestIsLessOp.getValue() ?
7419 (IsConstNeg || (IsUnsigned && Subtract)) :
7420 (IsConstPos || (IsUnsigned && !Subtract))))) {
7421 SemaRef.Diag(NewStep->getExprLoc(),
7422 diag::err_omp_loop_incr_not_compatible)
7423 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7424 SemaRef.Diag(ConditionLoc,
7425 diag::note_omp_loop_cond_requres_compatible_incr)
7426 << TestIsLessOp.getValue() << ConditionSrcRange;
7427 return true;
7428 }
7429 if (TestIsLessOp.getValue() == Subtract) {
7430 NewStep =
7431 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7432 .get();
7433 Subtract = !Subtract;
7434 }
7435 }
7436
7437 Step = NewStep;
7438 SubtractStep = Subtract;
7439 return false;
7440}
7441
7442namespace {
7443/// Checker for the non-rectangular loops. Checks if the initializer or
7444/// condition expression references loop counter variable.
7445class LoopCounterRefChecker final
7446 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7447 Sema &SemaRef;
7448 DSAStackTy &Stack;
7449 const ValueDecl *CurLCDecl = nullptr;
7450 const ValueDecl *DepDecl = nullptr;
7451 const ValueDecl *PrevDepDecl = nullptr;
7452 bool IsInitializer = true;
7453 bool SupportsNonRectangular;
7454 unsigned BaseLoopId = 0;
7455 bool checkDecl(const Expr *E, const ValueDecl *VD) {
7456 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7457 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7458 << (IsInitializer ? 0 : 1);
7459 return false;
7460 }
7461 const auto &&Data = Stack.isLoopControlVariable(VD);
7462 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7463 // The type of the loop iterator on which we depend may not have a random
7464 // access iterator type.
7465 if (Data.first && VD->getType()->isRecordType()) {
7466 SmallString<128> Name;
7467 llvm::raw_svector_ostream OS(Name);
7468 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7469 /*Qualified=*/true);
7470 SemaRef.Diag(E->getExprLoc(),
7471 diag::err_omp_wrong_dependency_iterator_type)
7472 << OS.str();
7473 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7474 return false;
7475 }
7476 if (Data.first && !SupportsNonRectangular) {
7477 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7478 return false;
7479 }
7480 if (Data.first &&
7481 (DepDecl || (PrevDepDecl &&
7482 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7483 if (!DepDecl && PrevDepDecl)
7484 DepDecl = PrevDepDecl;
7485 SmallString<128> Name;
7486 llvm::raw_svector_ostream OS(Name);
7487 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7488 /*Qualified=*/true);
7489 SemaRef.Diag(E->getExprLoc(),
7490 diag::err_omp_invariant_or_linear_dependency)
7491 << OS.str();
7492 return false;
7493 }
7494 if (Data.first) {
7495 DepDecl = VD;
7496 BaseLoopId = Data.first;
7497 }
7498 return Data.first;
7499 }
7500
7501public:
7502 bool VisitDeclRefExpr(const DeclRefExpr *E) {
7503 const ValueDecl *VD = E->getDecl();
7504 if (isa<VarDecl>(VD))
7505 return checkDecl(E, VD);
7506 return false;
7507 }
7508 bool VisitMemberExpr(const MemberExpr *E) {
7509 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7510 const ValueDecl *VD = E->getMemberDecl();
7511 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7512 return checkDecl(E, VD);
7513 }
7514 return false;
7515 }
7516 bool VisitStmt(const Stmt *S) {
7517 bool Res = false;
7518 for (const Stmt *Child : S->children())
7519 Res = (Child && Visit(Child)) || Res;
7520 return Res;
7521 }
7522 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7523 const ValueDecl *CurLCDecl, bool IsInitializer,
7524 const ValueDecl *PrevDepDecl = nullptr,
7525 bool SupportsNonRectangular = true)
7526 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7527 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7528 SupportsNonRectangular(SupportsNonRectangular) {}
7529 unsigned getBaseLoopId() const {
7530 assert(CurLCDecl && "Expected loop dependency.")((void)0);
7531 return BaseLoopId;
7532 }
7533 const ValueDecl *getDepDecl() const {
7534 assert(CurLCDecl && "Expected loop dependency.")((void)0);
7535 return DepDecl;
7536 }
7537};
7538} // namespace
7539
7540Optional<unsigned>
7541OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7542 bool IsInitializer) {
7543 // Check for the non-rectangular loops.
7544 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7545 DepDecl, SupportsNonRectangular);
7546 if (LoopStmtChecker.Visit(S)) {
7547 DepDecl = LoopStmtChecker.getDepDecl();
7548 return LoopStmtChecker.getBaseLoopId();
7549 }
7550 return llvm::None;
7551}
7552
7553bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7554 // Check init-expr for canonical loop form and save loop counter
7555 // variable - #Var and its initialization value - #LB.
7556 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7557 // var = lb
7558 // integer-type var = lb
7559 // random-access-iterator-type var = lb
7560 // pointer-type var = lb
7561 //
7562 if (!S) {
7563 if (EmitDiags) {
7564 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7565 }
7566 return true;
7567 }
7568 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7569 if (!ExprTemp->cleanupsHaveSideEffects())
7570 S = ExprTemp->getSubExpr();
7571
7572 InitSrcRange = S->getSourceRange();
7573 if (Expr *E = dyn_cast<Expr>(S))
7574 S = E->IgnoreParens();
7575 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7576 if (BO->getOpcode() == BO_Assign) {
7577 Expr *LHS = BO->getLHS()->IgnoreParens();
7578 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7579 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7580 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7581 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7582 EmitDiags);
7583 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7584 }
7585 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7586 if (ME->isArrow() &&
7587 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7588 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7589 EmitDiags);
7590 }
7591 }
7592 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7593 if (DS->isSingleDecl()) {
7594 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7595 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7596 // Accept non-canonical init form here but emit ext. warning.
7597 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7598 SemaRef.Diag(S->getBeginLoc(),
7599 diag::ext_omp_loop_not_canonical_init)
7600 << S->getSourceRange();
7601 return setLCDeclAndLB(
7602 Var,
7603 buildDeclRefExpr(SemaRef, Var,
7604 Var->getType().getNonReferenceType(),
7605 DS->getBeginLoc()),
7606 Var->getInit(), EmitDiags);
7607 }
7608 }
7609 }
7610 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7611 if (CE->getOperator() == OO_Equal) {
7612 Expr *LHS = CE->getArg(0);
7613 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7614 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7615 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7616 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7617 EmitDiags);
7618 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7619 }
7620 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7621 if (ME->isArrow() &&
7622 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7623 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7624 EmitDiags);
7625 }
7626 }
7627 }
7628
7629 if (dependent() || SemaRef.CurContext->isDependentContext())
7630 return false;
7631 if (EmitDiags) {
7632 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7633 << S->getSourceRange();
7634 }
7635 return true;
7636}
7637
7638/// Ignore parenthesizes, implicit casts, copy constructor and return the
7639/// variable (which may be the loop variable) if possible.
7640static const ValueDecl *getInitLCDecl(const Expr *E) {
7641 if (!E)
7642 return nullptr;
7643 E = getExprAsWritten(E);
7644 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7645 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7646 if ((Ctor->isCopyOrMoveConstructor() ||
7647 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7648 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7649 E = CE->getArg(0)->IgnoreParenImpCasts();
7650 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7651 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7652 return getCanonicalDecl(VD);
7653 }
7654 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7655 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7656 return getCanonicalDecl(ME->getMemberDecl());
7657 return nullptr;
7658}
7659
7660bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7661 // Check test-expr for canonical form, save upper-bound UB, flags for
7662 // less/greater and for strict/non-strict comparison.
7663 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7664 // var relational-op b
7665 // b relational-op var
7666 //
7667 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7668 if (!S) {
7669 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7670 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7671 return true;
7672 }
7673 Condition = S;
7674 S = getExprAsWritten(S);
7675 SourceLocation CondLoc = S->getBeginLoc();
7676 auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
7677 BinaryOperatorKind Opcode, const Expr *LHS,
7678 const Expr *RHS, SourceRange SR,
7679 SourceLocation OpLoc) -> llvm::Optional<bool> {
7680 if (BinaryOperator::isRelationalOp(Opcode)) {
7681 if (getInitLCDecl(LHS) == LCDecl)
7682 return setUB(const_cast<Expr *>(RHS),
7683 (Opcode == BO_LT || Opcode == BO_LE),
7684 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7685 if (getInitLCDecl(RHS) == LCDecl)
7686 return setUB(const_cast<Expr *>(LHS),
7687 (Opcode == BO_GT || Opcode == BO_GE),
7688 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7689 } else if (IneqCondIsCanonical && Opcode == BO_NE) {
7690 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
7691 /*LessOp=*/llvm::None,
7692 /*StrictOp=*/true, SR, OpLoc);
7693 }
7694 return llvm::None;
7695 };
7696 llvm::Optional<bool> Res;
7697 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
7698 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
7699 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
7700 RBO->getOperatorLoc());
7701 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7702 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
7703 BO->getSourceRange(), BO->getOperatorLoc());
7704 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7705 if (CE->getNumArgs() == 2) {
7706 Res = CheckAndSetCond(
7707 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
7708 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
7709 }
7710 }
7711 if (Res.hasValue())
7712 return *Res;
7713 if (dependent() || SemaRef.CurContext->isDependentContext())
7714 return false;
7715 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7716 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7717 return true;
7718}
7719
7720bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7721 // RHS of canonical loop form increment can be:
7722 // var + incr
7723 // incr + var
7724 // var - incr
7725 //
7726 RHS = RHS->IgnoreParenImpCasts();
7727 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7728 if (BO->isAdditiveOp()) {
7729 bool IsAdd = BO->getOpcode() == BO_Add;
7730 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7731 return setStep(BO->getRHS(), !IsAdd);
7732 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7733 return setStep(BO->getLHS(), /*Subtract=*/false);
7734 }
7735 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7736 bool IsAdd = CE->getOperator() == OO_Plus;
7737 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7738 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7739 return setStep(CE->getArg(1), !IsAdd);
7740 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7741 return setStep(CE->getArg(0), /*Subtract=*/false);
7742 }
7743 }
7744 if (dependent() || SemaRef.CurContext->isDependentContext())
7745 return false;
7746 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7747 << RHS->getSourceRange() << LCDecl;
7748 return true;
7749}
7750
7751bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7752 // Check incr-expr for canonical loop form and return true if it
7753 // does not conform.
7754 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7755 // ++var
7756 // var++
7757 // --var
7758 // var--
7759 // var += incr
7760 // var -= incr
7761 // var = var + incr
7762 // var = incr + var
7763 // var = var - incr
7764 //
7765 if (!S) {
7766 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7767 return true;
7768 }
7769 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7770 if (!ExprTemp->cleanupsHaveSideEffects())
7771 S = ExprTemp->getSubExpr();
7772
7773 IncrementSrcRange = S->getSourceRange();
7774 S = S->IgnoreParens();
7775 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7776 if (UO->isIncrementDecrementOp() &&
7777 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7778 return setStep(SemaRef
7779 .ActOnIntegerConstant(UO->getBeginLoc(),
7780 (UO->isDecrementOp() ? -1 : 1))
7781 .get(),
7782 /*Subtract=*/false);
7783 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7784 switch (BO->getOpcode()) {
7785 case BO_AddAssign:
7786 case BO_SubAssign:
7787 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7788 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7789 break;
7790 case BO_Assign:
7791 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7792 return checkAndSetIncRHS(BO->getRHS());
7793 break;
7794 default:
7795 break;
7796 }
7797 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7798 switch (CE->getOperator()) {
7799 case OO_PlusPlus:
7800 case OO_MinusMinus:
7801 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7802 return setStep(SemaRef
7803 .ActOnIntegerConstant(
7804 CE->getBeginLoc(),
7805 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7806 .get(),
7807 /*Subtract=*/false);
7808 break;
7809 case OO_PlusEqual:
7810 case OO_MinusEqual:
7811 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7812 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7813 break;
7814 case OO_Equal:
7815 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7816 return checkAndSetIncRHS(CE->getArg(1));
7817 break;
7818 default:
7819 break;
7820 }
7821 }
7822 if (dependent() || SemaRef.CurContext->isDependentContext())
7823 return false;
7824 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7825 << S->getSourceRange() << LCDecl;
7826 return true;
7827}
7828
7829static ExprResult
7830tryBuildCapture(Sema &SemaRef, Expr *Capture,
7831 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7832 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7833 return Capture;
7834 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7835 return SemaRef.PerformImplicitConversion(
7836 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7837 /*AllowExplicit=*/true);
7838 auto I = Captures.find(Capture);
7839 if (I != Captures.end())
7840 return buildCapture(SemaRef, Capture, I->second);
7841 DeclRefExpr *Ref = nullptr;
7842 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7843 Captures[Capture] = Ref;
7844 return Res;
7845}
7846
7847/// Calculate number of iterations, transforming to unsigned, if number of
7848/// iterations may be larger than the original type.
7849static Expr *
7850calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7851 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7852 bool TestIsStrictOp, bool RoundToStep,
7853 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7854 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7855 if (!NewStep.isUsable())
7856 return nullptr;
7857 llvm::APSInt LRes, SRes;
7858 bool IsLowerConst = false, IsStepConst = false;
7859 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7860 LRes = *Res;
7861 IsLowerConst = true;
7862 }
7863 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7864 SRes = *Res;
7865 IsStepConst = true;
7866 }
7867 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7868 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7869 (TestIsStrictOp && LRes.isStrictlyPositive()));
7870 bool NeedToReorganize = false;
7871 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7872 if (!NoNeedToConvert && IsLowerConst &&
7873 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7874 NoNeedToConvert = true;
7875 if (RoundToStep) {
7876 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7877 ? LRes.getBitWidth()
7878 : SRes.getBitWidth();
7879 LRes = LRes.extend(BW + 1);
7880 LRes.setIsSigned(true);
7881 SRes = SRes.extend(BW + 1);
7882 SRes.setIsSigned(true);
7883 LRes -= SRes;
7884 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7885 LRes = LRes.trunc(BW);
7886 }
7887 if (TestIsStrictOp) {
7888 unsigned BW = LRes.getBitWidth();
7889 LRes = LRes.extend(BW + 1);
7890 LRes.setIsSigned(true);
7891 ++LRes;
7892 NoNeedToConvert =
7893 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7894 // truncate to the original bitwidth.
7895 LRes = LRes.trunc(BW);
7896 }
7897 NeedToReorganize = NoNeedToConvert;
7898 }
7899 llvm::APSInt URes;
7900 bool IsUpperConst = false;
7901 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7902 URes = *Res;
7903 IsUpperConst = true;
7904 }
7905 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7906 (!RoundToStep || IsStepConst)) {
7907 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7908 : URes.getBitWidth();
7909 LRes = LRes.extend(BW + 1);
7910 LRes.setIsSigned(true);
7911 URes = URes.extend(BW + 1);
7912 URes.setIsSigned(true);
7913 URes -= LRes;
7914 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7915 NeedToReorganize = NoNeedToConvert;
7916 }
7917 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7918 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7919 // unsigned.
7920 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7921 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7922 QualType LowerTy = Lower->getType();
7923 QualType UpperTy = Upper->getType();
7924 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7925 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7926 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7927 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7928 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7929 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7930 Upper =
7931 SemaRef
7932 .PerformImplicitConversion(
7933 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7934 CastType, Sema::AA_Converting)
7935 .get();
7936 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7937 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7938 }
7939 }
7940 if (!Lower || !Upper || NewStep.isInvalid())
7941 return nullptr;
7942
7943 ExprResult Diff;
7944 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7945 // 1]).
7946 if (NeedToReorganize) {
7947 Diff = Lower;
7948
7949 if (RoundToStep) {
7950 // Lower - Step
7951 Diff =
7952 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7953 if (!Diff.isUsable())
7954 return nullptr;
7955 }
7956
7957 // Lower - Step [+ 1]
7958 if (TestIsStrictOp)
7959 Diff = SemaRef.BuildBinOp(
7960 S, DefaultLoc, BO_Add, Diff.get(),
7961 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7962 if (!Diff.isUsable())
7963 return nullptr;
7964
7965 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7966 if (!Diff.isUsable())
7967 return nullptr;
7968
7969 // Upper - (Lower - Step [+ 1]).
7970 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7971 if (!Diff.isUsable())
7972 return nullptr;
7973 } else {
7974 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7975
7976 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7977 // BuildBinOp already emitted error, this one is to point user to upper
7978 // and lower bound, and to tell what is passed to 'operator-'.
7979 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7980 << Upper->getSourceRange() << Lower->getSourceRange();
7981 return nullptr;
7982 }
7983
7984 if (!Diff.isUsable())
7985 return nullptr;
7986
7987 // Upper - Lower [- 1]
7988 if (TestIsStrictOp)
7989 Diff = SemaRef.BuildBinOp(
7990 S, DefaultLoc, BO_Sub, Diff.get(),
7991 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7992 if (!Diff.isUsable())
7993 return nullptr;
7994
7995 if (RoundToStep) {
7996 // Upper - Lower [- 1] + Step
7997 Diff =
7998 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7999 if (!Diff.isUsable())
8000 return nullptr;
8001 }
8002 }
8003
8004 // Parentheses (for dumping/debugging purposes only).
8005 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8006 if (!Diff.isUsable())
8007 return nullptr;
8008
8009 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8010 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8011 if (!Diff.isUsable())
8012 return nullptr;
8013
8014 return Diff.get();
8015}
8016
8017/// Build the expression to calculate the number of iterations.
8018Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8019 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8020 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8021 QualType VarType = LCDecl->getType().getNonReferenceType();
8022 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8023 !SemaRef.getLangOpts().CPlusPlus)
8024 return nullptr;
8025 Expr *LBVal = LB;
8026 Expr *UBVal = UB;
8027 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8028 // max(LB(MinVal), LB(MaxVal))
8029 if (InitDependOnLC) {
8030 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8031 if (!IS.MinValue || !IS.MaxValue)
8032 return nullptr;
8033 // OuterVar = Min
8034 ExprResult MinValue =
8035 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8036 if (!MinValue.isUsable())
8037 return nullptr;
8038
8039 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8040 IS.CounterVar, MinValue.get());
8041 if (!LBMinVal.isUsable())
8042 return nullptr;
8043 // OuterVar = Min, LBVal
8044 LBMinVal =
8045 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8046 if (!LBMinVal.isUsable())
8047 return nullptr;
8048 // (OuterVar = Min, LBVal)
8049 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8050 if (!LBMinVal.isUsable())
8051 return nullptr;
8052
8053 // OuterVar = Max
8054 ExprResult MaxValue =
8055 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8056 if (!MaxValue.isUsable())
8057 return nullptr;
8058
8059 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8060 IS.CounterVar, MaxValue.get());
8061 if (!LBMaxVal.isUsable())
8062 return nullptr;
8063 // OuterVar = Max, LBVal
8064 LBMaxVal =
8065 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8066 if (!LBMaxVal.isUsable())
8067 return nullptr;
8068 // (OuterVar = Max, LBVal)
8069 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8070 if (!LBMaxVal.isUsable())
8071 return nullptr;
8072
8073 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8074 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8075 if (!LBMin || !LBMax)
8076 return nullptr;
8077 // LB(MinVal) < LB(MaxVal)
8078 ExprResult MinLessMaxRes =
8079 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8080 if (!MinLessMaxRes.isUsable())
8081 return nullptr;
8082 Expr *MinLessMax =
8083 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8084 if (!MinLessMax)
8085 return nullptr;
8086 if (TestIsLessOp.getValue()) {
8087 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8088 // LB(MaxVal))
8089 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8090 MinLessMax, LBMin, LBMax);
8091 if (!MinLB.isUsable())
8092 return nullptr;
8093 LBVal = MinLB.get();
8094 } else {
8095 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8096 // LB(MaxVal))
8097 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8098 MinLessMax, LBMax, LBMin);
8099 if (!MaxLB.isUsable())
8100 return nullptr;
8101 LBVal = MaxLB.get();
8102 }
8103 }
8104 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8105 // min(UB(MinVal), UB(MaxVal))
8106 if (CondDependOnLC) {
8107 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8108 if (!IS.MinValue || !IS.MaxValue)
8109 return nullptr;
8110 // OuterVar = Min
8111 ExprResult MinValue =
8112 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8113 if (!MinValue.isUsable())
8114 return nullptr;
8115
8116 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8117 IS.CounterVar, MinValue.get());
8118 if (!UBMinVal.isUsable())
8119 return nullptr;
8120 // OuterVar = Min, UBVal
8121 UBMinVal =
8122 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8123 if (!UBMinVal.isUsable())
8124 return nullptr;
8125 // (OuterVar = Min, UBVal)
8126 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8127 if (!UBMinVal.isUsable())
8128 return nullptr;
8129
8130 // OuterVar = Max
8131 ExprResult MaxValue =
8132 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8133 if (!MaxValue.isUsable())
8134 return nullptr;
8135
8136 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8137 IS.CounterVar, MaxValue.get());
8138 if (!UBMaxVal.isUsable())
8139 return nullptr;
8140 // OuterVar = Max, UBVal
8141 UBMaxVal =
8142 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8143 if (!UBMaxVal.isUsable())
8144 return nullptr;
8145 // (OuterVar = Max, UBVal)
8146 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8147 if (!UBMaxVal.isUsable())
8148 return nullptr;
8149
8150 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8151 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8152 if (!UBMin || !UBMax)
8153 return nullptr;
8154 // UB(MinVal) > UB(MaxVal)
8155 ExprResult MinGreaterMaxRes =
8156 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8157 if (!MinGreaterMaxRes.isUsable())
8158 return nullptr;
8159 Expr *MinGreaterMax =
8160 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8161 if (!MinGreaterMax)
8162 return nullptr;
8163 if (TestIsLessOp.getValue()) {
8164 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8165 // UB(MaxVal))
8166 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8167 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8168 if (!MaxUB.isUsable())
8169 return nullptr;
8170 UBVal = MaxUB.get();
8171 } else {
8172 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8173 // UB(MaxVal))
8174 ExprResult MinUB = SemaRef.ActOnConditionalOp(
8175 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8176 if (!MinUB.isUsable())
8177 return nullptr;
8178 UBVal = MinUB.get();
8179 }
8180 }
8181 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8182 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8183 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8184 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8185 if (!Upper || !Lower)
8186 return nullptr;
8187
8188 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8189 Step, VarType, TestIsStrictOp,
8190 /*RoundToStep=*/true, Captures);
8191 if (!Diff.isUsable())
8192 return nullptr;
8193
8194 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8195 QualType Type = Diff.get()->getType();
8196 ASTContext &C = SemaRef.Context;
8197 bool UseVarType = VarType->hasIntegerRepresentation() &&
8198 C.getTypeSize(Type) > C.getTypeSize(VarType);
8199 if (!Type->isIntegerType() || UseVarType) {
8200 unsigned NewSize =
8201 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8202 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8203 : Type->hasSignedIntegerRepresentation();
8204 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8205 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8206 Diff = SemaRef.PerformImplicitConversion(
8207 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8208 if (!Diff.isUsable())
8209 return nullptr;
8210 }
8211 }
8212 if (LimitedType) {
8213 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8214 if (NewSize != C.getTypeSize(Type)) {
8215 if (NewSize < C.getTypeSize(Type)) {
8216 assert(NewSize == 64 && "incorrect loop var size")((void)0);
8217 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8218 << InitSrcRange << ConditionSrcRange;
8219 }
8220 QualType NewType = C.getIntTypeForBitwidth(
8221 NewSize, Type->hasSignedIntegerRepresentation() ||
8222 C.getTypeSize(Type) < NewSize);
8223 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8224 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8225 Sema::AA_Converting, true);
8226 if (!Diff.isUsable())
8227 return nullptr;
8228 }
8229 }
8230 }
8231
8232 return Diff.get();
8233}
8234
8235std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8236 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8237 // Do not build for iterators, they cannot be used in non-rectangular loop
8238 // nests.
8239 if (LCDecl->getType()->isRecordType())
8240 return std::make_pair(nullptr, nullptr);
8241 // If we subtract, the min is in the condition, otherwise the min is in the
8242 // init value.
8243 Expr *MinExpr = nullptr;
8244 Expr *MaxExpr = nullptr;
8245 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8246 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8247 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8248 : CondDependOnLC.hasValue();
8249 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8250 : InitDependOnLC.hasValue();
8251 Expr *Lower =
8252 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8253 Expr *Upper =
8254 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8255 if (!Upper || !Lower)
8256 return std::make_pair(nullptr, nullptr);
8257
8258 if (TestIsLessOp.getValue())
8259 MinExpr = Lower;
8260 else
8261 MaxExpr = Upper;
8262
8263 // Build minimum/maximum value based on number of iterations.
8264 QualType VarType = LCDecl->getType().getNonReferenceType();
8265
8266 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8267 Step, VarType, TestIsStrictOp,
8268 /*RoundToStep=*/false, Captures);
8269 if (!Diff.isUsable())
8270 return std::make_pair(nullptr, nullptr);
8271
8272 // ((Upper - Lower [- 1]) / Step) * Step
8273 // Parentheses (for dumping/debugging purposes only).
8274 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8275 if (!Diff.isUsable())
8276 return std::make_pair(nullptr, nullptr);
8277
8278 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8279 if (!NewStep.isUsable())
8280 return std::make_pair(nullptr, nullptr);
8281 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8282 if (!Diff.isUsable())
8283 return std::make_pair(nullptr, nullptr);
8284
8285 // Parentheses (for dumping/debugging purposes only).
8286 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8287 if (!Diff.isUsable())
8288 return std::make_pair(nullptr, nullptr);
8289
8290 // Convert to the ptrdiff_t, if original type is pointer.
8291 if (VarType->isAnyPointerType() &&
8292 !SemaRef.Context.hasSameType(
8293 Diff.get()->getType(),
8294 SemaRef.Context.getUnsignedPointerDiffType())) {
8295 Diff = SemaRef.PerformImplicitConversion(
8296 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8297 Sema::AA_Converting, /*AllowExplicit=*/true);
8298 }
8299 if (!Diff.isUsable())
8300 return std::make_pair(nullptr, nullptr);
8301
8302 if (TestIsLessOp.getValue()) {
8303 // MinExpr = Lower;
8304 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8305 Diff = SemaRef.BuildBinOp(
8306 S, DefaultLoc, BO_Add,
8307 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8308 Diff.get());
8309 if (!Diff.isUsable())
8310 return std::make_pair(nullptr, nullptr);
8311 } else {
8312 // MaxExpr = Upper;
8313 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8314 Diff = SemaRef.BuildBinOp(
8315 S, DefaultLoc, BO_Sub,
8316 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8317 Diff.get());
8318 if (!Diff.isUsable())
8319 return std::make_pair(nullptr, nullptr);
8320 }
8321
8322 // Convert to the original type.
8323 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8324 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8325 Sema::AA_Converting,
8326 /*AllowExplicit=*/true);
8327 if (!Diff.isUsable())
8328 return std::make_pair(nullptr, nullptr);
8329
8330 Sema::TentativeAnalysisScope Trap(SemaRef);
8331 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8332 if (!Diff.isUsable())
8333 return std::make_pair(nullptr, nullptr);
8334
8335 if (TestIsLessOp.getValue())
8336 MaxExpr = Diff.get();
8337 else
8338 MinExpr = Diff.get();
8339
8340 return std::make_pair(MinExpr, MaxExpr);
8341}
8342
8343Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8344 if (InitDependOnLC || CondDependOnLC)
8345 return Condition;
8346 return nullptr;
8347}
8348
8349Expr *OpenMPIterationSpaceChecker::buildPreCond(
8350 Scope *S, Expr *Cond,
8351 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8352 // Do not build a precondition when the condition/initialization is dependent
8353 // to prevent pessimistic early loop exit.
8354 // TODO: this can be improved by calculating min/max values but not sure that
8355 // it will be very effective.
8356 if (CondDependOnLC || InitDependOnLC)
8357 return SemaRef.PerformImplicitConversion(
8358 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8359 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8360 /*AllowExplicit=*/true).get();
8361
8362 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8363 Sema::TentativeAnalysisScope Trap(SemaRef);
8364
8365 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8366 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8367 if (!NewLB.isUsable() || !NewUB.isUsable())
8368 return nullptr;
8369
8370 ExprResult CondExpr =
8371 SemaRef.BuildBinOp(S, DefaultLoc,
8372 TestIsLessOp.getValue() ?
8373 (TestIsStrictOp ? BO_LT : BO_LE) :
8374 (TestIsStrictOp ? BO_GT : BO_GE),
8375 NewLB.get(), NewUB.get());
8376 if (CondExpr.isUsable()) {
8377 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8378 SemaRef.Context.BoolTy))
8379 CondExpr = SemaRef.PerformImplicitConversion(
8380 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8381 /*AllowExplicit=*/true);
8382 }
8383
8384 // Otherwise use original loop condition and evaluate it in runtime.
8385 return CondExpr.isUsable() ? CondExpr.get() : Cond;
8386}
8387
8388/// Build reference expression to the counter be used for codegen.
8389DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8390 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8391 DSAStackTy &DSA) const {
8392 auto *VD = dyn_cast<VarDecl>(LCDecl);
8393 if (!VD) {
8394 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8395 DeclRefExpr *Ref = buildDeclRefExpr(
8396 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8397 const DSAStackTy::DSAVarData Data =
8398 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8399 // If the loop control decl is explicitly marked as private, do not mark it
8400 // as captured again.
8401 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8402 Captures.insert(std::make_pair(LCRef, Ref));
8403 return Ref;
8404 }
8405 return cast<DeclRefExpr>(LCRef);
8406}
8407
8408Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8409 if (LCDecl && !LCDecl->isInvalidDecl()) {
8410 QualType Type = LCDecl->getType().getNonReferenceType();
8411 VarDecl *PrivateVar = buildVarDecl(
8412 SemaRef, DefaultLoc, Type, LCDecl->getName(),
8413 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8414 isa<VarDecl>(LCDecl)
8415 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8416 : nullptr);
8417 if (PrivateVar->isInvalidDecl())
8418 return nullptr;
8419 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8420 }
8421 return nullptr;
8422}
8423
8424/// Build initialization of the counter to be used for codegen.
8425Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8426
8427/// Build step of the counter be used for codegen.
8428Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8429
8430Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8431 Scope *S, Expr *Counter,
8432 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8433 Expr *Inc, OverloadedOperatorKind OOK) {
8434 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8435 if (!Cnt)
8436 return nullptr;
8437 if (Inc) {
8438 assert((OOK == OO_Plus || OOK == OO_Minus) &&((void)0)
8439 "Expected only + or - operations for depend clauses.")((void)0);
8440 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8441 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8442 if (!Cnt)
8443 return nullptr;
8444 }
8445 QualType VarType = LCDecl->getType().getNonReferenceType();
8446 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8447 !SemaRef.getLangOpts().CPlusPlus)
8448 return nullptr;
8449 // Upper - Lower
8450 Expr *Upper = TestIsLessOp.getValue()
8451 ? Cnt
8452 : tryBuildCapture(SemaRef, LB, Captures).get();
8453 Expr *Lower = TestIsLessOp.getValue()
8454 ? tryBuildCapture(SemaRef, LB, Captures).get()
8455 : Cnt;
8456 if (!Upper || !Lower)
8457 return nullptr;
8458
8459 ExprResult Diff = calculateNumIters(
8460 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8461 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8462 if (!Diff.isUsable())
8463 return nullptr;
8464
8465 return Diff.get();
8466}
8467} // namespace
8468
8469void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8470 assert(getLangOpts().OpenMP && "OpenMP is not active.")((void)0);
8471 assert(Init && "Expected loop in canonical form.")((void)0);
8472 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
8473 if (AssociatedLoops > 0 &&
8474 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
8475 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
8476 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8477 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
8478 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8479 if (ValueDecl *D = ISC.getLoopDecl()) {
8480 auto *VD = dyn_cast<VarDecl>(D);
8481 DeclRefExpr *PrivateRef = nullptr;
8482 if (!VD) {
8483 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8484 VD = Private;
8485 } else {
8486 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8487 /*WithInit=*/false);
8488 VD = cast<VarDecl>(PrivateRef->getDecl());
8489 }
8490 }
8491 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
8492 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
8493 if (LD != D->getCanonicalDecl()) {
8494 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
8495 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8496 MarkDeclarationsReferencedInExpr(
8497 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8498 Var->getType().getNonLValueExprType(Context),
8499 ForLoc, /*RefersToCapture=*/true));
8500 }
8501 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
8502 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8503 // Referenced in a Construct, C/C++]. The loop iteration variable in the
8504 // associated for-loop of a simd construct with just one associated
8505 // for-loop may be listed in a linear clause with a constant-linear-step
8506 // that is the increment of the associated for-loop. The loop iteration
8507 // variable(s) in the associated for-loop(s) of a for or parallel for
8508 // construct may be listed in a private or lastprivate clause.
8509 DSAStackTy::DSAVarData DVar =
8510 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
8511 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8512 // is declared in the loop and it is predetermined as a private.
8513 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8514 OpenMPClauseKind PredeterminedCKind =
8515 isOpenMPSimdDirective(DKind)
8516 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8517 : OMPC_private;
8518 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8519 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8520 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8521 DVar.CKind != OMPC_private))) ||
8522 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8523 DKind == OMPD_master_taskloop ||
8524 DKind == OMPD_parallel_master_taskloop ||
8525 isOpenMPDistributeDirective(DKind)) &&
8526 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8527 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8528 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8529 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8530 << getOpenMPClauseName(DVar.CKind)
8531 << getOpenMPDirectiveName(DKind)
8532 << getOpenMPClauseName(PredeterminedCKind);
8533 if (DVar.RefExpr == nullptr)
8534 DVar.CKind = PredeterminedCKind;
8535 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
8536 /*IsLoopIterVar=*/true);
8537 } else if (LoopDeclRefExpr) {
8538 // Make the loop iteration variable private (for worksharing
8539 // constructs), linear (for simd directives with the only one
8540 // associated loop) or lastprivate (for simd directives with several
8541 // collapsed or ordered loops).
8542 if (DVar.CKind == OMPC_unknown)
8543 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8544 PrivateRef);
8545 }
8546 }
8547 }
8548 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
8549 }
8550}
8551
8552/// Called on a for stmt to check and extract its iteration space
8553/// for further processing (such as collapsing).
8554static bool checkOpenMPIterationSpace(
8555 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8556 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8557 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8558 Expr *OrderedLoopCountExpr,
8559 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8560 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8561 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8562 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8563 // OpenMP [2.9.1, Canonical Loop Form]
8564 // for (init-expr; test-expr; incr-expr) structured-block
8565 // for (range-decl: range-expr) structured-block
8566 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8567 S = CanonLoop->getLoopStmt();
8568 auto *For = dyn_cast_or_null<ForStmt>(S);
8569 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8570 // Ranged for is supported only in OpenMP 5.0.
8571 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8572 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8573 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8574 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8575 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8576 if (TotalNestedLoopCount > 1) {
8577 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8578 SemaRef.Diag(DSA.getConstructLoc(),
8579 diag::note_omp_collapse_ordered_expr)
8580 << 2 << CollapseLoopCountExpr->getSourceRange()
8581 << OrderedLoopCountExpr->getSourceRange();
8582 else if (CollapseLoopCountExpr)
8583 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8584 diag::note_omp_collapse_ordered_expr)
8585 << 0 << CollapseLoopCountExpr->getSourceRange();
8586 else
8587 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8588 diag::note_omp_collapse_ordered_expr)
8589 << 1 << OrderedLoopCountExpr->getSourceRange();
8590 }
8591 return true;
8592 }
8593 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&((void)0)
8594 "No loop body.")((void)0);
8595
8596 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8597 For ? For->getForLoc() : CXXFor->getForLoc());
8598
8599 // Check init.
8600 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8601 if (ISC.checkAndSetInit(Init))
8602 return true;
8603
8604 bool HasErrors = false;
8605
8606 // Check loop variable's type.
8607 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8608 // OpenMP [2.6, Canonical Loop Form]
8609 // Var is one of the following:
8610 // A variable of signed or unsigned integer type.
8611 // For C++, a variable of a random access iterator type.
8612 // For C, a variable of a pointer type.
8613 QualType VarType = LCDecl->getType().getNonReferenceType();
8614 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8615 !VarType->isPointerType() &&
8616 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8617 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8618 << SemaRef.getLangOpts().CPlusPlus;
8619 HasErrors = true;
8620 }
8621
8622 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8623 // a Construct
8624 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8625 // parallel for construct is (are) private.
8626 // The loop iteration variable in the associated for-loop of a simd
8627 // construct with just one associated for-loop is linear with a
8628 // constant-linear-step that is the increment of the associated for-loop.
8629 // Exclude loop var from the list of variables with implicitly defined data
8630 // sharing attributes.
8631 VarsWithImplicitDSA.erase(LCDecl);
8632
8633 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")((void)0);
8634
8635 // Check test-expr.
8636 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8637
8638 // Check incr-expr.
8639 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8640 }
8641
8642 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8643 return HasErrors;
8644
8645 // Build the loop's iteration space representation.
8646 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8647 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8648 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8649 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8650 (isOpenMPWorksharingDirective(DKind) ||
8651 isOpenMPTaskLoopDirective(DKind) ||
8652 isOpenMPDistributeDirective(DKind) ||
8653 isOpenMPLoopTransformationDirective(DKind)),
8654 Captures);
8655 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8656 ISC.buildCounterVar(Captures, DSA);
8657 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8658 ISC.buildPrivateCounterVar();
8659 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8660 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8661 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8662 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8663 ISC.getConditionSrcRange();
8664 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8665 ISC.getIncrementSrcRange();
8666 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8667 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8668 ISC.isStrictTestOp();
8669 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8670 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8671 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8672 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8673 ISC.buildFinalCondition(DSA.getCurScope());
8674 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8675 ISC.doesInitDependOnLC();
8676 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8677 ISC.doesCondDependOnLC();
8678 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8679 ISC.getLoopDependentIdx();
8680
8681 HasErrors |=
8682 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8683 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8684 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8685 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8686 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8687 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8688 if (!HasErrors && DSA.isOrderedRegion()) {
8689 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8690 if (CurrentNestedLoopCount <
8691 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8692 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8693 CurrentNestedLoopCount,
8694 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8695 DSA.getOrderedRegionParam().second->setLoopCounter(
8696 CurrentNestedLoopCount,
8697 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8698 }
8699 }
8700 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8701 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8702 // Erroneous case - clause has some problems.
8703 continue;
8704 }
8705 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8706 Pair.second.size() <= CurrentNestedLoopCount) {
8707 // Erroneous case - clause has some problems.
8708 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8709 continue;
8710 }
8711 Expr *CntValue;
8712 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8713 CntValue = ISC.buildOrderedLoopData(
8714 DSA.getCurScope(),
8715 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8716 Pair.first->getDependencyLoc());
8717 else
8718 CntValue = ISC.buildOrderedLoopData(
8719 DSA.getCurScope(),
8720 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8721 Pair.first->getDependencyLoc(),
8722 Pair.second[CurrentNestedLoopCount].first,
8723 Pair.second[CurrentNestedLoopCount].second);
8724 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8725 }
8726 }
8727
8728 return HasErrors;
8729}
8730
8731/// Build 'VarRef = Start.
8732static ExprResult
8733buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8734 ExprResult Start, bool IsNonRectangularLB,
8735 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8736 // Build 'VarRef = Start.
8737 ExprResult NewStart = IsNonRectangularLB
8738 ? Start.get()
8739 : tryBuildCapture(SemaRef, Start.get(), Captures);
8740 if (!NewStart.isUsable())
8741 return ExprError();
8742 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8743 VarRef.get()->getType())) {
8744 NewStart = SemaRef.PerformImplicitConversion(
8745 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8746 /*AllowExplicit=*/true);
8747 if (!NewStart.isUsable())
8748 return ExprError();
8749 }
8750
8751 ExprResult Init =
8752 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8753 return Init;
8754}
8755
8756/// Build 'VarRef = Start + Iter * Step'.
8757static ExprResult buildCounterUpdate(
8758 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8759 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8760 bool IsNonRectangularLB,
8761 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8762 // Add parentheses (for debugging purposes only).
8763 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8764 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8765 !Step.isUsable())
8766 return ExprError();
8767
8768 ExprResult NewStep = Step;
8769 if (Captures)
8770 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8771 if (NewStep.isInvalid())
8772 return ExprError();
8773 ExprResult Update =
8774 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8775 if (!Update.isUsable())
8776 return ExprError();
8777
8778 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8779 // 'VarRef = Start (+|-) Iter * Step'.
8780 if (!Start.isUsable())
8781 return ExprError();
8782 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8783 if (!NewStart.isUsable())
8784 return ExprError();
8785 if (Captures && !IsNonRectangularLB)
8786 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8787 if (NewStart.isInvalid())
8788 return ExprError();
8789
8790 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8791 ExprResult SavedUpdate = Update;
8792 ExprResult UpdateVal;
8793 if (VarRef.get()->getType()->isOverloadableType() ||
8794 NewStart.get()->getType()->isOverloadableType() ||
8795 Update.get()->getType()->isOverloadableType()) {
8796 Sema::TentativeAnalysisScope Trap(SemaRef);
8797
8798 Update =
8799 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8800 if (Update.isUsable()) {
8801 UpdateVal =
8802 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8803 VarRef.get(), SavedUpdate.get());
8804 if (UpdateVal.isUsable()) {
8805 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8806 UpdateVal.get());
8807 }
8808 }
8809 }
8810
8811 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8812 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8813 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8814 NewStart.get(), SavedUpdate.get());
8815 if (!Update.isUsable())
8816 return ExprError();
8817
8818 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8819 VarRef.get()->getType())) {
8820 Update = SemaRef.PerformImplicitConversion(
8821 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8822 if (!Update.isUsable())
8823 return ExprError();
8824 }
8825
8826 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8827 }
8828 return Update;
8829}
8830
8831/// Convert integer expression \a E to make it have at least \a Bits
8832/// bits.
8833static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8834 if (E == nullptr)
8835 return ExprError();
8836 ASTContext &C = SemaRef.Context;
8837 QualType OldType = E->getType();
8838 unsigned HasBits = C.getTypeSize(OldType);
8839 if (HasBits >= Bits)
8840 return ExprResult(E);
8841 // OK to convert to signed, because new type has more bits than old.
8842 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8843 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8844 true);
8845}
8846
8847/// Check if the given expression \a E is a constant integer that fits
8848/// into \a Bits bits.
8849static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8850 if (E == nullptr)
8851 return false;
8852 if (Optional<llvm::APSInt> Result =
8853 E->getIntegerConstantExpr(SemaRef.Context))
8854 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8855 return false;
8856}
8857
8858/// Build preinits statement for the given declarations.
8859static Stmt *buildPreInits(ASTContext &Context,
8860 MutableArrayRef<Decl *> PreInits) {
8861 if (!PreInits.empty()) {
8862 return new (Context) DeclStmt(
8863 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8864 SourceLocation(), SourceLocation());
8865 }
8866 return nullptr;
8867}
8868
8869/// Build preinits statement for the given declarations.
8870static Stmt *
8871buildPreInits(ASTContext &Context,
8872 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8873 if (!Captures.empty()) {
8874 SmallVector<Decl *, 16> PreInits;
8875 for (const auto &Pair : Captures)
8876 PreInits.push_back(Pair.second->getDecl());
8877 return buildPreInits(Context, PreInits);
8878 }
8879 return nullptr;
8880}
8881
8882/// Build postupdate expression for the given list of postupdates expressions.
8883static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8884 Expr *PostUpdate = nullptr;
8885 if (!PostUpdates.empty()) {
8886 for (Expr *E : PostUpdates) {
8887 Expr *ConvE = S.BuildCStyleCastExpr(
8888 E->getExprLoc(),
8889 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8890 E->getExprLoc(), E)
8891 .get();
8892 PostUpdate = PostUpdate
8893 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8894 PostUpdate, ConvE)
8895 .get()
8896 : ConvE;
8897 }
8898 }
8899 return PostUpdate;
8900}
8901
8902/// Called on a for stmt to check itself and nested loops (if any).
8903/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8904/// number of collapsed loops otherwise.
8905static unsigned
8906checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8907 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8908 DSAStackTy &DSA,
8909 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8910 OMPLoopBasedDirective::HelperExprs &Built) {
8911 unsigned NestedLoopCount = 1;
8912 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8913 !isOpenMPLoopTransformationDirective(DKind);
8914
8915 if (CollapseLoopCountExpr) {
8916 // Found 'collapse' clause - calculate collapse number.
8917 Expr::EvalResult Result;
8918 if (!CollapseLoopCountExpr->isValueDependent() &&
8919 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8920 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8921 } else {
8922 Built.clear(/*Size=*/1);
8923 return 1;
8924 }
8925 }
8926 unsigned OrderedLoopCount = 1;
8927 if (OrderedLoopCountExpr) {
8928 // Found 'ordered' clause - calculate collapse number.
8929 Expr::EvalResult EVResult;
8930 if (!OrderedLoopCountExpr->isValueDependent() &&
8931 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8932 SemaRef.getASTContext())) {
8933 llvm::APSInt Result = EVResult.Val.getInt();
8934 if (Result.getLimitedValue() < NestedLoopCount) {
8935 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8936 diag::err_omp_wrong_ordered_loop_count)
8937 << OrderedLoopCountExpr->getSourceRange();
8938 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8939 diag::note_collapse_loop_count)
8940 << CollapseLoopCountExpr->getSourceRange();
8941 }
8942 OrderedLoopCount = Result.getLimitedValue();
8943 } else {
8944 Built.clear(/*Size=*/1);
8945 return 1;
8946 }
8947 }
8948 // This is helper routine for loop directives (e.g., 'for', 'simd',
8949 // 'for simd', etc.).
8950 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8951 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
8952 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
8953 if (!OMPLoopBasedDirective::doForAllLoops(
8954 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
8955 SupportsNonPerfectlyNested, NumLoops,
8956 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
8957 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
8958 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
8959 if (checkOpenMPIterationSpace(
8960 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8961 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
8962 VarsWithImplicitDSA, IterSpaces, Captures))
8963 return true;
8964 if (Cnt > 0 && Cnt >= NestedLoopCount &&
8965 IterSpaces[Cnt].CounterVar) {
8966 // Handle initialization of captured loop iterator variables.
8967 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8968 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8969 Captures[DRE] = DRE;
8970 }
8971 }
8972 return false;
8973 },
8974 [&SemaRef, &Captures](OMPLoopBasedDirective *Transform) {
8975 Stmt *DependentPreInits;
8976 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) {
8977 DependentPreInits = Dir->getPreInits();
8978 } else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) {
8979 DependentPreInits = Dir->getPreInits();
8980 } else {
8981 llvm_unreachable("Unexpected loop transformation")__builtin_unreachable();
8982 }
8983 if (!DependentPreInits)
8984 return;
8985 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
8986 auto *D = cast<VarDecl>(C);
8987 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
8988 Transform->getBeginLoc());
8989 Captures[Ref] = Ref;
8990 }
8991 }))
8992 return 0;
8993
8994 Built.clear(/* size */ NestedLoopCount);
8995
8996 if (SemaRef.CurContext->isDependentContext())
8997 return NestedLoopCount;
8998
8999 // An example of what is generated for the following code:
9000 //
9001 // #pragma omp simd collapse(2) ordered(2)
9002 // for (i = 0; i < NI; ++i)
9003 // for (k = 0; k < NK; ++k)
9004 // for (j = J0; j < NJ; j+=2) {
9005 // <loop body>
9006 // }
9007 //
9008 // We generate the code below.
9009 // Note: the loop body may be outlined in CodeGen.
9010 // Note: some counters may be C++ classes, operator- is used to find number of
9011 // iterations and operator+= to calculate counter value.
9012 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9013 // or i64 is currently supported).
9014 //
9015 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9016 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9017 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9018 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9019 // // similar updates for vars in clauses (e.g. 'linear')
9020 // <loop body (using local i and j)>
9021 // }
9022 // i = NI; // assign final values of counters
9023 // j = NJ;
9024 //
9025
9026 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9027 // the iteration counts of the collapsed for loops.
9028 // Precondition tests if there is at least one iteration (all conditions are
9029 // true).
9030 auto PreCond = ExprResult(IterSpaces[0].PreCond);
9031 Expr *N0 = IterSpaces[0].NumIterations;
9032 ExprResult LastIteration32 =
9033 widenIterationCount(/*Bits=*/32,
9034 SemaRef
9035 .PerformImplicitConversion(
9036 N0->IgnoreImpCasts(), N0->getType(),
9037 Sema::AA_Converting, /*AllowExplicit=*/true)
9038 .get(),
9039 SemaRef);
9040 ExprResult LastIteration64 = widenIterationCount(
9041 /*Bits=*/64,
9042 SemaRef
9043 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9044 Sema::AA_Converting,
9045 /*AllowExplicit=*/true)
9046 .get(),
9047 SemaRef);
9048
9049 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9050 return NestedLoopCount;
9051
9052 ASTContext &C = SemaRef.Context;
9053 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9054
9055 Scope *CurScope = DSA.getCurScope();
9056 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9057 if (PreCond.isUsable()) {
9058 PreCond =
9059 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9060 PreCond.get(), IterSpaces[Cnt].PreCond);
9061 }
9062 Expr *N = IterSpaces[Cnt].NumIterations;
9063 SourceLocation Loc = N->getExprLoc();
9064 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9065 if (LastIteration32.isUsable())
9066 LastIteration32 = SemaRef.BuildBinOp(
9067 CurScope, Loc, BO_Mul, LastIteration32.get(),
9068 SemaRef
9069 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9070 Sema::AA_Converting,
9071 /*AllowExplicit=*/true)
9072 .get());
9073 if (LastIteration64.isUsable())
9074 LastIteration64 = SemaRef.BuildBinOp(
9075 CurScope, Loc, BO_Mul, LastIteration64.get(),
9076 SemaRef
9077 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9078 Sema::AA_Converting,
9079 /*AllowExplicit=*/true)
9080 .get());
9081 }
9082
9083 // Choose either the 32-bit or 64-bit version.
9084 ExprResult LastIteration = LastIteration64;
9085 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9086 (LastIteration32.isUsable() &&
9087 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9088 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9089 fitsInto(
9090 /*Bits=*/32,
9091 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9092 LastIteration64.get(), SemaRef))))
9093 LastIteration = LastIteration32;
9094 QualType VType = LastIteration.get()->getType();
9095 QualType RealVType = VType;
9096 QualType StrideVType = VType;
9097 if (isOpenMPTaskLoopDirective(DKind)) {
9098 VType =
9099 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9100 StrideVType =
9101 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9102 }
9103
9104 if (!LastIteration.isUsable())
9105 return 0;
9106
9107 // Save the number of iterations.
9108 ExprResult NumIterations = LastIteration;
9109 {
9110 LastIteration = SemaRef.BuildBinOp(
9111 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9112 LastIteration.get(),
9113 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9114 if (!LastIteration.isUsable())
9115 return 0;
9116 }
9117
9118 // Calculate the last iteration number beforehand instead of doing this on
9119 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9120 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9121 ExprResult CalcLastIteration;
9122 if (!IsConstant) {
9123 ExprResult SaveRef =
9124 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9125 LastIteration = SaveRef;
9126
9127 // Prepare SaveRef + 1.
9128 NumIterations = SemaRef.BuildBinOp(
9129 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9130 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9131 if (!NumIterations.isUsable())
9132 return 0;
9133 }
9134
9135 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9136
9137 // Build variables passed into runtime, necessary for worksharing directives.
9138 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9139 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9140 isOpenMPDistributeDirective(DKind) ||
9141 isOpenMPLoopTransformationDirective(DKind)) {
9142 // Lower bound variable, initialized with zero.
9143 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9144 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9145 SemaRef.AddInitializerToDecl(LBDecl,
9146 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9147 /*DirectInit*/ false);
9148
9149 // Upper bound variable, initialized with last iteration number.
9150 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9151 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9152 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9153 /*DirectInit*/ false);
9154
9155 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9156 // This will be used to implement clause 'lastprivate'.
9157 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9158 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9159 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9160 SemaRef.AddInitializerToDecl(ILDecl,
9161 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9162 /*DirectInit*/ false);
9163
9164 // Stride variable returned by runtime (we initialize it to 1 by default).
9165 VarDecl *STDecl =
9166 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9167 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9168 SemaRef.AddInitializerToDecl(STDecl,
9169 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9170 /*DirectInit*/ false);
9171
9172 // Build expression: UB = min(UB, LastIteration)
9173 // It is necessary for CodeGen of directives with static scheduling.
9174 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9175 UB.get(), LastIteration.get());
9176 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9177 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9178 LastIteration.get(), UB.get());
9179 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9180 CondOp.get());
9181 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9182
9183 // If we have a combined directive that combines 'distribute', 'for' or
9184 // 'simd' we need to be able to access the bounds of the schedule of the
9185 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9186 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9187 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9188 // Lower bound variable, initialized with zero.
9189 VarDecl *CombLBDecl =
9190 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9191 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9192 SemaRef.AddInitializerToDecl(
9193 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9194 /*DirectInit*/ false);
9195
9196 // Upper bound variable, initialized with last iteration number.
9197 VarDecl *CombUBDecl =
9198 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9199 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9200 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9201 /*DirectInit*/ false);
9202
9203 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9204 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9205 ExprResult CombCondOp =
9206 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9207 LastIteration.get(), CombUB.get());
9208 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9209 CombCondOp.get());
9210 CombEUB =
9211 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9212
9213 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9214 // We expect to have at least 2 more parameters than the 'parallel'
9215 // directive does - the lower and upper bounds of the previous schedule.
9216 assert(CD->getNumParams() >= 4 &&((void)0)
9217 "Unexpected number of parameters in loop combined directive")((void)0);
9218
9219 // Set the proper type for the bounds given what we learned from the
9220 // enclosed loops.
9221 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9222 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9223
9224 // Previous lower and upper bounds are obtained from the region
9225 // parameters.
9226 PrevLB =
9227 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9228 PrevUB =
9229 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9230 }
9231 }
9232
9233 // Build the iteration variable and its initialization before loop.
9234 ExprResult IV;
9235 ExprResult Init, CombInit;
9236 {
9237 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9238 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9239 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9240 isOpenMPTaskLoopDirective(DKind) ||
9241 isOpenMPDistributeDirective(DKind) ||
9242 isOpenMPLoopTransformationDirective(DKind))
9243 ? LB.get()
9244 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9245 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9246 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9247
9248 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9249 Expr *CombRHS =
9250 (isOpenMPWorksharingDirective(DKind) ||
9251 isOpenMPTaskLoopDirective(DKind) ||
9252 isOpenMPDistributeDirective(DKind))
9253 ? CombLB.get()
9254 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9255 CombInit =
9256 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9257 CombInit =
9258 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9259 }
9260 }
9261
9262 bool UseStrictCompare =
9263 RealVType->hasUnsignedIntegerRepresentation() &&
9264 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9265 return LIS.IsStrictCompare;
9266 });
9267 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9268 // unsigned IV)) for worksharing loops.
9269 SourceLocation CondLoc = AStmt->getBeginLoc();
9270 Expr *BoundUB = UB.get();
9271 if (UseStrictCompare) {
9272 BoundUB =
9273 SemaRef
9274 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9275 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9276 .get();
9277 BoundUB =
9278 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9279 }
9280 ExprResult Cond =
9281 (isOpenMPWorksharingDirective(DKind) ||
9282 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9283 isOpenMPLoopTransformationDirective(DKind))
9284 ? SemaRef.BuildBinOp(CurScope, CondLoc,
9285 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9286 BoundUB)
9287 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9288 NumIterations.get());
9289 ExprResult CombDistCond;
9290 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9291 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9292 NumIterations.get());
9293 }
9294
9295 ExprResult CombCond;
9296 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9297 Expr *BoundCombUB = CombUB.get();
9298 if (UseStrictCompare) {
9299 BoundCombUB =
9300 SemaRef
9301 .BuildBinOp(
9302 CurScope, CondLoc, BO_Add, BoundCombUB,
9303 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9304 .get();
9305 BoundCombUB =
9306 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9307 .get();
9308 }
9309 CombCond =
9310 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9311 IV.get(), BoundCombUB);
9312 }
9313 // Loop increment (IV = IV + 1)
9314 SourceLocation IncLoc = AStmt->getBeginLoc();
9315 ExprResult Inc =
9316 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9317 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9318 if (!Inc.isUsable())
9319 return 0;
9320 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9321 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9322 if (!Inc.isUsable())
9323 return 0;
9324
9325 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9326 // Used for directives with static scheduling.
9327 // In combined construct, add combined version that use CombLB and CombUB
9328 // base variables for the update
9329 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9330 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9331 isOpenMPDistributeDirective(DKind) ||
9332 isOpenMPLoopTransformationDirective(DKind)) {
9333 // LB + ST
9334 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9335 if (!NextLB.isUsable())
9336 return 0;
9337 // LB = LB + ST
9338 NextLB =
9339 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9340 NextLB =
9341 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9342 if (!NextLB.isUsable())
9343 return 0;
9344 // UB + ST
9345 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9346 if (!NextUB.isUsable())
9347 return 0;
9348 // UB = UB + ST
9349 NextUB =
9350 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9351 NextUB =
9352 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9353 if (!NextUB.isUsable())
9354 return 0;
9355 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9356 CombNextLB =
9357 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9358 if (!NextLB.isUsable())
9359 return 0;
9360 // LB = LB + ST
9361 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9362 CombNextLB.get());
9363 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9364 /*DiscardedValue*/ false);
9365 if (!CombNextLB.isUsable())
9366 return 0;
9367 // UB + ST
9368 CombNextUB =
9369 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9370 if (!CombNextUB.isUsable())
9371 return 0;
9372 // UB = UB + ST
9373 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9374 CombNextUB.get());
9375 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9376 /*DiscardedValue*/ false);
9377 if (!CombNextUB.isUsable())
9378 return 0;
9379 }
9380 }
9381
9382 // Create increment expression for distribute loop when combined in a same
9383 // directive with for as IV = IV + ST; ensure upper bound expression based
9384 // on PrevUB instead of NumIterations - used to implement 'for' when found
9385 // in combination with 'distribute', like in 'distribute parallel for'
9386 SourceLocation DistIncLoc = AStmt->getBeginLoc();
9387 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9388 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9389 DistCond = SemaRef.BuildBinOp(
9390 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9391 assert(DistCond.isUsable() && "distribute cond expr was not built")((void)0);
9392
9393 DistInc =
9394 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9395 assert(DistInc.isUsable() && "distribute inc expr was not built")((void)0);
9396 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9397 DistInc.get());
9398 DistInc =
9399 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9400 assert(DistInc.isUsable() && "distribute inc expr was not built")((void)0);
9401
9402 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9403 // construct
9404 ExprResult NewPrevUB = PrevUB;
9405 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9406 if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9407 PrevUB.get()->getType())) {
9408 NewPrevUB = SemaRef.BuildCStyleCastExpr(
9409 DistEUBLoc,
9410 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9411 DistEUBLoc, NewPrevUB.get());
9412 if (!NewPrevUB.isUsable())
9413 return 0;
9414 }
9415 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9416 UB.get(), NewPrevUB.get());
9417 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9418 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9419 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9420 CondOp.get());
9421 PrevEUB =
9422 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9423
9424 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9425 // parallel for is in combination with a distribute directive with
9426 // schedule(static, 1)
9427 Expr *BoundPrevUB = PrevUB.get();
9428 if (UseStrictCompare) {
9429 BoundPrevUB =
9430 SemaRef
9431 .BuildBinOp(
9432 CurScope, CondLoc, BO_Add, BoundPrevUB,
9433 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9434 .get();
9435 BoundPrevUB =
9436 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9437 .get();
9438 }
9439 ParForInDistCond =
9440 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9441 IV.get(), BoundPrevUB);
9442 }
9443
9444 // Build updates and final values of the loop counters.
9445 bool HasErrors = false;
9446 Built.Counters.resize(NestedLoopCount);
9447 Built.Inits.resize(NestedLoopCount);
9448 Built.Updates.resize(NestedLoopCount);
9449 Built.Finals.resize(NestedLoopCount);
9450 Built.DependentCounters.resize(NestedLoopCount);
9451 Built.DependentInits.resize(NestedLoopCount);
9452 Built.FinalsConditions.resize(NestedLoopCount);
9453 {
9454 // We implement the following algorithm for obtaining the
9455 // original loop iteration variable values based on the
9456 // value of the collapsed loop iteration variable IV.
9457 //
9458 // Let n+1 be the number of collapsed loops in the nest.
9459 // Iteration variables (I0, I1, .... In)
9460 // Iteration counts (N0, N1, ... Nn)
9461 //
9462 // Acc = IV;
9463 //
9464 // To compute Ik for loop k, 0 <= k <= n, generate:
9465 // Prod = N(k+1) * N(k+2) * ... * Nn;
9466 // Ik = Acc / Prod;
9467 // Acc -= Ik * Prod;
9468 //
9469 ExprResult Acc = IV;
9470 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9471 LoopIterationSpace &IS = IterSpaces[Cnt];
9472 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9473 ExprResult Iter;
9474
9475 // Compute prod
9476 ExprResult Prod =
9477 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9478 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9479 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9480 IterSpaces[K].NumIterations);
9481
9482 // Iter = Acc / Prod
9483 // If there is at least one more inner loop to avoid
9484 // multiplication by 1.
9485 if (Cnt + 1 < NestedLoopCount)
9486 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9487 Acc.get(), Prod.get());
9488 else
9489 Iter = Acc;
9490 if (!Iter.isUsable()) {
9491 HasErrors = true;
9492 break;
9493 }
9494
9495 // Update Acc:
9496 // Acc -= Iter * Prod
9497 // Check if there is at least one more inner loop to avoid
9498 // multiplication by 1.
9499 if (Cnt + 1 < NestedLoopCount)
9500 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9501 Iter.get(), Prod.get());
9502 else
9503 Prod = Iter;
9504 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9505 Acc.get(), Prod.get());
9506
9507 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9508 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9509 DeclRefExpr *CounterVar = buildDeclRefExpr(
9510 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9511 /*RefersToCapture=*/true);
9512 ExprResult Init =
9513 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9514 IS.CounterInit, IS.IsNonRectangularLB, Captures);
9515 if (!Init.isUsable()) {
9516 HasErrors = true;
9517 break;
9518 }
9519 ExprResult Update = buildCounterUpdate(
9520 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9521 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9522 if (!Update.isUsable()) {
9523 HasErrors = true;
9524 break;
9525 }
9526
9527 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9528 ExprResult Final =
9529 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9530 IS.CounterInit, IS.NumIterations, IS.CounterStep,
9531 IS.Subtract, IS.IsNonRectangularLB, &Captures);
9532 if (!Final.isUsable()) {
9533 HasErrors = true;
9534 break;
9535 }
9536
9537 if (!Update.isUsable() || !Final.isUsable()) {
9538 HasErrors = true;
9539 break;
9540 }
9541 // Save results
9542 Built.Counters[Cnt] = IS.CounterVar;
9543 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9544 Built.Inits[Cnt] = Init.get();
9545 Built.Updates[Cnt] = Update.get();
9546 Built.Finals[Cnt] = Final.get();
9547 Built.DependentCounters[Cnt] = nullptr;
9548 Built.DependentInits[Cnt] = nullptr;
9549 Built.FinalsConditions[Cnt] = nullptr;
9550 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9551 Built.DependentCounters[Cnt] =
9552 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9553 Built.DependentInits[Cnt] =
9554 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9555 Built.FinalsConditions[Cnt] = IS.FinalCondition;
9556 }
9557 }
9558 }
9559
9560 if (HasErrors)
9561 return 0;
9562
9563 // Save results
9564 Built.IterationVarRef = IV.get();
9565 Built.LastIteration = LastIteration.get();
9566 Built.NumIterations = NumIterations.get();
9567 Built.CalcLastIteration = SemaRef
9568 .ActOnFinishFullExpr(CalcLastIteration.get(),
9569 /*DiscardedValue=*/false)
9570 .get();
9571 Built.PreCond = PreCond.get();
9572 Built.PreInits = buildPreInits(C, Captures);
9573 Built.Cond = Cond.get();
9574 Built.Init = Init.get();
9575 Built.Inc = Inc.get();
9576 Built.LB = LB.get();
9577 Built.UB = UB.get();
9578 Built.IL = IL.get();
9579 Built.ST = ST.get();
9580 Built.EUB = EUB.get();
9581 Built.NLB = NextLB.get();
9582 Built.NUB = NextUB.get();
9583 Built.PrevLB = PrevLB.get();
9584 Built.PrevUB = PrevUB.get();
9585 Built.DistInc = DistInc.get();
9586 Built.PrevEUB = PrevEUB.get();
9587 Built.DistCombinedFields.LB = CombLB.get();
9588 Built.DistCombinedFields.UB = CombUB.get();
9589 Built.DistCombinedFields.EUB = CombEUB.get();
9590 Built.DistCombinedFields.Init = CombInit.get();
9591 Built.DistCombinedFields.Cond = CombCond.get();
9592 Built.DistCombinedFields.NLB = CombNextLB.get();
9593 Built.DistCombinedFields.NUB = CombNextUB.get();
9594 Built.DistCombinedFields.DistCond = CombDistCond.get();
9595 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9596
9597 return NestedLoopCount;
9598}
9599
9600static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9601 auto CollapseClauses =
9602 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9603 if (CollapseClauses.begin() != CollapseClauses.end())
9604 return (*CollapseClauses.begin())->getNumForLoops();
9605 return nullptr;
9606}
9607
9608static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9609 auto OrderedClauses =
9610 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9611 if (OrderedClauses.begin() != OrderedClauses.end())
9612 return (*OrderedClauses.begin())->getNumForLoops();
9613 return nullptr;
9614}
9615
9616static bool checkSimdlenSafelenSpecified(Sema &S,
9617 const ArrayRef<OMPClause *> Clauses) {
9618 const OMPSafelenClause *Safelen = nullptr;
9619 const OMPSimdlenClause *Simdlen = nullptr;
9620
9621 for (const OMPClause *Clause : Clauses) {
9622 if (Clause->getClauseKind() == OMPC_safelen)
9623 Safelen = cast<OMPSafelenClause>(Clause);
9624 else if (Clause->getClauseKind() == OMPC_simdlen)
9625 Simdlen = cast<OMPSimdlenClause>(Clause);
9626 if (Safelen && Simdlen)
9627 break;
9628 }
9629
9630 if (Simdlen && Safelen) {
9631 const Expr *SimdlenLength = Simdlen->getSimdlen();
9632 const Expr *SafelenLength = Safelen->getSafelen();
9633 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9634 SimdlenLength->isInstantiationDependent() ||
9635 SimdlenLength->containsUnexpandedParameterPack())
9636 return false;
9637 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9638 SafelenLength->isInstantiationDependent() ||
9639 SafelenLength->containsUnexpandedParameterPack())
9640 return false;
9641 Expr::EvalResult SimdlenResult, SafelenResult;
9642 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9643 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9644 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9645 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9646 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9647 // If both simdlen and safelen clauses are specified, the value of the
9648 // simdlen parameter must be less than or equal to the value of the safelen
9649 // parameter.
9650 if (SimdlenRes > SafelenRes) {
9651 S.Diag(SimdlenLength->getExprLoc(),
9652 diag::err_omp_wrong_simdlen_safelen_values)
9653 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9654 return true;
9655 }
9656 }
9657 return false;
9658}
9659
9660StmtResult
9661Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9662 SourceLocation StartLoc, SourceLocation EndLoc,
9663 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9664 if (!AStmt)
9665 return StmtError();
9666
9667 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
9668 OMPLoopBasedDirective::HelperExprs B;
9669 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9670 // define the nested loops number.
9671 unsigned NestedLoopCount = checkOpenMPLoop(
9672 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9673 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9674 if (NestedLoopCount == 0)
9675 return StmtError();
9676
9677 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
9678 "omp simd loop exprs were not built")((void)0);
9679
9680 if (!CurContext->isDependentContext()) {
9681 // Finalize the clauses that need pre-built expressions for CodeGen.
9682 for (OMPClause *C : Clauses) {
9683 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9684 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9685 B.NumIterations, *this, CurScope,
9686 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9687 return StmtError();
9688 }
9689 }
9690
9691 if (checkSimdlenSafelenSpecified(*this, Clauses))
9692 return StmtError();
9693
9694 setFunctionHasBranchProtectedScope();
9695 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9696 Clauses, AStmt, B);
9697}
9698
9699StmtResult
9700Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9701 SourceLocation StartLoc, SourceLocation EndLoc,
9702 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9703 if (!AStmt)
9704 return StmtError();
9705
9706 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
9707 OMPLoopBasedDirective::HelperExprs B;
9708 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9709 // define the nested loops number.
9710 unsigned NestedLoopCount = checkOpenMPLoop(
9711 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9712 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9713 if (NestedLoopCount == 0)
9714 return StmtError();
9715
9716 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
9717 "omp for loop exprs were not built")((void)0);
9718
9719 if (!CurContext->isDependentContext()) {
9720 // Finalize the clauses that need pre-built expressions for CodeGen.
9721 for (OMPClause *C : Clauses) {
9722 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9723 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9724 B.NumIterations, *this, CurScope,
9725 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9726 return StmtError();
9727 }
9728 }
9729
9730 setFunctionHasBranchProtectedScope();
9731 return OMPForDirective::Create(
9732 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9733 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9734}
9735
9736StmtResult Sema::ActOnOpenMPForSimdDirective(
9737 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9738 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9739 if (!AStmt)
9740 return StmtError();
9741
9742 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
9743 OMPLoopBasedDirective::HelperExprs B;
9744 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9745 // define the nested loops number.
9746 unsigned NestedLoopCount =
9747 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9748 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9749 VarsWithImplicitDSA, B);
9750 if (NestedLoopCount == 0)
9751 return StmtError();
9752
9753 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
9754 "omp for simd loop exprs were not built")((void)0);
9755
9756 if (!CurContext->isDependentContext()) {
9757 // Finalize the clauses that need pre-built expressions for CodeGen.
9758 for (OMPClause *C : Clauses) {
9759 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9760 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9761 B.NumIterations, *this, CurScope,
9762 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9763 return StmtError();
9764 }
9765 }
9766
9767 if (checkSimdlenSafelenSpecified(*this, Clauses))
9768 return StmtError();
9769
9770 setFunctionHasBranchProtectedScope();
9771 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9772 Clauses, AStmt, B);
9773}
9774
9775StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9776 Stmt *AStmt,
9777 SourceLocation StartLoc,
9778 SourceLocation EndLoc) {
9779 if (!AStmt)
9780 return StmtError();
9781
9782 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
9783 auto BaseStmt = AStmt;
9784 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9785 BaseStmt = CS->getCapturedStmt();
9786 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9787 auto S = C->children();
9788 if (S.begin() == S.end())
9789 return StmtError();
9790 // All associated statements must be '#pragma omp section' except for
9791 // the first one.
9792 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9793 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9794 if (SectionStmt)
9795 Diag(SectionStmt->getBeginLoc(),
9796 diag::err_omp_sections_substmt_not_section);
9797 return StmtError();
9798 }
9799 cast<OMPSectionDirective>(SectionStmt)
9800 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9801 }
9802 } else {
9803 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9804 return StmtError();
9805 }
9806
9807 setFunctionHasBranchProtectedScope();
9808
9809 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9810 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
9811 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9812}
9813
9814StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9815 SourceLocation StartLoc,
9816 SourceLocation EndLoc) {
9817 if (!AStmt)
9818 return StmtError();
9819
9820 setFunctionHasBranchProtectedScope();
9821 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9822
9823 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9824 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9825}
9826
9827static Expr *getDirectCallExpr(Expr *E) {
9828 E = E->IgnoreParenCasts()->IgnoreImplicit();
9829 if (auto *CE = dyn_cast<CallExpr>(E))
9830 if (CE->getDirectCallee())
9831 return E;
9832 return nullptr;
9833}
9834
9835StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
9836 Stmt *AStmt,
9837 SourceLocation StartLoc,
9838 SourceLocation EndLoc) {
9839 if (!AStmt)
9840 return StmtError();
9841
9842 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
9843
9844 // 5.1 OpenMP
9845 // expression-stmt : an expression statement with one of the following forms:
9846 // expression = target-call ( [expression-list] );
9847 // target-call ( [expression-list] );
9848
9849 SourceLocation TargetCallLoc;
9850
9851 if (!CurContext->isDependentContext()) {
9852 Expr *TargetCall = nullptr;
9853
9854 auto *E = dyn_cast<Expr>(S);
9855 if (!E) {
9856 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9857 return StmtError();
9858 }
9859
9860 E = E->IgnoreParenCasts()->IgnoreImplicit();
9861
9862 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
9863 if (BO->getOpcode() == BO_Assign)
9864 TargetCall = getDirectCallExpr(BO->getRHS());
9865 } else {
9866 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
9867 if (COCE->getOperator() == OO_Equal)
9868 TargetCall = getDirectCallExpr(COCE->getArg(1));
9869 if (!TargetCall)
9870 TargetCall = getDirectCallExpr(E);
9871 }
9872 if (!TargetCall) {
9873 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9874 return StmtError();
9875 }
9876 TargetCallLoc = TargetCall->getExprLoc();
9877 }
9878
9879 setFunctionHasBranchProtectedScope();
9880
9881 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9882 TargetCallLoc);
9883}
9884
9885StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9886 Stmt *AStmt,
9887 SourceLocation StartLoc,
9888 SourceLocation EndLoc) {
9889 if (!AStmt)
9890 return StmtError();
9891
9892 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
9893
9894 setFunctionHasBranchProtectedScope();
9895
9896 // OpenMP [2.7.3, single Construct, Restrictions]
9897 // The copyprivate clause must not be used with the nowait clause.
9898 const OMPClause *Nowait = nullptr;
9899 const OMPClause *Copyprivate = nullptr;
9900 for (const OMPClause *Clause : Clauses) {
9901 if (Clause->getClauseKind() == OMPC_nowait)
9902 Nowait = Clause;
9903 else if (Clause->getClauseKind() == OMPC_copyprivate)
9904 Copyprivate = Clause;
9905 if (Copyprivate && Nowait) {
9906 Diag(Copyprivate->getBeginLoc(),
9907 diag::err_omp_single_copyprivate_with_nowait);
9908 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9909 return StmtError();
9910 }
9911 }
9912
9913 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9914}
9915
9916StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9917 SourceLocation StartLoc,
9918 SourceLocation EndLoc) {
9919 if (!AStmt)
9920 return StmtError();
9921
9922 setFunctionHasBranchProtectedScope();
9923
9924 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9925}
9926
9927StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
9928 Stmt *AStmt,
9929 SourceLocation StartLoc,
9930 SourceLocation EndLoc) {
9931 if (!AStmt)
9932 return StmtError();
9933
9934 setFunctionHasBranchProtectedScope();
9935
9936 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9937}
9938
9939StmtResult Sema::ActOnOpenMPCriticalDirective(
9940 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9941 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9942 if (!AStmt)
9943 return StmtError();
9944
9945 bool ErrorFound = false;
9946 llvm::APSInt Hint;
9947 SourceLocation HintLoc;
9948 bool DependentHint = false;
9949 for (const OMPClause *C : Clauses) {
9950 if (C->getClauseKind() == OMPC_hint) {
9951 if (!DirName.getName()) {
9952 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9953 ErrorFound = true;
9954 }
9955 Expr *E = cast<OMPHintClause>(C)->getHint();
9956 if (E->isTypeDependent() || E->isValueDependent() ||
9957 E->isInstantiationDependent()) {
9958 DependentHint = true;
9959 } else {
9960 Hint = E->EvaluateKnownConstInt(Context);
9961 HintLoc = C->getBeginLoc();
9962 }
9963 }
9964 }
9965 if (ErrorFound)
9966 return StmtError();
9967 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
9968 if (Pair.first && DirName.getName() && !DependentHint) {
9969 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9970 Diag(StartLoc, diag::err_omp_critical_with_hint);
9971 if (HintLoc.isValid())
9972 Diag(HintLoc, diag::note_omp_critical_hint_here)
9973 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
9974 else
9975 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9976 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9977 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9978 << 1
9979 << toString(C->getHint()->EvaluateKnownConstInt(Context),
9980 /*Radix=*/10, /*Signed=*/false);
9981 } else {
9982 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9983 }
9984 }
9985 }
9986
9987 setFunctionHasBranchProtectedScope();
9988
9989 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9990 Clauses, AStmt);
9991 if (!Pair.first && DirName.getName() && !DependentHint)
9992 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
9993 return Dir;
9994}
9995
9996StmtResult Sema::ActOnOpenMPParallelForDirective(
9997 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9998 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9999 if (!AStmt)
10000 return StmtError();
10001
10002 auto *CS = cast<CapturedStmt>(AStmt);
10003 // 1.2.2 OpenMP Language Terminology
10004 // Structured block - An executable statement with a single entry at the
10005 // top and a single exit at the bottom.
10006 // The point of exit cannot be a branch out of the structured block.
10007 // longjmp() and throw() must not violate the entry/exit criteria.
10008 CS->getCapturedDecl()->setNothrow();
10009
10010 OMPLoopBasedDirective::HelperExprs B;
10011 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10012 // define the nested loops number.
10013 unsigned NestedLoopCount =
10014 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10015 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10016 VarsWithImplicitDSA, B);
10017 if (NestedLoopCount == 0)
10018 return StmtError();
10019
10020 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
10021 "omp parallel for loop exprs were not built")((void)0);
10022
10023 if (!CurContext->isDependentContext()) {
10024 // Finalize the clauses that need pre-built expressions for CodeGen.
10025 for (OMPClause *C : Clauses) {
10026 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10027 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10028 B.NumIterations, *this, CurScope,
10029 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10030 return StmtError();
10031 }
10032 }
10033
10034 setFunctionHasBranchProtectedScope();
10035 return OMPParallelForDirective::Create(
10036 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10037 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10038}
10039
10040StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10041 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10042 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10043 if (!AStmt)
10044 return StmtError();
10045
10046 auto *CS = cast<CapturedStmt>(AStmt);
10047 // 1.2.2 OpenMP Language Terminology
10048 // Structured block - An executable statement with a single entry at the
10049 // top and a single exit at the bottom.
10050 // The point of exit cannot be a branch out of the structured block.
10051 // longjmp() and throw() must not violate the entry/exit criteria.
10052 CS->getCapturedDecl()->setNothrow();
10053
10054 OMPLoopBasedDirective::HelperExprs B;
10055 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10056 // define the nested loops number.
10057 unsigned NestedLoopCount =
10058 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10059 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10060 VarsWithImplicitDSA, B);
10061 if (NestedLoopCount == 0)
10062 return StmtError();
10063
10064 if (!CurContext->isDependentContext()) {
10065 // Finalize the clauses that need pre-built expressions for CodeGen.
10066 for (OMPClause *C : Clauses) {
10067 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10068 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10069 B.NumIterations, *this, CurScope,
10070 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10071 return StmtError();
10072 }
10073 }
10074
10075 if (checkSimdlenSafelenSpecified(*this, Clauses))
10076 return StmtError();
10077
10078 setFunctionHasBranchProtectedScope();
10079 return OMPParallelForSimdDirective::Create(
10080 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10081}
10082
10083StmtResult
10084Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10085 Stmt *AStmt, SourceLocation StartLoc,
10086 SourceLocation EndLoc) {
10087 if (!AStmt)
10088 return StmtError();
10089
10090 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
10091 auto *CS = cast<CapturedStmt>(AStmt);
10092 // 1.2.2 OpenMP Language Terminology
10093 // Structured block - An executable statement with a single entry at the
10094 // top and a single exit at the bottom.
10095 // The point of exit cannot be a branch out of the structured block.
10096 // longjmp() and throw() must not violate the entry/exit criteria.
10097 CS->getCapturedDecl()->setNothrow();
10098
10099 setFunctionHasBranchProtectedScope();
10100
10101 return OMPParallelMasterDirective::Create(
10102 Context, StartLoc, EndLoc, Clauses, AStmt,
10103 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10104}
10105
10106StmtResult
10107Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10108 Stmt *AStmt, SourceLocation StartLoc,
10109 SourceLocation EndLoc) {
10110 if (!AStmt)
10111 return StmtError();
10112
10113 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
10114 auto BaseStmt = AStmt;
10115 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10116 BaseStmt = CS->getCapturedStmt();
10117 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10118 auto S = C->children();
10119 if (S.begin() == S.end())
10120 return StmtError();
10121 // All associated statements must be '#pragma omp section' except for
10122 // the first one.
10123 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
10124 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10125 if (SectionStmt)
10126 Diag(SectionStmt->getBeginLoc(),
10127 diag::err_omp_parallel_sections_substmt_not_section);
10128 return StmtError();
10129 }
10130 cast<OMPSectionDirective>(SectionStmt)
10131 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10132 }
10133 } else {
10134 Diag(AStmt->getBeginLoc(),
10135 diag::err_omp_parallel_sections_not_compound_stmt);
10136 return StmtError();
10137 }
10138
10139 setFunctionHasBranchProtectedScope();
10140
10141 return OMPParallelSectionsDirective::Create(
10142 Context, StartLoc, EndLoc, Clauses, AStmt,
10143 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10144}
10145
10146/// Find and diagnose mutually exclusive clause kinds.
10147static bool checkMutuallyExclusiveClauses(
10148 Sema &S, ArrayRef<OMPClause *> Clauses,
10149 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10150 const OMPClause *PrevClause = nullptr;
10151 bool ErrorFound = false;
10152 for (const OMPClause *C : Clauses) {
10153 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10154 if (!PrevClause) {
10155 PrevClause = C;
10156 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10157 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10158 << getOpenMPClauseName(C->getClauseKind())
10159 << getOpenMPClauseName(PrevClause->getClauseKind());
10160 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10161 << getOpenMPClauseName(PrevClause->getClauseKind());
10162 ErrorFound = true;
10163 }
10164 }
10165 }
10166 return ErrorFound;
10167}
10168
10169StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10170 Stmt *AStmt, SourceLocation StartLoc,
10171 SourceLocation EndLoc) {
10172 if (!AStmt)
10173 return StmtError();
10174
10175 // OpenMP 5.0, 2.10.1 task Construct
10176 // If a detach clause appears on the directive, then a mergeable clause cannot
10177 // appear on the same directive.
10178 if (checkMutuallyExclusiveClauses(*this, Clauses,
10179 {OMPC_detach, OMPC_mergeable}))
10180 return StmtError();
10181
10182 auto *CS = cast<CapturedStmt>(AStmt);
10183 // 1.2.2 OpenMP Language Terminology
10184 // Structured block - An executable statement with a single entry at the
10185 // top and a single exit at the bottom.
10186 // The point of exit cannot be a branch out of the structured block.
10187 // longjmp() and throw() must not violate the entry/exit criteria.
10188 CS->getCapturedDecl()->setNothrow();
10189
10190 setFunctionHasBranchProtectedScope();
10191
10192 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10193 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10194}
10195
10196StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10197 SourceLocation EndLoc) {
10198 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10199}
10200
10201StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10202 SourceLocation EndLoc) {
10203 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10204}
10205
10206StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
10207 SourceLocation EndLoc) {
10208 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
10209}
10210
10211StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10212 Stmt *AStmt,
10213 SourceLocation StartLoc,
10214 SourceLocation EndLoc) {
10215 if (!AStmt)
10216 return StmtError();
10217
10218 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
10219
10220 setFunctionHasBranchProtectedScope();
10221
10222 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10223 AStmt,
10224 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10225}
10226
10227StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10228 SourceLocation StartLoc,
10229 SourceLocation EndLoc) {
10230 OMPFlushClause *FC = nullptr;
10231 OMPClause *OrderClause = nullptr;
10232 for (OMPClause *C : Clauses) {
10233 if (C->getClauseKind() == OMPC_flush)
10234 FC = cast<OMPFlushClause>(C);
10235 else
10236 OrderClause = C;
10237 }
10238 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10239 SourceLocation MemOrderLoc;
10240 for (const OMPClause *C : Clauses) {
10241 if (C->getClauseKind() == OMPC_acq_rel ||
10242 C->getClauseKind() == OMPC_acquire ||
10243 C->getClauseKind() == OMPC_release) {
10244 if (MemOrderKind != OMPC_unknown) {
10245 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10246 << getOpenMPDirectiveName(OMPD_flush) << 1
10247 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10248 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10249 << getOpenMPClauseName(MemOrderKind);
10250 } else {
10251 MemOrderKind = C->getClauseKind();
10252 MemOrderLoc = C->getBeginLoc();
10253 }
10254 }
10255 }
10256 if (FC && OrderClause) {
10257 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10258 << getOpenMPClauseName(OrderClause->getClauseKind());
10259 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10260 << getOpenMPClauseName(OrderClause->getClauseKind());
10261 return StmtError();
10262 }
10263 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10264}
10265
10266StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10267 SourceLocation StartLoc,
10268 SourceLocation EndLoc) {
10269 if (Clauses.empty()) {
10270 Diag(StartLoc, diag::err_omp_depobj_expected);
10271 return StmtError();
10272 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10273 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10274 return StmtError();
10275 }
10276 // Only depobj expression and another single clause is allowed.
10277 if (Clauses.size() > 2) {
10278 Diag(Clauses[2]->getBeginLoc(),
10279 diag::err_omp_depobj_single_clause_expected);
10280 return StmtError();
10281 } else if (Clauses.size() < 1) {
10282 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10283 return StmtError();
10284 }
10285 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10286}
10287
10288StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10289 SourceLocation StartLoc,
10290 SourceLocation EndLoc) {
10291 // Check that exactly one clause is specified.
10292 if (Clauses.size() != 1) {
10293 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10294 diag::err_omp_scan_single_clause_expected);
10295 return StmtError();
10296 }
10297 // Check that scan directive is used in the scopeof the OpenMP loop body.
10298 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
10299 Scope *ParentS = S->getParent();
10300 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10301 !ParentS->getBreakParent()->isOpenMPLoopScope())
10302 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10303 << getOpenMPDirectiveName(OMPD_scan) << 5);
10304 }
10305 // Check that only one instance of scan directives is used in the same outer
10306 // region.
10307 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
10308 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10309 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
10310 diag::note_omp_previous_directive)
10311 << "scan";
10312 return StmtError();
10313 }
10314 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
10315 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10316}
10317
10318StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10319 Stmt *AStmt,
10320 SourceLocation StartLoc,
10321 SourceLocation EndLoc) {
10322 const OMPClause *DependFound = nullptr;
10323 const OMPClause *DependSourceClause = nullptr;
10324 const OMPClause *DependSinkClause = nullptr;
10325 bool ErrorFound = false;
10326 const OMPThreadsClause *TC = nullptr;
10327 const OMPSIMDClause *SC = nullptr;
10328 for (const OMPClause *C : Clauses) {
10329 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10330 DependFound = C;
10331 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10332 if (DependSourceClause) {
10333 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10334 << getOpenMPDirectiveName(OMPD_ordered)
10335 << getOpenMPClauseName(OMPC_depend) << 2;
10336 ErrorFound = true;
10337 } else {
10338 DependSourceClause = C;
10339 }
10340 if (DependSinkClause) {
10341 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10342 << 0;
10343 ErrorFound = true;
10344 }
10345 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10346 if (DependSourceClause) {
10347 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10348 << 1;
10349 ErrorFound = true;
10350 }
10351 DependSinkClause = C;
10352 }
10353 } else if (C->getClauseKind() == OMPC_threads) {
10354 TC = cast<OMPThreadsClause>(C);
10355 } else if (C->getClauseKind() == OMPC_simd) {
10356 SC = cast<OMPSIMDClause>(C);
10357 }
10358 }
10359 if (!ErrorFound && !SC &&
10360 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
10361 // OpenMP [2.8.1,simd Construct, Restrictions]
10362 // An ordered construct with the simd clause is the only OpenMP construct
10363 // that can appear in the simd region.
10364 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10365 << (LangOpts.OpenMP >= 50 ? 1 : 0);
10366 ErrorFound = true;
10367 } else if (DependFound && (TC || SC)) {
10368 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10369 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10370 ErrorFound = true;
10371 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10372 Diag(DependFound->getBeginLoc(),
10373 diag::err_omp_ordered_directive_without_param);
10374 ErrorFound = true;
10375 } else if (TC || Clauses.empty()) {
10376 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10377 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10378 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10379 << (TC != nullptr);
10380 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10381 ErrorFound = true;
10382 }
10383 }
10384 if ((!AStmt && !DependFound) || ErrorFound)
10385 return StmtError();
10386
10387 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10388 // During execution of an iteration of a worksharing-loop or a loop nest
10389 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10390 // must not execute more than one ordered region corresponding to an ordered
10391 // construct without a depend clause.
10392 if (!DependFound) {
10393 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
10394 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10395 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
10396 diag::note_omp_previous_directive)
10397 << "ordered";
10398 return StmtError();
10399 }
10400 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
10401 }
10402
10403 if (AStmt) {
10404 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
10405
10406 setFunctionHasBranchProtectedScope();
10407 }
10408
10409 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10410}
10411
10412namespace {
10413/// Helper class for checking expression in 'omp atomic [update]'
10414/// construct.
10415class OpenMPAtomicUpdateChecker {
10416 /// Error results for atomic update expressions.
10417 enum ExprAnalysisErrorCode {
10418 /// A statement is not an expression statement.
10419 NotAnExpression,
10420 /// Expression is not builtin binary or unary operation.
10421 NotABinaryOrUnaryExpression,
10422 /// Unary operation is not post-/pre- increment/decrement operation.
10423 NotAnUnaryIncDecExpression,
10424 /// An expression is not of scalar type.
10425 NotAScalarType,
10426 /// A binary operation is not an assignment operation.
10427 NotAnAssignmentOp,
10428 /// RHS part of the binary operation is not a binary expression.
10429 NotABinaryExpression,
10430 /// RHS part is not additive/multiplicative/shift/biwise binary
10431 /// expression.
10432 NotABinaryOperator,
10433 /// RHS binary operation does not have reference to the updated LHS
10434 /// part.
10435 NotAnUpdateExpression,
10436 /// No errors is found.
10437 NoError
10438 };
10439 /// Reference to Sema.
10440 Sema &SemaRef;
10441 /// A location for note diagnostics (when error is found).
10442 SourceLocation NoteLoc;
10443 /// 'x' lvalue part of the source atomic expression.
10444 Expr *X;
10445 /// 'expr' rvalue part of the source atomic expression.
10446 Expr *E;
10447 /// Helper expression of the form
10448 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10449 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10450 Expr *UpdateExpr;
10451 /// Is 'x' a LHS in a RHS part of full update expression. It is
10452 /// important for non-associative operations.
10453 bool IsXLHSInRHSPart;
10454 BinaryOperatorKind Op;
10455 SourceLocation OpLoc;
10456 /// true if the source expression is a postfix unary operation, false
10457 /// if it is a prefix unary operation.
10458 bool IsPostfixUpdate;
10459
10460public:
10461 OpenMPAtomicUpdateChecker(Sema &SemaRef)
10462 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10463 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10464 /// Check specified statement that it is suitable for 'atomic update'
10465 /// constructs and extract 'x', 'expr' and Operation from the original
10466 /// expression. If DiagId and NoteId == 0, then only check is performed
10467 /// without error notification.
10468 /// \param DiagId Diagnostic which should be emitted if error is found.
10469 /// \param NoteId Diagnostic note for the main error message.
10470 /// \return true if statement is not an update expression, false otherwise.
10471 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10472 /// Return the 'x' lvalue part of the source atomic expression.
10473 Expr *getX() const { return X; }
10474 /// Return the 'expr' rvalue part of the source atomic expression.
10475 Expr *getExpr() const { return E; }
10476 /// Return the update expression used in calculation of the updated
10477 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10478 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10479 Expr *getUpdateExpr() const { return UpdateExpr; }
10480 /// Return true if 'x' is LHS in RHS part of full update expression,
10481 /// false otherwise.
10482 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10483
10484 /// true if the source expression is a postfix unary operation, false
10485 /// if it is a prefix unary operation.
10486 bool isPostfixUpdate() const { return IsPostfixUpdate; }
10487
10488private:
10489 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10490 unsigned NoteId = 0);
10491};
10492} // namespace
10493
10494bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10495 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10496 ExprAnalysisErrorCode ErrorFound = NoError;
10497 SourceLocation ErrorLoc, NoteLoc;
10498 SourceRange ErrorRange, NoteRange;
10499 // Allowed constructs are:
10500 // x = x binop expr;
10501 // x = expr binop x;
10502 if (AtomicBinOp->getOpcode() == BO_Assign) {
10503 X = AtomicBinOp->getLHS();
10504 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10505 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10506 if (AtomicInnerBinOp->isMultiplicativeOp() ||
10507 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10508 AtomicInnerBinOp->isBitwiseOp()) {
10509 Op = AtomicInnerBinOp->getOpcode();
10510 OpLoc = AtomicInnerBinOp->getOperatorLoc();
10511 Expr *LHS = AtomicInnerBinOp->getLHS();
10512 Expr *RHS = AtomicInnerBinOp->getRHS();
10513 llvm::FoldingSetNodeID XId, LHSId, RHSId;
10514 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10515 /*Canonical=*/true);
10516 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10517 /*Canonical=*/true);
10518 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10519 /*Canonical=*/true);
10520 if (XId == LHSId) {
10521 E = RHS;
10522 IsXLHSInRHSPart = true;
10523 } else if (XId == RHSId) {
10524 E = LHS;
10525 IsXLHSInRHSPart = false;
10526 } else {
10527 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10528 ErrorRange = AtomicInnerBinOp->getSourceRange();
10529 NoteLoc = X->getExprLoc();
10530 NoteRange = X->getSourceRange();
10531 ErrorFound = NotAnUpdateExpression;
10532 }
10533 } else {
10534 ErrorLoc = AtomicInnerBinOp->getExprLoc();
10535 ErrorRange = AtomicInnerBinOp->getSourceRange();
10536 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10537 NoteRange = SourceRange(NoteLoc, NoteLoc);
10538 ErrorFound = NotABinaryOperator;
10539 }
10540 } else {
10541 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10542 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10543 ErrorFound = NotABinaryExpression;
10544 }
10545 } else {
10546 ErrorLoc = AtomicBinOp->getExprLoc();
10547 ErrorRange = AtomicBinOp->getSourceRange();
10548 NoteLoc = AtomicBinOp->getOperatorLoc();
10549 NoteRange = SourceRange(NoteLoc, NoteLoc);
10550 ErrorFound = NotAnAssignmentOp;
10551 }
10552 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10553 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10554 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10555 return true;
10556 }
10557 if (SemaRef.CurContext->isDependentContext())
10558 E = X = UpdateExpr = nullptr;
10559 return ErrorFound != NoError;
10560}
10561
10562bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10563 unsigned NoteId) {
10564 ExprAnalysisErrorCode ErrorFound = NoError;
10565 SourceLocation ErrorLoc, NoteLoc;
10566 SourceRange ErrorRange, NoteRange;
10567 // Allowed constructs are:
10568 // x++;
10569 // x--;
10570 // ++x;
10571 // --x;
10572 // x binop= expr;
10573 // x = x binop expr;
10574 // x = expr binop x;
10575 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10576 AtomicBody = AtomicBody->IgnoreParenImpCasts();
10577 if (AtomicBody->getType()->isScalarType() ||
10578 AtomicBody->isInstantiationDependent()) {
10579 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10580 AtomicBody->IgnoreParenImpCasts())) {
10581 // Check for Compound Assignment Operation
10582 Op = BinaryOperator::getOpForCompoundAssignment(
10583 AtomicCompAssignOp->getOpcode());
10584 OpLoc = AtomicCompAssignOp->getOperatorLoc();
10585 E = AtomicCompAssignOp->getRHS();
10586 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10587 IsXLHSInRHSPart = true;
10588 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10589 AtomicBody->IgnoreParenImpCasts())) {
10590 // Check for Binary Operation
10591 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10592 return true;
10593 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10594 AtomicBody->IgnoreParenImpCasts())) {
10595 // Check for Unary Operation
10596 if (AtomicUnaryOp->isIncrementDecrementOp()) {
10597 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10598 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10599 OpLoc = AtomicUnaryOp->getOperatorLoc();
10600 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10601 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10602 IsXLHSInRHSPart = true;
10603 } else {
10604 ErrorFound = NotAnUnaryIncDecExpression;
10605 ErrorLoc = AtomicUnaryOp->getExprLoc();
10606 ErrorRange = AtomicUnaryOp->getSourceRange();
10607 NoteLoc = AtomicUnaryOp->getOperatorLoc();
10608 NoteRange = SourceRange(NoteLoc, NoteLoc);
10609 }
10610 } else if (!AtomicBody->isInstantiationDependent()) {
10611 ErrorFound = NotABinaryOrUnaryExpression;
10612 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10613 NoteRange = ErrorRange = AtomicBody->getSourceRange();
10614 }
10615 } else {
10616 ErrorFound = NotAScalarType;
10617 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10618 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10619 }
10620 } else {
10621 ErrorFound = NotAnExpression;
10622 NoteLoc = ErrorLoc = S->getBeginLoc();
10623 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10624 }
10625 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10626 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10627 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10628 return true;
10629 }
10630 if (SemaRef.CurContext->isDependentContext())
10631 E = X = UpdateExpr = nullptr;
10632 if (ErrorFound == NoError && E && X) {
10633 // Build an update expression of form 'OpaqueValueExpr(x) binop
10634 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10635 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10636 auto *OVEX = new (SemaRef.getASTContext())
10637 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
10638 auto *OVEExpr = new (SemaRef.getASTContext())
10639 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
10640 ExprResult Update =
10641 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10642 IsXLHSInRHSPart ? OVEExpr : OVEX);
10643 if (Update.isInvalid())
10644 return true;
10645 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10646 Sema::AA_Casting);
10647 if (Update.isInvalid())
10648 return true;
10649 UpdateExpr = Update.get();
10650 }
10651 return ErrorFound != NoError;
10652}
10653
10654StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10655 Stmt *AStmt,
10656 SourceLocation StartLoc,
10657 SourceLocation EndLoc) {
10658 // Register location of the first atomic directive.
10659 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
10660 if (!AStmt)
10661 return StmtError();
10662
10663 // 1.2.2 OpenMP Language Terminology
10664 // Structured block - An executable statement with a single entry at the
10665 // top and a single exit at the bottom.
10666 // The point of exit cannot be a branch out of the structured block.
10667 // longjmp() and throw() must not violate the entry/exit criteria.
10668 OpenMPClauseKind AtomicKind = OMPC_unknown;
10669 SourceLocation AtomicKindLoc;
10670 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10671 SourceLocation MemOrderLoc;
10672 for (const OMPClause *C : Clauses) {
10673 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10674 C->getClauseKind() == OMPC_update ||
10675 C->getClauseKind() == OMPC_capture) {
10676 if (AtomicKind != OMPC_unknown) {
10677 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10678 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10679 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10680 << getOpenMPClauseName(AtomicKind);
10681 } else {
10682 AtomicKind = C->getClauseKind();
10683 AtomicKindLoc = C->getBeginLoc();
10684 }
10685 }
10686 if (C->getClauseKind() == OMPC_seq_cst ||
10687 C->getClauseKind() == OMPC_acq_rel ||
10688 C->getClauseKind() == OMPC_acquire ||
10689 C->getClauseKind() == OMPC_release ||
10690 C->getClauseKind() == OMPC_relaxed) {
10691 if (MemOrderKind != OMPC_unknown) {
10692 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10693 << getOpenMPDirectiveName(OMPD_atomic) << 0
10694 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10695 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10696 << getOpenMPClauseName(MemOrderKind);
10697 } else {
10698 MemOrderKind = C->getClauseKind();
10699 MemOrderLoc = C->getBeginLoc();
10700 }
10701 }
10702 }
10703 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10704 // If atomic-clause is read then memory-order-clause must not be acq_rel or
10705 // release.
10706 // If atomic-clause is write then memory-order-clause must not be acq_rel or
10707 // acquire.
10708 // If atomic-clause is update or not present then memory-order-clause must not
10709 // be acq_rel or acquire.
10710 if ((AtomicKind == OMPC_read &&
10711 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10712 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10713 AtomicKind == OMPC_unknown) &&
10714 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10715 SourceLocation Loc = AtomicKindLoc;
10716 if (AtomicKind == OMPC_unknown)
10717 Loc = StartLoc;
10718 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10719 << getOpenMPClauseName(AtomicKind)
10720 << (AtomicKind == OMPC_unknown ? 1 : 0)
10721 << getOpenMPClauseName(MemOrderKind);
10722 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10723 << getOpenMPClauseName(MemOrderKind);
10724 }
10725
10726 Stmt *Body = AStmt;
10727 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10728 Body = EWC->getSubExpr();
10729
10730 Expr *X = nullptr;
10731 Expr *V = nullptr;
10732 Expr *E = nullptr;
10733 Expr *UE = nullptr;
10734 bool IsXLHSInRHSPart = false;
10735 bool IsPostfixUpdate = false;
10736 // OpenMP [2.12.6, atomic Construct]
10737 // In the next expressions:
10738 // * x and v (as applicable) are both l-value expressions with scalar type.
10739 // * During the execution of an atomic region, multiple syntactic
10740 // occurrences of x must designate the same storage location.
10741 // * Neither of v and expr (as applicable) may access the storage location
10742 // designated by x.
10743 // * Neither of x and expr (as applicable) may access the storage location
10744 // designated by v.
10745 // * expr is an expression with scalar type.
10746 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10747 // * binop, binop=, ++, and -- are not overloaded operators.
10748 // * The expression x binop expr must be numerically equivalent to x binop
10749 // (expr). This requirement is satisfied if the operators in expr have
10750 // precedence greater than binop, or by using parentheses around expr or
10751 // subexpressions of expr.
10752 // * The expression expr binop x must be numerically equivalent to (expr)
10753 // binop x. This requirement is satisfied if the operators in expr have
10754 // precedence equal to or greater than binop, or by using parentheses around
10755 // expr or subexpressions of expr.
10756 // * For forms that allow multiple occurrences of x, the number of times
10757 // that x is evaluated is unspecified.
10758 if (AtomicKind == OMPC_read) {
10759 enum {
10760 NotAnExpression,
10761 NotAnAssignmentOp,
10762 NotAScalarType,
10763 NotAnLValue,
10764 NoError
10765 } ErrorFound = NoError;
10766 SourceLocation ErrorLoc, NoteLoc;
10767 SourceRange ErrorRange, NoteRange;
10768 // If clause is read:
10769 // v = x;
10770 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10771 const auto *AtomicBinOp =
10772 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10773 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10774 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10775 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10776 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10777 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10778 if (!X->isLValue() || !V->isLValue()) {
10779 const Expr *NotLValueExpr = X->isLValue() ? V : X;
10780 ErrorFound = NotAnLValue;
10781 ErrorLoc = AtomicBinOp->getExprLoc();
10782 ErrorRange = AtomicBinOp->getSourceRange();
10783 NoteLoc = NotLValueExpr->getExprLoc();
10784 NoteRange = NotLValueExpr->getSourceRange();
10785 }
10786 } else if (!X->isInstantiationDependent() ||
10787 !V->isInstantiationDependent()) {
10788 const Expr *NotScalarExpr =
10789 (X->isInstantiationDependent() || X->getType()->isScalarType())
10790 ? V
10791 : X;
10792 ErrorFound = NotAScalarType;
10793 ErrorLoc = AtomicBinOp->getExprLoc();
10794 ErrorRange = AtomicBinOp->getSourceRange();
10795 NoteLoc = NotScalarExpr->getExprLoc();
10796 NoteRange = NotScalarExpr->getSourceRange();
10797 }
10798 } else if (!AtomicBody->isInstantiationDependent()) {
10799 ErrorFound = NotAnAssignmentOp;
10800 ErrorLoc = AtomicBody->getExprLoc();
10801 ErrorRange = AtomicBody->getSourceRange();
10802 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10803 : AtomicBody->getExprLoc();
10804 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10805 : AtomicBody->getSourceRange();
10806 }
10807 } else {
10808 ErrorFound = NotAnExpression;
10809 NoteLoc = ErrorLoc = Body->getBeginLoc();
10810 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10811 }
10812 if (ErrorFound != NoError) {
10813 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10814 << ErrorRange;
10815 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10816 << NoteRange;
10817 return StmtError();
10818 }
10819 if (CurContext->isDependentContext())
10820 V = X = nullptr;
10821 } else if (AtomicKind == OMPC_write) {
10822 enum {
10823 NotAnExpression,
10824 NotAnAssignmentOp,
10825 NotAScalarType,
10826 NotAnLValue,
10827 NoError
10828 } ErrorFound = NoError;
10829 SourceLocation ErrorLoc, NoteLoc;
10830 SourceRange ErrorRange, NoteRange;
10831 // If clause is write:
10832 // x = expr;
10833 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10834 const auto *AtomicBinOp =
10835 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10836 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10837 X = AtomicBinOp->getLHS();
10838 E = AtomicBinOp->getRHS();
10839 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10840 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10841 if (!X->isLValue()) {
10842 ErrorFound = NotAnLValue;
10843 ErrorLoc = AtomicBinOp->getExprLoc();
10844 ErrorRange = AtomicBinOp->getSourceRange();
10845 NoteLoc = X->getExprLoc();
10846 NoteRange = X->getSourceRange();
10847 }
10848 } else if (!X->isInstantiationDependent() ||
10849 !E->isInstantiationDependent()) {
10850 const Expr *NotScalarExpr =
10851 (X->isInstantiationDependent() || X->getType()->isScalarType())
10852 ? E
10853 : X;
10854 ErrorFound = NotAScalarType;
10855 ErrorLoc = AtomicBinOp->getExprLoc();
10856 ErrorRange = AtomicBinOp->getSourceRange();
10857 NoteLoc = NotScalarExpr->getExprLoc();
10858 NoteRange = NotScalarExpr->getSourceRange();
10859 }
10860 } else if (!AtomicBody->isInstantiationDependent()) {
10861 ErrorFound = NotAnAssignmentOp;
10862 ErrorLoc = AtomicBody->getExprLoc();
10863 ErrorRange = AtomicBody->getSourceRange();
10864 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10865 : AtomicBody->getExprLoc();
10866 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10867 : AtomicBody->getSourceRange();
10868 }
10869 } else {
10870 ErrorFound = NotAnExpression;
10871 NoteLoc = ErrorLoc = Body->getBeginLoc();
10872 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10873 }
10874 if (ErrorFound != NoError) {
10875 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10876 << ErrorRange;
10877 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10878 << NoteRange;
10879 return StmtError();
10880 }
10881 if (CurContext->isDependentContext())
10882 E = X = nullptr;
10883 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10884 // If clause is update:
10885 // x++;
10886 // x--;
10887 // ++x;
10888 // --x;
10889 // x binop= expr;
10890 // x = x binop expr;
10891 // x = expr binop x;
10892 OpenMPAtomicUpdateChecker Checker(*this);
10893 if (Checker.checkStatement(
10894 Body, (AtomicKind == OMPC_update)
10895 ? diag::err_omp_atomic_update_not_expression_statement
10896 : diag::err_omp_atomic_not_expression_statement,
10897 diag::note_omp_atomic_update))
10898 return StmtError();
10899 if (!CurContext->isDependentContext()) {
10900 E = Checker.getExpr();
10901 X = Checker.getX();
10902 UE = Checker.getUpdateExpr();
10903 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10904 }
10905 } else if (AtomicKind == OMPC_capture) {
10906 enum {
10907 NotAnAssignmentOp,
10908 NotACompoundStatement,
10909 NotTwoSubstatements,
10910 NotASpecificExpression,
10911 NoError
10912 } ErrorFound = NoError;
10913 SourceLocation ErrorLoc, NoteLoc;
10914 SourceRange ErrorRange, NoteRange;
10915 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10916 // If clause is a capture:
10917 // v = x++;
10918 // v = x--;
10919 // v = ++x;
10920 // v = --x;
10921 // v = x binop= expr;
10922 // v = x = x binop expr;
10923 // v = x = expr binop x;
10924 const auto *AtomicBinOp =
10925 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10926 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10927 V = AtomicBinOp->getLHS();
10928 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10929 OpenMPAtomicUpdateChecker Checker(*this);
10930 if (Checker.checkStatement(
10931 Body, diag::err_omp_atomic_capture_not_expression_statement,
10932 diag::note_omp_atomic_update))
10933 return StmtError();
10934 E = Checker.getExpr();
10935 X = Checker.getX();
10936 UE = Checker.getUpdateExpr();
10937 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10938 IsPostfixUpdate = Checker.isPostfixUpdate();
10939 } else if (!AtomicBody->isInstantiationDependent()) {
10940 ErrorLoc = AtomicBody->getExprLoc();
10941 ErrorRange = AtomicBody->getSourceRange();
10942 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10943 : AtomicBody->getExprLoc();
10944 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10945 : AtomicBody->getSourceRange();
10946 ErrorFound = NotAnAssignmentOp;
10947 }
10948 if (ErrorFound != NoError) {
10949 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10950 << ErrorRange;
10951 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10952 return StmtError();
10953 }
10954 if (CurContext->isDependentContext())
10955 UE = V = E = X = nullptr;
10956 } else {
10957 // If clause is a capture:
10958 // { v = x; x = expr; }
10959 // { v = x; x++; }
10960 // { v = x; x--; }
10961 // { v = x; ++x; }
10962 // { v = x; --x; }
10963 // { v = x; x binop= expr; }
10964 // { v = x; x = x binop expr; }
10965 // { v = x; x = expr binop x; }
10966 // { x++; v = x; }
10967 // { x--; v = x; }
10968 // { ++x; v = x; }
10969 // { --x; v = x; }
10970 // { x binop= expr; v = x; }
10971 // { x = x binop expr; v = x; }
10972 // { x = expr binop x; v = x; }
10973 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10974 // Check that this is { expr1; expr2; }
10975 if (CS->size() == 2) {
10976 Stmt *First = CS->body_front();
10977 Stmt *Second = CS->body_back();
10978 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10979 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10980 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10981 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10982 // Need to find what subexpression is 'v' and what is 'x'.
10983 OpenMPAtomicUpdateChecker Checker(*this);
10984 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10985 BinaryOperator *BinOp = nullptr;
10986 if (IsUpdateExprFound) {
10987 BinOp = dyn_cast<BinaryOperator>(First);
10988 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10989 }
10990 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10991 // { v = x; x++; }
10992 // { v = x; x--; }
10993 // { v = x; ++x; }
10994 // { v = x; --x; }
10995 // { v = x; x binop= expr; }
10996 // { v = x; x = x binop expr; }
10997 // { v = x; x = expr binop x; }
10998 // Check that the first expression has form v = x.
10999 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11000 llvm::FoldingSetNodeID XId, PossibleXId;
11001 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11002 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11003 IsUpdateExprFound = XId == PossibleXId;
11004 if (IsUpdateExprFound) {
11005 V = BinOp->getLHS();
11006 X = Checker.getX();
11007 E = Checker.getExpr();
11008 UE = Checker.getUpdateExpr();
11009 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11010 IsPostfixUpdate = true;
11011 }
11012 }
11013 if (!IsUpdateExprFound) {
11014 IsUpdateExprFound = !Checker.checkStatement(First);
11015 BinOp = nullptr;
11016 if (IsUpdateExprFound) {
11017 BinOp = dyn_cast<BinaryOperator>(Second);
11018 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
11019 }
11020 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
11021 // { x++; v = x; }
11022 // { x--; v = x; }
11023 // { ++x; v = x; }
11024 // { --x; v = x; }
11025 // { x binop= expr; v = x; }
11026 // { x = x binop expr; v = x; }
11027 // { x = expr binop x; v = x; }
11028 // Check that the second expression has form v = x.
11029 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11030 llvm::FoldingSetNodeID XId, PossibleXId;
11031 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11032 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11033 IsUpdateExprFound = XId == PossibleXId;
11034 if (IsUpdateExprFound) {
11035 V = BinOp->getLHS();
11036 X = Checker.getX();
11037 E = Checker.getExpr();
11038 UE = Checker.getUpdateExpr();
11039 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11040 IsPostfixUpdate = false;
11041 }
11042 }
11043 }
11044 if (!IsUpdateExprFound) {
11045 // { v = x; x = expr; }
11046 auto *FirstExpr = dyn_cast<Expr>(First);
11047 auto *SecondExpr = dyn_cast<Expr>(Second);
11048 if (!FirstExpr || !SecondExpr ||
11049 !(FirstExpr->isInstantiationDependent() ||
11050 SecondExpr->isInstantiationDependent())) {
11051 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
11052 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
11053 ErrorFound = NotAnAssignmentOp;
11054 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
11055 : First->getBeginLoc();
11056 NoteRange = ErrorRange = FirstBinOp
11057 ? FirstBinOp->getSourceRange()
11058 : SourceRange(ErrorLoc, ErrorLoc);
11059 } else {
11060 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
11061 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
11062 ErrorFound = NotAnAssignmentOp;
11063 NoteLoc = ErrorLoc = SecondBinOp
11064 ? SecondBinOp->getOperatorLoc()
11065 : Second->getBeginLoc();
11066 NoteRange = ErrorRange =
11067 SecondBinOp ? SecondBinOp->getSourceRange()
11068 : SourceRange(ErrorLoc, ErrorLoc);
11069 } else {
11070 Expr *PossibleXRHSInFirst =
11071 FirstBinOp->getRHS()->IgnoreParenImpCasts();
11072 Expr *PossibleXLHSInSecond =
11073 SecondBinOp->getLHS()->IgnoreParenImpCasts();
11074 llvm::FoldingSetNodeID X1Id, X2Id;
11075 PossibleXRHSInFirst->Profile(X1Id, Context,
11076 /*Canonical=*/true);
11077 PossibleXLHSInSecond->Profile(X2Id, Context,
11078 /*Canonical=*/true);
11079 IsUpdateExprFound = X1Id == X2Id;
11080 if (IsUpdateExprFound) {
11081 V = FirstBinOp->getLHS();
11082 X = SecondBinOp->getLHS();
11083 E = SecondBinOp->getRHS();
11084 UE = nullptr;
11085 IsXLHSInRHSPart = false;
11086 IsPostfixUpdate = true;
11087 } else {
11088 ErrorFound = NotASpecificExpression;
11089 ErrorLoc = FirstBinOp->getExprLoc();
11090 ErrorRange = FirstBinOp->getSourceRange();
11091 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
11092 NoteRange = SecondBinOp->getRHS()->getSourceRange();
11093 }
11094 }
11095 }
11096 }
11097 }
11098 } else {
11099 NoteLoc = ErrorLoc = Body->getBeginLoc();
11100 NoteRange = ErrorRange =
11101 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11102 ErrorFound = NotTwoSubstatements;
11103 }
11104 } else {
11105 NoteLoc = ErrorLoc = Body->getBeginLoc();
11106 NoteRange = ErrorRange =
11107 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11108 ErrorFound = NotACompoundStatement;
11109 }
11110 if (ErrorFound != NoError) {
11111 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
11112 << ErrorRange;
11113 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11114 return StmtError();
11115 }
11116 if (CurContext->isDependentContext())
11117 UE = V = E = X = nullptr;
11118 }
11119 }
11120
11121 setFunctionHasBranchProtectedScope();
11122
11123 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11124 X, V, E, UE, IsXLHSInRHSPart,
11125 IsPostfixUpdate);
11126}
11127
11128StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
11129 Stmt *AStmt,
11130 SourceLocation StartLoc,
11131 SourceLocation EndLoc) {
11132 if (!AStmt)
11133 return StmtError();
11134
11135 auto *CS = cast<CapturedStmt>(AStmt);
11136 // 1.2.2 OpenMP Language Terminology
11137 // Structured block - An executable statement with a single entry at the
11138 // top and a single exit at the bottom.
11139 // The point of exit cannot be a branch out of the structured block.
11140 // longjmp() and throw() must not violate the entry/exit criteria.
11141 CS->getCapturedDecl()->setNothrow();
11142 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
11143 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11144 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11145 // 1.2.2 OpenMP Language Terminology
11146 // Structured block - An executable statement with a single entry at the
11147 // top and a single exit at the bottom.
11148 // The point of exit cannot be a branch out of the structured block.
11149 // longjmp() and throw() must not violate the entry/exit criteria.
11150 CS->getCapturedDecl()->setNothrow();
11151 }
11152
11153 // OpenMP [2.16, Nesting of Regions]
11154 // If specified, a teams construct must be contained within a target
11155 // construct. That target construct must contain no statements or directives
11156 // outside of the teams construct.
11157 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
11158 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
11159 bool OMPTeamsFound = true;
11160 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
11161 auto I = CS->body_begin();
11162 while (I != CS->body_end()) {
11163 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
11164 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
11165 OMPTeamsFound) {
11166
11167 OMPTeamsFound = false;
11168 break;
11169 }
11170 ++I;
11171 }
11172 assert(I != CS->body_end() && "Not found statement")((void)0);
11173 S = *I;
11174 } else {
11175 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
11176 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
11177 }
11178 if (!OMPTeamsFound) {
11179 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
11180 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
11181 diag::note_omp_nested_teams_construct_here);
11182 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
11183 << isa<OMPExecutableDirective>(S);
11184 return StmtError();
11185 }
11186 }
11187
11188 setFunctionHasBranchProtectedScope();
11189
11190 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11191}
11192
11193StmtResult
11194Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
11195 Stmt *AStmt, SourceLocation StartLoc,
11196 SourceLocation EndLoc) {
11197 if (!AStmt)
11198 return StmtError();
11199
11200 auto *CS = cast<CapturedStmt>(AStmt);
11201 // 1.2.2 OpenMP Language Terminology
11202 // Structured block - An executable statement with a single entry at the
11203 // top and a single exit at the bottom.
11204 // The point of exit cannot be a branch out of the structured block.
11205 // longjmp() and throw() must not violate the entry/exit criteria.
11206 CS->getCapturedDecl()->setNothrow();
11207 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
11208 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11209 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11210 // 1.2.2 OpenMP Language Terminology
11211 // Structured block - An executable statement with a single entry at the
11212 // top and a single exit at the bottom.
11213 // The point of exit cannot be a branch out of the structured block.
11214 // longjmp() and throw() must not violate the entry/exit criteria.
11215 CS->getCapturedDecl()->setNothrow();
11216 }
11217
11218 setFunctionHasBranchProtectedScope();
11219
11220 return OMPTargetParallelDirective::Create(
11221 Context, StartLoc, EndLoc, Clauses, AStmt,
11222 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11223}
11224
11225StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
11226 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11227 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11228 if (!AStmt)
11229 return StmtError();
11230
11231 auto *CS = cast<CapturedStmt>(AStmt);
11232 // 1.2.2 OpenMP Language Terminology
11233 // Structured block - An executable statement with a single entry at the
11234 // top and a single exit at the bottom.
11235 // The point of exit cannot be a branch out of the structured block.
11236 // longjmp() and throw() must not violate the entry/exit criteria.
11237 CS->getCapturedDecl()->setNothrow();
11238 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11239 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11240 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11241 // 1.2.2 OpenMP Language Terminology
11242 // Structured block - An executable statement with a single entry at the
11243 // top and a single exit at the bottom.
11244 // The point of exit cannot be a branch out of the structured block.
11245 // longjmp() and throw() must not violate the entry/exit criteria.
11246 CS->getCapturedDecl()->setNothrow();
11247 }
11248
11249 OMPLoopBasedDirective::HelperExprs B;
11250 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11251 // define the nested loops number.
11252 unsigned NestedLoopCount =
11253 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
11254 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11255 VarsWithImplicitDSA, B);
11256 if (NestedLoopCount == 0)
11257 return StmtError();
11258
11259 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11260 "omp target parallel for loop exprs were not built")((void)0);
11261
11262 if (!CurContext->isDependentContext()) {
11263 // Finalize the clauses that need pre-built expressions for CodeGen.
11264 for (OMPClause *C : Clauses) {
11265 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11266 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11267 B.NumIterations, *this, CurScope,
11268 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11269 return StmtError();
11270 }
11271 }
11272
11273 setFunctionHasBranchProtectedScope();
11274 return OMPTargetParallelForDirective::Create(
11275 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11276 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11277}
11278
11279/// Check for existence of a map clause in the list of clauses.
11280static bool hasClauses(ArrayRef<OMPClause *> Clauses,
11281 const OpenMPClauseKind K) {
11282 return llvm::any_of(
11283 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
11284}
11285
11286template <typename... Params>
11287static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
11288 const Params... ClauseTypes) {
11289 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
11290}
11291
11292StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
11293 Stmt *AStmt,
11294 SourceLocation StartLoc,
11295 SourceLocation EndLoc) {
11296 if (!AStmt)
11297 return StmtError();
11298
11299 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11300
11301 // OpenMP [2.12.2, target data Construct, Restrictions]
11302 // At least one map, use_device_addr or use_device_ptr clause must appear on
11303 // the directive.
11304 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
11305 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
11306 StringRef Expected;
11307 if (LangOpts.OpenMP < 50)
11308 Expected = "'map' or 'use_device_ptr'";
11309 else
11310 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
11311 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11312 << Expected << getOpenMPDirectiveName(OMPD_target_data);
11313 return StmtError();
11314 }
11315
11316 setFunctionHasBranchProtectedScope();
11317
11318 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11319 AStmt);
11320}
11321
11322StmtResult
11323Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
11324 SourceLocation StartLoc,
11325 SourceLocation EndLoc, Stmt *AStmt) {
11326 if (!AStmt)
11327 return StmtError();
11328
11329 auto *CS = cast<CapturedStmt>(AStmt);
11330 // 1.2.2 OpenMP Language Terminology
11331 // Structured block - An executable statement with a single entry at the
11332 // top and a single exit at the bottom.
11333 // The point of exit cannot be a branch out of the structured block.
11334 // longjmp() and throw() must not violate the entry/exit criteria.
11335 CS->getCapturedDecl()->setNothrow();
11336 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
11337 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11338 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11339 // 1.2.2 OpenMP Language Terminology
11340 // Structured block - An executable statement with a single entry at the
11341 // top and a single exit at the bottom.
11342 // The point of exit cannot be a branch out of the structured block.
11343 // longjmp() and throw() must not violate the entry/exit criteria.
11344 CS->getCapturedDecl()->setNothrow();
11345 }
11346
11347 // OpenMP [2.10.2, Restrictions, p. 99]
11348 // At least one map clause must appear on the directive.
11349 if (!hasClauses(Clauses, OMPC_map)) {
11350 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11351 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
11352 return StmtError();
11353 }
11354
11355 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11356 AStmt);
11357}
11358
11359StmtResult
11360Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
11361 SourceLocation StartLoc,
11362 SourceLocation EndLoc, Stmt *AStmt) {
11363 if (!AStmt)
11364 return StmtError();
11365
11366 auto *CS = cast<CapturedStmt>(AStmt);
11367 // 1.2.2 OpenMP Language Terminology
11368 // Structured block - An executable statement with a single entry at the
11369 // top and a single exit at the bottom.
11370 // The point of exit cannot be a branch out of the structured block.
11371 // longjmp() and throw() must not violate the entry/exit criteria.
11372 CS->getCapturedDecl()->setNothrow();
11373 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
11374 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11375 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11376 // 1.2.2 OpenMP Language Terminology
11377 // Structured block - An executable statement with a single entry at the
11378 // top and a single exit at the bottom.
11379 // The point of exit cannot be a branch out of the structured block.
11380 // longjmp() and throw() must not violate the entry/exit criteria.
11381 CS->getCapturedDecl()->setNothrow();
11382 }
11383
11384 // OpenMP [2.10.3, Restrictions, p. 102]
11385 // At least one map clause must appear on the directive.
11386 if (!hasClauses(Clauses, OMPC_map)) {
11387 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11388 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
11389 return StmtError();
11390 }
11391
11392 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11393 AStmt);
11394}
11395
11396StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
11397 SourceLocation StartLoc,
11398 SourceLocation EndLoc,
11399 Stmt *AStmt) {
11400 if (!AStmt)
11401 return StmtError();
11402
11403 auto *CS = cast<CapturedStmt>(AStmt);
11404 // 1.2.2 OpenMP Language Terminology
11405 // Structured block - An executable statement with a single entry at the
11406 // top and a single exit at the bottom.
11407 // The point of exit cannot be a branch out of the structured block.
11408 // longjmp() and throw() must not violate the entry/exit criteria.
11409 CS->getCapturedDecl()->setNothrow();
11410 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
11411 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11412 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11413 // 1.2.2 OpenMP Language Terminology
11414 // Structured block - An executable statement with a single entry at the
11415 // top and a single exit at the bottom.
11416 // The point of exit cannot be a branch out of the structured block.
11417 // longjmp() and throw() must not violate the entry/exit criteria.
11418 CS->getCapturedDecl()->setNothrow();
11419 }
11420
11421 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
11422 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
11423 return StmtError();
11424 }
11425 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
11426 AStmt);
11427}
11428
11429StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
11430 Stmt *AStmt, SourceLocation StartLoc,
11431 SourceLocation EndLoc) {
11432 if (!AStmt)
11433 return StmtError();
11434
11435 auto *CS = cast<CapturedStmt>(AStmt);
11436 // 1.2.2 OpenMP Language Terminology
11437 // Structured block - An executable statement with a single entry at the
11438 // top and a single exit at the bottom.
11439 // The point of exit cannot be a branch out of the structured block.
11440 // longjmp() and throw() must not violate the entry/exit criteria.
11441 CS->getCapturedDecl()->setNothrow();
11442
11443 setFunctionHasBranchProtectedScope();
11444
11445 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11446
11447 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11448}
11449
11450StmtResult
11451Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
11452 SourceLocation EndLoc,
11453 OpenMPDirectiveKind CancelRegion) {
11454 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
11455 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
11456 return StmtError();
11457 }
11458 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
11459 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
11460 return StmtError();
11461 }
11462 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
11463 CancelRegion);
11464}
11465
11466StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
11467 SourceLocation StartLoc,
11468 SourceLocation EndLoc,
11469 OpenMPDirectiveKind CancelRegion) {
11470 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
11471 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
11472 return StmtError();
11473 }
11474 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
11475 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
11476 return StmtError();
11477 }
11478 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
11479 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
11480 CancelRegion);
11481}
11482
11483static bool checkReductionClauseWithNogroup(Sema &S,
11484 ArrayRef<OMPClause *> Clauses) {
11485 const OMPClause *ReductionClause = nullptr;
11486 const OMPClause *NogroupClause = nullptr;
11487 for (const OMPClause *C : Clauses) {
11488 if (C->getClauseKind() == OMPC_reduction) {
11489 ReductionClause = C;
11490 if (NogroupClause)
11491 break;
11492 continue;
11493 }
11494 if (C->getClauseKind() == OMPC_nogroup) {
11495 NogroupClause = C;
11496 if (ReductionClause)
11497 break;
11498 continue;
11499 }
11500 }
11501 if (ReductionClause && NogroupClause) {
11502 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
11503 << SourceRange(NogroupClause->getBeginLoc(),
11504 NogroupClause->getEndLoc());
11505 return true;
11506 }
11507 return false;
11508}
11509
11510StmtResult Sema::ActOnOpenMPTaskLoopDirective(
11511 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11512 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11513 if (!AStmt)
11514 return StmtError();
11515
11516 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11517 OMPLoopBasedDirective::HelperExprs B;
11518 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11519 // define the nested loops number.
11520 unsigned NestedLoopCount =
11521 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11522 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11523 VarsWithImplicitDSA, B);
11524 if (NestedLoopCount == 0)
11525 return StmtError();
11526
11527 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11528 "omp for loop exprs were not built")((void)0);
11529
11530 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11531 // The grainsize clause and num_tasks clause are mutually exclusive and may
11532 // not appear on the same taskloop directive.
11533 if (checkMutuallyExclusiveClauses(*this, Clauses,
11534 {OMPC_grainsize, OMPC_num_tasks}))
11535 return StmtError();
11536 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11537 // If a reduction clause is present on the taskloop directive, the nogroup
11538 // clause must not be specified.
11539 if (checkReductionClauseWithNogroup(*this, Clauses))
11540 return StmtError();
11541
11542 setFunctionHasBranchProtectedScope();
11543 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11544 NestedLoopCount, Clauses, AStmt, B,
11545 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11546}
11547
11548StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11549 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11550 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11551 if (!AStmt)
11552 return StmtError();
11553
11554 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11555 OMPLoopBasedDirective::HelperExprs B;
11556 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11557 // define the nested loops number.
11558 unsigned NestedLoopCount =
11559 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11560 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11561 VarsWithImplicitDSA, B);
11562 if (NestedLoopCount == 0)
11563 return StmtError();
11564
11565 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11566 "omp for loop exprs were not built")((void)0);
11567
11568 if (!CurContext->isDependentContext()) {
11569 // Finalize the clauses that need pre-built expressions for CodeGen.
11570 for (OMPClause *C : Clauses) {
11571 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11572 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11573 B.NumIterations, *this, CurScope,
11574 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11575 return StmtError();
11576 }
11577 }
11578
11579 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11580 // The grainsize clause and num_tasks clause are mutually exclusive and may
11581 // not appear on the same taskloop directive.
11582 if (checkMutuallyExclusiveClauses(*this, Clauses,
11583 {OMPC_grainsize, OMPC_num_tasks}))
11584 return StmtError();
11585 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11586 // If a reduction clause is present on the taskloop directive, the nogroup
11587 // clause must not be specified.
11588 if (checkReductionClauseWithNogroup(*this, Clauses))
11589 return StmtError();
11590 if (checkSimdlenSafelenSpecified(*this, Clauses))
11591 return StmtError();
11592
11593 setFunctionHasBranchProtectedScope();
11594 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11595 NestedLoopCount, Clauses, AStmt, B);
11596}
11597
11598StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11599 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11600 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11601 if (!AStmt)
11602 return StmtError();
11603
11604 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11605 OMPLoopBasedDirective::HelperExprs B;
11606 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11607 // define the nested loops number.
11608 unsigned NestedLoopCount =
11609 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11610 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11611 VarsWithImplicitDSA, B);
11612 if (NestedLoopCount == 0)
11613 return StmtError();
11614
11615 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11616 "omp for loop exprs were not built")((void)0);
11617
11618 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11619 // The grainsize clause and num_tasks clause are mutually exclusive and may
11620 // not appear on the same taskloop directive.
11621 if (checkMutuallyExclusiveClauses(*this, Clauses,
11622 {OMPC_grainsize, OMPC_num_tasks}))
11623 return StmtError();
11624 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11625 // If a reduction clause is present on the taskloop directive, the nogroup
11626 // clause must not be specified.
11627 if (checkReductionClauseWithNogroup(*this, Clauses))
11628 return StmtError();
11629
11630 setFunctionHasBranchProtectedScope();
11631 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11632 NestedLoopCount, Clauses, AStmt, B,
11633 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11634}
11635
11636StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11637 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11638 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11639 if (!AStmt)
11640 return StmtError();
11641
11642 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11643 OMPLoopBasedDirective::HelperExprs B;
11644 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11645 // define the nested loops number.
11646 unsigned NestedLoopCount =
11647 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11648 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11649 VarsWithImplicitDSA, B);
11650 if (NestedLoopCount == 0)
11651 return StmtError();
11652
11653 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11654 "omp for loop exprs were not built")((void)0);
11655
11656 if (!CurContext->isDependentContext()) {
11657 // Finalize the clauses that need pre-built expressions for CodeGen.
11658 for (OMPClause *C : Clauses) {
11659 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11660 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11661 B.NumIterations, *this, CurScope,
11662 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11663 return StmtError();
11664 }
11665 }
11666
11667 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11668 // The grainsize clause and num_tasks clause are mutually exclusive and may
11669 // not appear on the same taskloop directive.
11670 if (checkMutuallyExclusiveClauses(*this, Clauses,
11671 {OMPC_grainsize, OMPC_num_tasks}))
11672 return StmtError();
11673 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11674 // If a reduction clause is present on the taskloop directive, the nogroup
11675 // clause must not be specified.
11676 if (checkReductionClauseWithNogroup(*this, Clauses))
11677 return StmtError();
11678 if (checkSimdlenSafelenSpecified(*this, Clauses))
11679 return StmtError();
11680
11681 setFunctionHasBranchProtectedScope();
11682 return OMPMasterTaskLoopSimdDirective::Create(
11683 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11684}
11685
11686StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11687 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11688 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11689 if (!AStmt)
11690 return StmtError();
11691
11692 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11693 auto *CS = cast<CapturedStmt>(AStmt);
11694 // 1.2.2 OpenMP Language Terminology
11695 // Structured block - An executable statement with a single entry at the
11696 // top and a single exit at the bottom.
11697 // The point of exit cannot be a branch out of the structured block.
11698 // longjmp() and throw() must not violate the entry/exit criteria.
11699 CS->getCapturedDecl()->setNothrow();
11700 for (int ThisCaptureLevel =
11701 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11702 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11703 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11704 // 1.2.2 OpenMP Language Terminology
11705 // Structured block - An executable statement with a single entry at the
11706 // top and a single exit at the bottom.
11707 // The point of exit cannot be a branch out of the structured block.
11708 // longjmp() and throw() must not violate the entry/exit criteria.
11709 CS->getCapturedDecl()->setNothrow();
11710 }
11711
11712 OMPLoopBasedDirective::HelperExprs B;
11713 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11714 // define the nested loops number.
11715 unsigned NestedLoopCount = checkOpenMPLoop(
11716 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11717 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11718 VarsWithImplicitDSA, B);
11719 if (NestedLoopCount == 0)
11720 return StmtError();
11721
11722 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11723 "omp for loop exprs were not built")((void)0);
11724
11725 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11726 // The grainsize clause and num_tasks clause are mutually exclusive and may
11727 // not appear on the same taskloop directive.
11728 if (checkMutuallyExclusiveClauses(*this, Clauses,
11729 {OMPC_grainsize, OMPC_num_tasks}))
11730 return StmtError();
11731 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11732 // If a reduction clause is present on the taskloop directive, the nogroup
11733 // clause must not be specified.
11734 if (checkReductionClauseWithNogroup(*this, Clauses))
11735 return StmtError();
11736
11737 setFunctionHasBranchProtectedScope();
11738 return OMPParallelMasterTaskLoopDirective::Create(
11739 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11740 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11741}
11742
11743StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11744 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11745 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11746 if (!AStmt)
11747 return StmtError();
11748
11749 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11750 auto *CS = cast<CapturedStmt>(AStmt);
11751 // 1.2.2 OpenMP Language Terminology
11752 // Structured block - An executable statement with a single entry at the
11753 // top and a single exit at the bottom.
11754 // The point of exit cannot be a branch out of the structured block.
11755 // longjmp() and throw() must not violate the entry/exit criteria.
11756 CS->getCapturedDecl()->setNothrow();
11757 for (int ThisCaptureLevel =
11758 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11759 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11760 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11761 // 1.2.2 OpenMP Language Terminology
11762 // Structured block - An executable statement with a single entry at the
11763 // top and a single exit at the bottom.
11764 // The point of exit cannot be a branch out of the structured block.
11765 // longjmp() and throw() must not violate the entry/exit criteria.
11766 CS->getCapturedDecl()->setNothrow();
11767 }
11768
11769 OMPLoopBasedDirective::HelperExprs B;
11770 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11771 // define the nested loops number.
11772 unsigned NestedLoopCount = checkOpenMPLoop(
11773 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11774 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11775 VarsWithImplicitDSA, B);
11776 if (NestedLoopCount == 0)
11777 return StmtError();
11778
11779 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11780 "omp for loop exprs were not built")((void)0);
11781
11782 if (!CurContext->isDependentContext()) {
11783 // Finalize the clauses that need pre-built expressions for CodeGen.
11784 for (OMPClause *C : Clauses) {
11785 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11786 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11787 B.NumIterations, *this, CurScope,
11788 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11789 return StmtError();
11790 }
11791 }
11792
11793 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11794 // The grainsize clause and num_tasks clause are mutually exclusive and may
11795 // not appear on the same taskloop directive.
11796 if (checkMutuallyExclusiveClauses(*this, Clauses,
11797 {OMPC_grainsize, OMPC_num_tasks}))
11798 return StmtError();
11799 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11800 // If a reduction clause is present on the taskloop directive, the nogroup
11801 // clause must not be specified.
11802 if (checkReductionClauseWithNogroup(*this, Clauses))
11803 return StmtError();
11804 if (checkSimdlenSafelenSpecified(*this, Clauses))
11805 return StmtError();
11806
11807 setFunctionHasBranchProtectedScope();
11808 return OMPParallelMasterTaskLoopSimdDirective::Create(
11809 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11810}
11811
11812StmtResult Sema::ActOnOpenMPDistributeDirective(
11813 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11814 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11815 if (!AStmt)
11816 return StmtError();
11817
11818 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((void)0);
11819 OMPLoopBasedDirective::HelperExprs B;
11820 // In presence of clause 'collapse' with number of loops, it will
11821 // define the nested loops number.
11822 unsigned NestedLoopCount =
11823 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11824 nullptr /*ordered not a clause on distribute*/, AStmt,
11825 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11826 if (NestedLoopCount == 0)
11827 return StmtError();
11828
11829 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11830 "omp for loop exprs were not built")((void)0);
11831
11832 setFunctionHasBranchProtectedScope();
11833 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11834 NestedLoopCount, Clauses, AStmt, B);
11835}
11836
11837StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11838 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11839 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11840 if (!AStmt)
11841 return StmtError();
11842
11843 auto *CS = cast<CapturedStmt>(AStmt);
11844 // 1.2.2 OpenMP Language Terminology
11845 // Structured block - An executable statement with a single entry at the
11846 // top and a single exit at the bottom.
11847 // The point of exit cannot be a branch out of the structured block.
11848 // longjmp() and throw() must not violate the entry/exit criteria.
11849 CS->getCapturedDecl()->setNothrow();
11850 for (int ThisCaptureLevel =
11851 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11852 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11853 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11854 // 1.2.2 OpenMP Language Terminology
11855 // Structured block - An executable statement with a single entry at the
11856 // top and a single exit at the bottom.
11857 // The point of exit cannot be a branch out of the structured block.
11858 // longjmp() and throw() must not violate the entry/exit criteria.
11859 CS->getCapturedDecl()->setNothrow();
11860 }
11861
11862 OMPLoopBasedDirective::HelperExprs B;
11863 // In presence of clause 'collapse' with number of loops, it will
11864 // define the nested loops number.
11865 unsigned NestedLoopCount = checkOpenMPLoop(
11866 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11867 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11868 VarsWithImplicitDSA, B);
11869 if (NestedLoopCount == 0)
11870 return StmtError();
11871
11872 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11873 "omp for loop exprs were not built")((void)0);
11874
11875 setFunctionHasBranchProtectedScope();
11876 return OMPDistributeParallelForDirective::Create(
11877 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11878 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11879}
11880
11881StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11882 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11883 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11884 if (!AStmt)
11885 return StmtError();
11886
11887 auto *CS = cast<CapturedStmt>(AStmt);
11888 // 1.2.2 OpenMP Language Terminology
11889 // Structured block - An executable statement with a single entry at the
11890 // top and a single exit at the bottom.
11891 // The point of exit cannot be a branch out of the structured block.
11892 // longjmp() and throw() must not violate the entry/exit criteria.
11893 CS->getCapturedDecl()->setNothrow();
11894 for (int ThisCaptureLevel =
11895 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11896 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11897 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11898 // 1.2.2 OpenMP Language Terminology
11899 // Structured block - An executable statement with a single entry at the
11900 // top and a single exit at the bottom.
11901 // The point of exit cannot be a branch out of the structured block.
11902 // longjmp() and throw() must not violate the entry/exit criteria.
11903 CS->getCapturedDecl()->setNothrow();
11904 }
11905
11906 OMPLoopBasedDirective::HelperExprs B;
11907 // In presence of clause 'collapse' with number of loops, it will
11908 // define the nested loops number.
11909 unsigned NestedLoopCount = checkOpenMPLoop(
11910 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11911 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11912 VarsWithImplicitDSA, B);
11913 if (NestedLoopCount == 0)
11914 return StmtError();
11915
11916 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11917 "omp for loop exprs were not built")((void)0);
11918
11919 if (!CurContext->isDependentContext()) {
11920 // Finalize the clauses that need pre-built expressions for CodeGen.
11921 for (OMPClause *C : Clauses) {
11922 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11923 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11924 B.NumIterations, *this, CurScope,
11925 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11926 return StmtError();
11927 }
11928 }
11929
11930 if (checkSimdlenSafelenSpecified(*this, Clauses))
11931 return StmtError();
11932
11933 setFunctionHasBranchProtectedScope();
11934 return OMPDistributeParallelForSimdDirective::Create(
11935 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11936}
11937
11938StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11939 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11940 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11941 if (!AStmt)
11942 return StmtError();
11943
11944 auto *CS = cast<CapturedStmt>(AStmt);
11945 // 1.2.2 OpenMP Language Terminology
11946 // Structured block - An executable statement with a single entry at the
11947 // top and a single exit at the bottom.
11948 // The point of exit cannot be a branch out of the structured block.
11949 // longjmp() and throw() must not violate the entry/exit criteria.
11950 CS->getCapturedDecl()->setNothrow();
11951 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11952 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11953 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11954 // 1.2.2 OpenMP Language Terminology
11955 // Structured block - An executable statement with a single entry at the
11956 // top and a single exit at the bottom.
11957 // The point of exit cannot be a branch out of the structured block.
11958 // longjmp() and throw() must not violate the entry/exit criteria.
11959 CS->getCapturedDecl()->setNothrow();
11960 }
11961
11962 OMPLoopBasedDirective::HelperExprs B;
11963 // In presence of clause 'collapse' with number of loops, it will
11964 // define the nested loops number.
11965 unsigned NestedLoopCount =
11966 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11967 nullptr /*ordered not a clause on distribute*/, CS, *this,
11968 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11969 if (NestedLoopCount == 0)
11970 return StmtError();
11971
11972 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
11973 "omp for loop exprs were not built")((void)0);
11974
11975 if (!CurContext->isDependentContext()) {
11976 // Finalize the clauses that need pre-built expressions for CodeGen.
11977 for (OMPClause *C : Clauses) {
11978 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11979 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11980 B.NumIterations, *this, CurScope,
11981 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11982 return StmtError();
11983 }
11984 }
11985
11986 if (checkSimdlenSafelenSpecified(*this, Clauses))
11987 return StmtError();
11988
11989 setFunctionHasBranchProtectedScope();
11990 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11991 NestedLoopCount, Clauses, AStmt, B);
11992}
11993
11994StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11995 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11996 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11997 if (!AStmt)
11998 return StmtError();
11999
12000 auto *CS = cast<CapturedStmt>(AStmt);
12001 // 1.2.2 OpenMP Language Terminology
12002 // Structured block - An executable statement with a single entry at the
12003 // top and a single exit at the bottom.
12004 // The point of exit cannot be a branch out of the structured block.
12005 // longjmp() and throw() must not violate the entry/exit criteria.
12006 CS->getCapturedDecl()->setNothrow();
12007 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12008 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12009 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12010 // 1.2.2 OpenMP Language Terminology
12011 // Structured block - An executable statement with a single entry at the
12012 // top and a single exit at the bottom.
12013 // The point of exit cannot be a branch out of the structured block.
12014 // longjmp() and throw() must not violate the entry/exit criteria.
12015 CS->getCapturedDecl()->setNothrow();
12016 }
12017
12018 OMPLoopBasedDirective::HelperExprs B;
12019 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12020 // define the nested loops number.
12021 unsigned NestedLoopCount = checkOpenMPLoop(
12022 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
12023 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12024 VarsWithImplicitDSA, B);
12025 if (NestedLoopCount == 0)
12026 return StmtError();
12027
12028 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12029 "omp target parallel for simd loop exprs were not built")((void)0);
12030
12031 if (!CurContext->isDependentContext()) {
12032 // Finalize the clauses that need pre-built expressions for CodeGen.
12033 for (OMPClause *C : Clauses) {
12034 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12035 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12036 B.NumIterations, *this, CurScope,
12037 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12038 return StmtError();
12039 }
12040 }
12041 if (checkSimdlenSafelenSpecified(*this, Clauses))
12042 return StmtError();
12043
12044 setFunctionHasBranchProtectedScope();
12045 return OMPTargetParallelForSimdDirective::Create(
12046 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12047}
12048
12049StmtResult Sema::ActOnOpenMPTargetSimdDirective(
12050 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12051 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12052 if (!AStmt)
12053 return StmtError();
12054
12055 auto *CS = cast<CapturedStmt>(AStmt);
12056 // 1.2.2 OpenMP Language Terminology
12057 // Structured block - An executable statement with a single entry at the
12058 // top and a single exit at the bottom.
12059 // The point of exit cannot be a branch out of the structured block.
12060 // longjmp() and throw() must not violate the entry/exit criteria.
12061 CS->getCapturedDecl()->setNothrow();
12062 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
12063 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12064 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12065 // 1.2.2 OpenMP Language Terminology
12066 // Structured block - An executable statement with a single entry at the
12067 // top and a single exit at the bottom.
12068 // The point of exit cannot be a branch out of the structured block.
12069 // longjmp() and throw() must not violate the entry/exit criteria.
12070 CS->getCapturedDecl()->setNothrow();
12071 }
12072
12073 OMPLoopBasedDirective::HelperExprs B;
12074 // In presence of clause 'collapse' with number of loops, it will define the
12075 // nested loops number.
12076 unsigned NestedLoopCount =
12077 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
12078 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12079 VarsWithImplicitDSA, B);
12080 if (NestedLoopCount == 0)
12081 return StmtError();
12082
12083 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12084 "omp target simd loop exprs were not built")((void)0);
12085
12086 if (!CurContext->isDependentContext()) {
12087 // Finalize the clauses that need pre-built expressions for CodeGen.
12088 for (OMPClause *C : Clauses) {
12089 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12090 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12091 B.NumIterations, *this, CurScope,
12092 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12093 return StmtError();
12094 }
12095 }
12096
12097 if (checkSimdlenSafelenSpecified(*this, Clauses))
12098 return StmtError();
12099
12100 setFunctionHasBranchProtectedScope();
12101 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
12102 NestedLoopCount, Clauses, AStmt, B);
12103}
12104
12105StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
12106 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12107 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12108 if (!AStmt)
12109 return StmtError();
12110
12111 auto *CS = cast<CapturedStmt>(AStmt);
12112 // 1.2.2 OpenMP Language Terminology
12113 // Structured block - An executable statement with a single entry at the
12114 // top and a single exit at the bottom.
12115 // The point of exit cannot be a branch out of the structured block.
12116 // longjmp() and throw() must not violate the entry/exit criteria.
12117 CS->getCapturedDecl()->setNothrow();
12118 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
12119 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12120 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12121 // 1.2.2 OpenMP Language Terminology
12122 // Structured block - An executable statement with a single entry at the
12123 // top and a single exit at the bottom.
12124 // The point of exit cannot be a branch out of the structured block.
12125 // longjmp() and throw() must not violate the entry/exit criteria.
12126 CS->getCapturedDecl()->setNothrow();
12127 }
12128
12129 OMPLoopBasedDirective::HelperExprs B;
12130 // In presence of clause 'collapse' with number of loops, it will
12131 // define the nested loops number.
12132 unsigned NestedLoopCount =
12133 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
12134 nullptr /*ordered not a clause on distribute*/, CS, *this,
12135 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
12136 if (NestedLoopCount == 0)
12137 return StmtError();
12138
12139 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12140 "omp teams distribute loop exprs were not built")((void)0);
12141
12142 setFunctionHasBranchProtectedScope();
12143
12144 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12145
12146 return OMPTeamsDistributeDirective::Create(
12147 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12148}
12149
12150StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
12151 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12152 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12153 if (!AStmt)
12154 return StmtError();
12155
12156 auto *CS = cast<CapturedStmt>(AStmt);
12157 // 1.2.2 OpenMP Language Terminology
12158 // Structured block - An executable statement with a single entry at the
12159 // top and a single exit at the bottom.
12160 // The point of exit cannot be a branch out of the structured block.
12161 // longjmp() and throw() must not violate the entry/exit criteria.
12162 CS->getCapturedDecl()->setNothrow();
12163 for (int ThisCaptureLevel =
12164 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
12165 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12166 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12167 // 1.2.2 OpenMP Language Terminology
12168 // Structured block - An executable statement with a single entry at the
12169 // top and a single exit at the bottom.
12170 // The point of exit cannot be a branch out of the structured block.
12171 // longjmp() and throw() must not violate the entry/exit criteria.
12172 CS->getCapturedDecl()->setNothrow();
12173 }
12174
12175 OMPLoopBasedDirective::HelperExprs B;
12176 // In presence of clause 'collapse' with number of loops, it will
12177 // define the nested loops number.
12178 unsigned NestedLoopCount = checkOpenMPLoop(
12179 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12180 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12181 VarsWithImplicitDSA, B);
12182
12183 if (NestedLoopCount == 0)
12184 return StmtError();
12185
12186 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12187 "omp teams distribute simd loop exprs were not built")((void)0);
12188
12189 if (!CurContext->isDependentContext()) {
12190 // Finalize the clauses that need pre-built expressions for CodeGen.
12191 for (OMPClause *C : Clauses) {
12192 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12193 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12194 B.NumIterations, *this, CurScope,
12195 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12196 return StmtError();
12197 }
12198 }
12199
12200 if (checkSimdlenSafelenSpecified(*this, Clauses))
12201 return StmtError();
12202
12203 setFunctionHasBranchProtectedScope();
12204
12205 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12206
12207 return OMPTeamsDistributeSimdDirective::Create(
12208 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12209}
12210
12211StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
12212 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12213 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12214 if (!AStmt)
12215 return StmtError();
12216
12217 auto *CS = cast<CapturedStmt>(AStmt);
12218 // 1.2.2 OpenMP Language Terminology
12219 // Structured block - An executable statement with a single entry at the
12220 // top and a single exit at the bottom.
12221 // The point of exit cannot be a branch out of the structured block.
12222 // longjmp() and throw() must not violate the entry/exit criteria.
12223 CS->getCapturedDecl()->setNothrow();
12224
12225 for (int ThisCaptureLevel =
12226 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
12227 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12228 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12229 // 1.2.2 OpenMP Language Terminology
12230 // Structured block - An executable statement with a single entry at the
12231 // top and a single exit at the bottom.
12232 // The point of exit cannot be a branch out of the structured block.
12233 // longjmp() and throw() must not violate the entry/exit criteria.
12234 CS->getCapturedDecl()->setNothrow();
12235 }
12236
12237 OMPLoopBasedDirective::HelperExprs B;
12238 // In presence of clause 'collapse' with number of loops, it will
12239 // define the nested loops number.
12240 unsigned NestedLoopCount = checkOpenMPLoop(
12241 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
12242 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12243 VarsWithImplicitDSA, B);
12244
12245 if (NestedLoopCount == 0)
12246 return StmtError();
12247
12248 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12249 "omp for loop exprs were not built")((void)0);
12250
12251 if (!CurContext->isDependentContext()) {
12252 // Finalize the clauses that need pre-built expressions for CodeGen.
12253 for (OMPClause *C : Clauses) {
12254 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12255 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12256 B.NumIterations, *this, CurScope,
12257 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12258 return StmtError();
12259 }
12260 }
12261
12262 if (checkSimdlenSafelenSpecified(*this, Clauses))
12263 return StmtError();
12264
12265 setFunctionHasBranchProtectedScope();
12266
12267 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12268
12269 return OMPTeamsDistributeParallelForSimdDirective::Create(
12270 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12271}
12272
12273StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
12274 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12275 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12276 if (!AStmt)
12277 return StmtError();
12278
12279 auto *CS = cast<CapturedStmt>(AStmt);
12280 // 1.2.2 OpenMP Language Terminology
12281 // Structured block - An executable statement with a single entry at the
12282 // top and a single exit at the bottom.
12283 // The point of exit cannot be a branch out of the structured block.
12284 // longjmp() and throw() must not violate the entry/exit criteria.
12285 CS->getCapturedDecl()->setNothrow();
12286
12287 for (int ThisCaptureLevel =
12288 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
12289 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12290 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12291 // 1.2.2 OpenMP Language Terminology
12292 // Structured block - An executable statement with a single entry at the
12293 // top and a single exit at the bottom.
12294 // The point of exit cannot be a branch out of the structured block.
12295 // longjmp() and throw() must not violate the entry/exit criteria.
12296 CS->getCapturedDecl()->setNothrow();
12297 }
12298
12299 OMPLoopBasedDirective::HelperExprs B;
12300 // In presence of clause 'collapse' with number of loops, it will
12301 // define the nested loops number.
12302 unsigned NestedLoopCount = checkOpenMPLoop(
12303 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12304 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12305 VarsWithImplicitDSA, B);
12306
12307 if (NestedLoopCount == 0)
12308 return StmtError();
12309
12310 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12311 "omp for loop exprs were not built")((void)0);
12312
12313 setFunctionHasBranchProtectedScope();
12314
12315 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12316
12317 return OMPTeamsDistributeParallelForDirective::Create(
12318 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12319 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12320}
12321
12322StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
12323 Stmt *AStmt,
12324 SourceLocation StartLoc,
12325 SourceLocation EndLoc) {
12326 if (!AStmt)
12327 return StmtError();
12328
12329 auto *CS = cast<CapturedStmt>(AStmt);
12330 // 1.2.2 OpenMP Language Terminology
12331 // Structured block - An executable statement with a single entry at the
12332 // top and a single exit at the bottom.
12333 // The point of exit cannot be a branch out of the structured block.
12334 // longjmp() and throw() must not violate the entry/exit criteria.
12335 CS->getCapturedDecl()->setNothrow();
12336
12337 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
12338 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12339 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12340 // 1.2.2 OpenMP Language Terminology
12341 // Structured block - An executable statement with a single entry at the
12342 // top and a single exit at the bottom.
12343 // The point of exit cannot be a branch out of the structured block.
12344 // longjmp() and throw() must not violate the entry/exit criteria.
12345 CS->getCapturedDecl()->setNothrow();
12346 }
12347 setFunctionHasBranchProtectedScope();
12348
12349 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
12350 AStmt);
12351}
12352
12353StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
12354 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12355 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12356 if (!AStmt)
12357 return StmtError();
12358
12359 auto *CS = cast<CapturedStmt>(AStmt);
12360 // 1.2.2 OpenMP Language Terminology
12361 // Structured block - An executable statement with a single entry at the
12362 // top and a single exit at the bottom.
12363 // The point of exit cannot be a branch out of the structured block.
12364 // longjmp() and throw() must not violate the entry/exit criteria.
12365 CS->getCapturedDecl()->setNothrow();
12366 for (int ThisCaptureLevel =
12367 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
12368 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12369 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12370 // 1.2.2 OpenMP Language Terminology
12371 // Structured block - An executable statement with a single entry at the
12372 // top and a single exit at the bottom.
12373 // The point of exit cannot be a branch out of the structured block.
12374 // longjmp() and throw() must not violate the entry/exit criteria.
12375 CS->getCapturedDecl()->setNothrow();
12376 }
12377
12378 OMPLoopBasedDirective::HelperExprs B;
12379 // In presence of clause 'collapse' with number of loops, it will
12380 // define the nested loops number.
12381 unsigned NestedLoopCount = checkOpenMPLoop(
12382 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
12383 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12384 VarsWithImplicitDSA, B);
12385 if (NestedLoopCount == 0)
12386 return StmtError();
12387
12388 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12389 "omp target teams distribute loop exprs were not built")((void)0);
12390
12391 setFunctionHasBranchProtectedScope();
12392 return OMPTargetTeamsDistributeDirective::Create(
12393 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12394}
12395
12396StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
12397 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12398 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12399 if (!AStmt)
12400 return StmtError();
12401
12402 auto *CS = cast<CapturedStmt>(AStmt);
12403 // 1.2.2 OpenMP Language Terminology
12404 // Structured block - An executable statement with a single entry at the
12405 // top and a single exit at the bottom.
12406 // The point of exit cannot be a branch out of the structured block.
12407 // longjmp() and throw() must not violate the entry/exit criteria.
12408 CS->getCapturedDecl()->setNothrow();
12409 for (int ThisCaptureLevel =
12410 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
12411 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12412 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12413 // 1.2.2 OpenMP Language Terminology
12414 // Structured block - An executable statement with a single entry at the
12415 // top and a single exit at the bottom.
12416 // The point of exit cannot be a branch out of the structured block.
12417 // longjmp() and throw() must not violate the entry/exit criteria.
12418 CS->getCapturedDecl()->setNothrow();
12419 }
12420
12421 OMPLoopBasedDirective::HelperExprs B;
12422 // In presence of clause 'collapse' with number of loops, it will
12423 // define the nested loops number.
12424 unsigned NestedLoopCount = checkOpenMPLoop(
12425 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12426 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12427 VarsWithImplicitDSA, B);
12428 if (NestedLoopCount == 0)
12429 return StmtError();
12430
12431 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12432 "omp target teams distribute parallel for loop exprs were not built")((void)0);
12433
12434 if (!CurContext->isDependentContext()) {
12435 // Finalize the clauses that need pre-built expressions for CodeGen.
12436 for (OMPClause *C : Clauses) {
12437 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12438 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12439 B.NumIterations, *this, CurScope,
12440 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12441 return StmtError();
12442 }
12443 }
12444
12445 setFunctionHasBranchProtectedScope();
12446 return OMPTargetTeamsDistributeParallelForDirective::Create(
12447 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12448 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12449}
12450
12451StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
12452 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12453 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12454 if (!AStmt)
12455 return StmtError();
12456
12457 auto *CS = cast<CapturedStmt>(AStmt);
12458 // 1.2.2 OpenMP Language Terminology
12459 // Structured block - An executable statement with a single entry at the
12460 // top and a single exit at the bottom.
12461 // The point of exit cannot be a branch out of the structured block.
12462 // longjmp() and throw() must not violate the entry/exit criteria.
12463 CS->getCapturedDecl()->setNothrow();
12464 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
12465 OMPD_target_teams_distribute_parallel_for_simd);
12466 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12467 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12468 // 1.2.2 OpenMP Language Terminology
12469 // Structured block - An executable statement with a single entry at the
12470 // top and a single exit at the bottom.
12471 // The point of exit cannot be a branch out of the structured block.
12472 // longjmp() and throw() must not violate the entry/exit criteria.
12473 CS->getCapturedDecl()->setNothrow();
12474 }
12475
12476 OMPLoopBasedDirective::HelperExprs B;
12477 // In presence of clause 'collapse' with number of loops, it will
12478 // define the nested loops number.
12479 unsigned NestedLoopCount =
12480 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
12481 getCollapseNumberExpr(Clauses),
12482 nullptr /*ordered not a clause on distribute*/, CS, *this,
12483 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
12484 if (NestedLoopCount == 0)
12485 return StmtError();
12486
12487 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12488 "omp target teams distribute parallel for simd loop exprs were not "((void)0)
12489 "built")((void)0);
12490
12491 if (!CurContext->isDependentContext()) {
12492 // Finalize the clauses that need pre-built expressions for CodeGen.
12493 for (OMPClause *C : Clauses) {
12494 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12495 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12496 B.NumIterations, *this, CurScope,
12497 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12498 return StmtError();
12499 }
12500 }
12501
12502 if (checkSimdlenSafelenSpecified(*this, Clauses))
12503 return StmtError();
12504
12505 setFunctionHasBranchProtectedScope();
12506 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
12507 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12508}
12509
12510StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
12511 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12512 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12513 if (!AStmt)
12514 return StmtError();
12515
12516 auto *CS = cast<CapturedStmt>(AStmt);
12517 // 1.2.2 OpenMP Language Terminology
12518 // Structured block - An executable statement with a single entry at the
12519 // top and a single exit at the bottom.
12520 // The point of exit cannot be a branch out of the structured block.
12521 // longjmp() and throw() must not violate the entry/exit criteria.
12522 CS->getCapturedDecl()->setNothrow();
12523 for (int ThisCaptureLevel =
12524 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12525 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12526 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12527 // 1.2.2 OpenMP Language Terminology
12528 // Structured block - An executable statement with a single entry at the
12529 // top and a single exit at the bottom.
12530 // The point of exit cannot be a branch out of the structured block.
12531 // longjmp() and throw() must not violate the entry/exit criteria.
12532 CS->getCapturedDecl()->setNothrow();
12533 }
12534
12535 OMPLoopBasedDirective::HelperExprs B;
12536 // In presence of clause 'collapse' with number of loops, it will
12537 // define the nested loops number.
12538 unsigned NestedLoopCount = checkOpenMPLoop(
12539 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12540 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12541 VarsWithImplicitDSA, B);
12542 if (NestedLoopCount == 0)
12543 return StmtError();
12544
12545 assert((CurContext->isDependentContext() || B.builtAll()) &&((void)0)
12546 "omp target teams distribute simd loop exprs were not built")((void)0);
12547
12548 if (!CurContext->isDependentContext()) {
12549 // Finalize the clauses that need pre-built expressions for CodeGen.
12550 for (OMPClause *C : Clauses) {
12551 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12552 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12553 B.NumIterations, *this, CurScope,
12554 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12555 return StmtError();
12556 }
12557 }
12558
12559 if (checkSimdlenSafelenSpecified(*this, Clauses))
12560 return StmtError();
12561
12562 setFunctionHasBranchProtectedScope();
12563 return OMPTargetTeamsDistributeSimdDirective::Create(
12564 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12565}
12566
12567bool Sema::checkTransformableLoopNest(
12568 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
12569 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
12570 Stmt *&Body,
12571 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
12572 &OriginalInits) {
12573 OriginalInits.emplace_back();
12574 bool Result = OMPLoopBasedDirective::doForAllLoops(
12575 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
12576 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
12577 Stmt *CurStmt) {
12578 VarsWithInheritedDSAType TmpDSA;
12579 unsigned SingleNumLoops =
12580 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12581 TmpDSA, LoopHelpers[Cnt]);
12582 if (SingleNumLoops == 0)
12583 return true;
12584 assert(SingleNumLoops == 1 && "Expect single loop iteration space")((void)0);
12585 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12586 OriginalInits.back().push_back(For->getInit());
12587 Body = For->getBody();
12588 } else {
12589 assert(isa<CXXForRangeStmt>(CurStmt) &&((void)0)
12590 "Expected canonical for or range-based for loops.")((void)0);
12591 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12592 OriginalInits.back().push_back(CXXFor->getBeginStmt());
12593 Body = CXXFor->getBody();
12594 }
12595 OriginalInits.emplace_back();
12596 return false;
12597 },
12598 [&OriginalInits](OMPLoopBasedDirective *Transform) {
12599 Stmt *DependentPreInits;
12600 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
12601 DependentPreInits = Dir->getPreInits();
12602 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
12603 DependentPreInits = Dir->getPreInits();
12604 else
12605 llvm_unreachable("Unhandled loop transformation")__builtin_unreachable();
12606 if (!DependentPreInits)
12607 return;
12608 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup())
12609 OriginalInits.back().push_back(C);
12610 });
12611 assert(OriginalInits.back().empty() && "No preinit after innermost loop")((void)0);
12612 OriginalInits.pop_back();
12613 return Result;
12614}
12615
12616StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12617 Stmt *AStmt, SourceLocation StartLoc,
12618 SourceLocation EndLoc) {
12619 auto SizesClauses =
12620 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12621 if (SizesClauses.empty()) {
12622 // A missing 'sizes' clause is already reported by the parser.
12623 return StmtError();
12624 }
12625 const OMPSizesClause *SizesClause = *SizesClauses.begin();
12626 unsigned NumLoops = SizesClause->getNumSizes();
12627
12628 // Empty statement should only be possible if there already was an error.
12629 if (!AStmt)
12630 return StmtError();
12631
12632 // Verify and diagnose loop nest.
12633 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12634 Stmt *Body = nullptr;
12635 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
12636 OriginalInits;
12637 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
12638 OriginalInits))
12639 return StmtError();
12640
12641 // Delay tiling to when template is completely instantiated.
12642 if (CurContext->isDependentContext())
12643 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12644 NumLoops, AStmt, nullptr, nullptr);
12645
12646 SmallVector<Decl *, 4> PreInits;
12647
12648 // Create iteration variables for the generated loops.
12649 SmallVector<VarDecl *, 4> FloorIndVars;
12650 SmallVector<VarDecl *, 4> TileIndVars;
12651 FloorIndVars.resize(NumLoops);
12652 TileIndVars.resize(NumLoops);
12653 for (unsigned I = 0; I < NumLoops; ++I) {
12654 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12655
12656 assert(LoopHelper.Counters.size() == 1 &&((void)0)
12657 "Expect single-dimensional loop iteration space")((void)0);
12658 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12659 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12660 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12661 QualType CntTy = IterVarRef->getType();
12662
12663 // Iteration variable for the floor (i.e. outer) loop.
12664 {
12665 std::string FloorCntName =
12666 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12667 VarDecl *FloorCntDecl =
12668 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12669 FloorIndVars[I] = FloorCntDecl;
12670 }
12671
12672 // Iteration variable for the tile (i.e. inner) loop.
12673 {
12674 std::string TileCntName =
12675 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12676
12677 // Reuse the iteration variable created by checkOpenMPLoop. It is also
12678 // used by the expressions to derive the original iteration variable's
12679 // value from the logical iteration number.
12680 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12681 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12682 TileIndVars[I] = TileCntDecl;
12683 }
12684 for (auto &P : OriginalInits[I]) {
12685 if (auto *D = P.dyn_cast<Decl *>())
12686 PreInits.push_back(D);
12687 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
12688 PreInits.append(PI->decl_begin(), PI->decl_end());
12689 }
12690 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12691 PreInits.append(PI->decl_begin(), PI->decl_end());
12692 // Gather declarations for the data members used as counters.
12693 for (Expr *CounterRef : LoopHelper.Counters) {
12694 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12695 if (isa<OMPCapturedExprDecl>(CounterDecl))
12696 PreInits.push_back(CounterDecl);
12697 }
12698 }
12699
12700 // Once the original iteration values are set, append the innermost body.
12701 Stmt *Inner = Body;
12702
12703 // Create tile loops from the inside to the outside.
12704 for (int I = NumLoops - 1; I >= 0; --I) {
12705 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12706 Expr *NumIterations = LoopHelper.NumIterations;
12707 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12708 QualType CntTy = OrigCntVar->getType();
12709 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12710 Scope *CurScope = getCurScope();
12711
12712 // Commonly used variables.
12713 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12714 OrigCntVar->getExprLoc());
12715 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12716 OrigCntVar->getExprLoc());
12717
12718 // For init-statement: auto .tile.iv = .floor.iv
12719 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12720 /*DirectInit=*/false);
12721 Decl *CounterDecl = TileIndVars[I];
12722 StmtResult InitStmt = new (Context)
12723 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12724 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12725 if (!InitStmt.isUsable())
12726 return StmtError();
12727
12728 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12729 // NumIterations)
12730 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12731 BO_Add, FloorIV, DimTileSize);
12732 if (!EndOfTile.isUsable())
12733 return StmtError();
12734 ExprResult IsPartialTile =
12735 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12736 NumIterations, EndOfTile.get());
12737 if (!IsPartialTile.isUsable())
12738 return StmtError();
12739 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12740 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12741 IsPartialTile.get(), NumIterations, EndOfTile.get());
12742 if (!MinTileAndIterSpace.isUsable())
12743 return StmtError();
12744 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12745 BO_LT, TileIV, MinTileAndIterSpace.get());
12746 if (!CondExpr.isUsable())
12747 return StmtError();
12748
12749 // For incr-statement: ++.tile.iv
12750 ExprResult IncrStmt =
12751 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12752 if (!IncrStmt.isUsable())
12753 return StmtError();
12754
12755 // Statements to set the original iteration variable's value from the
12756 // logical iteration number.
12757 // Generated for loop is:
12758 // Original_for_init;
12759 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12760 // NumIterations); ++.tile.iv) {
12761 // Original_Body;
12762 // Original_counter_update;
12763 // }
12764 // FIXME: If the innermost body is an loop itself, inserting these
12765 // statements stops it being recognized as a perfectly nested loop (e.g.
12766 // for applying tiling again). If this is the case, sink the expressions
12767 // further into the inner loop.
12768 SmallVector<Stmt *, 4> BodyParts;
12769 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12770 BodyParts.push_back(Inner);
12771 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12772 Inner->getEndLoc());
12773 Inner = new (Context)
12774 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12775 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12776 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12777 }
12778
12779 // Create floor loops from the inside to the outside.
12780 for (int I = NumLoops - 1; I >= 0; --I) {
12781 auto &LoopHelper = LoopHelpers[I];
12782 Expr *NumIterations = LoopHelper.NumIterations;
12783 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12784 QualType CntTy = OrigCntVar->getType();
12785 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12786 Scope *CurScope = getCurScope();
12787
12788 // Commonly used variables.
12789 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12790 OrigCntVar->getExprLoc());
12791
12792 // For init-statement: auto .floor.iv = 0
12793 AddInitializerToDecl(
12794 FloorIndVars[I],
12795 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12796 /*DirectInit=*/false);
12797 Decl *CounterDecl = FloorIndVars[I];
12798 StmtResult InitStmt = new (Context)
12799 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12800 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12801 if (!InitStmt.isUsable())
12802 return StmtError();
12803
12804 // For cond-expression: .floor.iv < NumIterations
12805 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12806 BO_LT, FloorIV, NumIterations);
12807 if (!CondExpr.isUsable())
12808 return StmtError();
12809
12810 // For incr-statement: .floor.iv += DimTileSize
12811 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12812 BO_AddAssign, FloorIV, DimTileSize);
12813 if (!IncrStmt.isUsable())
12814 return StmtError();
12815
12816 Inner = new (Context)
12817 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12818 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12819 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12820 }
12821
12822 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12823 AStmt, Inner,
12824 buildPreInits(Context, PreInits));
12825}
12826
12827StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
12828 Stmt *AStmt,
12829 SourceLocation StartLoc,
12830 SourceLocation EndLoc) {
12831 // Empty statement should only be possible if there already was an error.
12832 if (!AStmt)
12833 return StmtError();
12834
12835 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
12836 return StmtError();
12837
12838 const OMPFullClause *FullClause =
12839 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
12840 const OMPPartialClause *PartialClause =
12841 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
12842 assert(!(FullClause && PartialClause) &&((void)0)
12843 "mutual exclusivity must have been checked before")((void)0);
12844
12845 constexpr unsigned NumLoops = 1;
12846 Stmt *Body = nullptr;
12847 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
12848 NumLoops);
12849 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
12850 OriginalInits;
12851 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
12852 Body, OriginalInits))
12853 return StmtError();
12854
12855 // Delay unrolling to when template is completely instantiated.
12856 if (CurContext->isDependentContext())
12857 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12858 nullptr, nullptr);
12859
12860 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
12861
12862 if (FullClause) {
12863 if (!VerifyPositiveIntegerConstantInClause(
12864 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
12865 /*SuppressExprDigs=*/true)
12866 .isUsable()) {
12867 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
12868 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
12869 << "#pragma omp unroll full";
12870 return StmtError();
12871 }
12872 }
12873
12874 // The generated loop may only be passed to other loop-associated directive
12875 // when a partial clause is specified. Without the requirement it is
12876 // sufficient to generate loop unroll metadata at code-generation.
12877 if (!PartialClause)
12878 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12879 nullptr, nullptr);
12880
12881 // Otherwise, we need to provide a de-sugared/transformed AST that can be
12882 // associated with another loop directive.
12883 //
12884 // The canonical loop analysis return by checkTransformableLoopNest assumes
12885 // the following structure to be the same loop without transformations or
12886 // directives applied: \code OriginalInits; LoopHelper.PreInits;
12887 // LoopHelper.Counters;
12888 // for (; IV < LoopHelper.NumIterations; ++IV) {
12889 // LoopHelper.Updates;
12890 // Body;
12891 // }
12892 // \endcode
12893 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
12894 // and referenced by LoopHelper.IterationVarRef.
12895 //
12896 // The unrolling directive transforms this into the following loop:
12897 // \code
12898 // OriginalInits; \
12899 // LoopHelper.PreInits; > NewPreInits
12900 // LoopHelper.Counters; /
12901 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
12902 // #pragma clang loop unroll_count(Factor)
12903 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
12904 // {
12905 // LoopHelper.Updates;
12906 // Body;
12907 // }
12908 // }
12909 // \endcode
12910 // where UIV is a new logical iteration counter. IV must be the same VarDecl
12911 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
12912 // references it. If the partially unrolled loop is associated with another
12913 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
12914 // analyze this loop, i.e. the outer loop must fulfill the constraints of an
12915 // OpenMP canonical loop. The inner loop is not an associable canonical loop
12916 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
12917 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
12918 // property of the OMPLoopBasedDirective instead of statements in
12919 // CompoundStatement. This is to allow the loop to become a non-outermost loop
12920 // of a canonical loop nest where these PreInits are emitted before the
12921 // outermost directive.
12922
12923 // Determine the PreInit declarations.
12924 SmallVector<Decl *, 4> PreInits;
12925 assert(OriginalInits.size() == 1 &&((void)0)
12926 "Expecting a single-dimensional loop iteration space")((void)0);
12927 for (auto &P : OriginalInits[0]) {
12928 if (auto *D = P.dyn_cast<Decl *>())
12929 PreInits.push_back(D);
12930 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
12931 PreInits.append(PI->decl_begin(), PI->decl_end());
12932 }
12933 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12934 PreInits.append(PI->decl_begin(), PI->decl_end());
12935 // Gather declarations for the data members used as counters.
12936 for (Expr *CounterRef : LoopHelper.Counters) {
12937 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12938 if (isa<OMPCapturedExprDecl>(CounterDecl))
12939 PreInits.push_back(CounterDecl);
12940 }
12941
12942 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12943 QualType IVTy = IterationVarRef->getType();
12944 assert(LoopHelper.Counters.size() == 1 &&((void)0)
12945 "Expecting a single-dimensional loop iteration space")((void)0);
12946 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12947
12948 // Determine the unroll factor.
12949 uint64_t Factor;
12950 SourceLocation FactorLoc;
12951 if (Expr *FactorVal = PartialClause->getFactor()) {
12952 Factor =
12953 FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue();
12954 FactorLoc = FactorVal->getExprLoc();
12955 } else {
12956 // TODO: Use a better profitability model.
12957 Factor = 2;
12958 }
12959 assert(Factor > 0 && "Expected positive unroll factor")((void)0);
12960 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
12961 return IntegerLiteral::Create(
12962 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
12963 FactorLoc);
12964 };
12965
12966 // Iteration variable SourceLocations.
12967 SourceLocation OrigVarLoc = OrigVar->getExprLoc();
12968 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
12969 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
12970
12971 // Internal variable names.
12972 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
12973 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
12974 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
12975 std::string InnerTripCountName =
12976 (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
12977
12978 // Create the iteration variable for the unrolled loop.
12979 VarDecl *OuterIVDecl =
12980 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
12981 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
12982 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
12983 };
12984
12985 // Iteration variable for the inner loop: Reuse the iteration variable created
12986 // by checkOpenMPLoop.
12987 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
12988 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
12989 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
12990 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
12991 };
12992
12993 // Make a copy of the NumIterations expression for each use: By the AST
12994 // constraints, every expression object in a DeclContext must be unique.
12995 CaptureVars CopyTransformer(*this);
12996 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
12997 return AssertSuccess(
12998 CopyTransformer.TransformExpr(LoopHelper.NumIterations));
12999 };
13000
13001 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
13002 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
13003 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
13004 StmtResult InnerInit = new (Context)
13005 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13006 if (!InnerInit.isUsable())
13007 return StmtError();
13008
13009 // Inner For cond-expression:
13010 // \code
13011 // .unroll_inner.iv < .unrolled.iv + Factor &&
13012 // .unroll_inner.iv < NumIterations
13013 // \endcode
13014 // This conjunction of two conditions allows ScalarEvolution to derive the
13015 // maximum trip count of the inner loop.
13016 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13017 BO_Add, MakeOuterRef(), MakeFactorExpr());
13018 if (!EndOfTile.isUsable())
13019 return StmtError();
13020 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13021 BO_LE, MakeInnerRef(), EndOfTile.get());
13022 if (!InnerCond1.isUsable())
13023 return StmtError();
13024 ExprResult InnerCond2 =
13025 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
13026 MakeNumIterations());
13027 if (!InnerCond2.isUsable())
13028 return StmtError();
13029 ExprResult InnerCond =
13030 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
13031 InnerCond1.get(), InnerCond2.get());
13032 if (!InnerCond.isUsable())
13033 return StmtError();
13034
13035 // Inner For incr-statement: ++.unroll_inner.iv
13036 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
13037 UO_PreInc, MakeInnerRef());
13038 if (!InnerIncr.isUsable())
13039 return StmtError();
13040
13041 // Inner For statement.
13042 SmallVector<Stmt *> InnerBodyStmts;
13043 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
13044 InnerBodyStmts.push_back(Body);
13045 CompoundStmt *InnerBody = CompoundStmt::Create(
13046 Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
13047 ForStmt *InnerFor = new (Context)
13048 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
13049 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
13050 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13051
13052 // Unroll metadata for the inner loop.
13053 // This needs to take into account the remainder portion of the unrolled loop,
13054 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
13055 // supports multiple loop exits. Instead, unroll using a factor equivalent to
13056 // the maximum trip count, which will also generate a remainder loop. Just
13057 // `unroll(enable)` (which could have been useful if the user has not
13058 // specified a concrete factor; even though the outer loop cannot be
13059 // influenced anymore, would avoid more code bloat than necessary) will refuse
13060 // the loop because "Won't unroll; remainder loop could not be generated when
13061 // assuming runtime trip count". Even if it did work, it must not choose a
13062 // larger unroll factor than the maximum loop length, or it would always just
13063 // execute the remainder loop.
13064 LoopHintAttr *UnrollHintAttr =
13065 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
13066 LoopHintAttr::Numeric, MakeFactorExpr());
13067 AttributedStmt *InnerUnrolled =
13068 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
13069
13070 // Outer For init-statement: auto .unrolled.iv = 0
13071 AddInitializerToDecl(
13072 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
13073 /*DirectInit=*/false);
13074 StmtResult OuterInit = new (Context)
13075 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13076 if (!OuterInit.isUsable())
13077 return StmtError();
13078
13079 // Outer For cond-expression: .unrolled.iv < NumIterations
13080 ExprResult OuterConde =
13081 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
13082 MakeNumIterations());
13083 if (!OuterConde.isUsable())
13084 return StmtError();
13085
13086 // Outer For incr-statement: .unrolled.iv += Factor
13087 ExprResult OuterIncr =
13088 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
13089 MakeOuterRef(), MakeFactorExpr());
13090 if (!OuterIncr.isUsable())
13091 return StmtError();
13092
13093 // Outer For statement.
13094 ForStmt *OuterFor = new (Context)
13095 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
13096 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
13097 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13098
13099 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
13100 OuterFor, buildPreInits(Context, PreInits));
13101}
13102
13103OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
13104 SourceLocation StartLoc,
13105 SourceLocation LParenLoc,
13106 SourceLocation EndLoc) {
13107 OMPClause *Res = nullptr;
13108 switch (Kind) {
13109 case OMPC_final:
13110 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
13111 break;
13112 case OMPC_num_threads:
13113 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
13114 break;
13115 case OMPC_safelen:
13116 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
13117 break;
13118 case OMPC_simdlen:
13119 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
13120 break;
13121 case OMPC_allocator:
13122 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
13123 break;
13124 case OMPC_collapse:
13125 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
13126 break;
13127 case OMPC_ordered:
13128 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
13129 break;
13130 case OMPC_num_teams:
13131 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
13132 break;
13133 case OMPC_thread_limit:
13134 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
13135 break;
13136 case OMPC_priority:
13137 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
13138 break;
13139 case OMPC_grainsize:
13140 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
13141 break;
13142 case OMPC_num_tasks:
13143 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
13144 break;
13145 case OMPC_hint:
13146 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
13147 break;
13148 case OMPC_depobj:
13149 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
13150 break;
13151 case OMPC_detach:
13152 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
13153 break;
13154 case OMPC_novariants:
13155 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
13156 break;
13157 case OMPC_nocontext:
13158 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
13159 break;
13160 case OMPC_filter:
13161 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
13162 break;
13163 case OMPC_partial:
13164 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
13165 break;
13166 case OMPC_device:
13167 case OMPC_if:
13168 case OMPC_default:
13169 case OMPC_proc_bind:
13170 case OMPC_schedule:
13171 case OMPC_private:
13172 case OMPC_firstprivate:
13173 case OMPC_lastprivate:
13174 case OMPC_shared:
13175 case OMPC_reduction:
13176 case OMPC_task_reduction:
13177 case OMPC_in_reduction:
13178 case OMPC_linear:
13179 case OMPC_aligned:
13180 case OMPC_copyin:
13181 case OMPC_copyprivate:
13182 case OMPC_nowait:
13183 case OMPC_untied:
13184 case OMPC_mergeable:
13185 case OMPC_threadprivate:
13186 case OMPC_sizes:
13187 case OMPC_allocate:
13188 case OMPC_flush:
13189 case OMPC_read:
13190 case OMPC_write:
13191 case OMPC_update:
13192 case OMPC_capture:
13193 case OMPC_seq_cst:
13194 case OMPC_acq_rel:
13195 case OMPC_acquire:
13196 case OMPC_release:
13197 case OMPC_relaxed:
13198 case OMPC_depend:
13199 case OMPC_threads:
13200 case OMPC_simd:
13201 case OMPC_map:
13202 case OMPC_nogroup:
13203 case OMPC_dist_schedule:
13204 case OMPC_defaultmap:
13205 case OMPC_unknown:
13206 case OMPC_uniform:
13207 case OMPC_to:
13208 case OMPC_from:
13209 case OMPC_use_device_ptr:
13210 case OMPC_use_device_addr:
13211 case OMPC_is_device_ptr:
13212 case OMPC_unified_address:
13213 case OMPC_unified_shared_memory:
13214 case OMPC_reverse_offload:
13215 case OMPC_dynamic_allocators:
13216 case OMPC_atomic_default_mem_order:
13217 case OMPC_device_type:
13218 case OMPC_match:
13219 case OMPC_nontemporal:
13220 case OMPC_order:
13221 case OMPC_destroy:
13222 case OMPC_inclusive:
13223 case OMPC_exclusive:
13224 case OMPC_uses_allocators:
13225 case OMPC_affinity:
13226 default:
13227 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
13228 }
13229 return Res;
13230}
13231
13232// An OpenMP directive such as 'target parallel' has two captured regions:
13233// for the 'target' and 'parallel' respectively. This function returns
13234// the region in which to capture expressions associated with a clause.
13235// A return value of OMPD_unknown signifies that the expression should not
13236// be captured.
13237static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
13238 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
13239 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
13240 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13241 switch (CKind) {
13242 case OMPC_if:
13243 switch (DKind) {
13244 case OMPD_target_parallel_for_simd:
13245 if (OpenMPVersion >= 50 &&
13246 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13247 CaptureRegion = OMPD_parallel;
13248 break;
13249 }
13250 LLVM_FALLTHROUGH[[gnu::fallthrough]];
13251 case OMPD_target_parallel:
13252 case OMPD_target_parallel_for:
13253 // If this clause applies to the nested 'parallel' region, capture within
13254 // the 'target' region, otherwise do not capture.
13255 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13256 CaptureRegion = OMPD_target;
13257 break;
13258 case OMPD_target_teams_distribute_parallel_for_simd:
13259 if (OpenMPVersion >= 50 &&
13260 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13261 CaptureRegion = OMPD_parallel;
13262 break;
13263 }
13264 LLVM_FALLTHROUGH[[gnu::fallthrough]];
13265 case OMPD_target_teams_distribute_parallel_for:
13266 // If this clause applies to the nested 'parallel' region, capture within
13267 // the 'teams' region, otherwise do not capture.
13268 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13269 CaptureRegion = OMPD_teams;
13270 break;
13271 case OMPD_teams_distribute_parallel_for_simd:
13272 if (OpenMPVersion >= 50 &&
13273 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13274 CaptureRegion = OMPD_parallel;
13275 break;
13276 }
13277 LLVM_FALLTHROUGH[[gnu::fallthrough]];
13278 case OMPD_teams_distribute_parallel_for:
13279 CaptureRegion = OMPD_teams;
13280 break;
13281 case OMPD_target_update:
13282 case OMPD_target_enter_data:
13283 case OMPD_target_exit_data:
13284 CaptureRegion = OMPD_task;
13285 break;
13286 case OMPD_parallel_master_taskloop:
13287 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
13288 CaptureRegion = OMPD_parallel;
13289 break;
13290 case OMPD_parallel_master_taskloop_simd:
13291 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
13292 NameModifier == OMPD_taskloop) {
13293 CaptureRegion = OMPD_parallel;
13294 break;
13295 }
13296 if (OpenMPVersion <= 45)
13297 break;
13298 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13299 CaptureRegion = OMPD_taskloop;
13300 break;
13301 case OMPD_parallel_for_simd:
13302 if (OpenMPVersion <= 45)
13303 break;
13304 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13305 CaptureRegion = OMPD_parallel;
13306 break;
13307 case OMPD_taskloop_simd:
13308 case OMPD_master_taskloop_simd:
13309 if (OpenMPVersion <= 45)
13310 break;
13311 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13312 CaptureRegion = OMPD_taskloop;
13313 break;
13314 case OMPD_distribute_parallel_for_simd:
13315 if (OpenMPVersion <= 45)
13316 break;
13317 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13318 CaptureRegion = OMPD_parallel;
13319 break;
13320 case OMPD_target_simd:
13321 if (OpenMPVersion >= 50 &&
13322 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13323 CaptureRegion = OMPD_target;
13324 break;
13325 case OMPD_teams_distribute_simd:
13326 case OMPD_target_teams_distribute_simd:
13327 if (OpenMPVersion >= 50 &&
13328 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13329 CaptureRegion = OMPD_teams;
13330 break;
13331 case OMPD_cancel:
13332 case OMPD_parallel:
13333 case OMPD_parallel_master:
13334 case OMPD_parallel_sections:
13335 case OMPD_parallel_for:
13336 case OMPD_target:
13337 case OMPD_target_teams:
13338 case OMPD_target_teams_distribute:
13339 case OMPD_distribute_parallel_for:
13340 case OMPD_task:
13341 case OMPD_taskloop:
13342 case OMPD_master_taskloop:
13343 case OMPD_target_data:
13344 case OMPD_simd:
13345 case OMPD_for_simd:
13346 case OMPD_distribute_simd:
13347 // Do not capture if-clause expressions.
13348 break;
13349 case OMPD_threadprivate:
13350 case OMPD_allocate:
13351 case OMPD_taskyield:
13352 case OMPD_barrier:
13353 case OMPD_taskwait:
13354 case OMPD_cancellation_point:
13355 case OMPD_flush:
13356 case OMPD_depobj:
13357 case OMPD_scan:
13358 case OMPD_declare_reduction:
13359 case OMPD_declare_mapper:
13360 case OMPD_declare_simd:
13361 case OMPD_declare_variant:
13362 case OMPD_begin_declare_variant:
13363 case OMPD_end_declare_variant:
13364 case OMPD_declare_target:
13365 case OMPD_end_declare_target:
13366 case OMPD_teams:
13367 case OMPD_tile:
13368 case OMPD_unroll:
13369 case OMPD_for:
13370 case OMPD_sections:
13371 case OMPD_section:
13372 case OMPD_single:
13373 case OMPD_master:
13374 case OMPD_masked:
13375 case OMPD_critical:
13376 case OMPD_taskgroup:
13377 case OMPD_distribute:
13378 case OMPD_ordered:
13379 case OMPD_atomic:
13380 case OMPD_teams_distribute:
13381 case OMPD_requires:
13382 llvm_unreachable("Unexpected OpenMP directive with if-clause")__builtin_unreachable();
13383 case OMPD_unknown:
13384 default:
13385 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13386 }
13387 break;
13388 case OMPC_num_threads:
13389 switch (DKind) {
13390 case OMPD_target_parallel:
13391 case OMPD_target_parallel_for:
13392 case OMPD_target_parallel_for_simd:
13393 CaptureRegion = OMPD_target;
13394 break;
13395 case OMPD_teams_distribute_parallel_for:
13396 case OMPD_teams_distribute_parallel_for_simd:
13397 case OMPD_target_teams_distribute_parallel_for:
13398 case OMPD_target_teams_distribute_parallel_for_simd:
13399 CaptureRegion = OMPD_teams;
13400 break;
13401 case OMPD_parallel:
13402 case OMPD_parallel_master:
13403 case OMPD_parallel_sections:
13404 case OMPD_parallel_for:
13405 case OMPD_parallel_for_simd:
13406 case OMPD_distribute_parallel_for:
13407 case OMPD_distribute_parallel_for_simd:
13408 case OMPD_parallel_master_taskloop:
13409 case OMPD_parallel_master_taskloop_simd:
13410 // Do not capture num_threads-clause expressions.
13411 break;
13412 case OMPD_target_data:
13413 case OMPD_target_enter_data:
13414 case OMPD_target_exit_data:
13415 case OMPD_target_update:
13416 case OMPD_target:
13417 case OMPD_target_simd:
13418 case OMPD_target_teams:
13419 case OMPD_target_teams_distribute:
13420 case OMPD_target_teams_distribute_simd:
13421 case OMPD_cancel:
13422 case OMPD_task:
13423 case OMPD_taskloop:
13424 case OMPD_taskloop_simd:
13425 case OMPD_master_taskloop:
13426 case OMPD_master_taskloop_simd:
13427 case OMPD_threadprivate:
13428 case OMPD_allocate:
13429 case OMPD_taskyield:
13430 case OMPD_barrier:
13431 case OMPD_taskwait:
13432 case OMPD_cancellation_point:
13433 case OMPD_flush:
13434 case OMPD_depobj:
13435 case OMPD_scan:
13436 case OMPD_declare_reduction:
13437 case OMPD_declare_mapper:
13438 case OMPD_declare_simd:
13439 case OMPD_declare_variant:
13440 case OMPD_begin_declare_variant:
13441 case OMPD_end_declare_variant:
13442 case OMPD_declare_target:
13443 case OMPD_end_declare_target:
13444 case OMPD_teams:
13445 case OMPD_simd:
13446 case OMPD_tile:
13447 case OMPD_unroll:
13448 case OMPD_for:
13449 case OMPD_for_simd:
13450 case OMPD_sections:
13451 case OMPD_section:
13452 case OMPD_single:
13453 case OMPD_master:
13454 case OMPD_masked:
13455 case OMPD_critical:
13456 case OMPD_taskgroup:
13457 case OMPD_distribute:
13458 case OMPD_ordered:
13459 case OMPD_atomic:
13460 case OMPD_distribute_simd:
13461 case OMPD_teams_distribute:
13462 case OMPD_teams_distribute_simd:
13463 case OMPD_requires:
13464 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")__builtin_unreachable();
13465 case OMPD_unknown:
13466 default:
13467 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13468 }
13469 break;
13470 case OMPC_num_teams:
13471 switch (DKind) {
13472 case OMPD_target_teams:
13473 case OMPD_target_teams_distribute:
13474 case OMPD_target_teams_distribute_simd:
13475 case OMPD_target_teams_distribute_parallel_for:
13476 case OMPD_target_teams_distribute_parallel_for_simd:
13477 CaptureRegion = OMPD_target;
13478 break;
13479 case OMPD_teams_distribute_parallel_for:
13480 case OMPD_teams_distribute_parallel_for_simd:
13481 case OMPD_teams:
13482 case OMPD_teams_distribute:
13483 case OMPD_teams_distribute_simd:
13484 // Do not capture num_teams-clause expressions.
13485 break;
13486 case OMPD_distribute_parallel_for:
13487 case OMPD_distribute_parallel_for_simd:
13488 case OMPD_task:
13489 case OMPD_taskloop:
13490 case OMPD_taskloop_simd:
13491 case OMPD_master_taskloop:
13492 case OMPD_master_taskloop_simd:
13493 case OMPD_parallel_master_taskloop:
13494 case OMPD_parallel_master_taskloop_simd:
13495 case OMPD_target_data:
13496 case OMPD_target_enter_data:
13497 case OMPD_target_exit_data:
13498 case OMPD_target_update:
13499 case OMPD_cancel:
13500 case OMPD_parallel:
13501 case OMPD_parallel_master:
13502 case OMPD_parallel_sections:
13503 case OMPD_parallel_for:
13504 case OMPD_parallel_for_simd:
13505 case OMPD_target:
13506 case OMPD_target_simd:
13507 case OMPD_target_parallel:
13508 case OMPD_target_parallel_for:
13509 case OMPD_target_parallel_for_simd:
13510 case OMPD_threadprivate:
13511 case OMPD_allocate:
13512 case OMPD_taskyield:
13513 case OMPD_barrier:
13514 case OMPD_taskwait:
13515 case OMPD_cancellation_point:
13516 case OMPD_flush:
13517 case OMPD_depobj:
13518 case OMPD_scan:
13519 case OMPD_declare_reduction:
13520 case OMPD_declare_mapper:
13521 case OMPD_declare_simd:
13522 case OMPD_declare_variant:
13523 case OMPD_begin_declare_variant:
13524 case OMPD_end_declare_variant:
13525 case OMPD_declare_target:
13526 case OMPD_end_declare_target:
13527 case OMPD_simd:
13528 case OMPD_tile:
13529 case OMPD_unroll:
13530 case OMPD_for:
13531 case OMPD_for_simd:
13532 case OMPD_sections:
13533 case OMPD_section:
13534 case OMPD_single:
13535 case OMPD_master:
13536 case OMPD_masked:
13537 case OMPD_critical:
13538 case OMPD_taskgroup:
13539 case OMPD_distribute:
13540 case OMPD_ordered:
13541 case OMPD_atomic:
13542 case OMPD_distribute_simd:
13543 case OMPD_requires:
13544 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")__builtin_unreachable();
13545 case OMPD_unknown:
13546 default:
13547 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13548 }
13549 break;
13550 case OMPC_thread_limit:
13551 switch (DKind) {
13552 case OMPD_target_teams:
13553 case OMPD_target_teams_distribute:
13554 case OMPD_target_teams_distribute_simd:
13555 case OMPD_target_teams_distribute_parallel_for:
13556 case OMPD_target_teams_distribute_parallel_for_simd:
13557 CaptureRegion = OMPD_target;
13558 break;
13559 case OMPD_teams_distribute_parallel_for:
13560 case OMPD_teams_distribute_parallel_for_simd:
13561 case OMPD_teams:
13562 case OMPD_teams_distribute:
13563 case OMPD_teams_distribute_simd:
13564 // Do not capture thread_limit-clause expressions.
13565 break;
13566 case OMPD_distribute_parallel_for:
13567 case OMPD_distribute_parallel_for_simd:
13568 case OMPD_task:
13569 case OMPD_taskloop:
13570 case OMPD_taskloop_simd:
13571 case OMPD_master_taskloop:
13572 case OMPD_master_taskloop_simd:
13573 case OMPD_parallel_master_taskloop:
13574 case OMPD_parallel_master_taskloop_simd:
13575 case OMPD_target_data:
13576 case OMPD_target_enter_data:
13577 case OMPD_target_exit_data:
13578 case OMPD_target_update:
13579 case OMPD_cancel:
13580 case OMPD_parallel:
13581 case OMPD_parallel_master:
13582 case OMPD_parallel_sections:
13583 case OMPD_parallel_for:
13584 case OMPD_parallel_for_simd:
13585 case OMPD_target:
13586 case OMPD_target_simd:
13587 case OMPD_target_parallel:
13588 case OMPD_target_parallel_for:
13589 case OMPD_target_parallel_for_simd:
13590 case OMPD_threadprivate:
13591 case OMPD_allocate:
13592 case OMPD_taskyield:
13593 case OMPD_barrier:
13594 case OMPD_taskwait:
13595 case OMPD_cancellation_point:
13596 case OMPD_flush:
13597 case OMPD_depobj:
13598 case OMPD_scan:
13599 case OMPD_declare_reduction:
13600 case OMPD_declare_mapper:
13601 case OMPD_declare_simd:
13602 case OMPD_declare_variant:
13603 case OMPD_begin_declare_variant:
13604 case OMPD_end_declare_variant:
13605 case OMPD_declare_target:
13606 case OMPD_end_declare_target:
13607 case OMPD_simd:
13608 case OMPD_tile:
13609 case OMPD_unroll:
13610 case OMPD_for:
13611 case OMPD_for_simd:
13612 case OMPD_sections:
13613 case OMPD_section:
13614 case OMPD_single:
13615 case OMPD_master:
13616 case OMPD_masked:
13617 case OMPD_critical:
13618 case OMPD_taskgroup:
13619 case OMPD_distribute:
13620 case OMPD_ordered:
13621 case OMPD_atomic:
13622 case OMPD_distribute_simd:
13623 case OMPD_requires:
13624 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")__builtin_unreachable();
13625 case OMPD_unknown:
13626 default:
13627 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13628 }
13629 break;
13630 case OMPC_schedule:
13631 switch (DKind) {
13632 case OMPD_parallel_for:
13633 case OMPD_parallel_for_simd:
13634 case OMPD_distribute_parallel_for:
13635 case OMPD_distribute_parallel_for_simd:
13636 case OMPD_teams_distribute_parallel_for:
13637 case OMPD_teams_distribute_parallel_for_simd:
13638 case OMPD_target_parallel_for:
13639 case OMPD_target_parallel_for_simd:
13640 case OMPD_target_teams_distribute_parallel_for:
13641 case OMPD_target_teams_distribute_parallel_for_simd:
13642 CaptureRegion = OMPD_parallel;
13643 break;
13644 case OMPD_for:
13645 case OMPD_for_simd:
13646 // Do not capture schedule-clause expressions.
13647 break;
13648 case OMPD_task:
13649 case OMPD_taskloop:
13650 case OMPD_taskloop_simd:
13651 case OMPD_master_taskloop:
13652 case OMPD_master_taskloop_simd:
13653 case OMPD_parallel_master_taskloop:
13654 case OMPD_parallel_master_taskloop_simd:
13655 case OMPD_target_data:
13656 case OMPD_target_enter_data:
13657 case OMPD_target_exit_data:
13658 case OMPD_target_update:
13659 case OMPD_teams:
13660 case OMPD_teams_distribute:
13661 case OMPD_teams_distribute_simd:
13662 case OMPD_target_teams_distribute:
13663 case OMPD_target_teams_distribute_simd:
13664 case OMPD_target:
13665 case OMPD_target_simd:
13666 case OMPD_target_parallel:
13667 case OMPD_cancel:
13668 case OMPD_parallel:
13669 case OMPD_parallel_master:
13670 case OMPD_parallel_sections:
13671 case OMPD_threadprivate:
13672 case OMPD_allocate:
13673 case OMPD_taskyield:
13674 case OMPD_barrier:
13675 case OMPD_taskwait:
13676 case OMPD_cancellation_point:
13677 case OMPD_flush:
13678 case OMPD_depobj:
13679 case OMPD_scan:
13680 case OMPD_declare_reduction:
13681 case OMPD_declare_mapper:
13682 case OMPD_declare_simd:
13683 case OMPD_declare_variant:
13684 case OMPD_begin_declare_variant:
13685 case OMPD_end_declare_variant:
13686 case OMPD_declare_target:
13687 case OMPD_end_declare_target:
13688 case OMPD_simd:
13689 case OMPD_tile:
13690 case OMPD_unroll:
13691 case OMPD_sections:
13692 case OMPD_section:
13693 case OMPD_single:
13694 case OMPD_master:
13695 case OMPD_masked:
13696 case OMPD_critical:
13697 case OMPD_taskgroup:
13698 case OMPD_distribute:
13699 case OMPD_ordered:
13700 case OMPD_atomic:
13701 case OMPD_distribute_simd:
13702 case OMPD_target_teams:
13703 case OMPD_requires:
13704 llvm_unreachable("Unexpected OpenMP directive with schedule clause")__builtin_unreachable();
13705 case OMPD_unknown:
13706 default:
13707 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13708 }
13709 break;
13710 case OMPC_dist_schedule:
13711 switch (DKind) {
13712 case OMPD_teams_distribute_parallel_for:
13713 case OMPD_teams_distribute_parallel_for_simd:
13714 case OMPD_teams_distribute:
13715 case OMPD_teams_distribute_simd:
13716 case OMPD_target_teams_distribute_parallel_for:
13717 case OMPD_target_teams_distribute_parallel_for_simd:
13718 case OMPD_target_teams_distribute:
13719 case OMPD_target_teams_distribute_simd:
13720 CaptureRegion = OMPD_teams;
13721 break;
13722 case OMPD_distribute_parallel_for:
13723 case OMPD_distribute_parallel_for_simd:
13724 case OMPD_distribute:
13725 case OMPD_distribute_simd:
13726 // Do not capture dist_schedule-clause expressions.
13727 break;
13728 case OMPD_parallel_for:
13729 case OMPD_parallel_for_simd:
13730 case OMPD_target_parallel_for_simd:
13731 case OMPD_target_parallel_for:
13732 case OMPD_task:
13733 case OMPD_taskloop:
13734 case OMPD_taskloop_simd:
13735 case OMPD_master_taskloop:
13736 case OMPD_master_taskloop_simd:
13737 case OMPD_parallel_master_taskloop:
13738 case OMPD_parallel_master_taskloop_simd:
13739 case OMPD_target_data:
13740 case OMPD_target_enter_data:
13741 case OMPD_target_exit_data:
13742 case OMPD_target_update:
13743 case OMPD_teams:
13744 case OMPD_target:
13745 case OMPD_target_simd:
13746 case OMPD_target_parallel:
13747 case OMPD_cancel:
13748 case OMPD_parallel:
13749 case OMPD_parallel_master:
13750 case OMPD_parallel_sections:
13751 case OMPD_threadprivate:
13752 case OMPD_allocate:
13753 case OMPD_taskyield:
13754 case OMPD_barrier:
13755 case OMPD_taskwait:
13756 case OMPD_cancellation_point:
13757 case OMPD_flush:
13758 case OMPD_depobj:
13759 case OMPD_scan:
13760 case OMPD_declare_reduction:
13761 case OMPD_declare_mapper:
13762 case OMPD_declare_simd:
13763 case OMPD_declare_variant:
13764 case OMPD_begin_declare_variant:
13765 case OMPD_end_declare_variant:
13766 case OMPD_declare_target:
13767 case OMPD_end_declare_target:
13768 case OMPD_simd:
13769 case OMPD_tile:
13770 case OMPD_unroll:
13771 case OMPD_for:
13772 case OMPD_for_simd:
13773 case OMPD_sections:
13774 case OMPD_section:
13775 case OMPD_single:
13776 case OMPD_master:
13777 case OMPD_masked:
13778 case OMPD_critical:
13779 case OMPD_taskgroup:
13780 case OMPD_ordered:
13781 case OMPD_atomic:
13782 case OMPD_target_teams:
13783 case OMPD_requires:
13784 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause")__builtin_unreachable();
13785 case OMPD_unknown:
13786 default:
13787 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13788 }
13789 break;
13790 case OMPC_device:
13791 switch (DKind) {
13792 case OMPD_target_update:
13793 case OMPD_target_enter_data:
13794 case OMPD_target_exit_data:
13795 case OMPD_target:
13796 case OMPD_target_simd:
13797 case OMPD_target_teams:
13798 case OMPD_target_parallel:
13799 case OMPD_target_teams_distribute:
13800 case OMPD_target_teams_distribute_simd:
13801 case OMPD_target_parallel_for:
13802 case OMPD_target_parallel_for_simd:
13803 case OMPD_target_teams_distribute_parallel_for:
13804 case OMPD_target_teams_distribute_parallel_for_simd:
13805 case OMPD_dispatch:
13806 CaptureRegion = OMPD_task;
13807 break;
13808 case OMPD_target_data:
13809 case OMPD_interop:
13810 // Do not capture device-clause expressions.
13811 break;
13812 case OMPD_teams_distribute_parallel_for:
13813 case OMPD_teams_distribute_parallel_for_simd:
13814 case OMPD_teams:
13815 case OMPD_teams_distribute:
13816 case OMPD_teams_distribute_simd:
13817 case OMPD_distribute_parallel_for:
13818 case OMPD_distribute_parallel_for_simd:
13819 case OMPD_task:
13820 case OMPD_taskloop:
13821 case OMPD_taskloop_simd:
13822 case OMPD_master_taskloop:
13823 case OMPD_master_taskloop_simd:
13824 case OMPD_parallel_master_taskloop:
13825 case OMPD_parallel_master_taskloop_simd:
13826 case OMPD_cancel:
13827 case OMPD_parallel:
13828 case OMPD_parallel_master:
13829 case OMPD_parallel_sections:
13830 case OMPD_parallel_for:
13831 case OMPD_parallel_for_simd:
13832 case OMPD_threadprivate:
13833 case OMPD_allocate:
13834 case OMPD_taskyield:
13835 case OMPD_barrier:
13836 case OMPD_taskwait:
13837 case OMPD_cancellation_point:
13838 case OMPD_flush:
13839 case OMPD_depobj:
13840 case OMPD_scan:
13841 case OMPD_declare_reduction:
13842 case OMPD_declare_mapper:
13843 case OMPD_declare_simd:
13844 case OMPD_declare_variant:
13845 case OMPD_begin_declare_variant:
13846 case OMPD_end_declare_variant:
13847 case OMPD_declare_target:
13848 case OMPD_end_declare_target:
13849 case OMPD_simd:
13850 case OMPD_tile:
13851 case OMPD_unroll:
13852 case OMPD_for:
13853 case OMPD_for_simd:
13854 case OMPD_sections:
13855 case OMPD_section:
13856 case OMPD_single:
13857 case OMPD_master:
13858 case OMPD_masked:
13859 case OMPD_critical:
13860 case OMPD_taskgroup:
13861 case OMPD_distribute:
13862 case OMPD_ordered:
13863 case OMPD_atomic:
13864 case OMPD_distribute_simd:
13865 case OMPD_requires:
13866 llvm_unreachable("Unexpected OpenMP directive with device-clause")__builtin_unreachable();
13867 case OMPD_unknown:
13868 default:
13869 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13870 }
13871 break;
13872 case OMPC_grainsize:
13873 case OMPC_num_tasks:
13874 case OMPC_final:
13875 case OMPC_priority:
13876 switch (DKind) {
13877 case OMPD_task:
13878 case OMPD_taskloop:
13879 case OMPD_taskloop_simd:
13880 case OMPD_master_taskloop:
13881 case OMPD_master_taskloop_simd:
13882 break;
13883 case OMPD_parallel_master_taskloop:
13884 case OMPD_parallel_master_taskloop_simd:
13885 CaptureRegion = OMPD_parallel;
13886 break;
13887 case OMPD_target_update:
13888 case OMPD_target_enter_data:
13889 case OMPD_target_exit_data:
13890 case OMPD_target:
13891 case OMPD_target_simd:
13892 case OMPD_target_teams:
13893 case OMPD_target_parallel:
13894 case OMPD_target_teams_distribute:
13895 case OMPD_target_teams_distribute_simd:
13896 case OMPD_target_parallel_for:
13897 case OMPD_target_parallel_for_simd:
13898 case OMPD_target_teams_distribute_parallel_for:
13899 case OMPD_target_teams_distribute_parallel_for_simd:
13900 case OMPD_target_data:
13901 case OMPD_teams_distribute_parallel_for:
13902 case OMPD_teams_distribute_parallel_for_simd:
13903 case OMPD_teams:
13904 case OMPD_teams_distribute:
13905 case OMPD_teams_distribute_simd:
13906 case OMPD_distribute_parallel_for:
13907 case OMPD_distribute_parallel_for_simd:
13908 case OMPD_cancel:
13909 case OMPD_parallel:
13910 case OMPD_parallel_master:
13911 case OMPD_parallel_sections:
13912 case OMPD_parallel_for:
13913 case OMPD_parallel_for_simd:
13914 case OMPD_threadprivate:
13915 case OMPD_allocate:
13916 case OMPD_taskyield:
13917 case OMPD_barrier:
13918 case OMPD_taskwait:
13919 case OMPD_cancellation_point:
13920 case OMPD_flush:
13921 case OMPD_depobj:
13922 case OMPD_scan:
13923 case OMPD_declare_reduction:
13924 case OMPD_declare_mapper:
13925 case OMPD_declare_simd:
13926 case OMPD_declare_variant:
13927 case OMPD_begin_declare_variant:
13928 case OMPD_end_declare_variant:
13929 case OMPD_declare_target:
13930 case OMPD_end_declare_target:
13931 case OMPD_simd:
13932 case OMPD_tile:
13933 case OMPD_unroll:
13934 case OMPD_for:
13935 case OMPD_for_simd:
13936 case OMPD_sections:
13937 case OMPD_section:
13938 case OMPD_single:
13939 case OMPD_master:
13940 case OMPD_masked:
13941 case OMPD_critical:
13942 case OMPD_taskgroup:
13943 case OMPD_distribute:
13944 case OMPD_ordered:
13945 case OMPD_atomic:
13946 case OMPD_distribute_simd:
13947 case OMPD_requires:
13948 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")__builtin_unreachable();
13949 case OMPD_unknown:
13950 default:
13951 llvm_unreachable("Unknown OpenMP directive")__builtin_unreachable();
13952 }
13953 break;
13954 case OMPC_novariants:
13955 case OMPC_nocontext:
13956 switch (DKind) {
13957 case OMPD_dispatch:
13958 CaptureRegion = OMPD_task;
13959 break;
13960 default:
13961 llvm_unreachable("Unexpected OpenMP directive")__builtin_unreachable();
13962 }
13963 break;
13964 case OMPC_filter:
13965 // Do not capture filter-clause expressions.
13966 break;
13967 case OMPC_firstprivate:
13968 case OMPC_lastprivate:
13969 case OMPC_reduction:
13970 case OMPC_task_reduction:
13971 case OMPC_in_reduction:
13972 case OMPC_linear:
13973 case OMPC_default:
13974 case OMPC_proc_bind:
13975 case OMPC_safelen:
13976 case OMPC_simdlen:
13977 case OMPC_sizes:
13978 case OMPC_allocator:
13979 case OMPC_collapse:
13980 case OMPC_private:
13981 case OMPC_shared:
13982 case OMPC_aligned:
13983 case OMPC_copyin:
13984 case OMPC_copyprivate:
13985 case OMPC_ordered:
13986 case OMPC_nowait:
13987 case OMPC_untied:
13988 case OMPC_mergeable:
13989 case OMPC_threadprivate:
13990 case OMPC_allocate:
13991 case OMPC_flush:
13992 case OMPC_depobj:
13993 case OMPC_read:
13994 case OMPC_write:
13995 case OMPC_update:
13996 case OMPC_capture:
13997 case OMPC_seq_cst:
13998 case OMPC_acq_rel:
13999 case OMPC_acquire:
14000 case OMPC_release:
14001 case OMPC_relaxed:
14002 case OMPC_depend:
14003 case OMPC_threads:
14004 case OMPC_simd:
14005 case OMPC_map:
14006 case OMPC_nogroup:
14007 case OMPC_hint:
14008 case OMPC_defaultmap:
14009 case OMPC_unknown:
14010 case OMPC_uniform:
14011 case OMPC_to:
14012 case OMPC_from:
14013 case OMPC_use_device_ptr:
14014 case OMPC_use_device_addr:
14015 case OMPC_is_device_ptr:
14016 case OMPC_unified_address:
14017 case OMPC_unified_shared_memory:
14018 case OMPC_reverse_offload:
14019 case OMPC_dynamic_allocators:
14020 case OMPC_atomic_default_mem_order:
14021 case OMPC_device_type:
14022 case OMPC_match:
14023 case OMPC_nontemporal:
14024 case OMPC_order:
14025 case OMPC_destroy:
14026 case OMPC_detach:
14027 case OMPC_inclusive:
14028 case OMPC_exclusive:
14029 case OMPC_uses_allocators:
14030 case OMPC_affinity:
14031 default:
14032 llvm_unreachable("Unexpected OpenMP clause.")__builtin_unreachable();
14033 }
14034 return CaptureRegion;
14035}
14036
14037OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
14038 Expr *Condition, SourceLocation StartLoc,
14039 SourceLocation LParenLoc,
14040 SourceLocation NameModifierLoc,
14041 SourceLocation ColonLoc,
14042 SourceLocation EndLoc) {
14043 Expr *ValExpr = Condition;
14044 Stmt *HelperValStmt = nullptr;
14045 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14046 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14047 !Condition->isInstantiationDependent() &&
14048 !Condition->containsUnexpandedParameterPack()) {
14049 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14050 if (Val.isInvalid())
14051 return nullptr;
14052
14053 ValExpr = Val.get();
14054
14055 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14056 CaptureRegion = getOpenMPCaptureRegionForClause(
14057 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
14058 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14059 ValExpr = MakeFullExpr(ValExpr).get();
14060 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14061 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14062 HelperValStmt = buildPreInits(Context, Captures);
14063 }
14064 }
14065
14066 return new (Context)
14067 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
14068 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
14069}
14070
14071OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
14072 SourceLocation StartLoc,
14073 SourceLocation LParenLoc,
14074 SourceLocation EndLoc) {
14075 Expr *ValExpr = Condition;
14076 Stmt *HelperValStmt = nullptr;
14077 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14078 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14079 !Condition->isInstantiationDependent() &&
14080 !Condition->containsUnexpandedParameterPack()) {
14081 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14082 if (Val.isInvalid())
14083 return nullptr;
14084
14085 ValExpr = MakeFullExpr(Val.get()).get();
14086
14087 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14088 CaptureRegion =
14089 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
14090 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14091 ValExpr = MakeFullExpr(ValExpr).get();
14092 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14093 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14094 HelperValStmt = buildPreInits(Context, Captures);
14095 }
14096 }
14097
14098 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
14099 StartLoc, LParenLoc, EndLoc);
14100}
14101
14102ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
14103 Expr *Op) {
14104 if (!Op)
14105 return ExprError();
14106
14107 class IntConvertDiagnoser : public ICEConvertDiagnoser {
14108 public:
14109 IntConvertDiagnoser()
14110 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
14111 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
14112 QualType T) override {
14113 return S.Diag(Loc, diag::err_omp_not_integral) << T;
14114 }
14115 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
14116 QualType T) override {
14117 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
14118 }
14119 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
14120 QualType T,
14121 QualType ConvTy) override {
14122 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
14123 }
14124 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
14125 QualType ConvTy) override {
14126 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14127 << ConvTy->isEnumeralType() << ConvTy;
14128 }
14129 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
14130 QualType T) override {
14131 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
14132 }
14133 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
14134 QualType ConvTy) override {
14135 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14136 << ConvTy->isEnumeralType() << ConvTy;
14137 }
14138 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
14139 QualType) override {
14140 llvm_unreachable("conversion functions are permitted")__builtin_unreachable();
14141 }
14142 } ConvertDiagnoser;
14143 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
14144}
14145
14146static bool
14147isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
14148 bool StrictlyPositive, bool BuildCapture = false,
14149 OpenMPDirectiveKind DKind = OMPD_unknown,
14150 OpenMPDirectiveKind *CaptureRegion = nullptr,
14151 Stmt **HelperValStmt = nullptr) {
14152 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
14153 !ValExpr->isInstantiationDependent()) {
14154 SourceLocation Loc = ValExpr->getExprLoc();
14155 ExprResult Value =
14156 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
14157 if (Value.isInvalid())
14158 return false;
14159
14160 ValExpr = Value.get();
14161 // The expression must evaluate to a non-negative integer value.
14162 if (Optional<llvm::APSInt> Result =
14163 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
14164 if (Result->isSigned() &&
14165 !((!StrictlyPositive && Result->isNonNegative()) ||
14166 (StrictlyPositive && Result->isStrictlyPositive()))) {
14167 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
14168 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14169 << ValExpr->getSourceRange();
14170 return false;
14171 }
14172 }
14173 if (!BuildCapture)
14174 return true;
14175 *CaptureRegion =
14176 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
14177 if (*CaptureRegion != OMPD_unknown &&
14178 !SemaRef.CurContext->isDependentContext()) {
14179 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
14180 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14181 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
14182 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
14183 }
14184 }
14185 return true;
14186}
14187
14188OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
14189 SourceLocation StartLoc,
14190 SourceLocation LParenLoc,
14191 SourceLocation EndLoc) {
14192 Expr *ValExpr = NumThreads;
14193 Stmt *HelperValStmt = nullptr;
14194
14195 // OpenMP [2.5, Restrictions]
14196 // The num_threads expression must evaluate to a positive integer value.
14197 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
14198 /*StrictlyPositive=*/true))
14199 return nullptr;
14200
14201 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14202 OpenMPDirectiveKind CaptureRegion =
14203 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
14204 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14205 ValExpr = MakeFullExpr(ValExpr).get();
14206 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14207 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14208 HelperValStmt = buildPreInits(Context, Captures);
14209 }
14210
14211 return new (Context) OMPNumThreadsClause(
14212 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14213}
14214
14215ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
14216 OpenMPClauseKind CKind,
14217 bool StrictlyPositive,
14218 bool SuppressExprDiags) {
14219 if (!E)
14220 return ExprError();
14221 if (E->isValueDependent() || E->isTypeDependent() ||
14222 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
14223 return E;
14224
14225 llvm::APSInt Result;
14226 ExprResult ICE;
14227 if (SuppressExprDiags) {
14228 // Use a custom diagnoser that suppresses 'note' diagnostics about the
14229 // expression.
14230 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
14231 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
14232 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
14233 SourceLocation Loc) override {
14234 llvm_unreachable("Diagnostic suppressed")__builtin_unreachable();
14235 }
14236 } Diagnoser;
14237 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
14238 } else {
14239 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
14240 }
14241 if (ICE.isInvalid())
14242 return ExprError();
14243
14244 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
14245 (!StrictlyPositive && !Result.isNonNegative())) {
14246 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
14247 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14248 << E->getSourceRange();
14249 return ExprError();
14250 }
14251 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
14252 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
14253 << E->getSourceRange();
14254 return ExprError();
14255 }
14256 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
14257 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
14258 else if (CKind == OMPC_ordered)
14259 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
14260 return ICE;
14261}
14262
14263OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
14264 SourceLocation LParenLoc,
14265 SourceLocation EndLoc) {
14266 // OpenMP [2.8.1, simd construct, Description]
14267 // The parameter of the safelen clause must be a constant
14268 // positive integer expression.
14269 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
14270 if (Safelen.isInvalid())
14271 return nullptr;
14272 return new (Context)
14273 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
14274}
14275
14276OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
14277 SourceLocation LParenLoc,
14278 SourceLocation EndLoc) {
14279 // OpenMP [2.8.1, simd construct, Description]
14280 // The parameter of the simdlen clause must be a constant
14281 // positive integer expression.
14282 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
14283 if (Simdlen.isInvalid())
14284 return nullptr;
14285 return new (Context)
14286 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
14287}
14288
14289/// Tries to find omp_allocator_handle_t type.
14290static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
14291 DSAStackTy *Stack) {
14292 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
14293 if (!OMPAllocatorHandleT.isNull())
14294 return true;
14295 // Build the predefined allocator expressions.
14296 bool ErrorFound = false;
14297 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
14298 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
14299 StringRef Allocator =
14300 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
14301 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
14302 auto *VD = dyn_cast_or_null<ValueDecl>(
14303 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
14304 if (!VD) {
14305 ErrorFound = true;
14306 break;
14307 }
14308 QualType AllocatorType =
14309 VD->getType().getNonLValueExprType(S.getASTContext());
14310 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
14311 if (!Res.isUsable()) {
14312 ErrorFound = true;
14313 break;
14314 }
14315 if (OMPAllocatorHandleT.isNull())
14316 OMPAllocatorHandleT = AllocatorType;
14317 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
14318 ErrorFound = true;
14319 break;
14320 }
14321 Stack->setAllocator(AllocatorKind, Res.get());
14322 }
14323 if (ErrorFound) {
14324 S.Diag(Loc, diag::err_omp_implied_type_not_found)
14325 << "omp_allocator_handle_t";
14326 return false;
14327 }
14328 OMPAllocatorHandleT.addConst();
14329 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
14330 return true;
14331}
14332
14333OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
14334 SourceLocation LParenLoc,
14335 SourceLocation EndLoc) {
14336 // OpenMP [2.11.3, allocate Directive, Description]
14337 // allocator is an expression of omp_allocator_handle_t type.
14338 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14339 return nullptr;
14340
14341 ExprResult Allocator = DefaultLvalueConversion(A);
14342 if (Allocator.isInvalid())
14343 return nullptr;
14344 Allocator = PerformImplicitConversion(Allocator.get(),
14345 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
14346 Sema::AA_Initializing,
14347 /*AllowExplicit=*/true);
14348 if (Allocator.isInvalid())
14349 return nullptr;
14350 return new (Context)
14351 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
14352}
14353
14354OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
14355 SourceLocation StartLoc,
14356 SourceLocation LParenLoc,
14357 SourceLocation EndLoc) {
14358 // OpenMP [2.7.1, loop construct, Description]
14359 // OpenMP [2.8.1, simd construct, Description]
14360 // OpenMP [2.9.6, distribute construct, Description]
14361 // The parameter of the collapse clause must be a constant
14362 // positive integer expression.
14363 ExprResult NumForLoopsResult =
14364 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
14365 if (NumForLoopsResult.isInvalid())
14366 return nullptr;
14367 return new (Context)
14368 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
14369}
14370
14371OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
14372 SourceLocation EndLoc,
14373 SourceLocation LParenLoc,
14374 Expr *NumForLoops) {
14375 // OpenMP [2.7.1, loop construct, Description]
14376 // OpenMP [2.8.1, simd construct, Description]
14377 // OpenMP [2.9.6, distribute construct, Description]
14378 // The parameter of the ordered clause must be a constant
14379 // positive integer expression if any.
14380 if (NumForLoops && LParenLoc.isValid()) {
14381 ExprResult NumForLoopsResult =
14382 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
14383 if (NumForLoopsResult.isInvalid())
14384 return nullptr;
14385 NumForLoops = NumForLoopsResult.get();
14386 } else {
14387 NumForLoops = nullptr;
14388 }
14389 auto *Clause = OMPOrderedClause::Create(
14390 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
14391 StartLoc, LParenLoc, EndLoc);
14392 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
14393 return Clause;
14394}
14395
14396OMPClause *Sema::ActOnOpenMPSimpleClause(
14397 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
14398 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14399 OMPClause *Res = nullptr;
14400 switch (Kind) {
14401 case OMPC_default:
14402 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
14403 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14404 break;
14405 case OMPC_proc_bind:
14406 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
14407 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14408 break;
14409 case OMPC_atomic_default_mem_order:
14410 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
14411 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
14412 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14413 break;
14414 case OMPC_order:
14415 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
14416 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14417 break;
14418 case OMPC_update:
14419 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
14420 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14421 break;
14422 case OMPC_if:
14423 case OMPC_final:
14424 case OMPC_num_threads:
14425 case OMPC_safelen:
14426 case OMPC_simdlen:
14427 case OMPC_sizes:
14428 case OMPC_allocator:
14429 case OMPC_collapse:
14430 case OMPC_schedule:
14431 case OMPC_private:
14432 case OMPC_firstprivate:
14433 case OMPC_lastprivate:
14434 case OMPC_shared:
14435 case OMPC_reduction:
14436 case OMPC_task_reduction:
14437 case OMPC_in_reduction:
14438 case OMPC_linear:
14439 case OMPC_aligned:
14440 case OMPC_copyin:
14441 case OMPC_copyprivate:
14442 case OMPC_ordered:
14443 case OMPC_nowait:
14444 case OMPC_untied:
14445 case OMPC_mergeable:
14446 case OMPC_threadprivate:
14447 case OMPC_allocate:
14448 case OMPC_flush:
14449 case OMPC_depobj:
14450 case OMPC_read:
14451 case OMPC_write:
14452 case OMPC_capture:
14453 case OMPC_seq_cst:
14454 case OMPC_acq_rel:
14455 case OMPC_acquire:
14456 case OMPC_release:
14457 case OMPC_relaxed:
14458 case OMPC_depend:
14459 case OMPC_device:
14460 case OMPC_threads:
14461 case OMPC_simd:
14462 case OMPC_map:
14463 case OMPC_num_teams:
14464 case OMPC_thread_limit:
14465 case OMPC_priority:
14466 case OMPC_grainsize:
14467 case OMPC_nogroup:
14468 case OMPC_num_tasks:
14469 case OMPC_hint:
14470 case OMPC_dist_schedule:
14471 case OMPC_defaultmap:
14472 case OMPC_unknown:
14473 case OMPC_uniform:
14474 case OMPC_to:
14475 case OMPC_from:
14476 case OMPC_use_device_ptr:
14477 case OMPC_use_device_addr:
14478 case OMPC_is_device_ptr:
14479 case OMPC_unified_address:
14480 case OMPC_unified_shared_memory:
14481 case OMPC_reverse_offload:
14482 case OMPC_dynamic_allocators:
14483 case OMPC_device_type:
14484 case OMPC_match:
14485 case OMPC_nontemporal:
14486 case OMPC_destroy:
14487 case OMPC_novariants:
14488 case OMPC_nocontext:
14489 case OMPC_detach:
14490 case OMPC_inclusive:
14491 case OMPC_exclusive:
14492 case OMPC_uses_allocators:
14493 case OMPC_affinity:
14494 default:
14495 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
14496 }
14497 return Res;
14498}
14499
14500static std::string
14501getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
14502 ArrayRef<unsigned> Exclude = llvm::None) {
14503 SmallString<256> Buffer;
14504 llvm::raw_svector_ostream Out(Buffer);
14505 unsigned Skipped = Exclude.size();
14506 auto S = Exclude.begin(), E = Exclude.end();
14507 for (unsigned I = First; I < Last; ++I) {
14508 if (std::find(S, E, I) != E) {
14509 --Skipped;
14510 continue;
14511 }
14512 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
14513 if (I + Skipped + 2 == Last)
14514 Out << " or ";
14515 else if (I + Skipped + 1 != Last)
14516 Out << ", ";
14517 }
14518 return std::string(Out.str());
14519}
14520
14521OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
14522 SourceLocation KindKwLoc,
14523 SourceLocation StartLoc,
14524 SourceLocation LParenLoc,
14525 SourceLocation EndLoc) {
14526 if (Kind == OMP_DEFAULT_unknown) {
14527 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14528 << getListOfPossibleValues(OMPC_default, /*First=*/0,
14529 /*Last=*/unsigned(OMP_DEFAULT_unknown))
14530 << getOpenMPClauseName(OMPC_default);
14531 return nullptr;
14532 }
14533
14534 switch (Kind) {
14535 case OMP_DEFAULT_none:
14536 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
14537 break;
14538 case OMP_DEFAULT_shared:
14539 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
14540 break;
14541 case OMP_DEFAULT_firstprivate:
14542 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
14543 break;
14544 default:
14545 llvm_unreachable("DSA unexpected in OpenMP default clause")__builtin_unreachable();
14546 }
14547
14548 return new (Context)
14549 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14550}
14551
14552OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
14553 SourceLocation KindKwLoc,
14554 SourceLocation StartLoc,
14555 SourceLocation LParenLoc,
14556 SourceLocation EndLoc) {
14557 if (Kind == OMP_PROC_BIND_unknown) {
14558 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14559 << getListOfPossibleValues(OMPC_proc_bind,
14560 /*First=*/unsigned(OMP_PROC_BIND_master),
14561 /*Last=*/
14562 unsigned(LangOpts.OpenMP > 50
14563 ? OMP_PROC_BIND_primary
14564 : OMP_PROC_BIND_spread) +
14565 1)
14566 << getOpenMPClauseName(OMPC_proc_bind);
14567 return nullptr;
14568 }
14569 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
14570 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14571 << getListOfPossibleValues(OMPC_proc_bind,
14572 /*First=*/unsigned(OMP_PROC_BIND_master),
14573 /*Last=*/
14574 unsigned(OMP_PROC_BIND_spread) + 1)
14575 << getOpenMPClauseName(OMPC_proc_bind);
14576 return new (Context)
14577 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14578}
14579
14580OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
14581 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
14582 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14583 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
14584 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14585 << getListOfPossibleValues(
14586 OMPC_atomic_default_mem_order, /*First=*/0,
14587 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
14588 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
14589 return nullptr;
14590 }
14591 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
14592 LParenLoc, EndLoc);
14593}
14594
14595OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
14596 SourceLocation KindKwLoc,
14597 SourceLocation StartLoc,
14598 SourceLocation LParenLoc,
14599 SourceLocation EndLoc) {
14600 if (Kind == OMPC_ORDER_unknown) {
14601 static_assert(OMPC_ORDER_unknown > 0,
14602 "OMPC_ORDER_unknown not greater than 0");
14603 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14604 << getListOfPossibleValues(OMPC_order, /*First=*/0,
14605 /*Last=*/OMPC_ORDER_unknown)
14606 << getOpenMPClauseName(OMPC_order);
14607 return nullptr;
14608 }
14609 return new (Context)
14610 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14611}
14612
14613OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
14614 SourceLocation KindKwLoc,
14615 SourceLocation StartLoc,
14616 SourceLocation LParenLoc,
14617 SourceLocation EndLoc) {
14618 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
14619 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
14620 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
14621 OMPC_DEPEND_depobj};
14622 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14623 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14624 /*Last=*/OMPC_DEPEND_unknown, Except)
14625 << getOpenMPClauseName(OMPC_update);
14626 return nullptr;
14627 }
14628 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
14629 EndLoc);
14630}
14631
14632OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
14633 SourceLocation StartLoc,
14634 SourceLocation LParenLoc,
14635 SourceLocation EndLoc) {
14636 for (Expr *SizeExpr : SizeExprs) {
14637 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
14638 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
14639 if (!NumForLoopsResult.isUsable())
14640 return nullptr;
14641 }
14642
14643 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(SizeExprs.size());
14644 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14645 SizeExprs);
14646}
14647
14648OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
14649 SourceLocation EndLoc) {
14650 return OMPFullClause::Create(Context, StartLoc, EndLoc);
14651}
14652
14653OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
14654 SourceLocation StartLoc,
14655 SourceLocation LParenLoc,
14656 SourceLocation EndLoc) {
14657 if (FactorExpr) {
14658 // If an argument is specified, it must be a constant (or an unevaluated
14659 // template expression).
14660 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
14661 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
14662 if (FactorResult.isInvalid())
14663 return nullptr;
14664 FactorExpr = FactorResult.get();
14665 }
14666
14667 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14668 FactorExpr);
14669}
14670
14671OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
14672 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
14673 SourceLocation StartLoc, SourceLocation LParenLoc,
14674 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
14675 SourceLocation EndLoc) {
14676 OMPClause *Res = nullptr;
14677 switch (Kind) {
14678 case OMPC_schedule:
14679 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
14680 assert(Argument.size() == NumberOfElements &&((void)0)
14681 ArgumentLoc.size() == NumberOfElements)((void)0);
14682 Res = ActOnOpenMPScheduleClause(
14683 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
14684 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
14685 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
14686 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
14687 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
14688 break;
14689 case OMPC_if:
14690 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((void)0);
14691 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
14692 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
14693 DelimLoc, EndLoc);
14694 break;
14695 case OMPC_dist_schedule:
14696 Res = ActOnOpenMPDistScheduleClause(
14697 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
14698 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
14699 break;
14700 case OMPC_defaultmap:
14701 enum { Modifier, DefaultmapKind };
14702 Res = ActOnOpenMPDefaultmapClause(
14703 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
14704 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
14705 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
14706 EndLoc);
14707 break;
14708 case OMPC_device:
14709 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((void)0);
14710 Res = ActOnOpenMPDeviceClause(
14711 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
14712 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
14713 break;
14714 case OMPC_final:
14715 case OMPC_num_threads:
14716 case OMPC_safelen:
14717 case OMPC_simdlen:
14718 case OMPC_sizes:
14719 case OMPC_allocator:
14720 case OMPC_collapse:
14721 case OMPC_default:
14722 case OMPC_proc_bind:
14723 case OMPC_private:
14724 case OMPC_firstprivate:
14725 case OMPC_lastprivate:
14726 case OMPC_shared:
14727 case OMPC_reduction:
14728 case OMPC_task_reduction:
14729 case OMPC_in_reduction:
14730 case OMPC_linear:
14731 case OMPC_aligned:
14732 case OMPC_copyin:
14733 case OMPC_copyprivate:
14734 case OMPC_ordered:
14735 case OMPC_nowait:
14736 case OMPC_untied:
14737 case OMPC_mergeable:
14738 case OMPC_threadprivate:
14739 case OMPC_allocate:
14740 case OMPC_flush:
14741 case OMPC_depobj:
14742 case OMPC_read:
14743 case OMPC_write:
14744 case OMPC_update:
14745 case OMPC_capture:
14746 case OMPC_seq_cst:
14747 case OMPC_acq_rel:
14748 case OMPC_acquire:
14749 case OMPC_release:
14750 case OMPC_relaxed:
14751 case OMPC_depend:
14752 case OMPC_threads:
14753 case OMPC_simd:
14754 case OMPC_map:
14755 case OMPC_num_teams:
14756 case OMPC_thread_limit:
14757 case OMPC_priority:
14758 case OMPC_grainsize:
14759 case OMPC_nogroup:
14760 case OMPC_num_tasks:
14761 case OMPC_hint:
14762 case OMPC_unknown:
14763 case OMPC_uniform:
14764 case OMPC_to:
14765 case OMPC_from:
14766 case OMPC_use_device_ptr:
14767 case OMPC_use_device_addr:
14768 case OMPC_is_device_ptr:
14769 case OMPC_unified_address:
14770 case OMPC_unified_shared_memory:
14771 case OMPC_reverse_offload:
14772 case OMPC_dynamic_allocators:
14773 case OMPC_atomic_default_mem_order:
14774 case OMPC_device_type:
14775 case OMPC_match:
14776 case OMPC_nontemporal:
14777 case OMPC_order:
14778 case OMPC_destroy:
14779 case OMPC_novariants:
14780 case OMPC_nocontext:
14781 case OMPC_detach:
14782 case OMPC_inclusive:
14783 case OMPC_exclusive:
14784 case OMPC_uses_allocators:
14785 case OMPC_affinity:
14786 default:
14787 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
14788 }
14789 return Res;
14790}
14791
14792static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
14793 OpenMPScheduleClauseModifier M2,
14794 SourceLocation M1Loc, SourceLocation M2Loc) {
14795 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
14796 SmallVector<unsigned, 2> Excluded;
14797 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
14798 Excluded.push_back(M2);
14799 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
14800 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
14801 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
14802 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
14803 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
14804 << getListOfPossibleValues(OMPC_schedule,
14805 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
14806 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14807 Excluded)
14808 << getOpenMPClauseName(OMPC_schedule);
14809 return true;
14810 }
14811 return false;
14812}
14813
14814OMPClause *Sema::ActOnOpenMPScheduleClause(
14815 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
14816 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14817 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
14818 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
14819 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
14820 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
14821 return nullptr;
14822 // OpenMP, 2.7.1, Loop Construct, Restrictions
14823 // Either the monotonic modifier or the nonmonotonic modifier can be specified
14824 // but not both.
14825 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
14826 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
14827 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
14828 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
14829 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
14830 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
14831 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
14832 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
14833 return nullptr;
14834 }
14835 if (Kind == OMPC_SCHEDULE_unknown) {
14836 std::string Values;
14837 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
14838 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
14839 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14840 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14841 Exclude);
14842 } else {
14843 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14844 /*Last=*/OMPC_SCHEDULE_unknown);
14845 }
14846 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14847 << Values << getOpenMPClauseName(OMPC_schedule);
14848 return nullptr;
14849 }
14850 // OpenMP, 2.7.1, Loop Construct, Restrictions
14851 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
14852 // schedule(guided).
14853 // OpenMP 5.0 does not have this restriction.
14854 if (LangOpts.OpenMP < 50 &&
14855 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
14856 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
14857 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
14858 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
14859 diag::err_omp_schedule_nonmonotonic_static);
14860 return nullptr;
14861 }
14862 Expr *ValExpr = ChunkSize;
14863 Stmt *HelperValStmt = nullptr;
14864 if (ChunkSize) {
14865 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14866 !ChunkSize->isInstantiationDependent() &&
14867 !ChunkSize->containsUnexpandedParameterPack()) {
14868 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14869 ExprResult Val =
14870 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14871 if (Val.isInvalid())
14872 return nullptr;
14873
14874 ValExpr = Val.get();
14875
14876 // OpenMP [2.7.1, Restrictions]
14877 // chunk_size must be a loop invariant integer expression with a positive
14878 // value.
14879 if (Optional<llvm::APSInt> Result =
14880 ValExpr->getIntegerConstantExpr(Context)) {
14881 if (Result->isSigned() && !Result->isStrictlyPositive()) {
14882 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14883 << "schedule" << 1 << ChunkSize->getSourceRange();
14884 return nullptr;
14885 }
14886 } else if (getOpenMPCaptureRegionForClause(
14887 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
14888 LangOpts.OpenMP) != OMPD_unknown &&
14889 !CurContext->isDependentContext()) {
14890 ValExpr = MakeFullExpr(ValExpr).get();
14891 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14892 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14893 HelperValStmt = buildPreInits(Context, Captures);
14894 }
14895 }
14896 }
14897
14898 return new (Context)
14899 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
14900 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
14901}
14902
14903OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
14904 SourceLocation StartLoc,
14905 SourceLocation EndLoc) {
14906 OMPClause *Res = nullptr;
14907 switch (Kind) {
14908 case OMPC_ordered:
14909 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
14910 break;
14911 case OMPC_nowait:
14912 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
14913 break;
14914 case OMPC_untied:
14915 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
14916 break;
14917 case OMPC_mergeable:
14918 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
14919 break;
14920 case OMPC_read:
14921 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
14922 break;
14923 case OMPC_write:
14924 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
14925 break;
14926 case OMPC_update:
14927 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
14928 break;
14929 case OMPC_capture:
14930 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
14931 break;
14932 case OMPC_seq_cst:
14933 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
14934 break;
14935 case OMPC_acq_rel:
14936 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
14937 break;
14938 case OMPC_acquire:
14939 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
14940 break;
14941 case OMPC_release:
14942 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
14943 break;
14944 case OMPC_relaxed:
14945 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
14946 break;
14947 case OMPC_threads:
14948 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
14949 break;
14950 case OMPC_simd:
14951 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
14952 break;
14953 case OMPC_nogroup:
14954 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
14955 break;
14956 case OMPC_unified_address:
14957 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
14958 break;
14959 case OMPC_unified_shared_memory:
14960 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14961 break;
14962 case OMPC_reverse_offload:
14963 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
14964 break;
14965 case OMPC_dynamic_allocators:
14966 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
14967 break;
14968 case OMPC_destroy:
14969 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
14970 /*LParenLoc=*/SourceLocation(),
14971 /*VarLoc=*/SourceLocation(), EndLoc);
14972 break;
14973 case OMPC_full:
14974 Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
14975 break;
14976 case OMPC_partial:
14977 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
14978 break;
14979 case OMPC_if:
14980 case OMPC_final:
14981 case OMPC_num_threads:
14982 case OMPC_safelen:
14983 case OMPC_simdlen:
14984 case OMPC_sizes:
14985 case OMPC_allocator:
14986 case OMPC_collapse:
14987 case OMPC_schedule:
14988 case OMPC_private:
14989 case OMPC_firstprivate:
14990 case OMPC_lastprivate:
14991 case OMPC_shared:
14992 case OMPC_reduction:
14993 case OMPC_task_reduction:
14994 case OMPC_in_reduction:
14995 case OMPC_linear:
14996 case OMPC_aligned:
14997 case OMPC_copyin:
14998 case OMPC_copyprivate:
14999 case OMPC_default:
15000 case OMPC_proc_bind:
15001 case OMPC_threadprivate:
15002 case OMPC_allocate:
15003 case OMPC_flush:
15004 case OMPC_depobj:
15005 case OMPC_depend:
15006 case OMPC_device:
15007 case OMPC_map:
15008 case OMPC_num_teams:
15009 case OMPC_thread_limit:
15010 case OMPC_priority:
15011 case OMPC_grainsize:
15012 case OMPC_num_tasks:
15013 case OMPC_hint:
15014 case OMPC_dist_schedule:
15015 case OMPC_defaultmap:
15016 case OMPC_unknown:
15017 case OMPC_uniform:
15018 case OMPC_to:
15019 case OMPC_from:
15020 case OMPC_use_device_ptr:
15021 case OMPC_use_device_addr:
15022 case OMPC_is_device_ptr:
15023 case OMPC_atomic_default_mem_order:
15024 case OMPC_device_type:
15025 case OMPC_match:
15026 case OMPC_nontemporal:
15027 case OMPC_order:
15028 case OMPC_novariants:
15029 case OMPC_nocontext:
15030 case OMPC_detach:
15031 case OMPC_inclusive:
15032 case OMPC_exclusive:
15033 case OMPC_uses_allocators:
15034 case OMPC_affinity:
15035 default:
15036 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
15037 }
15038 return Res;
15039}
15040
15041OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
15042 SourceLocation EndLoc) {
15043 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
15044 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
15045}
15046
15047OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
15048 SourceLocation EndLoc) {
15049 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
15050}
15051
15052OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
15053 SourceLocation EndLoc) {
15054 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
15055}
15056
15057OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
15058 SourceLocation EndLoc) {
15059 return new (Context) OMPReadClause(StartLoc, EndLoc);
15060}
15061
15062OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
15063 SourceLocation EndLoc) {
15064 return new (Context) OMPWriteClause(StartLoc, EndLoc);
15065}
15066
15067OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
15068 SourceLocation EndLoc) {
15069 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
15070}
15071
15072OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
15073 SourceLocation EndLoc) {
15074 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
15075}
15076
15077OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
15078 SourceLocation EndLoc) {
15079 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
15080}
15081
15082OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
15083 SourceLocation EndLoc) {
15084 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
15085}
15086
15087OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
15088 SourceLocation EndLoc) {
15089 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
15090}
15091
15092OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
15093 SourceLocation EndLoc) {
15094 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
15095}
15096
15097OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
15098 SourceLocation EndLoc) {
15099 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
15100}
15101
15102OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
15103 SourceLocation EndLoc) {
15104 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
15105}
15106
15107OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
15108 SourceLocation EndLoc) {
15109 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
15110}
15111
15112OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
15113 SourceLocation EndLoc) {
15114 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
15115}
15116
15117OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
15118 SourceLocation EndLoc) {
15119 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
15120}
15121
15122OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
15123 SourceLocation EndLoc) {
15124 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
15125}
15126
15127OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
15128 SourceLocation EndLoc) {
15129 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
15130}
15131
15132OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
15133 SourceLocation EndLoc) {
15134 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
15135}
15136
15137StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
15138 SourceLocation StartLoc,
15139 SourceLocation EndLoc) {
15140
15141 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15142 // At least one action-clause must appear on a directive.
15143 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
15144 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
15145 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
15146 << Expected << getOpenMPDirectiveName(OMPD_interop);
15147 return StmtError();
15148 }
15149
15150 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15151 // A depend clause can only appear on the directive if a targetsync
15152 // interop-type is present or the interop-var was initialized with
15153 // the targetsync interop-type.
15154
15155 // If there is any 'init' clause diagnose if there is no 'init' clause with
15156 // interop-type of 'targetsync'. Cases involving other directives cannot be
15157 // diagnosed.
15158 const OMPDependClause *DependClause = nullptr;
15159 bool HasInitClause = false;
15160 bool IsTargetSync = false;
15161 for (const OMPClause *C : Clauses) {
15162 if (IsTargetSync)
15163 break;
15164 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
15165 HasInitClause = true;
15166 if (InitClause->getIsTargetSync())
15167 IsTargetSync = true;
15168 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
15169 DependClause = DC;
15170 }
15171 }
15172 if (DependClause && HasInitClause && !IsTargetSync) {
15173 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
15174 return StmtError();
15175 }
15176
15177 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15178 // Each interop-var may be specified for at most one action-clause of each
15179 // interop construct.
15180 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
15181 for (const OMPClause *C : Clauses) {
15182 OpenMPClauseKind ClauseKind = C->getClauseKind();
15183 const DeclRefExpr *DRE = nullptr;
15184 SourceLocation VarLoc;
15185
15186 if (ClauseKind == OMPC_init) {
15187 const auto *IC = cast<OMPInitClause>(C);
15188 VarLoc = IC->getVarLoc();
15189 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
15190 } else if (ClauseKind == OMPC_use) {
15191 const auto *UC = cast<OMPUseClause>(C);
15192 VarLoc = UC->getVarLoc();
15193 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
15194 } else if (ClauseKind == OMPC_destroy) {
15195 const auto *DC = cast<OMPDestroyClause>(C);
15196 VarLoc = DC->getVarLoc();
15197 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
15198 }
15199
15200 if (!DRE)
15201 continue;
15202
15203 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
15204 if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
15205 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
15206 return StmtError();
15207 }
15208 }
15209 }
15210
15211 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
15212}
15213
15214static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
15215 SourceLocation VarLoc,
15216 OpenMPClauseKind Kind) {
15217 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
15218 InteropVarExpr->isInstantiationDependent() ||
15219 InteropVarExpr->containsUnexpandedParameterPack())
15220 return true;
15221
15222 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
15223 if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
15224 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
15225 return false;
15226 }
15227
15228 // Interop variable should be of type omp_interop_t.
15229 bool HasError = false;
15230 QualType InteropType;
15231 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
15232 VarLoc, Sema::LookupOrdinaryName);
15233 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
15234 NamedDecl *ND = Result.getFoundDecl();
15235 if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
15236 InteropType = QualType(TD->getTypeForDecl(), 0);
15237 } else {
15238 HasError = true;
15239 }
15240 } else {
15241 HasError = true;
15242 }
15243
15244 if (HasError) {
15245 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
15246 << "omp_interop_t";
15247 return false;
15248 }
15249
15250 QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
15251 if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
15252 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
15253 return false;
15254 }
15255
15256 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15257 // The interop-var passed to init or destroy must be non-const.
15258 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
15259 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
15260 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
15261 << /*non-const*/ 1;
15262 return false;
15263 }
15264 return true;
15265}
15266
15267OMPClause *
15268Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
15269 bool IsTarget, bool IsTargetSync,
15270 SourceLocation StartLoc, SourceLocation LParenLoc,
15271 SourceLocation VarLoc, SourceLocation EndLoc) {
15272
15273 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
15274 return nullptr;
15275
15276 // Check prefer_type values. These foreign-runtime-id values are either
15277 // string literals or constant integral expressions.
15278 for (const Expr *E : PrefExprs) {
15279 if (E->isValueDependent() || E->isTypeDependent() ||
15280 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
15281 continue;
15282 if (E->isIntegerConstantExpr(Context))
15283 continue;
15284 if (isa<StringLiteral>(E))
15285 continue;
15286 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
15287 return nullptr;
15288 }
15289
15290 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
15291 IsTargetSync, StartLoc, LParenLoc, VarLoc,
15292 EndLoc);
15293}
15294
15295OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
15296 SourceLocation LParenLoc,
15297 SourceLocation VarLoc,
15298 SourceLocation EndLoc) {
15299
15300 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
15301 return nullptr;
15302
15303 return new (Context)
15304 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15305}
15306
15307OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
15308 SourceLocation StartLoc,
15309 SourceLocation LParenLoc,
15310 SourceLocation VarLoc,
15311 SourceLocation EndLoc) {
15312 if (InteropVar &&
15313 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
15314 return nullptr;
15315
15316 return new (Context)
15317 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15318}
15319
15320OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
15321 SourceLocation StartLoc,
15322 SourceLocation LParenLoc,
15323 SourceLocation EndLoc) {
15324 Expr *ValExpr = Condition;
15325 Stmt *HelperValStmt = nullptr;
15326 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15327 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15328 !Condition->isInstantiationDependent() &&
15329 !Condition->containsUnexpandedParameterPack()) {
15330 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15331 if (Val.isInvalid())
15332 return nullptr;
15333
15334 ValExpr = MakeFullExpr(Val.get()).get();
15335
15336 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15337 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
15338 LangOpts.OpenMP);
15339 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15340 ValExpr = MakeFullExpr(ValExpr).get();
15341 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15342 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15343 HelperValStmt = buildPreInits(Context, Captures);
15344 }
15345 }
15346
15347 return new (Context) OMPNovariantsClause(
15348 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15349}
15350
15351OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
15352 SourceLocation StartLoc,
15353 SourceLocation LParenLoc,
15354 SourceLocation EndLoc) {
15355 Expr *ValExpr = Condition;
15356 Stmt *HelperValStmt = nullptr;
15357 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15358 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15359 !Condition->isInstantiationDependent() &&
15360 !Condition->containsUnexpandedParameterPack()) {
15361 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15362 if (Val.isInvalid())
15363 return nullptr;
15364
15365 ValExpr = MakeFullExpr(Val.get()).get();
15366
15367 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15368 CaptureRegion =
15369 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
15370 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15371 ValExpr = MakeFullExpr(ValExpr).get();
15372 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15373 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15374 HelperValStmt = buildPreInits(Context, Captures);
15375 }
15376 }
15377
15378 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
15379 StartLoc, LParenLoc, EndLoc);
15380}
15381
15382OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
15383 SourceLocation StartLoc,
15384 SourceLocation LParenLoc,
15385 SourceLocation EndLoc) {
15386 Expr *ValExpr = ThreadID;
15387 Stmt *HelperValStmt = nullptr;
15388
15389 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15390 OpenMPDirectiveKind CaptureRegion =
15391 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
15392 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15393 ValExpr = MakeFullExpr(ValExpr).get();
15394 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15395 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15396 HelperValStmt = buildPreInits(Context, Captures);
15397 }
15398
15399 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
15400 StartLoc, LParenLoc, EndLoc);
15401}
15402
15403OMPClause *Sema::ActOnOpenMPVarListClause(
15404 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
15405 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
15406 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
15407 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
15408 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15409 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
15410 SourceLocation ExtraModifierLoc,
15411 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
15412 ArrayRef<SourceLocation> MotionModifiersLoc) {
15413 SourceLocation StartLoc = Locs.StartLoc;
15414 SourceLocation LParenLoc = Locs.LParenLoc;
15415 SourceLocation EndLoc = Locs.EndLoc;
15416 OMPClause *Res = nullptr;
15417 switch (Kind) {
15418 case OMPC_private:
15419 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15420 break;
15421 case OMPC_firstprivate:
15422 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15423 break;
15424 case OMPC_lastprivate:
15425 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&((void)0)
15426 "Unexpected lastprivate modifier.")((void)0);
15427 Res = ActOnOpenMPLastprivateClause(
15428 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
15429 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
15430 break;
15431 case OMPC_shared:
15432 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
15433 break;
15434 case OMPC_reduction:
15435 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&((void)0)
15436 "Unexpected lastprivate modifier.")((void)0);
15437 Res = ActOnOpenMPReductionClause(
15438 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
15439 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
15440 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
15441 break;
15442 case OMPC_task_reduction:
15443 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15444 EndLoc, ReductionOrMapperIdScopeSpec,
15445 ReductionOrMapperId);
15446 break;
15447 case OMPC_in_reduction:
15448 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15449 EndLoc, ReductionOrMapperIdScopeSpec,
15450 ReductionOrMapperId);
15451 break;
15452 case OMPC_linear:
15453 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&((void)0)
15454 "Unexpected linear modifier.")((void)0);
15455 Res = ActOnOpenMPLinearClause(
15456 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
15457 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
15458 ColonLoc, EndLoc);
15459 break;
15460 case OMPC_aligned:
15461 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
15462 LParenLoc, ColonLoc, EndLoc);
15463 break;
15464 case OMPC_copyin:
15465 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
15466 break;
15467 case OMPC_copyprivate:
15468 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15469 break;
15470 case OMPC_flush:
15471 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
15472 break;
15473 case OMPC_depend:
15474 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&((void)0)
15475 "Unexpected depend modifier.")((void)0);
15476 Res = ActOnOpenMPDependClause(
15477 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
15478 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
15479 break;
15480 case OMPC_map:
15481 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&((void)0)
15482 "Unexpected map modifier.")((void)0);
15483 Res = ActOnOpenMPMapClause(
15484 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
15485 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
15486 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
15487 break;
15488 case OMPC_to:
15489 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
15490 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
15491 ColonLoc, VarList, Locs);
15492 break;
15493 case OMPC_from:
15494 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
15495 ReductionOrMapperIdScopeSpec,
15496 ReductionOrMapperId, ColonLoc, VarList, Locs);
15497 break;
15498 case OMPC_use_device_ptr:
15499 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
15500 break;
15501 case OMPC_use_device_addr:
15502 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
15503 break;
15504 case OMPC_is_device_ptr:
15505 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
15506 break;
15507 case OMPC_allocate:
15508 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
15509 LParenLoc, ColonLoc, EndLoc);
15510 break;
15511 case OMPC_nontemporal:
15512 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
15513 break;
15514 case OMPC_inclusive:
15515 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15516 break;
15517 case OMPC_exclusive:
15518 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15519 break;
15520 case OMPC_affinity:
15521 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
15522 DepModOrTailExpr, VarList);
15523 break;
15524 case OMPC_if:
15525 case OMPC_depobj:
15526 case OMPC_final:
15527 case OMPC_num_threads:
15528 case OMPC_safelen:
15529 case OMPC_simdlen:
15530 case OMPC_sizes:
15531 case OMPC_allocator:
15532 case OMPC_collapse:
15533 case OMPC_default:
15534 case OMPC_proc_bind:
15535 case OMPC_schedule:
15536 case OMPC_ordered:
15537 case OMPC_nowait:
15538 case OMPC_untied:
15539 case OMPC_mergeable:
15540 case OMPC_threadprivate:
15541 case OMPC_read:
15542 case OMPC_write:
15543 case OMPC_update:
15544 case OMPC_capture:
15545 case OMPC_seq_cst:
15546 case OMPC_acq_rel:
15547 case OMPC_acquire:
15548 case OMPC_release:
15549 case OMPC_relaxed:
15550 case OMPC_device:
15551 case OMPC_threads:
15552 case OMPC_simd:
15553 case OMPC_num_teams:
15554 case OMPC_thread_limit:
15555 case OMPC_priority:
15556 case OMPC_grainsize:
15557 case OMPC_nogroup:
15558 case OMPC_num_tasks:
15559 case OMPC_hint:
15560 case OMPC_dist_schedule:
15561 case OMPC_defaultmap:
15562 case OMPC_unknown:
15563 case OMPC_uniform:
15564 case OMPC_unified_address:
15565 case OMPC_unified_shared_memory:
15566 case OMPC_reverse_offload:
15567 case OMPC_dynamic_allocators:
15568 case OMPC_atomic_default_mem_order:
15569 case OMPC_device_type:
15570 case OMPC_match:
15571 case OMPC_order:
15572 case OMPC_destroy:
15573 case OMPC_novariants:
15574 case OMPC_nocontext:
15575 case OMPC_detach:
15576 case OMPC_uses_allocators:
15577 default:
15578 llvm_unreachable("Clause is not allowed.")__builtin_unreachable();
15579 }
15580 return Res;
15581}
15582
15583ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
15584 ExprObjectKind OK, SourceLocation Loc) {
15585 ExprResult Res = BuildDeclRefExpr(
15586 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
15587 if (!Res.isUsable())
15588 return ExprError();
15589 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
15590 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
15591 if (!Res.isUsable())
15592 return ExprError();
15593 }
15594 if (VK != VK_LValue && Res.get()->isGLValue()) {
15595 Res = DefaultLvalueConversion(Res.get());
15596 if (!Res.isUsable())
15597 return ExprError();
15598 }
15599 return Res;
15600}
15601
15602OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
15603 SourceLocation StartLoc,
15604 SourceLocation LParenLoc,
15605 SourceLocation EndLoc) {
15606 SmallVector<Expr *, 8> Vars;
15607 SmallVector<Expr *, 8> PrivateCopies;
15608 for (Expr *RefExpr : VarList) {
15609 assert(RefExpr && "NULL expr in OpenMP private clause.")((void)0);
15610 SourceLocation ELoc;
15611 SourceRange ERange;
15612 Expr *SimpleRefExpr = RefExpr;
15613 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15614 if (Res.second) {
15615 // It will be analyzed later.
15616 Vars.push_back(RefExpr);
15617 PrivateCopies.push_back(nullptr);
15618 }
15619 ValueDecl *D = Res.first;
15620 if (!D)
15621 continue;
15622
15623 QualType Type = D->getType();
15624 auto *VD = dyn_cast<VarDecl>(D);
15625
15626 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15627 // A variable that appears in a private clause must not have an incomplete
15628 // type or a reference type.
15629 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
15630 continue;
15631 Type = Type.getNonReferenceType();
15632
15633 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15634 // A variable that is privatized must not have a const-qualified type
15635 // unless it is of class type with a mutable member. This restriction does
15636 // not apply to the firstprivate clause.
15637 //
15638 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
15639 // A variable that appears in a private clause must not have a
15640 // const-qualified type unless it is of class type with a mutable member.
15641 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
15642 continue;
15643
15644 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15645 // in a Construct]
15646 // Variables with the predetermined data-sharing attributes may not be
15647 // listed in data-sharing attributes clauses, except for the cases
15648 // listed below. For these exceptions only, listing a predetermined
15649 // variable in a data-sharing attribute clause is allowed and overrides
15650 // the variable's predetermined data-sharing attributes.
15651 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15652 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
15653 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15654 << getOpenMPClauseName(OMPC_private);
15655 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15656 continue;
15657 }
15658
15659 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15660 // Variably modified types are not supported for tasks.
15661 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15662 isOpenMPTaskingDirective(CurrDir)) {
15663 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15664 << getOpenMPClauseName(OMPC_private) << Type
15665 << getOpenMPDirectiveName(CurrDir);
15666 bool IsDecl =
15667 !VD ||
15668 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15669 Diag(D->getLocation(),
15670 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15671 << D;
15672 continue;
15673 }
15674
15675 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15676 // A list item cannot appear in both a map clause and a data-sharing
15677 // attribute clause on the same construct
15678 //
15679 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15680 // A list item cannot appear in both a map clause and a data-sharing
15681 // attribute clause on the same construct unless the construct is a
15682 // combined construct.
15683 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
15684 CurrDir == OMPD_target) {
15685 OpenMPClauseKind ConflictKind;
15686 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
15687 VD, /*CurrentRegionOnly=*/true,
15688 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
15689 OpenMPClauseKind WhereFoundClauseKind) -> bool {
15690 ConflictKind = WhereFoundClauseKind;
15691 return true;
15692 })) {
15693 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15694 << getOpenMPClauseName(OMPC_private)
15695 << getOpenMPClauseName(ConflictKind)
15696 << getOpenMPDirectiveName(CurrDir);
15697 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15698 continue;
15699 }
15700 }
15701
15702 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
15703 // A variable of class type (or array thereof) that appears in a private
15704 // clause requires an accessible, unambiguous default constructor for the
15705 // class type.
15706 // Generate helper private variable and initialize it with the default
15707 // value. The address of the original variable is replaced by the address of
15708 // the new private variable in CodeGen. This new variable is not added to
15709 // IdResolver, so the code in the OpenMP region uses original variable for
15710 // proper diagnostics.
15711 Type = Type.getUnqualifiedType();
15712 VarDecl *VDPrivate =
15713 buildVarDecl(*this, ELoc, Type, D->getName(),
15714 D->hasAttrs() ? &D->getAttrs() : nullptr,
15715 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15716 ActOnUninitializedDecl(VDPrivate);
15717 if (VDPrivate->isInvalidDecl())
15718 continue;
15719 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15720 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15721
15722 DeclRefExpr *Ref = nullptr;
15723 if (!VD && !CurContext->isDependentContext())
15724 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15725 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
15726 Vars.push_back((VD || CurContext->isDependentContext())
15727 ? RefExpr->IgnoreParens()
15728 : Ref);
15729 PrivateCopies.push_back(VDPrivateRefExpr);
15730 }
15731
15732 if (Vars.empty())
15733 return nullptr;
15734
15735 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15736 PrivateCopies);
15737}
15738
15739namespace {
15740class DiagsUninitializedSeveretyRAII {
15741private:
15742 DiagnosticsEngine &Diags;
15743 SourceLocation SavedLoc;
15744 bool IsIgnored = false;
15745
15746public:
15747 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
15748 bool IsIgnored)
15749 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
15750 if (!IsIgnored) {
15751 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
15752 /*Map*/ diag::Severity::Ignored, Loc);
15753 }
15754 }
15755 ~DiagsUninitializedSeveretyRAII() {
15756 if (!IsIgnored)
15757 Diags.popMappings(SavedLoc);
15758 }
15759};
15760}
15761
15762OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
15763 SourceLocation StartLoc,
15764 SourceLocation LParenLoc,
15765 SourceLocation EndLoc) {
15766 SmallVector<Expr *, 8> Vars;
15767 SmallVector<Expr *, 8> PrivateCopies;
15768 SmallVector<Expr *, 8> Inits;
15769 SmallVector<Decl *, 4> ExprCaptures;
15770 bool IsImplicitClause =
15771 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
15772 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
15773
15774 for (Expr *RefExpr : VarList) {
15775 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")((void)0);
15776 SourceLocation ELoc;
15777 SourceRange ERange;
15778 Expr *SimpleRefExpr = RefExpr;
15779 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15780 if (Res.second) {
15781 // It will be analyzed later.
15782 Vars.push_back(RefExpr);
15783 PrivateCopies.push_back(nullptr);
15784 Inits.push_back(nullptr);
15785 }
15786 ValueDecl *D = Res.first;
15787 if (!D)
15788 continue;
15789
15790 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
15791 QualType Type = D->getType();
15792 auto *VD = dyn_cast<VarDecl>(D);
15793
15794 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15795 // A variable that appears in a private clause must not have an incomplete
15796 // type or a reference type.
15797 if (RequireCompleteType(ELoc, Type,
15798 diag::err_omp_firstprivate_incomplete_type))
15799 continue;
15800 Type = Type.getNonReferenceType();
15801
15802 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
15803 // A variable of class type (or array thereof) that appears in a private
15804 // clause requires an accessible, unambiguous copy constructor for the
15805 // class type.
15806 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15807
15808 // If an implicit firstprivate variable found it was checked already.
15809 DSAStackTy::DSAVarData TopDVar;
15810 if (!IsImplicitClause) {
15811 DSAStackTy::DSAVarData DVar =
15812 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15813 TopDVar = DVar;
15814 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15815 bool IsConstant = ElemType.isConstant(Context);
15816 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
15817 // A list item that specifies a given variable may not appear in more
15818 // than one clause on the same directive, except that a variable may be
15819 // specified in both firstprivate and lastprivate clauses.
15820 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15821 // A list item may appear in a firstprivate or lastprivate clause but not
15822 // both.
15823 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
15824 (isOpenMPDistributeDirective(CurrDir) ||
15825 DVar.CKind != OMPC_lastprivate) &&
15826 DVar.RefExpr) {
15827 Diag(ELoc, diag::err_omp_wrong_dsa)
15828 << getOpenMPClauseName(DVar.CKind)
15829 << getOpenMPClauseName(OMPC_firstprivate);
15830 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15831 continue;
15832 }
15833
15834 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15835 // in a Construct]
15836 // Variables with the predetermined data-sharing attributes may not be
15837 // listed in data-sharing attributes clauses, except for the cases
15838 // listed below. For these exceptions only, listing a predetermined
15839 // variable in a data-sharing attribute clause is allowed and overrides
15840 // the variable's predetermined data-sharing attributes.
15841 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15842 // in a Construct, C/C++, p.2]
15843 // Variables with const-qualified type having no mutable member may be
15844 // listed in a firstprivate clause, even if they are static data members.
15845 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
15846 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
15847 Diag(ELoc, diag::err_omp_wrong_dsa)
15848 << getOpenMPClauseName(DVar.CKind)
15849 << getOpenMPClauseName(OMPC_firstprivate);
15850 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15851 continue;
15852 }
15853
15854 // OpenMP [2.9.3.4, Restrictions, p.2]
15855 // A list item that is private within a parallel region must not appear
15856 // in a firstprivate clause on a worksharing construct if any of the
15857 // worksharing regions arising from the worksharing construct ever bind
15858 // to any of the parallel regions arising from the parallel construct.
15859 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15860 // A list item that is private within a teams region must not appear in a
15861 // firstprivate clause on a distribute construct if any of the distribute
15862 // regions arising from the distribute construct ever bind to any of the
15863 // teams regions arising from the teams construct.
15864 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15865 // A list item that appears in a reduction clause of a teams construct
15866 // must not appear in a firstprivate clause on a distribute construct if
15867 // any of the distribute regions arising from the distribute construct
15868 // ever bind to any of the teams regions arising from the teams construct.
15869 if ((isOpenMPWorksharingDirective(CurrDir) ||
15870 isOpenMPDistributeDirective(CurrDir)) &&
15871 !isOpenMPParallelDirective(CurrDir) &&
15872 !isOpenMPTeamsDirective(CurrDir)) {
15873 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
15874 if (DVar.CKind != OMPC_shared &&
15875 (isOpenMPParallelDirective(DVar.DKind) ||
15876 isOpenMPTeamsDirective(DVar.DKind) ||
15877 DVar.DKind == OMPD_unknown)) {
15878 Diag(ELoc, diag::err_omp_required_access)
15879 << getOpenMPClauseName(OMPC_firstprivate)
15880 << getOpenMPClauseName(OMPC_shared);
15881 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15882 continue;
15883 }
15884 }
15885 // OpenMP [2.9.3.4, Restrictions, p.3]
15886 // A list item that appears in a reduction clause of a parallel construct
15887 // must not appear in a firstprivate clause on a worksharing or task
15888 // construct if any of the worksharing or task regions arising from the
15889 // worksharing or task construct ever bind to any of the parallel regions
15890 // arising from the parallel construct.
15891 // OpenMP [2.9.3.4, Restrictions, p.4]
15892 // A list item that appears in a reduction clause in worksharing
15893 // construct must not appear in a firstprivate clause in a task construct
15894 // encountered during execution of any of the worksharing regions arising
15895 // from the worksharing construct.
15896 if (isOpenMPTaskingDirective(CurrDir)) {
15897 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
15898 D,
15899 [](OpenMPClauseKind C, bool AppliedToPointee) {
15900 return C == OMPC_reduction && !AppliedToPointee;
15901 },
15902 [](OpenMPDirectiveKind K) {
15903 return isOpenMPParallelDirective(K) ||
15904 isOpenMPWorksharingDirective(K) ||
15905 isOpenMPTeamsDirective(K);
15906 },
15907 /*FromParent=*/true);
15908 if (DVar.CKind == OMPC_reduction &&
15909 (isOpenMPParallelDirective(DVar.DKind) ||
15910 isOpenMPWorksharingDirective(DVar.DKind) ||
15911 isOpenMPTeamsDirective(DVar.DKind))) {
15912 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
15913 << getOpenMPDirectiveName(DVar.DKind);
15914 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15915 continue;
15916 }
15917 }
15918
15919 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15920 // A list item cannot appear in both a map clause and a data-sharing
15921 // attribute clause on the same construct
15922 //
15923 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15924 // A list item cannot appear in both a map clause and a data-sharing
15925 // attribute clause on the same construct unless the construct is a
15926 // combined construct.
15927 if ((LangOpts.OpenMP <= 45 &&
15928 isOpenMPTargetExecutionDirective(CurrDir)) ||
15929 CurrDir == OMPD_target) {
15930 OpenMPClauseKind ConflictKind;
15931 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
15932 VD, /*CurrentRegionOnly=*/true,
15933 [&ConflictKind](
15934 OMPClauseMappableExprCommon::MappableExprComponentListRef,
15935 OpenMPClauseKind WhereFoundClauseKind) {
15936 ConflictKind = WhereFoundClauseKind;
15937 return true;
15938 })) {
15939 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15940 << getOpenMPClauseName(OMPC_firstprivate)
15941 << getOpenMPClauseName(ConflictKind)
15942 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
15943 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15944 continue;
15945 }
15946 }
15947 }
15948
15949 // Variably modified types are not supported for tasks.
15950 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15951 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
15952 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15953 << getOpenMPClauseName(OMPC_firstprivate) << Type
15954 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
15955 bool IsDecl =
15956 !VD ||
15957 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15958 Diag(D->getLocation(),
15959 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15960 << D;
15961 continue;
15962 }
15963
15964 Type = Type.getUnqualifiedType();
15965 VarDecl *VDPrivate =
15966 buildVarDecl(*this, ELoc, Type, D->getName(),
15967 D->hasAttrs() ? &D->getAttrs() : nullptr,
15968 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15969 // Generate helper private variable and initialize it with the value of the
15970 // original variable. The address of the original variable is replaced by
15971 // the address of the new private variable in the CodeGen. This new variable
15972 // is not added to IdResolver, so the code in the OpenMP region uses
15973 // original variable for proper diagnostics and variable capturing.
15974 Expr *VDInitRefExpr = nullptr;
15975 // For arrays generate initializer for single element and replace it by the
15976 // original array element in CodeGen.
15977 if (Type->isArrayType()) {
15978 VarDecl *VDInit =
15979 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
15980 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
15981 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
15982 ElemType = ElemType.getUnqualifiedType();
15983 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
15984 ".firstprivate.temp");
15985 InitializedEntity Entity =
15986 InitializedEntity::InitializeVariable(VDInitTemp);
15987 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
15988
15989 InitializationSequence InitSeq(*this, Entity, Kind, Init);
15990 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
15991 if (Result.isInvalid())
15992 VDPrivate->setInvalidDecl();
15993 else
15994 VDPrivate->setInit(Result.getAs<Expr>());
15995 // Remove temp variable declaration.
15996 Context.Deallocate(VDInitTemp);
15997 } else {
15998 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
15999 ".firstprivate.temp");
16000 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
16001 RefExpr->getExprLoc());
16002 AddInitializerToDecl(VDPrivate,
16003 DefaultLvalueConversion(VDInitRefExpr).get(),
16004 /*DirectInit=*/false);
16005 }
16006 if (VDPrivate->isInvalidDecl()) {
16007 if (IsImplicitClause) {
16008 Diag(RefExpr->getExprLoc(),
16009 diag::note_omp_task_predetermined_firstprivate_here);
16010 }
16011 continue;
16012 }
16013 CurContext->addDecl(VDPrivate);
16014 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
16015 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
16016 RefExpr->getExprLoc());
16017 DeclRefExpr *Ref = nullptr;
16018 if (!VD && !CurContext->isDependentContext()) {
16019 if (TopDVar.CKind == OMPC_lastprivate) {
16020 Ref = TopDVar.PrivateCopy;
16021 } else {
16022 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16023 if (!isOpenMPCapturedDecl(D))
16024 ExprCaptures.push_back(Ref->getDecl());
16025 }
16026 }
16027 if (!IsImplicitClause)
16028 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
16029 Vars.push_back((VD || CurContext->isDependentContext())
16030 ? RefExpr->IgnoreParens()
16031 : Ref);
16032 PrivateCopies.push_back(VDPrivateRefExpr);
16033 Inits.push_back(VDInitRefExpr);
16034 }
16035
16036 if (Vars.empty())
16037 return nullptr;
16038
16039 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16040 Vars, PrivateCopies, Inits,
16041 buildPreInits(Context, ExprCaptures));
16042}
16043
16044OMPClause *Sema::ActOnOpenMPLastprivateClause(
16045 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
16046 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
16047 SourceLocation LParenLoc, SourceLocation EndLoc) {
16048 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
16049 assert(ColonLoc.isValid() && "Colon location must be valid.")((void)0);
16050 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
16051 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
16052 /*Last=*/OMPC_LASTPRIVATE_unknown)
16053 << getOpenMPClauseName(OMPC_lastprivate);
16054 return nullptr;
16055 }
16056
16057 SmallVector<Expr *, 8> Vars;
16058 SmallVector<Expr *, 8> SrcExprs;
16059 SmallVector<Expr *, 8> DstExprs;
16060 SmallVector<Expr *, 8> AssignmentOps;
16061 SmallVector<Decl *, 4> ExprCaptures;
16062 SmallVector<Expr *, 4> ExprPostUpdates;
16063 for (Expr *RefExpr : VarList) {
16064 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((void)0);
16065 SourceLocation ELoc;
16066 SourceRange ERange;
16067 Expr *SimpleRefExpr = RefExpr;
16068 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16069 if (Res.second) {
16070 // It will be analyzed later.
16071 Vars.push_back(RefExpr);
16072 SrcExprs.push_back(nullptr);
16073 DstExprs.push_back(nullptr);
16074 AssignmentOps.push_back(nullptr);
16075 }
16076 ValueDecl *D = Res.first;
16077 if (!D)
16078 continue;
16079
16080 QualType Type = D->getType();
16081 auto *VD = dyn_cast<VarDecl>(D);
16082
16083 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
16084 // A variable that appears in a lastprivate clause must not have an
16085 // incomplete type or a reference type.
16086 if (RequireCompleteType(ELoc, Type,
16087 diag::err_omp_lastprivate_incomplete_type))
16088 continue;
16089 Type = Type.getNonReferenceType();
16090
16091 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
16092 // A variable that is privatized must not have a const-qualified type
16093 // unless it is of class type with a mutable member. This restriction does
16094 // not apply to the firstprivate clause.
16095 //
16096 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
16097 // A variable that appears in a lastprivate clause must not have a
16098 // const-qualified type unless it is of class type with a mutable member.
16099 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
16100 continue;
16101
16102 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
16103 // A list item that appears in a lastprivate clause with the conditional
16104 // modifier must be a scalar variable.
16105 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
16106 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
16107 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16108 VarDecl::DeclarationOnly;
16109 Diag(D->getLocation(),
16110 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16111 << D;
16112 continue;
16113 }
16114
16115 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16116 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16117 // in a Construct]
16118 // Variables with the predetermined data-sharing attributes may not be
16119 // listed in data-sharing attributes clauses, except for the cases
16120 // listed below.
16121 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
16122 // A list item may appear in a firstprivate or lastprivate clause but not
16123 // both.
16124 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16125 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
16126 (isOpenMPDistributeDirective(CurrDir) ||
16127 DVar.CKind != OMPC_firstprivate) &&
16128 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
16129 Diag(ELoc, diag::err_omp_wrong_dsa)
16130 << getOpenMPClauseName(DVar.CKind)
16131 << getOpenMPClauseName(OMPC_lastprivate);
16132 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16133 continue;
16134 }
16135
16136 // OpenMP [2.14.3.5, Restrictions, p.2]
16137 // A list item that is private within a parallel region, or that appears in
16138 // the reduction clause of a parallel construct, must not appear in a
16139 // lastprivate clause on a worksharing construct if any of the corresponding
16140 // worksharing regions ever binds to any of the corresponding parallel
16141 // regions.
16142 DSAStackTy::DSAVarData TopDVar = DVar;
16143 if (isOpenMPWorksharingDirective(CurrDir) &&
16144 !isOpenMPParallelDirective(CurrDir) &&
16145 !isOpenMPTeamsDirective(CurrDir)) {
16146 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
16147 if (DVar.CKind != OMPC_shared) {
16148 Diag(ELoc, diag::err_omp_required_access)
16149 << getOpenMPClauseName(OMPC_lastprivate)
16150 << getOpenMPClauseName(OMPC_shared);
16151 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16152 continue;
16153 }
16154 }
16155
16156 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
16157 // A variable of class type (or array thereof) that appears in a
16158 // lastprivate clause requires an accessible, unambiguous default
16159 // constructor for the class type, unless the list item is also specified
16160 // in a firstprivate clause.
16161 // A variable of class type (or array thereof) that appears in a
16162 // lastprivate clause requires an accessible, unambiguous copy assignment
16163 // operator for the class type.
16164 Type = Context.getBaseElementType(Type).getNonReferenceType();
16165 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
16166 Type.getUnqualifiedType(), ".lastprivate.src",
16167 D->hasAttrs() ? &D->getAttrs() : nullptr);
16168 DeclRefExpr *PseudoSrcExpr =
16169 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
16170 VarDecl *DstVD =
16171 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
16172 D->hasAttrs() ? &D->getAttrs() : nullptr);
16173 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16174 // For arrays generate assignment operation for single element and replace
16175 // it by the original array element in CodeGen.
16176 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
16177 PseudoDstExpr, PseudoSrcExpr);
16178 if (AssignmentOp.isInvalid())
16179 continue;
16180 AssignmentOp =
16181 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16182 if (AssignmentOp.isInvalid())
16183 continue;
16184
16185 DeclRefExpr *Ref = nullptr;
16186 if (!VD && !CurContext->isDependentContext()) {
16187 if (TopDVar.CKind == OMPC_firstprivate) {
16188 Ref = TopDVar.PrivateCopy;
16189 } else {
16190 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16191 if (!isOpenMPCapturedDecl(D))
16192 ExprCaptures.push_back(Ref->getDecl());
16193 }
16194 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
16195 (!isOpenMPCapturedDecl(D) &&
16196 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
16197 ExprResult RefRes = DefaultLvalueConversion(Ref);
16198 if (!RefRes.isUsable())
16199 continue;
16200 ExprResult PostUpdateRes =
16201 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
16202 RefRes.get());
16203 if (!PostUpdateRes.isUsable())
16204 continue;
16205 ExprPostUpdates.push_back(
16206 IgnoredValueConversions(PostUpdateRes.get()).get());
16207 }
16208 }
16209 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
16210 Vars.push_back((VD || CurContext->isDependentContext())
16211 ? RefExpr->IgnoreParens()
16212 : Ref);
16213 SrcExprs.push_back(PseudoSrcExpr);
16214 DstExprs.push_back(PseudoDstExpr);
16215 AssignmentOps.push_back(AssignmentOp.get());
16216 }
16217
16218 if (Vars.empty())
16219 return nullptr;
16220
16221 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16222 Vars, SrcExprs, DstExprs, AssignmentOps,
16223 LPKind, LPKindLoc, ColonLoc,
16224 buildPreInits(Context, ExprCaptures),
16225 buildPostUpdate(*this, ExprPostUpdates));
16226}
16227
16228OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
16229 SourceLocation StartLoc,
16230 SourceLocation LParenLoc,
16231 SourceLocation EndLoc) {
16232 SmallVector<Expr *, 8> Vars;
16233 for (Expr *RefExpr : VarList) {
16234 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((void)0);
16235 SourceLocation ELoc;
16236 SourceRange ERange;
16237 Expr *SimpleRefExpr = RefExpr;
16238 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16239 if (Res.second) {
16240 // It will be analyzed later.
16241 Vars.push_back(RefExpr);
16242 }
16243 ValueDecl *D = Res.first;
16244 if (!D)
16245 continue;
16246
16247 auto *VD = dyn_cast<VarDecl>(D);
16248 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
16249 // in a Construct]
16250 // Variables with the predetermined data-sharing attributes may not be
16251 // listed in data-sharing attributes clauses, except for the cases
16252 // listed below. For these exceptions only, listing a predetermined
16253 // variable in a data-sharing attribute clause is allowed and overrides
16254 // the variable's predetermined data-sharing attributes.
16255 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16256 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
16257 DVar.RefExpr) {
16258 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
16259 << getOpenMPClauseName(OMPC_shared);
16260 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16261 continue;
16262 }
16263
16264 DeclRefExpr *Ref = nullptr;
16265 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
16266 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16267 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
16268 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
16269 ? RefExpr->IgnoreParens()
16270 : Ref);
16271 }
16272
16273 if (Vars.empty())
16274 return nullptr;
16275
16276 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
16277}
16278
16279namespace {
16280class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
16281 DSAStackTy *Stack;
16282
16283public:
16284 bool VisitDeclRefExpr(DeclRefExpr *E) {
16285 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
16286 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
16287 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
16288 return false;
16289 if (DVar.CKind != OMPC_unknown)
16290 return true;
16291 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
16292 VD,
16293 [](OpenMPClauseKind C, bool AppliedToPointee) {
16294 return isOpenMPPrivate(C) && !AppliedToPointee;
16295 },
16296 [](OpenMPDirectiveKind) { return true; },
16297 /*FromParent=*/true);
16298 return DVarPrivate.CKind != OMPC_unknown;
16299 }
16300 return false;
16301 }
16302 bool VisitStmt(Stmt *S) {
16303 for (Stmt *Child : S->children()) {
16304 if (Child && Visit(Child))
16305 return true;
16306 }
16307 return false;
16308 }
16309 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
16310};
16311} // namespace
16312
16313namespace {
16314// Transform MemberExpression for specified FieldDecl of current class to
16315// DeclRefExpr to specified OMPCapturedExprDecl.
16316class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
16317 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
16318 ValueDecl *Field = nullptr;
16319 DeclRefExpr *CapturedExpr = nullptr;
16320
16321public:
16322 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
16323 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
16324
16325 ExprResult TransformMemberExpr(MemberExpr *E) {
16326 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
16327 E->getMemberDecl() == Field) {
16328 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
16329 return CapturedExpr;
16330 }
16331 return BaseTransform::TransformMemberExpr(E);
16332 }
16333 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
16334};
16335} // namespace
16336
16337template <typename T, typename U>
16338static T filterLookupForUDReductionAndMapper(
16339 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
16340 for (U &Set : Lookups) {
16341 for (auto *D : Set) {
16342 if (T Res = Gen(cast<ValueDecl>(D)))
16343 return Res;
16344 }
16345 }
16346 return T();
16347}
16348
16349static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
16350 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")((void)0);
16351
16352 for (auto RD : D->redecls()) {
16353 // Don't bother with extra checks if we already know this one isn't visible.
16354 if (RD == D)
16355 continue;
16356
16357 auto ND = cast<NamedDecl>(RD);
16358 if (LookupResult::isVisible(SemaRef, ND))
16359 return ND;
16360 }
16361
16362 return nullptr;
16363}
16364
16365static void
16366argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
16367 SourceLocation Loc, QualType Ty,
16368 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
16369 // Find all of the associated namespaces and classes based on the
16370 // arguments we have.
16371 Sema::AssociatedNamespaceSet AssociatedNamespaces;
16372 Sema::AssociatedClassSet AssociatedClasses;
16373 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
16374 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
16375 AssociatedClasses);
16376
16377 // C++ [basic.lookup.argdep]p3:
16378 // Let X be the lookup set produced by unqualified lookup (3.4.1)
16379 // and let Y be the lookup set produced by argument dependent
16380 // lookup (defined as follows). If X contains [...] then Y is
16381 // empty. Otherwise Y is the set of declarations found in the
16382 // namespaces associated with the argument types as described
16383 // below. The set of declarations found by the lookup of the name
16384 // is the union of X and Y.
16385 //
16386 // Here, we compute Y and add its members to the overloaded
16387 // candidate set.
16388 for (auto *NS : AssociatedNamespaces) {
16389 // When considering an associated namespace, the lookup is the
16390 // same as the lookup performed when the associated namespace is
16391 // used as a qualifier (3.4.3.2) except that:
16392 //
16393 // -- Any using-directives in the associated namespace are
16394 // ignored.
16395 //
16396 // -- Any namespace-scope friend functions declared in
16397 // associated classes are visible within their respective
16398 // namespaces even if they are not visible during an ordinary
16399 // lookup (11.4).
16400 DeclContext::lookup_result R = NS->lookup(Id.getName());
16401 for (auto *D : R) {
16402 auto *Underlying = D;
16403 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16404 Underlying = USD->getTargetDecl();
16405
16406 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
16407 !isa<OMPDeclareMapperDecl>(Underlying))
16408 continue;
16409
16410 if (!SemaRef.isVisible(D)) {
16411 D = findAcceptableDecl(SemaRef, D);
16412 if (!D)
16413 continue;
16414 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16415 Underlying = USD->getTargetDecl();
16416 }
16417 Lookups.emplace_back();
16418 Lookups.back().addDecl(Underlying);
16419 }
16420 }
16421}
16422
16423static ExprResult
16424buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
16425 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
16426 const DeclarationNameInfo &ReductionId, QualType Ty,
16427 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
16428 if (ReductionIdScopeSpec.isInvalid())
16429 return ExprError();
16430 SmallVector<UnresolvedSet<8>, 4> Lookups;
16431 if (S) {
16432 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16433 Lookup.suppressDiagnostics();
16434 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
16435 NamedDecl *D = Lookup.getRepresentativeDecl();
16436 do {
16437 S = S->getParent();
16438 } while (S && !S->isDeclScope(D));
16439 if (S)
16440 S = S->getParent();
16441 Lookups.emplace_back();
16442 Lookups.back().append(Lookup.begin(), Lookup.end());
16443 Lookup.clear();
16444 }
16445 } else if (auto *ULE =
16446 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
16447 Lookups.push_back(UnresolvedSet<8>());
16448 Decl *PrevD = nullptr;
16449 for (NamedDecl *D : ULE->decls()) {
16450 if (D == PrevD)
16451 Lookups.push_back(UnresolvedSet<8>());
16452 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
16453 Lookups.back().addDecl(DRD);
16454 PrevD = D;
16455 }
16456 }
16457 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
16458 Ty->isInstantiationDependentType() ||
16459 Ty->containsUnexpandedParameterPack() ||
16460 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
16461 return !D->isInvalidDecl() &&
16462 (D->getType()->isDependentType() ||
16463 D->getType()->isInstantiationDependentType() ||
16464 D->getType()->containsUnexpandedParameterPack());
16465 })) {
16466 UnresolvedSet<8> ResSet;
16467 for (const UnresolvedSet<8> &Set : Lookups) {
16468 if (Set.empty())
16469 continue;
16470 ResSet.append(Set.begin(), Set.end());
16471 // The last item marks the end of all declarations at the specified scope.
16472 ResSet.addDecl(Set[Set.size() - 1]);
16473 }
16474 return UnresolvedLookupExpr::Create(
16475 SemaRef.Context, /*NamingClass=*/nullptr,
16476 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
16477 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
16478 }
16479 // Lookup inside the classes.
16480 // C++ [over.match.oper]p3:
16481 // For a unary operator @ with an operand of a type whose
16482 // cv-unqualified version is T1, and for a binary operator @ with
16483 // a left operand of a type whose cv-unqualified version is T1 and
16484 // a right operand of a type whose cv-unqualified version is T2,
16485 // three sets of candidate functions, designated member
16486 // candidates, non-member candidates and built-in candidates, are
16487 // constructed as follows:
16488 // -- If T1 is a complete class type or a class currently being
16489 // defined, the set of member candidates is the result of the
16490 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
16491 // the set of member candidates is empty.
16492 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16493 Lookup.suppressDiagnostics();
16494 if (const auto *TyRec = Ty->getAs<RecordType>()) {
16495 // Complete the type if it can be completed.
16496 // If the type is neither complete nor being defined, bail out now.
16497 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
16498 TyRec->getDecl()->getDefinition()) {
16499 Lookup.clear();
16500 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
16501 if (Lookup.empty()) {
16502 Lookups.emplace_back();
16503 Lookups.back().append(Lookup.begin(), Lookup.end());
16504 }
16505 }
16506 }
16507 // Perform ADL.
16508 if (SemaRef.getLangOpts().CPlusPlus)
16509 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
16510 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16511 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
16512 if (!D->isInvalidDecl() &&
16513 SemaRef.Context.hasSameType(D->getType(), Ty))
16514 return D;
16515 return nullptr;
16516 }))
16517 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
16518 VK_LValue, Loc);
16519 if (SemaRef.getLangOpts().CPlusPlus) {
16520 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16521 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
16522 if (!D->isInvalidDecl() &&
16523 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
16524 !Ty.isMoreQualifiedThan(D->getType()))
16525 return D;
16526 return nullptr;
16527 })) {
16528 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16529 /*DetectVirtual=*/false);
16530 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
16531 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16532 VD->getType().getUnqualifiedType()))) {
16533 if (SemaRef.CheckBaseClassAccess(
16534 Loc, VD->getType(), Ty, Paths.front(),
16535 /*DiagID=*/0) != Sema::AR_inaccessible) {
16536 SemaRef.BuildBasePathArray(Paths, BasePath);
16537 return SemaRef.BuildDeclRefExpr(
16538 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
16539 }
16540 }
16541 }
16542 }
16543 }
16544 if (ReductionIdScopeSpec.isSet()) {
16545 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
16546 << Ty << Range;
16547 return ExprError();
16548 }
16549 return ExprEmpty();
16550}
16551
16552namespace {
16553/// Data for the reduction-based clauses.
16554struct ReductionData {
16555 /// List of original reduction items.
16556 SmallVector<Expr *, 8> Vars;
16557 /// List of private copies of the reduction items.
16558 SmallVector<Expr *, 8> Privates;
16559 /// LHS expressions for the reduction_op expressions.
16560 SmallVector<Expr *, 8> LHSs;
16561 /// RHS expressions for the reduction_op expressions.
16562 SmallVector<Expr *, 8> RHSs;
16563 /// Reduction operation expression.
16564 SmallVector<Expr *, 8> ReductionOps;
16565 /// inscan copy operation expressions.
16566 SmallVector<Expr *, 8> InscanCopyOps;
16567 /// inscan copy temp array expressions for prefix sums.
16568 SmallVector<Expr *, 8> InscanCopyArrayTemps;
16569 /// inscan copy temp array element expressions for prefix sums.
16570 SmallVector<Expr *, 8> InscanCopyArrayElems;
16571 /// Taskgroup descriptors for the corresponding reduction items in
16572 /// in_reduction clauses.
16573 SmallVector<Expr *, 8> TaskgroupDescriptors;
16574 /// List of captures for clause.
16575 SmallVector<Decl *, 4> ExprCaptures;
16576 /// List of postupdate expressions.
16577 SmallVector<Expr *, 4> ExprPostUpdates;
16578 /// Reduction modifier.
16579 unsigned RedModifier = 0;
16580 ReductionData() = delete;
16581 /// Reserves required memory for the reduction data.
16582 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
16583 Vars.reserve(Size);
16584 Privates.reserve(Size);
16585 LHSs.reserve(Size);
16586 RHSs.reserve(Size);
16587 ReductionOps.reserve(Size);
16588 if (RedModifier == OMPC_REDUCTION_inscan) {
16589 InscanCopyOps.reserve(Size);
16590 InscanCopyArrayTemps.reserve(Size);
16591 InscanCopyArrayElems.reserve(Size);
16592 }
16593 TaskgroupDescriptors.reserve(Size);
16594 ExprCaptures.reserve(Size);
16595 ExprPostUpdates.reserve(Size);
16596 }
16597 /// Stores reduction item and reduction operation only (required for dependent
16598 /// reduction item).
16599 void push(Expr *Item, Expr *ReductionOp) {
16600 Vars.emplace_back(Item);
16601 Privates.emplace_back(nullptr);
16602 LHSs.emplace_back(nullptr);
16603 RHSs.emplace_back(nullptr);
16604 ReductionOps.emplace_back(ReductionOp);
16605 TaskgroupDescriptors.emplace_back(nullptr);
16606 if (RedModifier == OMPC_REDUCTION_inscan) {
16607 InscanCopyOps.push_back(nullptr);
16608 InscanCopyArrayTemps.push_back(nullptr);
16609 InscanCopyArrayElems.push_back(nullptr);
16610 }
16611 }
16612 /// Stores reduction data.
16613 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
16614 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
16615 Expr *CopyArrayElem) {
16616 Vars.emplace_back(Item);
16617 Privates.emplace_back(Private);
16618 LHSs.emplace_back(LHS);
16619 RHSs.emplace_back(RHS);
16620 ReductionOps.emplace_back(ReductionOp);
16621 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
16622 if (RedModifier == OMPC_REDUCTION_inscan) {
16623 InscanCopyOps.push_back(CopyOp);
16624 InscanCopyArrayTemps.push_back(CopyArrayTemp);
16625 InscanCopyArrayElems.push_back(CopyArrayElem);
16626 } else {
16627 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&((void)0)
16628 CopyArrayElem == nullptr &&((void)0)
16629 "Copy operation must be used for inscan reductions only.")((void)0);
16630 }
16631 }
16632};
16633} // namespace
16634
16635static bool checkOMPArraySectionConstantForReduction(
16636 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
16637 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
16638 const Expr *Length = OASE->getLength();
16639 if (Length == nullptr) {
16640 // For array sections of the form [1:] or [:], we would need to analyze
16641 // the lower bound...
16642 if (OASE->getColonLocFirst().isValid())
16643 return false;
16644
16645 // This is an array subscript which has implicit length 1!
16646 SingleElement = true;
16647 ArraySizes.push_back(llvm::APSInt::get(1));
16648 } else {
16649 Expr::EvalResult Result;
16650 if (!Length->EvaluateAsInt(Result, Context))
16651 return false;
16652
16653 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16654 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
16655 ArraySizes.push_back(ConstantLengthValue);
16656 }
16657
16658 // Get the base of this array section and walk up from there.
16659 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
16660
16661 // We require length = 1 for all array sections except the right-most to
16662 // guarantee that the memory region is contiguous and has no holes in it.
16663 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
16664 Length = TempOASE->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 ArraySizes.push_back(llvm::APSInt::get(1));
16673 } else {
16674 Expr::EvalResult Result;
16675 if (!Length->EvaluateAsInt(Result, Context))
16676 return false;
16677
16678 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16679 if (ConstantLengthValue.getSExtValue() != 1)
16680 return false;
16681
16682 ArraySizes.push_back(ConstantLengthValue);
16683 }
16684 Base = TempOASE->getBase()->IgnoreParenImpCasts();
16685 }
16686
16687 // If we have a single element, we don't need to add the implicit lengths.
16688 if (!SingleElement) {
16689 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
16690 // Has implicit length 1!
16691 ArraySizes.push_back(llvm::APSInt::get(1));
16692 Base = TempASE->getBase()->IgnoreParenImpCasts();
16693 }
16694 }
16695
16696 // This array section can be privatized as a single value or as a constant
16697 // sized array.
16698 return true;
16699}
16700
16701static BinaryOperatorKind
16702getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
16703 if (BOK == BO_Add)
16704 return BO_AddAssign;
16705 if (BOK == BO_Mul)
16706 return BO_MulAssign;
16707 if (BOK == BO_And)
16708 return BO_AndAssign;
16709 if (BOK == BO_Or)
16710 return BO_OrAssign;
16711 if (BOK == BO_Xor)
16712 return BO_XorAssign;
16713 return BOK;
16714}
16715
16716static bool actOnOMPReductionKindClause(
16717 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
16718 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16719 SourceLocation ColonLoc, SourceLocation EndLoc,
16720 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16721 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
16722 DeclarationName DN = ReductionId.getName();
16723 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
16724 BinaryOperatorKind BOK = BO_Comma;
16725
16726 ASTContext &Context = S.Context;
16727 // OpenMP [2.14.3.6, reduction clause]
16728 // C
16729 // reduction-identifier is either an identifier or one of the following
16730 // operators: +, -, *, &, |, ^, && and ||
16731 // C++
16732 // reduction-identifier is either an id-expression or one of the following
16733 // operators: +, -, *, &, |, ^, && and ||
16734 switch (OOK) {
16735 case OO_Plus:
16736 case OO_Minus:
16737 BOK = BO_Add;
16738 break;
16739 case OO_Star:
16740 BOK = BO_Mul;
16741 break;
16742 case OO_Amp:
16743 BOK = BO_And;
16744 break;
16745 case OO_Pipe:
16746 BOK = BO_Or;
16747 break;
16748 case OO_Caret:
16749 BOK = BO_Xor;
16750 break;
16751 case OO_AmpAmp:
16752 BOK = BO_LAnd;
16753 break;
16754 case OO_PipePipe:
16755 BOK = BO_LOr;
16756 break;
16757 case OO_New:
16758 case OO_Delete:
16759 case OO_Array_New:
16760 case OO_Array_Delete:
16761 case OO_Slash:
16762 case OO_Percent:
16763 case OO_Tilde:
16764 case OO_Exclaim:
16765 case OO_Equal:
16766 case OO_Less:
16767 case OO_Greater:
16768 case OO_LessEqual:
16769 case OO_GreaterEqual:
16770 case OO_PlusEqual:
16771 case OO_MinusEqual:
16772 case OO_StarEqual:
16773 case OO_SlashEqual:
16774 case OO_PercentEqual:
16775 case OO_CaretEqual:
16776 case OO_AmpEqual:
16777 case OO_PipeEqual:
16778 case OO_LessLess:
16779 case OO_GreaterGreater:
16780 case OO_LessLessEqual:
16781 case OO_GreaterGreaterEqual:
16782 case OO_EqualEqual:
16783 case OO_ExclaimEqual:
16784 case OO_Spaceship:
16785 case OO_PlusPlus:
16786 case OO_MinusMinus:
16787 case OO_Comma:
16788 case OO_ArrowStar:
16789 case OO_Arrow:
16790 case OO_Call:
16791 case OO_Subscript:
16792 case OO_Conditional:
16793 case OO_Coawait:
16794 case NUM_OVERLOADED_OPERATORS:
16795 llvm_unreachable("Unexpected reduction identifier")__builtin_unreachable();
16796 case OO_None:
16797 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
16798 if (II->isStr("max"))
16799 BOK = BO_GT;
16800 else if (II->isStr("min"))
16801 BOK = BO_LT;
16802 }
16803 break;
16804 }
16805 SourceRange ReductionIdRange;
16806 if (ReductionIdScopeSpec.isValid())
16807 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
16808 else
16809 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
16810 ReductionIdRange.setEnd(ReductionId.getEndLoc());
16811
16812 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
16813 bool FirstIter = true;
16814 for (Expr *RefExpr : VarList) {
16815 assert(RefExpr && "nullptr expr in OpenMP reduction clause.")((void)0);
16816 // OpenMP [2.1, C/C++]
16817 // A list item is a variable or array section, subject to the restrictions
16818 // specified in Section 2.4 on page 42 and in each of the sections
16819 // describing clauses and directives for which a list appears.
16820 // OpenMP [2.14.3.3, Restrictions, p.1]
16821 // A variable that is part of another variable (as an array or
16822 // structure element) cannot appear in a private clause.
16823 if (!FirstIter && IR != ER)
16824 ++IR;
16825 FirstIter = false;
16826 SourceLocation ELoc;
16827 SourceRange ERange;
16828 Expr *SimpleRefExpr = RefExpr;
16829 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
16830 /*AllowArraySection=*/true);
16831 if (Res.second) {
16832 // Try to find 'declare reduction' corresponding construct before using
16833 // builtin/overloaded operators.
16834 QualType Type = Context.DependentTy;
16835 CXXCastPath BasePath;
16836 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16837 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16838 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16839 Expr *ReductionOp = nullptr;
16840 if (S.CurContext->isDependentContext() &&
16841 (DeclareReductionRef.isUnset() ||
16842 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
16843 ReductionOp = DeclareReductionRef.get();
16844 // It will be analyzed later.
16845 RD.push(RefExpr, ReductionOp);
16846 }
16847 ValueDecl *D = Res.first;
16848 if (!D)
16849 continue;
16850
16851 Expr *TaskgroupDescriptor = nullptr;
16852 QualType Type;
16853 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
16854 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
16855 if (ASE) {
16856 Type = ASE->getType().getNonReferenceType();
16857 } else if (OASE) {
16858 QualType BaseType =
16859 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16860 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16861 Type = ATy->getElementType();
16862 else
16863 Type = BaseType->getPointeeType();
16864 Type = Type.getNonReferenceType();
16865 } else {
16866 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
16867 }
16868 auto *VD = dyn_cast<VarDecl>(D);
16869
16870 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16871 // A variable that appears in a private clause must not have an incomplete
16872 // type or a reference type.
16873 if (S.RequireCompleteType(ELoc, D->getType(),
16874 diag::err_omp_reduction_incomplete_type))
16875 continue;
16876 // OpenMP [2.14.3.6, reduction clause, Restrictions]
16877 // A list item that appears in a reduction clause must not be
16878 // const-qualified.
16879 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
16880 /*AcceptIfMutable*/ false, ASE || OASE))
16881 continue;
16882
16883 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
16884 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
16885 // If a list-item is a reference type then it must bind to the same object
16886 // for all threads of the team.
16887 if (!ASE && !OASE) {
16888 if (VD) {
16889 VarDecl *VDDef = VD->getDefinition();
16890 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
16891 DSARefChecker Check(Stack);
16892 if (Check.Visit(VDDef->getInit())) {
16893 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
16894 << getOpenMPClauseName(ClauseKind) << ERange;
16895 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
16896 continue;
16897 }
16898 }
16899 }
16900
16901 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16902 // in a Construct]
16903 // Variables with the predetermined data-sharing attributes may not be
16904 // listed in data-sharing attributes clauses, except for the cases
16905 // listed below. For these exceptions only, listing a predetermined
16906 // variable in a data-sharing attribute clause is allowed and overrides
16907 // the variable's predetermined data-sharing attributes.
16908 // OpenMP [2.14.3.6, Restrictions, p.3]
16909 // Any number of reduction clauses can be specified on the directive,
16910 // but a list item can appear only once in the reduction clauses for that
16911 // directive.
16912 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16913 if (DVar.CKind == OMPC_reduction) {
16914 S.Diag(ELoc, diag::err_omp_once_referenced)
16915 << getOpenMPClauseName(ClauseKind);
16916 if (DVar.RefExpr)
16917 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
16918 continue;
16919 }
16920 if (DVar.CKind != OMPC_unknown) {
16921 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16922 << getOpenMPClauseName(DVar.CKind)
16923 << getOpenMPClauseName(OMPC_reduction);
16924 reportOriginalDsa(S, Stack, D, DVar);
16925 continue;
16926 }
16927
16928 // OpenMP [2.14.3.6, Restrictions, p.1]
16929 // A list item that appears in a reduction clause of a worksharing
16930 // construct must be shared in the parallel regions to which any of the
16931 // worksharing regions arising from the worksharing construct bind.
16932 if (isOpenMPWorksharingDirective(CurrDir) &&
16933 !isOpenMPParallelDirective(CurrDir) &&
16934 !isOpenMPTeamsDirective(CurrDir)) {
16935 DVar = Stack->getImplicitDSA(D, true);
16936 if (DVar.CKind != OMPC_shared) {
16937 S.Diag(ELoc, diag::err_omp_required_access)
16938 << getOpenMPClauseName(OMPC_reduction)
16939 << getOpenMPClauseName(OMPC_shared);
16940 reportOriginalDsa(S, Stack, D, DVar);
16941 continue;
16942 }
16943 }
16944 } else {
16945 // Threadprivates cannot be shared between threads, so dignose if the base
16946 // is a threadprivate variable.
16947 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16948 if (DVar.CKind == OMPC_threadprivate) {
16949 S.Diag(ELoc, diag::err_omp_wrong_dsa)
16950 << getOpenMPClauseName(DVar.CKind)
16951 << getOpenMPClauseName(OMPC_reduction);
16952 reportOriginalDsa(S, Stack, D, DVar);
16953 continue;
16954 }
16955 }
16956
16957 // Try to find 'declare reduction' corresponding construct before using
16958 // builtin/overloaded operators.
16959 CXXCastPath BasePath;
16960 ExprResult DeclareReductionRef = buildDeclareReductionRef(
16961 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16962 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16963 if (DeclareReductionRef.isInvalid())
16964 continue;
16965 if (S.CurContext->isDependentContext() &&
16966 (DeclareReductionRef.isUnset() ||
16967 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
16968 RD.push(RefExpr, DeclareReductionRef.get());
16969 continue;
16970 }
16971 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
16972 // Not allowed reduction identifier is found.
16973 S.Diag(ReductionId.getBeginLoc(),
16974 diag::err_omp_unknown_reduction_identifier)
16975 << Type << ReductionIdRange;
16976 continue;
16977 }
16978
16979 // OpenMP [2.14.3.6, reduction clause, Restrictions]
16980 // The type of a list item that appears in a reduction clause must be valid
16981 // for the reduction-identifier. For a max or min reduction in C, the type
16982 // of the list item must be an allowed arithmetic data type: char, int,
16983 // float, double, or _Bool, possibly modified with long, short, signed, or
16984 // unsigned. For a max or min reduction in C++, the type of the list item
16985 // must be an allowed arithmetic data type: char, wchar_t, int, float,
16986 // double, or bool, possibly modified with long, short, signed, or unsigned.
16987 if (DeclareReductionRef.isUnset()) {
16988 if ((BOK == BO_GT || BOK == BO_LT) &&
16989 !(Type->isScalarType() ||
16990 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
16991 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
16992 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
16993 if (!ASE && !OASE) {
16994 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16995 VarDecl::DeclarationOnly;
16996 S.Diag(D->getLocation(),
16997 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16998 << D;
16999 }
17000 continue;
17001 }
17002 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
17003 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
17004 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
17005 << getOpenMPClauseName(ClauseKind);
17006 if (!ASE && !OASE) {
17007 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17008 VarDecl::DeclarationOnly;
17009 S.Diag(D->getLocation(),
17010 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17011 << D;
17012 }
17013 continue;
17014 }
17015 }
17016
17017 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
17018 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
17019 D->hasAttrs() ? &D->getAttrs() : nullptr);
17020 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
17021 D->hasAttrs() ? &D->getAttrs() : nullptr);
17022 QualType PrivateTy = Type;
17023
17024 // Try if we can determine constant lengths for all array sections and avoid
17025 // the VLA.
17026 bool ConstantLengthOASE = false;
17027 if (OASE) {
17028 bool SingleElement;
17029 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
17030 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
17031 Context, OASE, SingleElement, ArraySizes);
17032
17033 // If we don't have a single element, we must emit a constant array type.
17034 if (ConstantLengthOASE && !SingleElement) {
17035 for (llvm::APSInt &Size : ArraySizes)
17036 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
17037 ArrayType::Normal,
17038 /*IndexTypeQuals=*/0);
17039 }
17040 }
17041
17042 if ((OASE && !ConstantLengthOASE) ||
17043 (!OASE && !ASE &&
17044 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
17045 if (!Context.getTargetInfo().isVLASupported()) {
17046 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
17047 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17048 S.Diag(ELoc, diag::note_vla_unsupported);
17049 continue;
17050 } else {
17051 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17052 S.targetDiag(ELoc, diag::note_vla_unsupported);
17053 }
17054 }
17055 // For arrays/array sections only:
17056 // Create pseudo array type for private copy. The size for this array will
17057 // be generated during codegen.
17058 // For array subscripts or single variables Private Ty is the same as Type
17059 // (type of the variable or single array element).
17060 PrivateTy = Context.getVariableArrayType(
17061 Type,
17062 new (Context)
17063 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
17064 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
17065 } else if (!ASE && !OASE &&
17066 Context.getAsArrayType(D->getType().getNonReferenceType())) {
17067 PrivateTy = D->getType().getNonReferenceType();
17068 }
17069 // Private copy.
17070 VarDecl *PrivateVD =
17071 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17072 D->hasAttrs() ? &D->getAttrs() : nullptr,
17073 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17074 // Add initializer for private variable.
17075 Expr *Init = nullptr;
17076 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
17077 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
17078 if (DeclareReductionRef.isUsable()) {
17079 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
17080 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
17081 if (DRD->getInitializer()) {
17082 Init = DRDRef;
17083 RHSVD->setInit(DRDRef);
17084 RHSVD->setInitStyle(VarDecl::CallInit);
17085 }
17086 } else {
17087 switch (BOK) {
17088 case BO_Add:
17089 case BO_Xor:
17090 case BO_Or:
17091 case BO_LOr:
17092 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
17093 if (Type->isScalarType() || Type->isAnyComplexType())
17094 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
17095 break;
17096 case BO_Mul:
17097 case BO_LAnd:
17098 if (Type->isScalarType() || Type->isAnyComplexType()) {
17099 // '*' and '&&' reduction ops - initializer is '1'.
17100 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
17101 }
17102 break;
17103 case BO_And: {
17104 // '&' reduction op - initializer is '~0'.
17105 QualType OrigType = Type;
17106 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
17107 Type = ComplexTy->getElementType();
17108 if (Type->isRealFloatingType()) {
17109 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
17110 Context.getFloatTypeSemantics(Type),
17111 Context.getTypeSize(Type));
17112 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17113 Type, ELoc);
17114 } else if (Type->isScalarType()) {
17115 uint64_t Size = Context.getTypeSize(Type);
17116 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
17117 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
17118 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17119 }
17120 if (Init && OrigType->isAnyComplexType()) {
17121 // Init = 0xFFFF + 0xFFFFi;
17122 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
17123 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
17124 }
17125 Type = OrigType;
17126 break;
17127 }
17128 case BO_LT:
17129 case BO_GT: {
17130 // 'min' reduction op - initializer is 'Largest representable number in
17131 // the reduction list item type'.
17132 // 'max' reduction op - initializer is 'Least representable number in
17133 // the reduction list item type'.
17134 if (Type->isIntegerType() || Type->isPointerType()) {
17135 bool IsSigned = Type->hasSignedIntegerRepresentation();
17136 uint64_t Size = Context.getTypeSize(Type);
17137 QualType IntTy =
17138 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
17139 llvm::APInt InitValue =
17140 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
17141 : llvm::APInt::getMinValue(Size)
17142 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
17143 : llvm::APInt::getMaxValue(Size);
17144 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17145 if (Type->isPointerType()) {
17146 // Cast to pointer type.
17147 ExprResult CastExpr = S.BuildCStyleCastExpr(
17148 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
17149 if (CastExpr.isInvalid())
17150 continue;
17151 Init = CastExpr.get();
17152 }
17153 } else if (Type->isRealFloatingType()) {
17154 llvm::APFloat InitValue = llvm::APFloat::getLargest(
17155 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
17156 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17157 Type, ELoc);
17158 }
17159 break;
17160 }
17161 case BO_PtrMemD:
17162 case BO_PtrMemI:
17163 case BO_MulAssign:
17164 case BO_Div:
17165 case BO_Rem:
17166 case BO_Sub:
17167 case BO_Shl:
17168 case BO_Shr:
17169 case BO_LE:
17170 case BO_GE:
17171 case BO_EQ:
17172 case BO_NE:
17173 case BO_Cmp:
17174 case BO_AndAssign:
17175 case BO_XorAssign:
17176 case BO_OrAssign:
17177 case BO_Assign:
17178 case BO_AddAssign:
17179 case BO_SubAssign:
17180 case BO_DivAssign:
17181 case BO_RemAssign:
17182 case BO_ShlAssign:
17183 case BO_ShrAssign:
17184 case BO_Comma:
17185 llvm_unreachable("Unexpected reduction operation")__builtin_unreachable();
17186 }
17187 }
17188 if (Init && DeclareReductionRef.isUnset()) {
17189 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
17190 // Store initializer for single element in private copy. Will be used
17191 // during codegen.
17192 PrivateVD->setInit(RHSVD->getInit());
17193 PrivateVD->setInitStyle(RHSVD->getInitStyle());
17194 } else if (!Init) {
17195 S.ActOnUninitializedDecl(RHSVD);
17196 // Store initializer for single element in private copy. Will be used
17197 // during codegen.
17198 PrivateVD->setInit(RHSVD->getInit());
17199 PrivateVD->setInitStyle(RHSVD->getInitStyle());
17200 }
17201 if (RHSVD->isInvalidDecl())
17202 continue;
17203 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
17204 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
17205 << Type << ReductionIdRange;
17206 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17207 VarDecl::DeclarationOnly;
17208 S.Diag(D->getLocation(),
17209 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17210 << D;
17211 continue;
17212 }
17213 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
17214 ExprResult ReductionOp;
17215 if (DeclareReductionRef.isUsable()) {
17216 QualType RedTy = DeclareReductionRef.get()->getType();
17217 QualType PtrRedTy = Context.getPointerType(RedTy);
17218 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
17219 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
17220 if (!BasePath.empty()) {
17221 LHS = S.DefaultLvalueConversion(LHS.get());
17222 RHS = S.DefaultLvalueConversion(RHS.get());
17223 LHS = ImplicitCastExpr::Create(
17224 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
17225 LHS.get()->getValueKind(), FPOptionsOverride());
17226 RHS = ImplicitCastExpr::Create(
17227 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
17228 RHS.get()->getValueKind(), FPOptionsOverride());
17229 }
17230 FunctionProtoType::ExtProtoInfo EPI;
17231 QualType Params[] = {PtrRedTy, PtrRedTy};
17232 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
17233 auto *OVE = new (Context) OpaqueValueExpr(
17234 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
17235 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
17236 Expr *Args[] = {LHS.get(), RHS.get()};
17237 ReductionOp =
17238 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
17239 S.CurFPFeatureOverrides());
17240 } else {
17241 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
17242 if (Type->isRecordType() && CombBOK != BOK) {
17243 Sema::TentativeAnalysisScope Trap(S);
17244 ReductionOp =
17245 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17246 CombBOK, LHSDRE, RHSDRE);
17247 }
17248 if (!ReductionOp.isUsable()) {
17249 ReductionOp =
17250 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
17251 LHSDRE, RHSDRE);
17252 if (ReductionOp.isUsable()) {
17253 if (BOK != BO_LT && BOK != BO_GT) {
17254 ReductionOp =
17255 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17256 BO_Assign, LHSDRE, ReductionOp.get());
17257 } else {
17258 auto *ConditionalOp = new (Context)
17259 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
17260 RHSDRE, Type, VK_LValue, OK_Ordinary);
17261 ReductionOp =
17262 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17263 BO_Assign, LHSDRE, ConditionalOp);
17264 }
17265 }
17266 }
17267 if (ReductionOp.isUsable())
17268 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
17269 /*DiscardedValue*/ false);
17270 if (!ReductionOp.isUsable())
17271 continue;
17272 }
17273
17274 // Add copy operations for inscan reductions.
17275 // LHS = RHS;
17276 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
17277 if (ClauseKind == OMPC_reduction &&
17278 RD.RedModifier == OMPC_REDUCTION_inscan) {
17279 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
17280 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
17281 RHS.get());
17282 if (!CopyOpRes.isUsable())
17283 continue;
17284 CopyOpRes =
17285 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
17286 if (!CopyOpRes.isUsable())
17287 continue;
17288 // For simd directive and simd-based directives in simd mode no need to
17289 // construct temp array, need just a single temp element.
17290 if (Stack->getCurrentDirective() == OMPD_simd ||
17291 (S.getLangOpts().OpenMPSimd &&
17292 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
17293 VarDecl *TempArrayVD =
17294 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17295 D->hasAttrs() ? &D->getAttrs() : nullptr);
17296 // Add a constructor to the temp decl.
17297 S.ActOnUninitializedDecl(TempArrayVD);
17298 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
17299 } else {
17300 // Build temp array for prefix sum.
17301 auto *Dim = new (S.Context)
17302 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17303 QualType ArrayTy =
17304 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
17305 /*IndexTypeQuals=*/0, {ELoc, ELoc});
17306 VarDecl *TempArrayVD =
17307 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
17308 D->hasAttrs() ? &D->getAttrs() : nullptr);
17309 // Add a constructor to the temp decl.
17310 S.ActOnUninitializedDecl(TempArrayVD);
17311 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
17312 TempArrayElem =
17313 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
17314 auto *Idx = new (S.Context)
17315 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17316 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
17317 ELoc, Idx, ELoc);
17318 }
17319 }
17320
17321 // OpenMP [2.15.4.6, Restrictions, p.2]
17322 // A list item that appears in an in_reduction clause of a task construct
17323 // must appear in a task_reduction clause of a construct associated with a
17324 // taskgroup region that includes the participating task in its taskgroup
17325 // set. The construct associated with the innermost region that meets this
17326 // condition must specify the same reduction-identifier as the in_reduction
17327 // clause.
17328 if (ClauseKind == OMPC_in_reduction) {
17329 SourceRange ParentSR;
17330 BinaryOperatorKind ParentBOK;
17331 const Expr *ParentReductionOp = nullptr;
17332 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
17333 DSAStackTy::DSAVarData ParentBOKDSA =
17334 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
17335 ParentBOKTD);
17336 DSAStackTy::DSAVarData ParentReductionOpDSA =
17337 Stack->getTopMostTaskgroupReductionData(
17338 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
17339 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
17340 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
17341 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
17342 (DeclareReductionRef.isUsable() && IsParentBOK) ||
17343 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
17344 bool EmitError = true;
17345 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
17346 llvm::FoldingSetNodeID RedId, ParentRedId;
17347 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
17348 DeclareReductionRef.get()->Profile(RedId, Context,
17349 /*Canonical=*/true);
17350 EmitError = RedId != ParentRedId;
17351 }
17352 if (EmitError) {
17353 S.Diag(ReductionId.getBeginLoc(),
17354 diag::err_omp_reduction_identifier_mismatch)
17355 << ReductionIdRange << RefExpr->getSourceRange();
17356 S.Diag(ParentSR.getBegin(),
17357 diag::note_omp_previous_reduction_identifier)
17358 << ParentSR
17359 << (IsParentBOK ? ParentBOKDSA.RefExpr
17360 : ParentReductionOpDSA.RefExpr)
17361 ->getSourceRange();
17362 continue;
17363 }
17364 }
17365 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
17366 }
17367
17368 DeclRefExpr *Ref = nullptr;
17369 Expr *VarsExpr = RefExpr->IgnoreParens();
17370 if (!VD && !S.CurContext->isDependentContext()) {
17371 if (ASE || OASE) {
17372 TransformExprToCaptures RebuildToCapture(S, D);
17373 VarsExpr =
17374 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
17375 Ref = RebuildToCapture.getCapturedExpr();
17376 } else {
17377 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
17378 }
17379 if (!S.isOpenMPCapturedDecl(D)) {
17380 RD.ExprCaptures.emplace_back(Ref->getDecl());
17381 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17382 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
17383 if (!RefRes.isUsable())
17384 continue;
17385 ExprResult PostUpdateRes =
17386 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17387 RefRes.get());
17388 if (!PostUpdateRes.isUsable())
17389 continue;
17390 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
17391 Stack->getCurrentDirective() == OMPD_taskgroup) {
17392 S.Diag(RefExpr->getExprLoc(),
17393 diag::err_omp_reduction_non_addressable_expression)
17394 << RefExpr->getSourceRange();
17395 continue;
17396 }
17397 RD.ExprPostUpdates.emplace_back(
17398 S.IgnoredValueConversions(PostUpdateRes.get()).get());
17399 }
17400 }
17401 }
17402 // All reduction items are still marked as reduction (to do not increase
17403 // code base size).
17404 unsigned Modifier = RD.RedModifier;
17405 // Consider task_reductions as reductions with task modifier. Required for
17406 // correct analysis of in_reduction clauses.
17407 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
17408 Modifier = OMPC_REDUCTION_task;
17409 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
17410 ASE || OASE);
17411 if (Modifier == OMPC_REDUCTION_task &&
17412 (CurrDir == OMPD_taskgroup ||
17413 ((isOpenMPParallelDirective(CurrDir) ||
17414 isOpenMPWorksharingDirective(CurrDir)) &&
17415 !isOpenMPSimdDirective(CurrDir)))) {
17416 if (DeclareReductionRef.isUsable())
17417 Stack->addTaskgroupReductionData(D, ReductionIdRange,
17418 DeclareReductionRef.get());
17419 else
17420 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
17421 }
17422 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
17423 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
17424 TempArrayElem.get());
17425 }
17426 return RD.Vars.empty();
17427}
17428
17429OMPClause *Sema::ActOnOpenMPReductionClause(
17430 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
17431 SourceLocation StartLoc, SourceLocation LParenLoc,
17432 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
17433 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17434 ArrayRef<Expr *> UnresolvedReductions) {
17435 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
17436 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
17437 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
17438 /*Last=*/OMPC_REDUCTION_unknown)
17439 << getOpenMPClauseName(OMPC_reduction);
17440 return nullptr;
17441 }
17442 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
17443 // A reduction clause with the inscan reduction-modifier may only appear on a
17444 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
17445 // construct, a parallel worksharing-loop construct or a parallel
17446 // worksharing-loop SIMD construct.
17447 if (Modifier == OMPC_REDUCTION_inscan &&
17448 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
17449 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
17450 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
17451 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
17452 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
17453 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
17454 return nullptr;
17455 }
17456
17457 ReductionData RD(VarList.size(), Modifier);
17458 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
17459 StartLoc, LParenLoc, ColonLoc, EndLoc,
17460 ReductionIdScopeSpec, ReductionId,
17461 UnresolvedReductions, RD))
17462 return nullptr;
17463
17464 return OMPReductionClause::Create(
17465 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
17466 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17467 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
17468 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
17469 buildPreInits(Context, RD.ExprCaptures),
17470 buildPostUpdate(*this, RD.ExprPostUpdates));
17471}
17472
17473OMPClause *Sema::ActOnOpenMPTaskReductionClause(
17474 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17475 SourceLocation ColonLoc, SourceLocation EndLoc,
17476 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17477 ArrayRef<Expr *> UnresolvedReductions) {
17478 ReductionData RD(VarList.size());
17479 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
17480 StartLoc, LParenLoc, ColonLoc, EndLoc,
17481 ReductionIdScopeSpec, ReductionId,
17482 UnresolvedReductions, RD))
17483 return nullptr;
17484
17485 return OMPTaskReductionClause::Create(
17486 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17487 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17488 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
17489 buildPreInits(Context, RD.ExprCaptures),
17490 buildPostUpdate(*this, RD.ExprPostUpdates));
17491}
17492
17493OMPClause *Sema::ActOnOpenMPInReductionClause(
17494 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17495 SourceLocation ColonLoc, SourceLocation EndLoc,
17496 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17497 ArrayRef<Expr *> UnresolvedReductions) {
17498 ReductionData RD(VarList.size());
17499 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
17500 StartLoc, LParenLoc, ColonLoc, EndLoc,
17501 ReductionIdScopeSpec, ReductionId,
17502 UnresolvedReductions, RD))
17503 return nullptr;
17504
17505 return OMPInReductionClause::Create(
17506 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17507 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17508 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
17509 buildPreInits(Context, RD.ExprCaptures),
17510 buildPostUpdate(*this, RD.ExprPostUpdates));
17511}
17512
17513bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
17514 SourceLocation LinLoc) {
17515 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
17516 LinKind == OMPC_LINEAR_unknown) {
17517 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
17518 return true;
17519 }
17520 return false;
17521}
17522
17523bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
17524 OpenMPLinearClauseKind LinKind, QualType Type,
17525 bool IsDeclareSimd) {
17526 const auto *VD = dyn_cast_or_null<VarDecl>(D);
17527 // A variable must not have an incomplete type or a reference type.
17528 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
17529 return true;
17530 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
17531 !Type->isReferenceType()) {
17532 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
17533 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
17534 return true;
17535 }
17536 Type = Type.getNonReferenceType();
17537
17538 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17539 // A variable that is privatized must not have a const-qualified type
17540 // unless it is of class type with a mutable member. This restriction does
17541 // not apply to the firstprivate clause, nor to the linear clause on
17542 // declarative directives (like declare simd).
17543 if (!IsDeclareSimd &&
17544 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
17545 return true;
17546
17547 // A list item must be of integral or pointer type.
17548 Type = Type.getUnqualifiedType().getCanonicalType();
17549 const auto *Ty = Type.getTypePtrOrNull();
17550 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
17551 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
17552 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
17553 if (D) {
17554 bool IsDecl =
17555 !VD ||
17556 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17557 Diag(D->getLocation(),
17558 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17559 << D;
17560 }
17561 return true;
17562 }
17563 return false;
17564}
17565
17566OMPClause *Sema::ActOnOpenMPLinearClause(
17567 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
17568 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
17569 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17570 SmallVector<Expr *, 8> Vars;
17571 SmallVector<Expr *, 8> Privates;
17572 SmallVector<Expr *, 8> Inits;
17573 SmallVector<Decl *, 4> ExprCaptures;
17574 SmallVector<Expr *, 4> ExprPostUpdates;
17575 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
17576 LinKind = OMPC_LINEAR_val;
17577 for (Expr *RefExpr : VarList) {
17578 assert(RefExpr && "NULL expr in OpenMP linear clause.")((void)0);
17579 SourceLocation ELoc;
17580 SourceRange ERange;
17581 Expr *SimpleRefExpr = RefExpr;
17582 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17583 if (Res.second) {
17584 // It will be analyzed later.
17585 Vars.push_back(RefExpr);
17586 Privates.push_back(nullptr);
17587 Inits.push_back(nullptr);
17588 }
17589 ValueDecl *D = Res.first;
17590 if (!D)
17591 continue;
17592
17593 QualType Type = D->getType();
17594 auto *VD = dyn_cast<VarDecl>(D);
17595
17596 // OpenMP [2.14.3.7, linear clause]
17597 // A list-item cannot appear in more than one linear clause.
17598 // A list-item that appears in a linear clause cannot appear in any
17599 // other data-sharing attribute clause.
17600 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17601 if (DVar.RefExpr) {
17602 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17603 << getOpenMPClauseName(OMPC_linear);
17604 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17605 continue;
17606 }
17607
17608 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
17609 continue;
17610 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17611
17612 // Build private copy of original var.
17613 VarDecl *Private =
17614 buildVarDecl(*this, ELoc, Type, D->getName(),
17615 D->hasAttrs() ? &D->getAttrs() : nullptr,
17616 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17617 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
17618 // Build var to save initial value.
17619 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
17620 Expr *InitExpr;
17621 DeclRefExpr *Ref = nullptr;
17622 if (!VD && !CurContext->isDependentContext()) {
17623 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17624 if (!isOpenMPCapturedDecl(D)) {
17625 ExprCaptures.push_back(Ref->getDecl());
17626 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17627 ExprResult RefRes = DefaultLvalueConversion(Ref);
17628 if (!RefRes.isUsable())
17629 continue;
17630 ExprResult PostUpdateRes =
17631 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
17632 SimpleRefExpr, RefRes.get());
17633 if (!PostUpdateRes.isUsable())
17634 continue;
17635 ExprPostUpdates.push_back(
17636 IgnoredValueConversions(PostUpdateRes.get()).get());
17637 }
17638 }
17639 }
17640 if (LinKind == OMPC_LINEAR_uval)
17641 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
17642 else
17643 InitExpr = VD ? SimpleRefExpr : Ref;
17644 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
17645 /*DirectInit=*/false);
17646 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
17647
17648 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
17649 Vars.push_back((VD || CurContext->isDependentContext())
17650 ? RefExpr->IgnoreParens()
17651 : Ref);
17652 Privates.push_back(PrivateRef);
17653 Inits.push_back(InitRef);
17654 }
17655
17656 if (Vars.empty())
17657 return nullptr;
17658
17659 Expr *StepExpr = Step;
17660 Expr *CalcStepExpr = nullptr;
17661 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
17662 !Step->isInstantiationDependent() &&
17663 !Step->containsUnexpandedParameterPack()) {
17664 SourceLocation StepLoc = Step->getBeginLoc();
17665 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
17666 if (Val.isInvalid())
17667 return nullptr;
17668 StepExpr = Val.get();
17669
17670 // Build var to save the step value.
17671 VarDecl *SaveVar =
17672 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
17673 ExprResult SaveRef =
17674 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
17675 ExprResult CalcStep =
17676 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
17677 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
17678
17679 // Warn about zero linear step (it would be probably better specified as
17680 // making corresponding variables 'const').
17681 if (Optional<llvm::APSInt> Result =
17682 StepExpr->getIntegerConstantExpr(Context)) {
17683 if (!Result->isNegative() && !Result->isStrictlyPositive())
17684 Diag(StepLoc, diag::warn_omp_linear_step_zero)
17685 << Vars[0] << (Vars.size() > 1);
17686 } else if (CalcStep.isUsable()) {
17687 // Calculate the step beforehand instead of doing this on each iteration.
17688 // (This is not used if the number of iterations may be kfold-ed).
17689 CalcStepExpr = CalcStep.get();
17690 }
17691 }
17692
17693 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
17694 ColonLoc, EndLoc, Vars, Privates, Inits,
17695 StepExpr, CalcStepExpr,
17696 buildPreInits(Context, ExprCaptures),
17697 buildPostUpdate(*this, ExprPostUpdates));
17698}
17699
17700static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
17701 Expr *NumIterations, Sema &SemaRef,
17702 Scope *S, DSAStackTy *Stack) {
17703 // Walk the vars and build update/final expressions for the CodeGen.
17704 SmallVector<Expr *, 8> Updates;
17705 SmallVector<Expr *, 8> Finals;
17706 SmallVector<Expr *, 8> UsedExprs;
17707 Expr *Step = Clause.getStep();
17708 Expr *CalcStep = Clause.getCalcStep();
17709 // OpenMP [2.14.3.7, linear clause]
17710 // If linear-step is not specified it is assumed to be 1.
17711 if (!Step)
17712 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
17713 else if (CalcStep)
17714 Step = cast<BinaryOperator>(CalcStep)->getLHS();
17715 bool HasErrors = false;
17716 auto CurInit = Clause.inits().begin();
17717 auto CurPrivate = Clause.privates().begin();
17718 OpenMPLinearClauseKind LinKind = Clause.getModifier();
17719 for (Expr *RefExpr : Clause.varlists()) {
17720 SourceLocation ELoc;
17721 SourceRange ERange;
17722 Expr *SimpleRefExpr = RefExpr;
17723 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17724 ValueDecl *D = Res.first;
17725 if (Res.second || !D) {
17726 Updates.push_back(nullptr);
17727 Finals.push_back(nullptr);
17728 HasErrors = true;
17729 continue;
17730 }
17731 auto &&Info = Stack->isLoopControlVariable(D);
17732 // OpenMP [2.15.11, distribute simd Construct]
17733 // A list item may not appear in a linear clause, unless it is the loop
17734 // iteration variable.
17735 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
17736 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
17737 SemaRef.Diag(ELoc,
17738 diag::err_omp_linear_distribute_var_non_loop_iteration);
17739 Updates.push_back(nullptr);
17740 Finals.push_back(nullptr);
17741 HasErrors = true;
17742 continue;
17743 }
17744 Expr *InitExpr = *CurInit;
17745
17746 // Build privatized reference to the current linear var.
17747 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
17748 Expr *CapturedRef;
17749 if (LinKind == OMPC_LINEAR_uval)
17750 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
17751 else
17752 CapturedRef =
17753 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
17754 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
17755 /*RefersToCapture=*/true);
17756
17757 // Build update: Var = InitExpr + IV * Step
17758 ExprResult Update;
17759 if (!Info.first)
17760 Update = buildCounterUpdate(
17761 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
17762 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
17763 else
17764 Update = *CurPrivate;
17765 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
17766 /*DiscardedValue*/ false);
17767
17768 // Build final: Var = InitExpr + NumIterations * Step
17769 ExprResult Final;
17770 if (!Info.first)
17771 Final =
17772 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
17773 InitExpr, NumIterations, Step, /*Subtract=*/false,
17774 /*IsNonRectangularLB=*/false);
17775 else
17776 Final = *CurPrivate;
17777 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
17778 /*DiscardedValue*/ false);
17779
17780 if (!Update.isUsable() || !Final.isUsable()) {
17781 Updates.push_back(nullptr);
17782 Finals.push_back(nullptr);
17783 UsedExprs.push_back(nullptr);
17784 HasErrors = true;
17785 } else {
17786 Updates.push_back(Update.get());
17787 Finals.push_back(Final.get());
17788 if (!Info.first)
17789 UsedExprs.push_back(SimpleRefExpr);
17790 }
17791 ++CurInit;
17792 ++CurPrivate;
17793 }
17794 if (Expr *S = Clause.getStep())
17795 UsedExprs.push_back(S);
17796 // Fill the remaining part with the nullptr.
17797 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
17798 Clause.setUpdates(Updates);
17799 Clause.setFinals(Finals);
17800 Clause.setUsedExprs(UsedExprs);
17801 return HasErrors;
17802}
17803
17804OMPClause *Sema::ActOnOpenMPAlignedClause(
17805 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
17806 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17807 SmallVector<Expr *, 8> Vars;
17808 for (Expr *RefExpr : VarList) {
17809 assert(RefExpr && "NULL expr in OpenMP linear clause.")((void)0);
17810 SourceLocation ELoc;
17811 SourceRange ERange;
17812 Expr *SimpleRefExpr = RefExpr;
17813 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17814 if (Res.second) {
17815 // It will be analyzed later.
17816 Vars.push_back(RefExpr);
17817 }
17818 ValueDecl *D = Res.first;
17819 if (!D)
17820 continue;
17821
17822 QualType QType = D->getType();
17823 auto *VD = dyn_cast<VarDecl>(D);
17824
17825 // OpenMP [2.8.1, simd construct, Restrictions]
17826 // The type of list items appearing in the aligned clause must be
17827 // array, pointer, reference to array, or reference to pointer.
17828 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17829 const Type *Ty = QType.getTypePtrOrNull();
17830 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
17831 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
17832 << QType << getLangOpts().CPlusPlus << ERange;
17833 bool IsDecl =
17834 !VD ||
17835 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17836 Diag(D->getLocation(),
17837 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17838 << D;
17839 continue;
17840 }
17841
17842 // OpenMP [2.8.1, simd construct, Restrictions]
17843 // A list-item cannot appear in more than one aligned clause.
17844 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
17845 Diag(ELoc, diag::err_omp_used_in_clause_twice)
17846 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
17847 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17848 << getOpenMPClauseName(OMPC_aligned);
17849 continue;
17850 }
17851
17852 DeclRefExpr *Ref = nullptr;
17853 if (!VD && isOpenMPCapturedDecl(D))
17854 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17855 Vars.push_back(DefaultFunctionArrayConversion(
17856 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
17857 .get());
17858 }
17859
17860 // OpenMP [2.8.1, simd construct, Description]
17861 // The parameter of the aligned clause, alignment, must be a constant
17862 // positive integer expression.
17863 // If no optional parameter is specified, implementation-defined default
17864 // alignments for SIMD instructions on the target platforms are assumed.
17865 if (Alignment != nullptr) {
17866 ExprResult AlignResult =
17867 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
17868 if (AlignResult.isInvalid())
17869 return nullptr;
17870 Alignment = AlignResult.get();
17871 }
17872 if (Vars.empty())
17873 return nullptr;
17874
17875 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
17876 EndLoc, Vars, Alignment);
17877}
17878
17879OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
17880 SourceLocation StartLoc,
17881 SourceLocation LParenLoc,
17882 SourceLocation EndLoc) {
17883 SmallVector<Expr *, 8> Vars;
17884 SmallVector<Expr *, 8> SrcExprs;
17885 SmallVector<Expr *, 8> DstExprs;
17886 SmallVector<Expr *, 8> AssignmentOps;
17887 for (Expr *RefExpr : VarList) {
17888 assert(RefExpr && "NULL expr in OpenMP copyin clause.")((void)0);
17889 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17890 // It will be analyzed later.
17891 Vars.push_back(RefExpr);
17892 SrcExprs.push_back(nullptr);
17893 DstExprs.push_back(nullptr);
17894 AssignmentOps.push_back(nullptr);
17895 continue;
17896 }
17897
17898 SourceLocation ELoc = RefExpr->getExprLoc();
17899 // OpenMP [2.1, C/C++]
17900 // A list item is a variable name.
17901 // OpenMP [2.14.4.1, Restrictions, p.1]
17902 // A list item that appears in a copyin clause must be threadprivate.
17903 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
17904 if (!DE || !isa<VarDecl>(DE->getDecl())) {
17905 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
17906 << 0 << RefExpr->getSourceRange();
17907 continue;
17908 }
17909
17910 Decl *D = DE->getDecl();
17911 auto *VD = cast<VarDecl>(D);
17912
17913 QualType Type = VD->getType();
17914 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
17915 // It will be analyzed later.
17916 Vars.push_back(DE);
17917 SrcExprs.push_back(nullptr);
17918 DstExprs.push_back(nullptr);
17919 AssignmentOps.push_back(nullptr);
17920 continue;
17921 }
17922
17923 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
17924 // A list item that appears in a copyin clause must be threadprivate.
17925 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
17926 Diag(ELoc, diag::err_omp_required_access)
17927 << getOpenMPClauseName(OMPC_copyin)
17928 << getOpenMPDirectiveName(OMPD_threadprivate);
17929 continue;
17930 }
17931
17932 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17933 // A variable of class type (or array thereof) that appears in a
17934 // copyin clause requires an accessible, unambiguous copy assignment
17935 // operator for the class type.
17936 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17937 VarDecl *SrcVD =
17938 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
17939 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17940 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
17941 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
17942 VarDecl *DstVD =
17943 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
17944 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17945 DeclRefExpr *PseudoDstExpr =
17946 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
17947 // For arrays generate assignment operation for single element and replace
17948 // it by the original array element in CodeGen.
17949 ExprResult AssignmentOp =
17950 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
17951 PseudoSrcExpr);
17952 if (AssignmentOp.isInvalid())
17953 continue;
17954 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
17955 /*DiscardedValue*/ false);
17956 if (AssignmentOp.isInvalid())
17957 continue;
17958
17959 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
17960 Vars.push_back(DE);
17961 SrcExprs.push_back(PseudoSrcExpr);
17962 DstExprs.push_back(PseudoDstExpr);
17963 AssignmentOps.push_back(AssignmentOp.get());
17964 }
17965
17966 if (Vars.empty())
17967 return nullptr;
17968
17969 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17970 SrcExprs, DstExprs, AssignmentOps);
17971}
17972
17973OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
17974 SourceLocation StartLoc,
17975 SourceLocation LParenLoc,
17976 SourceLocation EndLoc) {
17977 SmallVector<Expr *, 8> Vars;
17978 SmallVector<Expr *, 8> SrcExprs;
17979 SmallVector<Expr *, 8> DstExprs;
17980 SmallVector<Expr *, 8> AssignmentOps;
17981 for (Expr *RefExpr : VarList) {
17982 assert(RefExpr && "NULL expr in OpenMP linear clause.")((void)0);
17983 SourceLocation ELoc;
17984 SourceRange ERange;
17985 Expr *SimpleRefExpr = RefExpr;
17986 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17987 if (Res.second) {
17988 // It will be analyzed later.
17989 Vars.push_back(RefExpr);
17990 SrcExprs.push_back(nullptr);
17991 DstExprs.push_back(nullptr);
17992 AssignmentOps.push_back(nullptr);
17993 }
17994 ValueDecl *D = Res.first;
17995 if (!D)
17996 continue;
17997
17998 QualType Type = D->getType();
17999 auto *VD = dyn_cast<VarDecl>(D);
18000
18001 // OpenMP [2.14.4.2, Restrictions, p.2]
18002 // A list item that appears in a copyprivate clause may not appear in a
18003 // private or firstprivate clause on the single construct.
18004 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
18005 DSAStackTy::DSAVarData DVar =
18006 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
18007 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
18008 DVar.RefExpr) {
18009 Diag(ELoc, diag::err_omp_wrong_dsa)
18010 << getOpenMPClauseName(DVar.CKind)
18011 << getOpenMPClauseName(OMPC_copyprivate);
18012 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18013 continue;
18014 }
18015
18016 // OpenMP [2.11.4.2, Restrictions, p.1]
18017 // All list items that appear in a copyprivate clause must be either
18018 // threadprivate or private in the enclosing context.
18019 if (DVar.CKind == OMPC_unknown) {
18020 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
18021 if (DVar.CKind == OMPC_shared) {
18022 Diag(ELoc, diag::err_omp_required_access)
18023 << getOpenMPClauseName(OMPC_copyprivate)
18024 << "threadprivate or private in the enclosing context";
18025 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18026 continue;
18027 }
18028 }
18029 }
18030
18031 // Variably modified types are not supported.
18032 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
18033 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18034 << getOpenMPClauseName(OMPC_copyprivate) << Type
18035 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
18036 bool IsDecl =
18037 !VD ||
18038 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
18039 Diag(D->getLocation(),
18040 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18041 << D;
18042 continue;
18043 }
18044
18045 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
18046 // A variable of class type (or array thereof) that appears in a
18047 // copyin clause requires an accessible, unambiguous copy assignment
18048 // operator for the class type.
18049 Type = Context.getBaseElementType(Type.getNonReferenceType())
18050 .getUnqualifiedType();
18051 VarDecl *SrcVD =
18052 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
18053 D->hasAttrs() ? &D->getAttrs() : nullptr);
18054 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
18055 VarDecl *DstVD =
18056 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
18057 D->hasAttrs() ? &D->getAttrs() : nullptr);
18058 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18059 ExprResult AssignmentOp = BuildBinOp(
18060 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
18061 if (AssignmentOp.isInvalid())
18062 continue;
18063 AssignmentOp =
18064 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18065 if (AssignmentOp.isInvalid())
18066 continue;
18067
18068 // No need to mark vars as copyprivate, they are already threadprivate or
18069 // implicitly private.
18070 assert(VD || isOpenMPCapturedDecl(D))((void)0);
18071 Vars.push_back(
18072 VD ? RefExpr->IgnoreParens()
18073 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
18074 SrcExprs.push_back(PseudoSrcExpr);
18075 DstExprs.push_back(PseudoDstExpr);
18076 AssignmentOps.push_back(AssignmentOp.get());
18077 }
18078
18079 if (Vars.empty())
18080 return nullptr;
18081
18082 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18083 Vars, SrcExprs, DstExprs, AssignmentOps);
18084}
18085
18086OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
18087 SourceLocation StartLoc,
18088 SourceLocation LParenLoc,
18089 SourceLocation EndLoc) {
18090 if (VarList.empty())
18091 return nullptr;
18092
18093 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
18094}
18095
18096/// Tries to find omp_depend_t. type.
18097static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
18098 bool Diagnose = true) {
18099 QualType OMPDependT = Stack->getOMPDependT();
18100 if (!OMPDependT.isNull())
18101 return true;
18102 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
18103 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18104 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18105 if (Diagnose)
18106 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
18107 return false;
18108 }
18109 Stack->setOMPDependT(PT.get());
18110 return true;
18111}
18112
18113OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
18114 SourceLocation LParenLoc,
18115 SourceLocation EndLoc) {
18116 if (!Depobj)
18117 return nullptr;
18118
18119 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
18120
18121 // OpenMP 5.0, 2.17.10.1 depobj Construct
18122 // depobj is an lvalue expression of type omp_depend_t.
18123 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
18124 !Depobj->isInstantiationDependent() &&
18125 !Depobj->containsUnexpandedParameterPack() &&
18126 (OMPDependTFound &&
18127 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
18128 /*CompareUnqualified=*/true))) {
18129 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18130 << 0 << Depobj->getType() << Depobj->getSourceRange();
18131 }
18132
18133 if (!Depobj->isLValue()) {
18134 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18135 << 1 << Depobj->getSourceRange();
18136 }
18137
18138 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
18139}
18140
18141OMPClause *
18142Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
18143 SourceLocation DepLoc, SourceLocation ColonLoc,
18144 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
18145 SourceLocation LParenLoc, SourceLocation EndLoc) {
18146 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
18147 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
18148 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18149 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
18150 return nullptr;
18151 }
18152 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
18153 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
18154 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
18155 DepKind == OMPC_DEPEND_sink ||
18156 ((LangOpts.OpenMP < 50 ||
18157 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
18158 DepKind == OMPC_DEPEND_depobj))) {
18159 SmallVector<unsigned, 3> Except;
18160 Except.push_back(OMPC_DEPEND_source);
18161 Except.push_back(OMPC_DEPEND_sink);
18162 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
18163 Except.push_back(OMPC_DEPEND_depobj);
18164 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
18165 ? "depend modifier(iterator) or "
18166 : "";
18167 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18168 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
18169 /*Last=*/OMPC_DEPEND_unknown,
18170 Except)
18171 << getOpenMPClauseName(OMPC_depend);
18172 return nullptr;
18173 }
18174 if (DepModifier &&
18175 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
18176 Diag(DepModifier->getExprLoc(),
18177 diag::err_omp_depend_sink_source_with_modifier);
18178 return nullptr;
18179 }
18180 if (DepModifier &&
18181 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
18182 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
18183
18184 SmallVector<Expr *, 8> Vars;
18185 DSAStackTy::OperatorOffsetTy OpsOffs;
18186 llvm::APSInt DepCounter(/*BitWidth=*/32);
18187 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
18188 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
18189 if (const Expr *OrderedCountExpr =
18190 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
18191 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
18192 TotalDepCount.setIsUnsigned(/*Val=*/true);
18193 }
18194 }
18195 for (Expr *RefExpr : VarList) {
18196 assert(RefExpr && "NULL expr in OpenMP shared clause.")((void)0);
18197 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
18198 // It will be analyzed later.
18199 Vars.push_back(RefExpr);
18200 continue;
18201 }
18202
18203 SourceLocation ELoc = RefExpr->getExprLoc();
18204 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
18205 if (DepKind == OMPC_DEPEND_sink) {
18206 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
18207 DepCounter >= TotalDepCount) {
18208 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
18209 continue;
18210 }
18211 ++DepCounter;
18212 // OpenMP [2.13.9, Summary]
18213 // depend(dependence-type : vec), where dependence-type is:
18214 // 'sink' and where vec is the iteration vector, which has the form:
18215 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
18216 // where n is the value specified by the ordered clause in the loop
18217 // directive, xi denotes the loop iteration variable of the i-th nested
18218 // loop associated with the loop directive, and di is a constant
18219 // non-negative integer.
18220 if (CurContext->isDependentContext()) {
18221 // It will be analyzed later.
18222 Vars.push_back(RefExpr);
18223 continue;
18224 }
18225 SimpleExpr = SimpleExpr->IgnoreImplicit();
18226 OverloadedOperatorKind OOK = OO_None;
18227 SourceLocation OOLoc;
18228 Expr *LHS = SimpleExpr;
18229 Expr *RHS = nullptr;
18230 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
18231 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
18232 OOLoc = BO->getOperatorLoc();
18233 LHS = BO->getLHS()->IgnoreParenImpCasts();
18234 RHS = BO->getRHS()->IgnoreParenImpCasts();
18235 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
18236 OOK = OCE->getOperator();
18237 OOLoc = OCE->getOperatorLoc();
18238 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18239 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
18240 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
18241 OOK = MCE->getMethodDecl()
18242 ->getNameInfo()
18243 .getName()
18244 .getCXXOverloadedOperator();
18245 OOLoc = MCE->getCallee()->getExprLoc();
18246 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
18247 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18248 }
18249 SourceLocation ELoc;
18250 SourceRange ERange;
18251 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
18252 if (Res.second) {
18253 // It will be analyzed later.
18254 Vars.push_back(RefExpr);
18255 }
18256 ValueDecl *D = Res.first;
18257 if (!D)
18258 continue;
18259
18260 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
18261 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
18262 continue;
18263 }
18264 if (RHS) {
18265 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
18266 RHS, OMPC_depend, /*StrictlyPositive=*/false);
18267 if (RHSRes.isInvalid())
18268 continue;
18269 }
18270 if (!CurContext->isDependentContext() &&
18271 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
18272 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
18273 const ValueDecl *VD =
18274 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
18275 if (VD)
18276 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
18277 << 1 << VD;
18278 else
18279 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
18280 continue;
18281 }
18282 OpsOffs.emplace_back(RHS, OOK);
18283 } else {
18284 bool OMPDependTFound = LangOpts.OpenMP >= 50;
18285 if (OMPDependTFound)
18286 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
18287 DepKind == OMPC_DEPEND_depobj);
18288 if (DepKind == OMPC_DEPEND_depobj) {
18289 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18290 // List items used in depend clauses with the depobj dependence type
18291 // must be expressions of the omp_depend_t type.
18292 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18293 !RefExpr->isInstantiationDependent() &&
18294 !RefExpr->containsUnexpandedParameterPack() &&
18295 (OMPDependTFound &&
18296 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
18297 RefExpr->getType()))) {
18298 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18299 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
18300 continue;
18301 }
18302 if (!RefExpr->isLValue()) {
18303 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18304 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
18305 continue;
18306 }
18307 } else {
18308 // OpenMP 5.0 [2.17.11, Restrictions]
18309 // List items used in depend clauses cannot be zero-length array
18310 // sections.
18311 QualType ExprTy = RefExpr->getType().getNonReferenceType();
18312 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
18313 if (OASE) {
18314 QualType BaseType =
18315 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18316 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18317 ExprTy = ATy->getElementType();
18318 else
18319 ExprTy = BaseType->getPointeeType();
18320 ExprTy = ExprTy.getNonReferenceType();
18321 const Expr *Length = OASE->getLength();
18322 Expr::EvalResult Result;
18323 if (Length && !Length->isValueDependent() &&
18324 Length->EvaluateAsInt(Result, Context) &&
18325 Result.Val.getInt().isNullValue()) {
18326 Diag(ELoc,
18327 diag::err_omp_depend_zero_length_array_section_not_allowed)
18328 << SimpleExpr->getSourceRange();
18329 continue;
18330 }
18331 }
18332
18333 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18334 // List items used in depend clauses with the in, out, inout or
18335 // mutexinoutset dependence types cannot be expressions of the
18336 // omp_depend_t type.
18337 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18338 !RefExpr->isInstantiationDependent() &&
18339 !RefExpr->containsUnexpandedParameterPack() &&
18340 (OMPDependTFound &&
18341 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
18342 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18343 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
18344 << RefExpr->getSourceRange();
18345 continue;
18346 }
18347
18348 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
18349 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
18350 (ASE && !ASE->getBase()->isTypeDependent() &&
18351 !ASE->getBase()
18352 ->getType()
18353 .getNonReferenceType()
18354 ->isPointerType() &&
18355 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
18356 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18357 << (LangOpts.OpenMP >= 50 ? 1 : 0)
18358 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18359 continue;
18360 }
18361
18362 ExprResult Res;
18363 {
18364 Sema::TentativeAnalysisScope Trap(*this);
18365 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
18366 RefExpr->IgnoreParenImpCasts());
18367 }
18368 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
18369 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
18370 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18371 << (LangOpts.OpenMP >= 50 ? 1 : 0)
18372 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18373 continue;
18374 }
18375 }
18376 }
18377 Vars.push_back(RefExpr->IgnoreParenImpCasts());
18378 }
18379
18380 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
18381 TotalDepCount > VarList.size() &&
18382 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
18383 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
18384 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
18385 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
18386 }
18387 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
18388 Vars.empty())
18389 return nullptr;
18390
18391 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18392 DepModifier, DepKind, DepLoc, ColonLoc,
18393 Vars, TotalDepCount.getZExtValue());
18394 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
18395 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
18396 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
18397 return C;
18398}
18399
18400OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
18401 Expr *Device, SourceLocation StartLoc,
18402 SourceLocation LParenLoc,
18403 SourceLocation ModifierLoc,
18404 SourceLocation EndLoc) {
18405 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&((void)0)
18406 "Unexpected device modifier in OpenMP < 50.")((void)0);
18407
18408 bool ErrorFound = false;
18409 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
18410 std::string Values =
18411 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
18412 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
18413 << Values << getOpenMPClauseName(OMPC_device);
18414 ErrorFound = true;
18415 }
18416
18417 Expr *ValExpr = Device;
18418 Stmt *HelperValStmt = nullptr;
18419
18420 // OpenMP [2.9.1, Restrictions]
18421 // The device expression must evaluate to a non-negative integer value.
18422 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
18423 /*StrictlyPositive=*/false) ||
18424 ErrorFound;
18425 if (ErrorFound)
18426 return nullptr;
18427
18428 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18429 OpenMPDirectiveKind CaptureRegion =
18430 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
18431 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18432 ValExpr = MakeFullExpr(ValExpr).get();
18433 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18434 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18435 HelperValStmt = buildPreInits(Context, Captures);
18436 }
18437
18438 return new (Context)
18439 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
18440 LParenLoc, ModifierLoc, EndLoc);
18441}
18442
18443static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
18444 DSAStackTy *Stack, QualType QTy,
18445 bool FullCheck = true) {
18446 NamedDecl *ND;
18447 if (QTy->isIncompleteType(&ND)) {
18448 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
18449 return false;
18450 }
18451 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
18452 !QTy.isTriviallyCopyableType(SemaRef.Context))
18453 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
18454 return true;
18455}
18456
18457/// Return true if it can be proven that the provided array expression
18458/// (array section or array subscript) does NOT specify the whole size of the
18459/// array whose base type is \a BaseQTy.
18460static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
18461 const Expr *E,
18462 QualType BaseQTy) {
18463 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18464
18465 // If this is an array subscript, it refers to the whole size if the size of
18466 // the dimension is constant and equals 1. Also, an array section assumes the
18467 // format of an array subscript if no colon is used.
18468 if (isa<ArraySubscriptExpr>(E) ||
18469 (OASE && OASE->getColonLocFirst().isInvalid())) {
18470 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18471 return ATy->getSize().getSExtValue() != 1;
18472 // Size can't be evaluated statically.
18473 return false;
18474 }
18475
18476 assert(OASE && "Expecting array section if not an array subscript.")((void)0);
18477 const Expr *LowerBound = OASE->getLowerBound();
18478 const Expr *Length = OASE->getLength();
18479
18480 // If there is a lower bound that does not evaluates to zero, we are not
18481 // covering the whole dimension.
18482 if (LowerBound) {
18483 Expr::EvalResult Result;
18484 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
18485 return false; // Can't get the integer value as a constant.
18486
18487 llvm::APSInt ConstLowerBound = Result.Val.getInt();
18488 if (ConstLowerBound.getSExtValue())
18489 return true;
18490 }
18491
18492 // If we don't have a length we covering the whole dimension.
18493 if (!Length)
18494 return false;
18495
18496 // If the base is a pointer, we don't have a way to get the size of the
18497 // pointee.
18498 if (BaseQTy->isPointerType())
18499 return false;
18500
18501 // We can only check if the length is the same as the size of the dimension
18502 // if we have a constant array.
18503 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
18504 if (!CATy)
18505 return false;
18506
18507 Expr::EvalResult Result;
18508 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18509 return false; // Can't get the integer value as a constant.
18510
18511 llvm::APSInt ConstLength = Result.Val.getInt();
18512 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
18513}
18514
18515// Return true if it can be proven that the provided array expression (array
18516// section or array subscript) does NOT specify a single element of the array
18517// whose base type is \a BaseQTy.
18518static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
18519 const Expr *E,
18520 QualType BaseQTy) {
18521 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18522
18523 // An array subscript always refer to a single element. Also, an array section
18524 // assumes the format of an array subscript if no colon is used.
18525 if (isa<ArraySubscriptExpr>(E) ||
18526 (OASE && OASE->getColonLocFirst().isInvalid()))
18527 return false;
18528
18529 assert(OASE && "Expecting array section if not an array subscript.")((void)0);
18530 const Expr *Length = OASE->getLength();
18531
18532 // If we don't have a length we have to check if the array has unitary size
18533 // for this dimension. Also, we should always expect a length if the base type
18534 // is pointer.
18535 if (!Length) {
18536 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18537 return ATy->getSize().getSExtValue() != 1;
18538 // We cannot assume anything.
18539 return false;
18540 }
18541
18542 // Check if the length evaluates to 1.
18543 Expr::EvalResult Result;
18544 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18545 return false; // Can't get the integer value as a constant.
18546
18547 llvm::APSInt ConstLength = Result.Val.getInt();
18548 return ConstLength.getSExtValue() != 1;
18549}
18550
18551// The base of elements of list in a map clause have to be either:
18552// - a reference to variable or field.
18553// - a member expression.
18554// - an array expression.
18555//
18556// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
18557// reference to 'r'.
18558//
18559// If we have:
18560//
18561// struct SS {
18562// Bla S;
18563// foo() {
18564// #pragma omp target map (S.Arr[:12]);
18565// }
18566// }
18567//
18568// We want to retrieve the member expression 'this->S';
18569
18570// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
18571// If a list item is an array section, it must specify contiguous storage.
18572//
18573// For this restriction it is sufficient that we make sure only references
18574// to variables or fields and array expressions, and that no array sections
18575// exist except in the rightmost expression (unless they cover the whole
18576// dimension of the array). E.g. these would be invalid:
18577//
18578// r.ArrS[3:5].Arr[6:7]
18579//
18580// r.ArrS[3:5].x
18581//
18582// but these would be valid:
18583// r.ArrS[3].Arr[6:7]
18584//
18585// r.ArrS[3].x
18586namespace {
18587class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
18588 Sema &SemaRef;
18589 OpenMPClauseKind CKind = OMPC_unknown;
18590 OpenMPDirectiveKind DKind = OMPD_unknown;
18591 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
18592 bool IsNonContiguous = false;
18593 bool NoDiagnose = false;
18594 const Expr *RelevantExpr = nullptr;
18595 bool AllowUnitySizeArraySection = true;
18596 bool AllowWholeSizeArraySection = true;
18597 bool AllowAnotherPtr = true;
18598 SourceLocation ELoc;
18599 SourceRange ERange;
18600
18601 void emitErrorMsg() {
18602 // If nothing else worked, this is not a valid map clause expression.
18603 if (SemaRef.getLangOpts().OpenMP < 50) {
18604 SemaRef.Diag(ELoc,
18605 diag::err_omp_expected_named_var_member_or_array_expression)
18606 << ERange;
18607 } else {
18608 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18609 << getOpenMPClauseName(CKind) << ERange;
18610 }
18611 }
18612
18613public:
18614 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
18615 if (!isa<VarDecl>(DRE->getDecl())) {
18616 emitErrorMsg();
18617 return false;
18618 }
18619 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((void)0);
18620 RelevantExpr = DRE;
18621 // Record the component.
18622 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
18623 return true;
18624 }
18625
18626 bool VisitMemberExpr(MemberExpr *ME) {
18627 Expr *E = ME;
18628 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
18629
18630 if (isa<CXXThisExpr>(BaseE)) {
18631 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((void)0);
18632 // We found a base expression: this->Val.
18633 RelevantExpr = ME;
18634 } else {
18635 E = BaseE;
18636 }
18637
18638 if (!isa<FieldDecl>(ME->getMemberDecl())) {
18639 if (!NoDiagnose) {
18640 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
18641 << ME->getSourceRange();
18642 return false;
18643 }
18644 if (RelevantExpr)
18645 return false;
18646 return Visit(E);
18647 }
18648
18649 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
18650
18651 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
18652 // A bit-field cannot appear in a map clause.
18653 //
18654 if (FD->isBitField()) {
18655 if (!NoDiagnose) {
18656 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
18657 << ME->getSourceRange() << getOpenMPClauseName(CKind);
18658 return false;
18659 }
18660 if (RelevantExpr)
18661 return false;
18662 return Visit(E);
18663 }
18664
18665 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18666 // If the type of a list item is a reference to a type T then the type
18667 // will be considered to be T for all purposes of this clause.
18668 QualType CurType = BaseE->getType().getNonReferenceType();
18669
18670 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
18671 // A list item cannot be a variable that is a member of a structure with
18672 // a union type.
18673 //
18674 if (CurType->isUnionType()) {
18675 if (!NoDiagnose) {
18676 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
18677 << ME->getSourceRange();
18678 return false;
18679 }
18680 return RelevantExpr || Visit(E);
18681 }
18682
18683 // If we got a member expression, we should not expect any array section
18684 // before that:
18685 //
18686 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
18687 // If a list item is an element of a structure, only the rightmost symbol
18688 // of the variable reference can be an array section.
18689 //
18690 AllowUnitySizeArraySection = false;
18691 AllowWholeSizeArraySection = false;
18692
18693 // Record the component.
18694 Components.emplace_back(ME, FD, IsNonContiguous);
18695 return RelevantExpr || Visit(E);
18696 }
18697
18698 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
18699 Expr *E = AE->getBase()->IgnoreParenImpCasts();
18700
18701 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
18702 if (!NoDiagnose) {
18703 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18704 << 0 << AE->getSourceRange();
18705 return false;
18706 }
18707 return RelevantExpr || Visit(E);
18708 }
18709
18710 // If we got an array subscript that express the whole dimension we
18711 // can have any array expressions before. If it only expressing part of
18712 // the dimension, we can only have unitary-size array expressions.
18713 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
18714 E->getType()))
18715 AllowWholeSizeArraySection = false;
18716
18717 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
18718 Expr::EvalResult Result;
18719 if (!AE->getIdx()->isValueDependent() &&
18720 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
18721 !Result.Val.getInt().isNullValue()) {
18722 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18723 diag::err_omp_invalid_map_this_expr);
18724 SemaRef.Diag(AE->getIdx()->getExprLoc(),
18725 diag::note_omp_invalid_subscript_on_this_ptr_map);
18726 }
18727 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((void)0);
18728 RelevantExpr = TE;
18729 }
18730
18731 // Record the component - we don't have any declaration associated.
18732 Components.emplace_back(AE, nullptr, IsNonContiguous);
18733
18734 return RelevantExpr || Visit(E);
18735 }
18736
18737 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
18738 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.")((void)0);
18739 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18740 QualType CurType =
18741 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18742
18743 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18744 // If the type of a list item is a reference to a type T then the type
18745 // will be considered to be T for all purposes of this clause.
18746 if (CurType->isReferenceType())
18747 CurType = CurType->getPointeeType();
18748
18749 bool IsPointer = CurType->isAnyPointerType();
18750
18751 if (!IsPointer && !CurType->isArrayType()) {
18752 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18753 << 0 << OASE->getSourceRange();
18754 return false;
18755 }
18756
18757 bool NotWhole =
18758 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
18759 bool NotUnity =
18760 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
18761
18762 if (AllowWholeSizeArraySection) {
18763 // Any array section is currently allowed. Allowing a whole size array
18764 // section implies allowing a unity array section as well.
18765 //
18766 // If this array section refers to the whole dimension we can still
18767 // accept other array sections before this one, except if the base is a
18768 // pointer. Otherwise, only unitary sections are accepted.
18769 if (NotWhole || IsPointer)
18770 AllowWholeSizeArraySection = false;
18771 } else if (DKind == OMPD_target_update &&
18772 SemaRef.getLangOpts().OpenMP >= 50) {
18773 if (IsPointer && !AllowAnotherPtr)
18774 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
18775 << /*array of unknown bound */ 1;
18776 else
18777 IsNonContiguous = true;
18778 } else if (AllowUnitySizeArraySection && NotUnity) {
18779 // A unity or whole array section is not allowed and that is not
18780 // compatible with the properties of the current array section.
18781 SemaRef.Diag(
18782 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
18783 << OASE->getSourceRange();
18784 return false;
18785 }
18786
18787 if (IsPointer)
18788 AllowAnotherPtr = false;
18789
18790 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
18791 Expr::EvalResult ResultR;
18792 Expr::EvalResult ResultL;
18793 if (!OASE->getLength()->isValueDependent() &&
18794 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
18795 !ResultR.Val.getInt().isOneValue()) {
18796 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18797 diag::err_omp_invalid_map_this_expr);
18798 SemaRef.Diag(OASE->getLength()->getExprLoc(),
18799 diag::note_omp_invalid_length_on_this_ptr_mapping);
18800 }
18801 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
18802 OASE->getLowerBound()->EvaluateAsInt(ResultL,
18803 SemaRef.getASTContext()) &&
18804 !ResultL.Val.getInt().isNullValue()) {
18805 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18806 diag::err_omp_invalid_map_this_expr);
18807 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18808 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
18809 }
18810 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((void)0);
18811 RelevantExpr = TE;
18812 }
18813
18814 // Record the component - we don't have any declaration associated.
18815 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
18816 return RelevantExpr || Visit(E);
18817 }
18818 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
18819 Expr *Base = E->getBase();
18820
18821 // Record the component - we don't have any declaration associated.
18822 Components.emplace_back(E, nullptr, IsNonContiguous);
18823
18824 return Visit(Base->IgnoreParenImpCasts());
18825 }
18826
18827 bool VisitUnaryOperator(UnaryOperator *UO) {
18828 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
18829 UO->getOpcode() != UO_Deref) {
18830 emitErrorMsg();
18831 return false;
18832 }
18833 if (!RelevantExpr) {
18834 // Record the component if haven't found base decl.
18835 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
18836 }
18837 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
18838 }
18839 bool VisitBinaryOperator(BinaryOperator *BO) {
18840 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
18841 emitErrorMsg();
18842 return false;
18843 }
18844
18845 // Pointer arithmetic is the only thing we expect to happen here so after we
18846 // make sure the binary operator is a pointer type, the we only thing need
18847 // to to is to visit the subtree that has the same type as root (so that we
18848 // know the other subtree is just an offset)
18849 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
18850 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
18851 Components.emplace_back(BO, nullptr, false);
18852 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||((void)0)
18853 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&((void)0)
18854 "Either LHS or RHS have base decl inside")((void)0);
18855 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
18856 return RelevantExpr || Visit(LE);
18857 return RelevantExpr || Visit(RE);
18858 }
18859 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
18860 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((void)0);
18861 RelevantExpr = CTE;
18862 Components.emplace_back(CTE, nullptr, IsNonContiguous);
18863 return true;
18864 }
18865 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
18866 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((void)0);
18867 Components.emplace_back(COCE, nullptr, IsNonContiguous);
18868 return true;
18869 }
18870 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
18871 Expr *Source = E->getSourceExpr();
18872 if (!Source) {
18873 emitErrorMsg();
18874 return false;
18875 }
18876 return Visit(Source);
18877 }
18878 bool VisitStmt(Stmt *) {
18879 emitErrorMsg();
18880 return false;
18881 }
18882 const Expr *getFoundBase() const {
18883 return RelevantExpr;
18884 }
18885 explicit MapBaseChecker(
18886 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
18887 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
18888 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
18889 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
18890 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
18891};
18892} // namespace
18893
18894/// Return the expression of the base of the mappable expression or null if it
18895/// cannot be determined and do all the necessary checks to see if the expression
18896/// is valid as a standalone mappable expression. In the process, record all the
18897/// components of the expression.
18898static const Expr *checkMapClauseExpressionBase(
18899 Sema &SemaRef, Expr *E,
18900 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
18901 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
18902 SourceLocation ELoc = E->getExprLoc();
18903 SourceRange ERange = E->getSourceRange();
18904 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
18905 ERange);
18906 if (Checker.Visit(E->IgnoreParens())) {
18907 // Check if the highest dimension array section has length specified
18908 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
18909 (CKind == OMPC_to || CKind == OMPC_from)) {
18910 auto CI = CurComponents.rbegin();
18911 auto CE = CurComponents.rend();
18912 for (; CI != CE; ++CI) {
18913 const auto *OASE =
18914 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
18915 if (!OASE)
18916 continue;
18917 if (OASE && OASE->getLength())
18918 break;
18919 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
18920 << ERange;
18921 }
18922 }
18923 return Checker.getFoundBase();
18924 }
18925 return nullptr;
18926}
18927
18928// Return true if expression E associated with value VD has conflicts with other
18929// map information.
18930static bool checkMapConflicts(
18931 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
18932 bool CurrentRegionOnly,
18933 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
18934 OpenMPClauseKind CKind) {
18935 assert(VD && E)((void)0);
18936 SourceLocation ELoc = E->getExprLoc();
18937 SourceRange ERange = E->getSourceRange();
18938
18939 // In order to easily check the conflicts we need to match each component of
18940 // the expression under test with the components of the expressions that are
18941 // already in the stack.
18942
18943 assert(!CurComponents.empty() && "Map clause expression with no components!")((void)0);
18944 assert(CurComponents.back().getAssociatedDeclaration() == VD &&((void)0)
18945 "Map clause expression with unexpected base!")((void)0);
18946
18947 // Variables to help detecting enclosing problems in data environment nests.
18948 bool IsEnclosedByDataEnvironmentExpr = false;
18949 const Expr *EnclosingExpr = nullptr;
18950
18951 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
18952 VD, CurrentRegionOnly,
18953 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
18954 ERange, CKind, &EnclosingExpr,
18955 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
18956 StackComponents,
18957 OpenMPClauseKind Kind) {
18958 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
18959 return false;
18960 assert(!StackComponents.empty() &&((void)0)
18961 "Map clause expression with no components!")((void)0);
18962 assert(StackComponents.back().getAssociatedDeclaration() == VD &&((void)0)
18963 "Map clause expression with unexpected base!")((void)0);
18964 (void)VD;
18965
18966 // The whole expression in the stack.
18967 const Expr *RE = StackComponents.front().getAssociatedExpression();
18968
18969 // Expressions must start from the same base. Here we detect at which
18970 // point both expressions diverge from each other and see if we can
18971 // detect if the memory referred to both expressions is contiguous and
18972 // do not overlap.
18973 auto CI = CurComponents.rbegin();
18974 auto CE = CurComponents.rend();
18975 auto SI = StackComponents.rbegin();
18976 auto SE = StackComponents.rend();
18977 for (; CI != CE && SI != SE; ++CI, ++SI) {
18978
18979 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
18980 // At most one list item can be an array item derived from a given
18981 // variable in map clauses of the same construct.
18982 if (CurrentRegionOnly &&
18983 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
18984 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
18985 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
18986 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
18987 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
18988 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
18989 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
18990 diag::err_omp_multiple_array_items_in_map_clause)
18991 << CI->getAssociatedExpression()->getSourceRange();
18992 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
18993 diag::note_used_here)
18994 << SI->getAssociatedExpression()->getSourceRange();
18995 return true;
18996 }
18997
18998 // Do both expressions have the same kind?
18999 if (CI->getAssociatedExpression()->getStmtClass() !=
19000 SI->getAssociatedExpression()->getStmtClass())
19001 break;
19002
19003 // Are we dealing with different variables/fields?
19004 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
19005 break;
19006 }
19007 // Check if the extra components of the expressions in the enclosing
19008 // data environment are redundant for the current base declaration.
19009 // If they are, the maps completely overlap, which is legal.
19010 for (; SI != SE; ++SI) {
19011 QualType Type;
19012 if (const auto *ASE =
19013 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
19014 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
19015 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
19016 SI->getAssociatedExpression())) {
19017 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
19018 Type =
19019 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
19020 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
19021 SI->getAssociatedExpression())) {
19022 Type = OASE->getBase()->getType()->getPointeeType();
19023 }
19024 if (Type.isNull() || Type->isAnyPointerType() ||
19025 checkArrayExpressionDoesNotReferToWholeSize(
19026 SemaRef, SI->getAssociatedExpression(), Type))
19027 break;
19028 }
19029
19030 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19031 // List items of map clauses in the same construct must not share
19032 // original storage.
19033 //
19034 // If the expressions are exactly the same or one is a subset of the
19035 // other, it means they are sharing storage.
19036 if (CI == CE && SI == SE) {
19037 if (CurrentRegionOnly) {
19038 if (CKind == OMPC_map) {
19039 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19040 } else {
19041 assert(CKind == OMPC_to || CKind == OMPC_from)((void)0);
19042 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19043 << ERange;
19044 }
19045 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19046 << RE->getSourceRange();
19047 return true;
19048 }
19049 // If we find the same expression in the enclosing data environment,
19050 // that is legal.
19051 IsEnclosedByDataEnvironmentExpr = true;
19052 return false;
19053 }
19054
19055 QualType DerivedType =
19056 std::prev(CI)->getAssociatedDeclaration()->getType();
19057 SourceLocation DerivedLoc =
19058 std::prev(CI)->getAssociatedExpression()->getExprLoc();
19059
19060 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19061 // If the type of a list item is a reference to a type T then the type
19062 // will be considered to be T for all purposes of this clause.
19063 DerivedType = DerivedType.getNonReferenceType();
19064
19065 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
19066 // A variable for which the type is pointer and an array section
19067 // derived from that variable must not appear as list items of map
19068 // clauses of the same construct.
19069 //
19070 // Also, cover one of the cases in:
19071 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19072 // If any part of the original storage of a list item has corresponding
19073 // storage in the device data environment, all of the original storage
19074 // must have corresponding storage in the device data environment.
19075 //
19076 if (DerivedType->isAnyPointerType()) {
19077 if (CI == CE || SI == SE) {
19078 SemaRef.Diag(
19079 DerivedLoc,
19080 diag::err_omp_pointer_mapped_along_with_derived_section)
19081 << DerivedLoc;
19082 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19083 << RE->getSourceRange();
19084 return true;
19085 }
19086 if (CI->getAssociatedExpression()->getStmtClass() !=
19087 SI->getAssociatedExpression()->getStmtClass() ||
19088 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
19089 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
19090 assert(CI != CE && SI != SE)((void)0);
19091 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
19092 << DerivedLoc;
19093 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19094 << RE->getSourceRange();
19095 return true;
19096 }
19097 }
19098
19099 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19100 // List items of map clauses in the same construct must not share
19101 // original storage.
19102 //
19103 // An expression is a subset of the other.
19104 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
19105 if (CKind == OMPC_map) {
19106 if (CI != CE || SI != SE) {
19107 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
19108 // a pointer.
19109 auto Begin =
19110 CI != CE ? CurComponents.begin() : StackComponents.begin();
19111 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
19112 auto It = Begin;
19113 while (It != End && !It->getAssociatedDeclaration())
19114 std::advance(It, 1);
19115 assert(It != End &&((void)0)
19116 "Expected at least one component with the declaration.")((void)0);
19117 if (It != Begin && It->getAssociatedDeclaration()
19118 ->getType()
19119 .getCanonicalType()
19120 ->isAnyPointerType()) {
19121 IsEnclosedByDataEnvironmentExpr = false;
19122 EnclosingExpr = nullptr;
19123 return false;
19124 }
19125 }
19126 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19127 } else {
19128 assert(CKind == OMPC_to || CKind == OMPC_from)((void)0);
19129 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19130 << ERange;
19131 }
19132 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19133 << RE->getSourceRange();
19134 return true;
19135 }
19136
19137 // The current expression uses the same base as other expression in the
19138 // data environment but does not contain it completely.
19139 if (!CurrentRegionOnly && SI != SE)
19140 EnclosingExpr = RE;
19141
19142 // The current expression is a subset of the expression in the data
19143 // environment.
19144 IsEnclosedByDataEnvironmentExpr |=
19145 (!CurrentRegionOnly && CI != CE && SI == SE);
19146
19147 return false;
19148 });
19149
19150 if (CurrentRegionOnly)
19151 return FoundError;
19152
19153 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19154 // If any part of the original storage of a list item has corresponding
19155 // storage in the device data environment, all of the original storage must
19156 // have corresponding storage in the device data environment.
19157 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
19158 // If a list item is an element of a structure, and a different element of
19159 // the structure has a corresponding list item in the device data environment
19160 // prior to a task encountering the construct associated with the map clause,
19161 // then the list item must also have a corresponding list item in the device
19162 // data environment prior to the task encountering the construct.
19163 //
19164 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
19165 SemaRef.Diag(ELoc,
19166 diag::err_omp_original_storage_is_shared_and_does_not_contain)
19167 << ERange;
19168 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
19169 << EnclosingExpr->getSourceRange();
19170 return true;
19171 }
19172
19173 return FoundError;
19174}
19175
19176// Look up the user-defined mapper given the mapper name and mapped type, and
19177// build a reference to it.
19178static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
19179 CXXScopeSpec &MapperIdScopeSpec,
19180 const DeclarationNameInfo &MapperId,
19181 QualType Type,
19182 Expr *UnresolvedMapper) {
19183 if (MapperIdScopeSpec.isInvalid())
19184 return ExprError();
19185 // Get the actual type for the array type.
19186 if (Type->isArrayType()) {
19187 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")((void)0);
19188 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
19189 }
19190 // Find all user-defined mappers with the given MapperId.
19191 SmallVector<UnresolvedSet<8>, 4> Lookups;
19192 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
19193 Lookup.suppressDiagnostics();
19194 if (S) {
19195 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
19196 NamedDecl *D = Lookup.getRepresentativeDecl();
19197 while (S && !S->isDeclScope(D))
19198 S = S->getParent();
19199 if (S)
19200 S = S->getParent();
19201 Lookups.emplace_back();
19202 Lookups.back().append(Lookup.begin(), Lookup.end());
19203 Lookup.clear();
19204 }
19205 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
19206 // Extract the user-defined mappers with the given MapperId.
19207 Lookups.push_back(UnresolvedSet<8>());
19208 for (NamedDecl *D : ULE->decls()) {
19209 auto *DMD = cast<OMPDeclareMapperDecl>(D);
19210 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")((void)0);
19211 Lookups.back().addDecl(DMD);
19212 }
19213 }
19214 // Defer the lookup for dependent types. The results will be passed through
19215 // UnresolvedMapper on instantiation.
19216 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
19217 Type->isInstantiationDependentType() ||
19218 Type->containsUnexpandedParameterPack() ||
19219 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
19220 return !D->isInvalidDecl() &&
19221 (D->getType()->isDependentType() ||
19222 D->getType()->isInstantiationDependentType() ||
19223 D->getType()->containsUnexpandedParameterPack());
19224 })) {
19225 UnresolvedSet<8> URS;
19226 for (const UnresolvedSet<8> &Set : Lookups) {
19227 if (Set.empty())
19228 continue;
19229 URS.append(Set.begin(), Set.end());
19230 }
19231 return UnresolvedLookupExpr::Create(
19232 SemaRef.Context, /*NamingClass=*/nullptr,
19233 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
19234 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
19235 }
19236 SourceLocation Loc = MapperId.getLoc();
19237 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19238 // The type must be of struct, union or class type in C and C++
19239 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
19240 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
19241 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
19242 return ExprError();
19243 }
19244 // Perform argument dependent lookup.
19245 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
19246 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
19247 // Return the first user-defined mapper with the desired type.
19248 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19249 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
19250 if (!D->isInvalidDecl() &&
19251 SemaRef.Context.hasSameType(D->getType(), Type))
19252 return D;
19253 return nullptr;
19254 }))
19255 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19256 // Find the first user-defined mapper with a type derived from the desired
19257 // type.
19258 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19259 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
19260 if (!D->isInvalidDecl() &&
19261 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
19262 !Type.isMoreQualifiedThan(D->getType()))
19263 return D;
19264 return nullptr;
19265 })) {
19266 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19267 /*DetectVirtual=*/false);
19268 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
19269 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19270 VD->getType().getUnqualifiedType()))) {
19271 if (SemaRef.CheckBaseClassAccess(
19272 Loc, VD->getType(), Type, Paths.front(),
19273 /*DiagID=*/0) != Sema::AR_inaccessible) {
19274 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19275 }
19276 }
19277 }
19278 }
19279 // Report error if a mapper is specified, but cannot be found.
19280 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
19281 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
19282 << Type << MapperId.getName();
19283 return ExprError();
19284 }
19285 return ExprEmpty();
19286}
19287
19288namespace {
19289// Utility struct that gathers all the related lists associated with a mappable
19290// expression.
19291struct MappableVarListInfo {
19292 // The list of expressions.
19293 ArrayRef<Expr *> VarList;
19294 // The list of processed expressions.
19295 SmallVector<Expr *, 16> ProcessedVarList;
19296 // The mappble components for each expression.
19297 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
19298 // The base declaration of the variable.
19299 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
19300 // The reference to the user-defined mapper associated with every expression.
19301 SmallVector<Expr *, 16> UDMapperList;
19302
19303 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
19304 // We have a list of components and base declarations for each entry in the
19305 // variable list.
19306 VarComponents.reserve(VarList.size());
19307 VarBaseDeclarations.reserve(VarList.size());
19308 }
19309};
19310}
19311
19312// Check the validity of the provided variable list for the provided clause kind
19313// \a CKind. In the check process the valid expressions, mappable expression
19314// components, variables, and user-defined mappers are extracted and used to
19315// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
19316// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
19317// and \a MapperId are expected to be valid if the clause kind is 'map'.
19318static void checkMappableExpressionList(
19319 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
19320 MappableVarListInfo &MVLI, SourceLocation StartLoc,
19321 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
19322 ArrayRef<Expr *> UnresolvedMappers,
19323 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
19324 bool IsMapTypeImplicit = false) {
19325 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
19326 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&((void)0)
19327 "Unexpected clause kind with mappable expressions!")((void)0);
19328
19329 // If the identifier of user-defined mapper is not specified, it is "default".
19330 // We do not change the actual name in this clause to distinguish whether a
19331 // mapper is specified explicitly, i.e., it is not explicitly specified when
19332 // MapperId.getName() is empty.
19333 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
19334 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
19335 MapperId.setName(DeclNames.getIdentifier(
19336 &SemaRef.getASTContext().Idents.get("default")));
19337 MapperId.setLoc(StartLoc);
19338 }
19339
19340 // Iterators to find the current unresolved mapper expression.
19341 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
19342 bool UpdateUMIt = false;
19343 Expr *UnresolvedMapper = nullptr;
19344
19345 // Keep track of the mappable components and base declarations in this clause.
19346 // Each entry in the list is going to have a list of components associated. We
19347 // record each set of the components so that we can build the clause later on.
19348 // In the end we should have the same amount of declarations and component
19349 // lists.
19350
19351 for (Expr *RE : MVLI.VarList) {
19352 assert(RE && "Null expr in omp to/from/map clause")((void)0);
19353 SourceLocation ELoc = RE->getExprLoc();
19354
19355 // Find the current unresolved mapper expression.
19356 if (UpdateUMIt && UMIt != UMEnd) {
19357 UMIt++;
19358 assert(((void)0)
19359 UMIt != UMEnd &&((void)0)
19360 "Expect the size of UnresolvedMappers to match with that of VarList")((void)0);
19361 }
19362 UpdateUMIt = true;
19363 if (UMIt != UMEnd)
19364 UnresolvedMapper = *UMIt;
19365
19366 const Expr *VE = RE->IgnoreParenLValueCasts();
19367
19368 if (VE->isValueDependent() || VE->isTypeDependent() ||
19369 VE->isInstantiationDependent() ||
19370 VE->containsUnexpandedParameterPack()) {
19371 // Try to find the associated user-defined mapper.
19372 ExprResult ER = buildUserDefinedMapperRef(
19373 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19374 VE->getType().getCanonicalType(), UnresolvedMapper);
19375 if (ER.isInvalid())
19376 continue;
19377 MVLI.UDMapperList.push_back(ER.get());
19378 // We can only analyze this information once the missing information is
19379 // resolved.
19380 MVLI.ProcessedVarList.push_back(RE);
19381 continue;
19382 }
19383
19384 Expr *SimpleExpr = RE->IgnoreParenCasts();
19385
19386 if (!RE->isLValue()) {
19387 if (SemaRef.getLangOpts().OpenMP < 50) {
19388 SemaRef.Diag(
19389 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
19390 << RE->getSourceRange();
19391 } else {
19392 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
19393 << getOpenMPClauseName(CKind) << RE->getSourceRange();
19394 }
19395 continue;
19396 }
19397
19398 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
19399 ValueDecl *CurDeclaration = nullptr;
19400
19401 // Obtain the array or member expression bases if required. Also, fill the
19402 // components array with all the components identified in the process.
19403 const Expr *BE = checkMapClauseExpressionBase(
19404 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
19405 /*NoDiagnose=*/false);
19406 if (!BE)
19407 continue;
19408
19409 assert(!CurComponents.empty() &&((void)0)
19410 "Invalid mappable expression information.")((void)0);
19411
19412 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
19413 // Add store "this" pointer to class in DSAStackTy for future checking
19414 DSAS->addMappedClassesQualTypes(TE->getType());
19415 // Try to find the associated user-defined mapper.
19416 ExprResult ER = buildUserDefinedMapperRef(
19417 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19418 VE->getType().getCanonicalType(), UnresolvedMapper);
19419 if (ER.isInvalid())
19420 continue;
19421 MVLI.UDMapperList.push_back(ER.get());
19422 // Skip restriction checking for variable or field declarations
19423 MVLI.ProcessedVarList.push_back(RE);
19424 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19425 MVLI.VarComponents.back().append(CurComponents.begin(),
19426 CurComponents.end());
19427 MVLI.VarBaseDeclarations.push_back(nullptr);
19428 continue;
19429 }
19430
19431 // For the following checks, we rely on the base declaration which is
19432 // expected to be associated with the last component. The declaration is
19433 // expected to be a variable or a field (if 'this' is being mapped).
19434 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
19435 assert(CurDeclaration && "Null decl on map clause.")((void)0);
19436 assert(((void)0)
19437 CurDeclaration->isCanonicalDecl() &&((void)0)
19438 "Expecting components to have associated only canonical declarations.")((void)0);
19439
19440 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
19441 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
19442
19443 assert((VD || FD) && "Only variables or fields are expected here!")((void)0);
19444 (void)FD;
19445
19446 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
19447 // threadprivate variables cannot appear in a map clause.
19448 // OpenMP 4.5 [2.10.5, target update Construct]
19449 // threadprivate variables cannot appear in a from clause.
19450 if (VD && DSAS->isThreadPrivate(VD)) {
19451 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19452 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
19453 << getOpenMPClauseName(CKind);
19454 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
19455 continue;
19456 }
19457
19458 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19459 // A list item cannot appear in both a map clause and a data-sharing
19460 // attribute clause on the same construct.
19461
19462 // Check conflicts with other map clause expressions. We check the conflicts
19463 // with the current construct separately from the enclosing data
19464 // environment, because the restrictions are different. We only have to
19465 // check conflicts across regions for the map clauses.
19466 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19467 /*CurrentRegionOnly=*/true, CurComponents, CKind))
19468 break;
19469 if (CKind == OMPC_map &&
19470 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
19471 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19472 /*CurrentRegionOnly=*/false, CurComponents, CKind))
19473 break;
19474
19475 // OpenMP 4.5 [2.10.5, target update Construct]
19476 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19477 // If the type of a list item is a reference to a type T then the type will
19478 // be considered to be T for all purposes of this clause.
19479 auto I = llvm::find_if(
19480 CurComponents,
19481 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
19482 return MC.getAssociatedDeclaration();
19483 });
19484 assert(I != CurComponents.end() && "Null decl on map clause.")((void)0);
19485 (void)I;
19486 QualType Type;
19487 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
19488 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
19489 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
19490 if (ASE) {
19491 Type = ASE->getType().getNonReferenceType();
19492 } else if (OASE) {
19493 QualType BaseType =
19494 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19495 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19496 Type = ATy->getElementType();
19497 else
19498 Type = BaseType->getPointeeType();
19499 Type = Type.getNonReferenceType();
19500 } else if (OAShE) {
19501 Type = OAShE->getBase()->getType()->getPointeeType();
19502 } else {
19503 Type = VE->getType();
19504 }
19505
19506 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
19507 // A list item in a to or from clause must have a mappable type.
19508 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19509 // A list item must have a mappable type.
19510 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
19511 DSAS, Type))
19512 continue;
19513
19514 if (CKind == OMPC_map) {
19515 // target enter data
19516 // OpenMP [2.10.2, Restrictions, p. 99]
19517 // A map-type must be specified in all map clauses and must be either
19518 // to or alloc.
19519 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
19520 if (DKind == OMPD_target_enter_data &&
19521 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
19522 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19523 << (IsMapTypeImplicit ? 1 : 0)
19524 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19525 << getOpenMPDirectiveName(DKind);
19526 continue;
19527 }
19528
19529 // target exit_data
19530 // OpenMP [2.10.3, Restrictions, p. 102]
19531 // A map-type must be specified in all map clauses and must be either
19532 // from, release, or delete.
19533 if (DKind == OMPD_target_exit_data &&
19534 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
19535 MapType == OMPC_MAP_delete)) {
19536 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19537 << (IsMapTypeImplicit ? 1 : 0)
19538 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19539 << getOpenMPDirectiveName(DKind);
19540 continue;
19541 }
19542
19543 // target, target data
19544 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
19545 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
19546 // A map-type in a map clause must be to, from, tofrom or alloc
19547 if ((DKind == OMPD_target_data ||
19548 isOpenMPTargetExecutionDirective(DKind)) &&
19549 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
19550 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
19551 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19552 << (IsMapTypeImplicit ? 1 : 0)
19553 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19554 << getOpenMPDirectiveName(DKind);
19555 continue;
19556 }
19557
19558 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
19559 // A list item cannot appear in both a map clause and a data-sharing
19560 // attribute clause on the same construct
19561 //
19562 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
19563 // A list item cannot appear in both a map clause and a data-sharing
19564 // attribute clause on the same construct unless the construct is a
19565 // combined construct.
19566 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
19567 isOpenMPTargetExecutionDirective(DKind)) ||
19568 DKind == OMPD_target)) {
19569 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19570 if (isOpenMPPrivate(DVar.CKind)) {
19571 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19572 << getOpenMPClauseName(DVar.CKind)
19573 << getOpenMPClauseName(OMPC_map)
19574 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
19575 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
19576 continue;
19577 }
19578 }
19579 }
19580
19581 // Try to find the associated user-defined mapper.
19582 ExprResult ER = buildUserDefinedMapperRef(
19583 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19584 Type.getCanonicalType(), UnresolvedMapper);
19585 if (ER.isInvalid())
19586 continue;
19587 MVLI.UDMapperList.push_back(ER.get());
19588
19589 // Save the current expression.
19590 MVLI.ProcessedVarList.push_back(RE);
19591
19592 // Store the components in the stack so that they can be used to check
19593 // against other clauses later on.
19594 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
19595 /*WhereFoundClauseKind=*/OMPC_map);
19596
19597 // Save the components and declaration to create the clause. For purposes of
19598 // the clause creation, any component list that has has base 'this' uses
19599 // null as base declaration.
19600 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19601 MVLI.VarComponents.back().append(CurComponents.begin(),
19602 CurComponents.end());
19603 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
19604 : CurDeclaration);
19605 }
19606}
19607
19608OMPClause *Sema::ActOnOpenMPMapClause(
19609 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
19610 ArrayRef<SourceLocation> MapTypeModifiersLoc,
19611 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19612 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
19613 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19614 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
19615 OpenMPMapModifierKind Modifiers[] = {
19616 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19617 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
19618 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
19619
19620 // Process map-type-modifiers, flag errors for duplicate modifiers.
19621 unsigned Count = 0;
19622 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
19623 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
19624 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
19625 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
19626 continue;
19627 }
19628 assert(Count < NumberOfOMPMapClauseModifiers &&((void)0)
19629 "Modifiers exceed the allowed number of map type modifiers")((void)0);
19630 Modifiers[Count] = MapTypeModifiers[I];
19631 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
19632 ++Count;
19633 }
19634
19635 MappableVarListInfo MVLI(VarList);
19636 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
19637 MapperIdScopeSpec, MapperId, UnresolvedMappers,
19638 MapType, IsMapTypeImplicit);
19639
19640 // We need to produce a map clause even if we don't have variables so that
19641 // other diagnostics related with non-existing map clauses are accurate.
19642 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
19643 MVLI.VarBaseDeclarations, MVLI.VarComponents,
19644 MVLI.UDMapperList, Modifiers, ModifiersLoc,
19645 MapperIdScopeSpec.getWithLocInContext(Context),
19646 MapperId, MapType, IsMapTypeImplicit, MapLoc);
19647}
19648
19649QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
19650 TypeResult ParsedType) {
19651 assert(ParsedType.isUsable())((void)0);
19652
19653 QualType ReductionType = GetTypeFromParser(ParsedType.get());
19654 if (ReductionType.isNull())
19655 return QualType();
19656
19657 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
19658 // A type name in a declare reduction directive cannot be a function type, an
19659 // array type, a reference type, or a type qualified with const, volatile or
19660 // restrict.
19661 if (ReductionType.hasQualifiers()) {
19662 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
19663 return QualType();
19664 }
19665
19666 if (ReductionType->isFunctionType()) {
19667 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
19668 return QualType();
19669 }
19670 if (ReductionType->isReferenceType()) {
19671 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
19672 return QualType();
19673 }
19674 if (ReductionType->isArrayType()) {
19675 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
19676 return QualType();
19677 }
19678 return ReductionType;
19679}
19680
19681Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
19682 Scope *S, DeclContext *DC, DeclarationName Name,
19683 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
19684 AccessSpecifier AS, Decl *PrevDeclInScope) {
19685 SmallVector<Decl *, 8> Decls;
19686 Decls.reserve(ReductionTypes.size());
19687
19688 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
19689 forRedeclarationInCurContext());
19690 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
19691 // A reduction-identifier may not be re-declared in the current scope for the
19692 // same type or for a type that is compatible according to the base language
19693 // rules.
19694 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19695 OMPDeclareReductionDecl *PrevDRD = nullptr;
19696 bool InCompoundScope = true;
19697 if (S != nullptr) {
19698 // Find previous declaration with the same name not referenced in other
19699 // declarations.
19700 FunctionScopeInfo *ParentFn = getEnclosingFunction();
19701 InCompoundScope =
19702 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19703 LookupName(Lookup, S);
19704 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19705 /*AllowInlineNamespace=*/false);
19706 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
19707 LookupResult::Filter Filter = Lookup.makeFilter();
19708 while (Filter.hasNext()) {
19709 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
19710 if (InCompoundScope) {
19711 auto I = UsedAsPrevious.find(PrevDecl);
19712 if (I == UsedAsPrevious.end())
19713 UsedAsPrevious[PrevDecl] = false;
19714 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
19715 UsedAsPrevious[D] = true;
19716 }
19717 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19718 PrevDecl->getLocation();
19719 }
19720 Filter.done();
19721 if (InCompoundScope) {
19722 for (const auto &PrevData : UsedAsPrevious) {
19723 if (!PrevData.second) {
19724 PrevDRD = PrevData.first;
19725 break;
19726 }
19727 }
19728 }
19729 } else if (PrevDeclInScope != nullptr) {
19730 auto *PrevDRDInScope = PrevDRD =
19731 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
19732 do {
19733 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
19734 PrevDRDInScope->getLocation();
19735 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
19736 } while (PrevDRDInScope != nullptr);
19737 }
19738 for (const auto &TyData : ReductionTypes) {
19739 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
19740 bool Invalid = false;
19741 if (I != PreviousRedeclTypes.end()) {
19742 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
19743 << TyData.first;
19744 Diag(I->second, diag::note_previous_definition);
19745 Invalid = true;
19746 }
19747 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
19748 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
19749 Name, TyData.first, PrevDRD);
19750 DC->addDecl(DRD);
19751 DRD->setAccess(AS);
19752 Decls.push_back(DRD);
19753 if (Invalid)
19754 DRD->setInvalidDecl();
19755 else
19756 PrevDRD = DRD;
19757 }
19758
19759 return DeclGroupPtrTy::make(
19760 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
19761}
19762
19763void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
19764 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19765
19766 // Enter new function scope.
19767 PushFunctionScope();
19768 setFunctionHasBranchProtectedScope();
19769 getCurFunction()->setHasOMPDeclareReductionCombiner();
19770
19771 if (S != nullptr)
19772 PushDeclContext(S, DRD);
19773 else
19774 CurContext = DRD;
19775
19776 PushExpressionEvaluationContext(
19777 ExpressionEvaluationContext::PotentiallyEvaluated);
19778
19779 QualType ReductionType = DRD->getType();
19780 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
19781 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
19782 // uses semantics of argument handles by value, but it should be passed by
19783 // reference. C lang does not support references, so pass all parameters as
19784 // pointers.
19785 // Create 'T omp_in;' variable.
19786 VarDecl *OmpInParm =
19787 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
19788 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
19789 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
19790 // uses semantics of argument handles by value, but it should be passed by
19791 // reference. C lang does not support references, so pass all parameters as
19792 // pointers.
19793 // Create 'T omp_out;' variable.
19794 VarDecl *OmpOutParm =
19795 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
19796 if (S != nullptr) {
19797 PushOnScopeChains(OmpInParm, S);
19798 PushOnScopeChains(OmpOutParm, S);
19799 } else {
19800 DRD->addDecl(OmpInParm);
19801 DRD->addDecl(OmpOutParm);
19802 }
19803 Expr *InE =
19804 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
19805 Expr *OutE =
19806 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
19807 DRD->setCombinerData(InE, OutE);
19808}
19809
19810void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
19811 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19812 DiscardCleanupsInEvaluationContext();
19813 PopExpressionEvaluationContext();
19814
19815 PopDeclContext();
19816 PopFunctionScopeInfo();
19817
19818 if (Combiner != nullptr)
19819 DRD->setCombiner(Combiner);
19820 else
19821 DRD->setInvalidDecl();
19822}
19823
19824VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
19825 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19826
19827 // Enter new function scope.
19828 PushFunctionScope();
19829 setFunctionHasBranchProtectedScope();
19830
19831 if (S != nullptr)
19832 PushDeclContext(S, DRD);
19833 else
19834 CurContext = DRD;
19835
19836 PushExpressionEvaluationContext(
19837 ExpressionEvaluationContext::PotentiallyEvaluated);
19838
19839 QualType ReductionType = DRD->getType();
19840 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
19841 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
19842 // uses semantics of argument handles by value, but it should be passed by
19843 // reference. C lang does not support references, so pass all parameters as
19844 // pointers.
19845 // Create 'T omp_priv;' variable.
19846 VarDecl *OmpPrivParm =
19847 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
19848 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
19849 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
19850 // uses semantics of argument handles by value, but it should be passed by
19851 // reference. C lang does not support references, so pass all parameters as
19852 // pointers.
19853 // Create 'T omp_orig;' variable.
19854 VarDecl *OmpOrigParm =
19855 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
19856 if (S != nullptr) {
19857 PushOnScopeChains(OmpPrivParm, S);
19858 PushOnScopeChains(OmpOrigParm, S);
19859 } else {
19860 DRD->addDecl(OmpPrivParm);
19861 DRD->addDecl(OmpOrigParm);
19862 }
19863 Expr *OrigE =
19864 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
19865 Expr *PrivE =
19866 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
19867 DRD->setInitializerData(OrigE, PrivE);
19868 return OmpPrivParm;
19869}
19870
19871void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
19872 VarDecl *OmpPrivParm) {
19873 auto *DRD = cast<OMPDeclareReductionDecl>(D);
19874 DiscardCleanupsInEvaluationContext();
19875 PopExpressionEvaluationContext();
19876
19877 PopDeclContext();
19878 PopFunctionScopeInfo();
19879
19880 if (Initializer != nullptr) {
19881 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
19882 } else if (OmpPrivParm->hasInit()) {
19883 DRD->setInitializer(OmpPrivParm->getInit(),
19884 OmpPrivParm->isDirectInit()
19885 ? OMPDeclareReductionDecl::DirectInit
19886 : OMPDeclareReductionDecl::CopyInit);
19887 } else {
19888 DRD->setInvalidDecl();
19889 }
19890}
19891
19892Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
19893 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
19894 for (Decl *D : DeclReductions.get()) {
19895 if (IsValid) {
19896 if (S)
19897 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
19898 /*AddToContext=*/false);
19899 } else {
19900 D->setInvalidDecl();
19901 }
19902 }
19903 return DeclReductions;
19904}
19905
19906TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
19907 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
19908 QualType T = TInfo->getType();
19909 if (D.isInvalidType())
19910 return true;
19911
19912 if (getLangOpts().CPlusPlus) {
19913 // Check that there are no default arguments (C++ only).
19914 CheckExtraCXXDefaultArguments(D);
19915 }
19916
19917 return CreateParsedType(T, TInfo);
19918}
19919
19920QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
19921 TypeResult ParsedType) {
19922 assert(ParsedType.isUsable() && "Expect usable parsed mapper type")((void)0);
19923
19924 QualType MapperType = GetTypeFromParser(ParsedType.get());
19925 assert(!MapperType.isNull() && "Expect valid mapper type")((void)0);
19926
19927 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19928 // The type must be of struct, union or class type in C and C++
19929 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
19930 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
19931 return QualType();
19932 }
19933 return MapperType;
19934}
19935
19936Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
19937 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
19938 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
19939 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
19940 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
19941 forRedeclarationInCurContext());
19942 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19943 // A mapper-identifier may not be redeclared in the current scope for the
19944 // same type or for a type that is compatible according to the base language
19945 // rules.
19946 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19947 OMPDeclareMapperDecl *PrevDMD = nullptr;
19948 bool InCompoundScope = true;
19949 if (S != nullptr) {
19950 // Find previous declaration with the same name not referenced in other
19951 // declarations.
19952 FunctionScopeInfo *ParentFn = getEnclosingFunction();
19953 InCompoundScope =
19954 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19955 LookupName(Lookup, S);
19956 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19957 /*AllowInlineNamespace=*/false);
19958 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
19959 LookupResult::Filter Filter = Lookup.makeFilter();
19960 while (Filter.hasNext()) {
19961 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
19962 if (InCompoundScope) {
19963 auto I = UsedAsPrevious.find(PrevDecl);
19964 if (I == UsedAsPrevious.end())
19965 UsedAsPrevious[PrevDecl] = false;
19966 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
19967 UsedAsPrevious[D] = true;
19968 }
19969 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19970 PrevDecl->getLocation();
19971 }
19972 Filter.done();
19973 if (InCompoundScope) {
19974 for (const auto &PrevData : UsedAsPrevious) {
19975 if (!PrevData.second) {
19976 PrevDMD = PrevData.first;
19977 break;
19978 }
19979 }
19980 }
19981 } else if (PrevDeclInScope) {
19982 auto *PrevDMDInScope = PrevDMD =
19983 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
19984 do {
19985 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
19986 PrevDMDInScope->getLocation();
19987 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
19988 } while (PrevDMDInScope != nullptr);
19989 }
19990 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
19991 bool Invalid = false;
19992 if (I != PreviousRedeclTypes.end()) {
19993 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
19994 << MapperType << Name;
19995 Diag(I->second, diag::note_previous_definition);
19996 Invalid = true;
19997 }
19998 // Build expressions for implicit maps of data members with 'default'
19999 // mappers.
20000 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
20001 Clauses.end());
20002 if (LangOpts.OpenMP >= 50)
20003 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ClausesWithImplicit);
20004 auto *DMD =
20005 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
20006 ClausesWithImplicit, PrevDMD);
20007 if (S)
20008 PushOnScopeChains(DMD, S);
20009 else
20010 DC->addDecl(DMD);
20011 DMD->setAccess(AS);
20012 if (Invalid)
20013 DMD->setInvalidDecl();
20014
20015 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
20016 VD->setDeclContext(DMD);
20017 VD->setLexicalDeclContext(DMD);
20018 DMD->addDecl(VD);
20019 DMD->setMapperVarRef(MapperVarRef);
20020
20021 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
20022}
20023
20024ExprResult
20025Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
20026 SourceLocation StartLoc,
20027 DeclarationName VN) {
20028 TypeSourceInfo *TInfo =
20029 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
20030 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
20031 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
20032 MapperType, TInfo, SC_None);
20033 if (S)
20034 PushOnScopeChains(VD, S, /*AddToContext=*/false);
20035 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
20036 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
20037 return E;
20038}
20039
20040bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
20041 assert(LangOpts.OpenMP && "Expected OpenMP mode.")((void)0);
20042 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
20043 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
20044 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
20045 return true;
20046 if (VD->isUsableInConstantExpressions(Context))
20047 return true;
20048 return false;
20049 }
20050 return true;
20051}
20052
20053const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
20054 assert(LangOpts.OpenMP && "Expected OpenMP mode.")((void)0);
20055 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
20056}
20057
20058OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
20059 SourceLocation StartLoc,
20060 SourceLocation LParenLoc,
20061 SourceLocation EndLoc) {
20062 Expr *ValExpr = NumTeams;
20063 Stmt *HelperValStmt = nullptr;
20064
20065 // OpenMP [teams Constrcut, Restrictions]
20066 // The num_teams expression must evaluate to a positive integer value.
20067 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
20068 /*StrictlyPositive=*/true))
20069 return nullptr;
20070
20071 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
20072 OpenMPDirectiveKind CaptureRegion =
20073 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
20074 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20075 ValExpr = MakeFullExpr(ValExpr).get();
20076 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20077 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20078 HelperValStmt = buildPreInits(Context, Captures);
20079 }
20080
20081 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
20082 StartLoc, LParenLoc, EndLoc);
20083}
20084
20085OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
20086 SourceLocation StartLoc,
20087 SourceLocation LParenLoc,
20088 SourceLocation EndLoc) {
20089 Expr *ValExpr = ThreadLimit;
20090 Stmt *HelperValStmt = nullptr;
20091
20092 // OpenMP [teams Constrcut, Restrictions]
20093 // The thread_limit expression must evaluate to a positive integer value.
20094 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
20095 /*StrictlyPositive=*/true))
20096 return nullptr;
20097
20098 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
20099 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
20100 DKind, OMPC_thread_limit, LangOpts.OpenMP);
20101 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20102 ValExpr = MakeFullExpr(ValExpr).get();
20103 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20104 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20105 HelperValStmt = buildPreInits(Context, Captures);
20106 }
20107
20108 return new (Context) OMPThreadLimitClause(
20109 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
20110}
20111
20112OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
20113 SourceLocation StartLoc,
20114 SourceLocation LParenLoc,
20115 SourceLocation EndLoc) {
20116 Expr *ValExpr = Priority;
20117 Stmt *HelperValStmt = nullptr;
20118 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20119
20120 // OpenMP [2.9.1, task Constrcut]
20121 // The priority-value is a non-negative numerical scalar expression.
20122 if (!isNonNegativeIntegerValue(
20123 ValExpr, *this, OMPC_priority,
20124 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
20125 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20126 return nullptr;
20127
20128 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
20129 StartLoc, LParenLoc, EndLoc);
20130}
20131
20132OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
20133 SourceLocation StartLoc,
20134 SourceLocation LParenLoc,
20135 SourceLocation EndLoc) {
20136 Expr *ValExpr = Grainsize;
20137 Stmt *HelperValStmt = nullptr;
20138 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20139
20140 // OpenMP [2.9.2, taskloop Constrcut]
20141 // The parameter of the grainsize clause must be a positive integer
20142 // expression.
20143 if (!isNonNegativeIntegerValue(
20144 ValExpr, *this, OMPC_grainsize,
20145 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20146 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20147 return nullptr;
20148
20149 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
20150 StartLoc, LParenLoc, EndLoc);
20151}
20152
20153OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
20154 SourceLocation StartLoc,
20155 SourceLocation LParenLoc,
20156 SourceLocation EndLoc) {
20157 Expr *ValExpr = NumTasks;
20158 Stmt *HelperValStmt = nullptr;
20159 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20160
20161 // OpenMP [2.9.2, taskloop Constrcut]
20162 // The parameter of the num_tasks clause must be a positive integer
20163 // expression.
20164 if (!isNonNegativeIntegerValue(
20165 ValExpr, *this, OMPC_num_tasks,
20166 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20167 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20168 return nullptr;
20169
20170 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
20171 StartLoc, LParenLoc, EndLoc);
20172}
20173
20174OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
20175 SourceLocation LParenLoc,
20176 SourceLocation EndLoc) {
20177 // OpenMP [2.13.2, critical construct, Description]
20178 // ... where hint-expression is an integer constant expression that evaluates
20179 // to a valid lock hint.
20180 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
20181 if (HintExpr.isInvalid())
20182 return nullptr;
20183 return new (Context)
20184 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
20185}
20186
20187/// Tries to find omp_event_handle_t type.
20188static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
20189 DSAStackTy *Stack) {
20190 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
20191 if (!OMPEventHandleT.isNull())
20192 return true;
20193 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
20194 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20195 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20196 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
20197 return false;
20198 }
20199 Stack->setOMPEventHandleT(PT.get());
20200 return true;
20201}
20202
20203OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
20204 SourceLocation LParenLoc,
20205 SourceLocation EndLoc) {
20206 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
20207 !Evt->isInstantiationDependent() &&
20208 !Evt->containsUnexpandedParameterPack()) {
20209 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
20210 return nullptr;
20211 // OpenMP 5.0, 2.10.1 task Construct.
20212 // event-handle is a variable of the omp_event_handle_t type.
20213 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
20214 if (!Ref) {
20215 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20216 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20217 return nullptr;
20218 }
20219 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
20220 if (!VD) {
20221 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20222 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20223 return nullptr;
20224 }
20225 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
20226 VD->getType()) ||
20227 VD->getType().isConstant(Context)) {
20228 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20229 << "omp_event_handle_t" << 1 << VD->getType()
20230 << Evt->getSourceRange();
20231 return nullptr;
20232 }
20233 // OpenMP 5.0, 2.10.1 task Construct
20234 // [detach clause]... The event-handle will be considered as if it was
20235 // specified on a firstprivate clause.
20236 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
20237 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
20238 DVar.RefExpr) {
20239 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
20240 << getOpenMPClauseName(DVar.CKind)
20241 << getOpenMPClauseName(OMPC_firstprivate);
20242 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
20243 return nullptr;
20244 }
20245 }
20246
20247 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
20248}
20249
20250OMPClause *Sema::ActOnOpenMPDistScheduleClause(
20251 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
20252 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
20253 SourceLocation EndLoc) {
20254 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
20255 std::string Values;
20256 Values += "'";
20257 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
20258 Values += "'";
20259 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20260 << Values << getOpenMPClauseName(OMPC_dist_schedule);
20261 return nullptr;
20262 }
20263 Expr *ValExpr = ChunkSize;
20264 Stmt *HelperValStmt = nullptr;
20265 if (ChunkSize) {
20266 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
20267 !ChunkSize->isInstantiationDependent() &&
20268 !ChunkSize->containsUnexpandedParameterPack()) {
20269 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
20270 ExprResult Val =
20271 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
20272 if (Val.isInvalid())
20273 return nullptr;
20274
20275 ValExpr = Val.get();
20276
20277 // OpenMP [2.7.1, Restrictions]
20278 // chunk_size must be a loop invariant integer expression with a positive
20279 // value.
20280 if (Optional<llvm::APSInt> Result =
20281 ValExpr->getIntegerConstantExpr(Context)) {
20282 if (Result->isSigned() && !Result->isStrictlyPositive()) {
20283 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
20284 << "dist_schedule" << ChunkSize->getSourceRange();
20285 return nullptr;
20286 }
20287 } else if (getOpenMPCaptureRegionForClause(
20288 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
20289 LangOpts.OpenMP) != OMPD_unknown &&
20290 !CurContext->isDependentContext()) {
20291 ValExpr = MakeFullExpr(ValExpr).get();
20292 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20293 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20294 HelperValStmt = buildPreInits(Context, Captures);
20295 }
20296 }
20297 }
20298
20299 return new (Context)
20300 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
20301 Kind, ValExpr, HelperValStmt);
20302}
20303
20304OMPClause *Sema::ActOnOpenMPDefaultmapClause(
20305 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
20306 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
20307 SourceLocation KindLoc, SourceLocation EndLoc) {
20308 if (getLangOpts().OpenMP < 50) {
20309 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
20310 Kind != OMPC_DEFAULTMAP_scalar) {
20311 std::string Value;
20312 SourceLocation Loc;
20313 Value += "'";
20314 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
20315 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20316 OMPC_DEFAULTMAP_MODIFIER_tofrom);
20317 Loc = MLoc;
20318 } else {
20319 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20320 OMPC_DEFAULTMAP_scalar);
20321 Loc = KindLoc;
20322 }
20323 Value += "'";
20324 Diag(Loc, diag::err_omp_unexpected_clause_value)
20325 << Value << getOpenMPClauseName(OMPC_defaultmap);
20326 return nullptr;
20327 }
20328 } else {
20329 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
20330 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
20331 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
20332 if (!isDefaultmapKind || !isDefaultmapModifier) {
20333 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
20334 if (LangOpts.OpenMP == 50) {
20335 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
20336 "'firstprivate', 'none', 'default'";
20337 if (!isDefaultmapKind && isDefaultmapModifier) {
20338 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20339 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20340 } else if (isDefaultmapKind && !isDefaultmapModifier) {
20341 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20342 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20343 } else {
20344 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20345 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20346 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20347 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20348 }
20349 } else {
20350 StringRef ModifierValue =
20351 "'alloc', 'from', 'to', 'tofrom', "
20352 "'firstprivate', 'none', 'default', 'present'";
20353 if (!isDefaultmapKind && isDefaultmapModifier) {
20354 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20355 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20356 } else if (isDefaultmapKind && !isDefaultmapModifier) {
20357 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20358 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20359 } else {
20360 Diag(MLoc, diag::err_omp_unexpected_clause_value)
20361 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20362 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20363 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20364 }
20365 }
20366 return nullptr;
20367 }
20368
20369 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
20370 // At most one defaultmap clause for each category can appear on the
20371 // directive.
20372 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
20373 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
20374 return nullptr;
20375 }
20376 }
20377 if (Kind == OMPC_DEFAULTMAP_unknown) {
20378 // Variable category is not specified - mark all categories.
20379 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
20380 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
20381 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
20382 } else {
20383 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
20384 }
20385
20386 return new (Context)
20387 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
20388}
20389
20390bool Sema::ActOnStartOpenMPDeclareTargetContext(
20391 DeclareTargetContextInfo &DTCI) {
20392 DeclContext *CurLexicalContext = getCurLexicalContext();
20393 if (!CurLexicalContext->isFileContext() &&
20394 !CurLexicalContext->isExternCContext() &&
20395 !CurLexicalContext->isExternCXXContext() &&
20396 !isa<CXXRecordDecl>(CurLexicalContext) &&
20397 !isa<ClassTemplateDecl>(CurLexicalContext) &&
20398 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
20399 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
20400 Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
20401 return false;
20402 }
20403 DeclareTargetNesting.push_back(DTCI);
20404 return true;
20405}
20406
20407const Sema::DeclareTargetContextInfo
20408Sema::ActOnOpenMPEndDeclareTargetDirective() {
20409 assert(!DeclareTargetNesting.empty() &&((void)0)
20410 "check isInOpenMPDeclareTargetContext() first!")((void)0);
20411 return DeclareTargetNesting.pop_back_val();
20412}
20413
20414void Sema::ActOnFinishedOpenMPDeclareTargetContext(
20415 DeclareTargetContextInfo &DTCI) {
20416 for (auto &It : DTCI.ExplicitlyMapped)
20417 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT,
20418 DTCI.DT);
20419}
20420
20421NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
20422 CXXScopeSpec &ScopeSpec,
20423 const DeclarationNameInfo &Id) {
20424 LookupResult Lookup(*this, Id, LookupOrdinaryName);
20425 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
20426
20427 if (Lookup.isAmbiguous())
20428 return nullptr;
20429 Lookup.suppressDiagnostics();
20430
20431 if (!Lookup.isSingleResult()) {
20432 VarOrFuncDeclFilterCCC CCC(*this);
20433 if (TypoCorrection Corrected =
20434 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
20435 CTK_ErrorRecovery)) {
20436 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
20437 << Id.getName());
20438 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
20439 return nullptr;
20440 }
20441
20442 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
20443 return nullptr;
20444 }
20445
20446 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
20447 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
20448 !isa<FunctionTemplateDecl>(ND)) {
20449 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
20450 return nullptr;
20451 }
20452 return ND;
20453}
20454
20455void Sema::ActOnOpenMPDeclareTargetName(
20456 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
20457 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
20458 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||((void)0)
20459 isa<FunctionTemplateDecl>(ND)) &&((void)0)
20460 "Expected variable, function or function template.")((void)0);
20461
20462 // Diagnose marking after use as it may lead to incorrect diagnosis and
20463 // codegen.
20464 if (LangOpts.OpenMP >= 50 &&
20465 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
20466 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
20467
20468 // Explicit declare target lists have precedence.
20469 const unsigned Level = -1;
20470
20471 auto *VD = cast<ValueDecl>(ND);
20472 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20473 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20474 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DT &&
20475 ActiveAttr.getValue()->getLevel() == Level) {
20476 Diag(Loc, diag::err_omp_device_type_mismatch)
20477 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
20478 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
20479 ActiveAttr.getValue()->getDevType());
20480 return;
20481 }
20482 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
20483 ActiveAttr.getValue()->getLevel() == Level) {
20484 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
20485 return;
20486 }
20487
20488 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
20489 return;
20490
20491 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, Level,
20492 SourceRange(Loc, Loc));
20493 ND->addAttr(A);
20494 if (ASTMutationListener *ML = Context.getASTMutationListener())
20495 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
20496 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
20497}
20498
20499static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
20500 Sema &SemaRef, Decl *D) {
20501 if (!D || !isa<VarDecl>(D))
20502 return;
20503 auto *VD = cast<VarDecl>(D);
20504 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
20505 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
20506 if (SemaRef.LangOpts.OpenMP >= 50 &&
20507 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
20508 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
20509 VD->hasGlobalStorage()) {
20510 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
20511 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
20512 // If a lambda declaration and definition appears between a
20513 // declare target directive and the matching end declare target
20514 // directive, all variables that are captured by the lambda
20515 // expression must also appear in a to clause.
20516 SemaRef.Diag(VD->getLocation(),
20517 diag::err_omp_lambda_capture_in_declare_target_not_to);
20518 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
20519 << VD << 0 << SR;
20520 return;
20521 }
20522 }
20523 if (MapTy.hasValue())
20524 return;
20525 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
20526 SemaRef.Diag(SL, diag::note_used_here) << SR;
20527}
20528
20529static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
20530 Sema &SemaRef, DSAStackTy *Stack,
20531 ValueDecl *VD) {
20532 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
20533 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
20534 /*FullCheck=*/false);
20535}
20536
20537void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
20538 SourceLocation IdLoc) {
20539 if (!D || D->isInvalidDecl())
20540 return;
20541 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
20542 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
20543 if (auto *VD = dyn_cast<VarDecl>(D)) {
20544 // Only global variables can be marked as declare target.
20545 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
20546 !VD->isStaticDataMember())
20547 return;
20548 // 2.10.6: threadprivate variable cannot appear in a declare target
20549 // directive.
20550 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
20551 Diag(SL, diag::err_omp_threadprivate_in_target);
20552 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
20553 return;
20554 }
20555 }
20556 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
20557 D = FTD->getTemplatedDecl();
20558 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
20559 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
20560 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
20561 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
20562 Diag(IdLoc, diag::err_omp_function_in_link_clause);
20563 Diag(FD->getLocation(), diag::note_defined_here) << FD;
20564 return;
20565 }
20566 }
20567 if (auto *VD = dyn_cast<ValueDecl>(D)) {
20568 // Problem if any with var declared with incomplete type will be reported
20569 // as normal, so no need to check it here.
20570 if ((E || !VD->getType()->isIncompleteType()) &&
20571 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
20572 return;
20573 if (!E && isInOpenMPDeclareTargetContext()) {
20574 // Checking declaration inside declare target region.
20575 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
20576 isa<FunctionTemplateDecl>(D)) {
20577 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20578 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20579 unsigned Level = DeclareTargetNesting.size();
20580 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
20581 return;
20582 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
20583 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
20584 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, Level,
20585 SourceRange(DTCI.Loc, DTCI.Loc));
20586 D->addAttr(A);
20587 if (ASTMutationListener *ML = Context.getASTMutationListener())
20588 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
20589 }
20590 return;
20591 }
20592 }
20593 if (!E)
20594 return;
20595 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
20596}
20597
20598OMPClause *Sema::ActOnOpenMPToClause(
20599 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20600 ArrayRef<SourceLocation> MotionModifiersLoc,
20601 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20602 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20603 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20604 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20605 OMPC_MOTION_MODIFIER_unknown};
20606 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20607
20608 // Process motion-modifiers, flag errors for duplicate modifiers.
20609 unsigned Count = 0;
20610 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20611 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20612 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20613 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20614 continue;
20615 }
20616 assert(Count < NumberOfOMPMotionModifiers &&((void)0)
20617 "Modifiers exceed the allowed number of motion modifiers")((void)0);
20618 Modifiers[Count] = MotionModifiers[I];
20619 ModifiersLoc[Count] = MotionModifiersLoc[I];
20620 ++Count;
20621 }
20622
20623 MappableVarListInfo MVLI(VarList);
20624 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
20625 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20626 if (MVLI.ProcessedVarList.empty())
20627 return nullptr;
20628
20629 return OMPToClause::Create(
20630 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20631 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20632 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20633}
20634
20635OMPClause *Sema::ActOnOpenMPFromClause(
20636 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20637 ArrayRef<SourceLocation> MotionModifiersLoc,
20638 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20639 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20640 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20641 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20642 OMPC_MOTION_MODIFIER_unknown};
20643 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20644
20645 // Process motion-modifiers, flag errors for duplicate modifiers.
20646 unsigned Count = 0;
20647 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20648 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20649 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20650 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20651 continue;
20652 }
20653 assert(Count < NumberOfOMPMotionModifiers &&((void)0)
20654 "Modifiers exceed the allowed number of motion modifiers")((void)0);
20655 Modifiers[Count] = MotionModifiers[I];
20656 ModifiersLoc[Count] = MotionModifiersLoc[I];
20657 ++Count;
20658 }
20659
20660 MappableVarListInfo MVLI(VarList);
20661 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
20662 MapperIdScopeSpec, MapperId, UnresolvedMappers);
20663 if (MVLI.ProcessedVarList.empty())
20664 return nullptr;
20665
20666 return OMPFromClause::Create(
20667 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20668 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20669 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20670}
20671
20672OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
20673 const OMPVarListLocTy &Locs) {
20674 MappableVarListInfo MVLI(VarList);
20675 SmallVector<Expr *, 8> PrivateCopies;
20676 SmallVector<Expr *, 8> Inits;
20677
20678 for (Expr *RefExpr : VarList) {
20679 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")((void)0);
20680 SourceLocation ELoc;
20681 SourceRange ERange;
20682 Expr *SimpleRefExpr = RefExpr;
20683 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20684 if (Res.second) {
20685 // It will be analyzed later.
20686 MVLI.ProcessedVarList.push_back(RefExpr);
20687 PrivateCopies.push_back(nullptr);
20688 Inits.push_back(nullptr);
20689 }
20690 ValueDecl *D = Res.first;
20691 if (!D)
20692 continue;
20693
20694 QualType Type = D->getType();
20695 Type = Type.getNonReferenceType().getUnqualifiedType();
20696
20697 auto *VD = dyn_cast<VarDecl>(D);
20698
20699 // Item should be a pointer or reference to pointer.
20700 if (!Type->isPointerType()) {
20701 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
20702 << 0 << RefExpr->getSourceRange();
20703 continue;
20704 }
20705
20706 // Build the private variable and the expression that refers to it.
20707 auto VDPrivate =
20708 buildVarDecl(*this, ELoc, Type, D->getName(),
20709 D->hasAttrs() ? &D->getAttrs() : nullptr,
20710 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20711 if (VDPrivate->isInvalidDecl())
20712 continue;
20713
20714 CurContext->addDecl(VDPrivate);
20715 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
20716 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
20717
20718 // Add temporary variable to initialize the private copy of the pointer.
20719 VarDecl *VDInit =
20720 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
20721 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
20722 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
20723 AddInitializerToDecl(VDPrivate,
20724 DefaultLvalueConversion(VDInitRefExpr).get(),
20725 /*DirectInit=*/false);
20726
20727 // If required, build a capture to implement the privatization initialized
20728 // with the current list item value.
20729 DeclRefExpr *Ref = nullptr;
20730 if (!VD)
20731 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20732 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20733 PrivateCopies.push_back(VDPrivateRefExpr);
20734 Inits.push_back(VDInitRefExpr);
20735
20736 // We need to add a data sharing attribute for this variable to make sure it
20737 // is correctly captured. A variable that shows up in a use_device_ptr has
20738 // similar properties of a first private variable.
20739 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20740
20741 // Create a mappable component for the list item. List items in this clause
20742 // only need a component.
20743 MVLI.VarBaseDeclarations.push_back(D);
20744 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20745 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
20746 /*IsNonContiguous=*/false);
20747 }
20748
20749 if (MVLI.ProcessedVarList.empty())
20750 return nullptr;
20751
20752 return OMPUseDevicePtrClause::Create(
20753 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
20754 MVLI.VarBaseDeclarations, MVLI.VarComponents);
20755}
20756
20757OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
20758 const OMPVarListLocTy &Locs) {
20759 MappableVarListInfo MVLI(VarList);
20760
20761 for (Expr *RefExpr : VarList) {
20762 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")((void)0);
20763 SourceLocation ELoc;
20764 SourceRange ERange;
20765 Expr *SimpleRefExpr = RefExpr;
20766 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20767 /*AllowArraySection=*/true);
20768 if (Res.second) {
20769 // It will be analyzed later.
20770 MVLI.ProcessedVarList.push_back(RefExpr);
20771 }
20772 ValueDecl *D = Res.first;
20773 if (!D)
20774 continue;
20775 auto *VD = dyn_cast<VarDecl>(D);
20776
20777 // If required, build a capture to implement the privatization initialized
20778 // with the current list item value.
20779 DeclRefExpr *Ref = nullptr;
20780 if (!VD)
20781 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20782 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20783
20784 // We need to add a data sharing attribute for this variable to make sure it
20785 // is correctly captured. A variable that shows up in a use_device_addr has
20786 // similar properties of a first private variable.
20787 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20788
20789 // Create a mappable component for the list item. List items in this clause
20790 // only need a component.
20791 MVLI.VarBaseDeclarations.push_back(D);
20792 MVLI.VarComponents.emplace_back();
20793 Expr *Component = SimpleRefExpr;
20794 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
20795 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
20796 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
20797 MVLI.VarComponents.back().emplace_back(Component, D,
20798 /*IsNonContiguous=*/false);
20799 }
20800
20801 if (MVLI.ProcessedVarList.empty())
20802 return nullptr;
20803
20804 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20805 MVLI.VarBaseDeclarations,
20806 MVLI.VarComponents);
20807}
20808
20809OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
20810 const OMPVarListLocTy &Locs) {
20811 MappableVarListInfo MVLI(VarList);
20812 for (Expr *RefExpr : VarList) {
20813 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")((void)0);
20814 SourceLocation ELoc;
20815 SourceRange ERange;
20816 Expr *SimpleRefExpr = RefExpr;
20817 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20818 if (Res.second) {
20819 // It will be analyzed later.
20820 MVLI.ProcessedVarList.push_back(RefExpr);
20821 }
20822 ValueDecl *D = Res.first;
20823 if (!D)
20824 continue;
20825
20826 QualType Type = D->getType();
20827 // item should be a pointer or array or reference to pointer or array
20828 if (!Type.getNonReferenceType()->isPointerType() &&
20829 !Type.getNonReferenceType()->isArrayType()) {
20830 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
20831 << 0 << RefExpr->getSourceRange();
20832 continue;
20833 }
20834
20835 // Check if the declaration in the clause does not show up in any data
20836 // sharing attribute.
20837 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
20838 if (isOpenMPPrivate(DVar.CKind)) {
20839 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20840 << getOpenMPClauseName(DVar.CKind)
20841 << getOpenMPClauseName(OMPC_is_device_ptr)
20842 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
20843 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
20844 continue;
20845 }
20846
20847 const Expr *ConflictExpr;
20848 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
20849 D, /*CurrentRegionOnly=*/true,
20850 [&ConflictExpr](
20851 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
20852 OpenMPClauseKind) -> bool {
20853 ConflictExpr = R.front().getAssociatedExpression();
20854 return true;
20855 })) {
20856 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
20857 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
20858 << ConflictExpr->getSourceRange();
20859 continue;
20860 }
20861
20862 // Store the components in the stack so that they can be used to check
20863 // against other clauses later on.
20864 OMPClauseMappableExprCommon::MappableComponent MC(
20865 SimpleRefExpr, D, /*IsNonContiguous=*/false);
20866 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
20867 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
20868
20869 // Record the expression we've just processed.
20870 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
20871
20872 // Create a mappable component for the list item. List items in this clause
20873 // only need a component. We use a null declaration to signal fields in
20874 // 'this'.
20875 assert((isa<DeclRefExpr>(SimpleRefExpr) ||((void)0)
20876 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&((void)0)
20877 "Unexpected device pointer expression!")((void)0);
20878 MVLI.VarBaseDeclarations.push_back(
20879 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
20880 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20881 MVLI.VarComponents.back().push_back(MC);
20882 }
20883
20884 if (MVLI.ProcessedVarList.empty())
20885 return nullptr;
20886
20887 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20888 MVLI.VarBaseDeclarations,
20889 MVLI.VarComponents);
20890}
20891
20892OMPClause *Sema::ActOnOpenMPAllocateClause(
20893 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
20894 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
20895 if (Allocator) {
20896 // OpenMP [2.11.4 allocate Clause, Description]
20897 // allocator is an expression of omp_allocator_handle_t type.
20898 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
20899 return nullptr;
20900
20901 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
20902 if (AllocatorRes.isInvalid())
20903 return nullptr;
20904 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
20905 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
20906 Sema::AA_Initializing,
20907 /*AllowExplicit=*/true);
20908 if (AllocatorRes.isInvalid())
20909 return nullptr;
20910 Allocator = AllocatorRes.get();
20911 } else {
20912 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
20913 // allocate clauses that appear on a target construct or on constructs in a
20914 // target region must specify an allocator expression unless a requires
20915 // directive with the dynamic_allocators clause is present in the same
20916 // compilation unit.
20917 if (LangOpts.OpenMPIsDevice &&
20918 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
20919 targetDiag(StartLoc, diag::err_expected_allocator_expression);
20920 }
20921 // Analyze and build list of variables.
20922 SmallVector<Expr *, 8> Vars;
20923 for (Expr *RefExpr : VarList) {
20924 assert(RefExpr && "NULL expr in OpenMP private clause.")((void)0);
20925 SourceLocation ELoc;
20926 SourceRange ERange;
20927 Expr *SimpleRefExpr = RefExpr;
20928 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20929 if (Res.second) {
20930 // It will be analyzed later.
20931 Vars.push_back(RefExpr);
20932 }
20933 ValueDecl *D = Res.first;
20934 if (!D)
20935 continue;
20936
20937 auto *VD = dyn_cast<VarDecl>(D);
20938 DeclRefExpr *Ref = nullptr;
20939 if (!VD && !CurContext->isDependentContext())
20940 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20941 Vars.push_back((VD || CurContext->isDependentContext())
20942 ? RefExpr->IgnoreParens()
20943 : Ref);
20944 }
20945
20946 if (Vars.empty())
20947 return nullptr;
20948
20949 if (Allocator)
20950 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
20951 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
20952 ColonLoc, EndLoc, Vars);
20953}
20954
20955OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
20956 SourceLocation StartLoc,
20957 SourceLocation LParenLoc,
20958 SourceLocation EndLoc) {
20959 SmallVector<Expr *, 8> Vars;
20960 for (Expr *RefExpr : VarList) {
20961 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((void)0);
20962 SourceLocation ELoc;
20963 SourceRange ERange;
20964 Expr *SimpleRefExpr = RefExpr;
20965 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20966 if (Res.second)
20967 // It will be analyzed later.
20968 Vars.push_back(RefExpr);
20969 ValueDecl *D = Res.first;
20970 if (!D)
20971 continue;
20972
20973 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
20974 // A list-item cannot appear in more than one nontemporal clause.
20975 if (const Expr *PrevRef =
20976 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
20977 Diag(ELoc, diag::err_omp_used_in_clause_twice)
20978 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
20979 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20980 << getOpenMPClauseName(OMPC_nontemporal);
20981 continue;
20982 }
20983
20984 Vars.push_back(RefExpr);
20985 }
20986
20987 if (Vars.empty())
20988 return nullptr;
20989
20990 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20991 Vars);
20992}
20993
20994OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
20995 SourceLocation StartLoc,
20996 SourceLocation LParenLoc,
20997 SourceLocation EndLoc) {
20998 SmallVector<Expr *, 8> Vars;
20999 for (Expr *RefExpr : VarList) {
21000 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((void)0);
21001 SourceLocation ELoc;
21002 SourceRange ERange;
21003 Expr *SimpleRefExpr = RefExpr;
21004 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21005 /*AllowArraySection=*/true);
21006 if (Res.second)
21007 // It will be analyzed later.
21008 Vars.push_back(RefExpr);
21009 ValueDecl *D = Res.first;
21010 if (!D)
21011 continue;
21012
21013 const DSAStackTy::DSAVarData DVar =
21014 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
21015 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21016 // A list item that appears in the inclusive or exclusive clause must appear
21017 // in a reduction clause with the inscan modifier on the enclosing
21018 // worksharing-loop, worksharing-loop SIMD, or simd construct.
21019 if (DVar.CKind != OMPC_reduction ||
21020 DVar.Modifier != OMPC_REDUCTION_inscan)
21021 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21022 << RefExpr->getSourceRange();
21023
21024 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
21025 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
21026 Vars.push_back(RefExpr);
21027 }
21028
21029 if (Vars.empty())
21030 return nullptr;
21031
21032 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21033}
21034
21035OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
21036 SourceLocation StartLoc,
21037 SourceLocation LParenLoc,
21038 SourceLocation EndLoc) {
21039 SmallVector<Expr *, 8> Vars;
21040 for (Expr *RefExpr : VarList) {
21041 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((void)0);
21042 SourceLocation ELoc;
21043 SourceRange ERange;
21044 Expr *SimpleRefExpr = RefExpr;
21045 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21046 /*AllowArraySection=*/true);
21047 if (Res.second)
21048 // It will be analyzed later.
21049 Vars.push_back(RefExpr);
21050 ValueDecl *D = Res.first;
21051 if (!D)
21052 continue;
21053
21054 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
21055 DSAStackTy::DSAVarData DVar;
21056 if (ParentDirective != OMPD_unknown)
21057 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
21058 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21059 // A list item that appears in the inclusive or exclusive clause must appear
21060 // in a reduction clause with the inscan modifier on the enclosing
21061 // worksharing-loop, worksharing-loop SIMD, or simd construct.
21062 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
21063 DVar.Modifier != OMPC_REDUCTION_inscan) {
21064 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21065 << RefExpr->getSourceRange();
21066 } else {
21067 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
21068 }
21069 Vars.push_back(RefExpr);
21070 }
21071
21072 if (Vars.empty())
21073 return nullptr;
21074
21075 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21076}
21077
21078/// Tries to find omp_alloctrait_t type.
21079static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
21080 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
21081 if (!OMPAlloctraitT.isNull())
21082 return true;
21083 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
21084 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
21085 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
21086 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
21087 return false;
21088 }
21089 Stack->setOMPAlloctraitT(PT.get());
21090 return true;
21091}
21092
21093OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
21094 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
21095 ArrayRef<UsesAllocatorsData> Data) {
21096 // OpenMP [2.12.5, target Construct]
21097 // allocator is an identifier of omp_allocator_handle_t type.
21098 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
21099 return nullptr;
21100 // OpenMP [2.12.5, target Construct]
21101 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
21102 if (llvm::any_of(
21103 Data,
21104 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
21105 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
21106 return nullptr;
21107 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
21108 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
21109 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
21110 StringRef Allocator =
21111 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
21112 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
21113 PredefinedAllocators.insert(LookupSingleName(
21114 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
21115 }
21116
21117 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
21118 for (const UsesAllocatorsData &D : Data) {
21119 Expr *AllocatorExpr = nullptr;
21120 // Check allocator expression.
21121 if (D.Allocator->isTypeDependent()) {
21122 AllocatorExpr = D.Allocator;
21123 } else {
21124 // Traits were specified - need to assign new allocator to the specified
21125 // allocator, so it must be an lvalue.
21126 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
21127 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
21128 bool IsPredefinedAllocator = false;
21129 if (DRE)
21130 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
21131 if (!DRE ||
21132 !(Context.hasSameUnqualifiedType(
21133 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
21134 Context.typesAreCompatible(AllocatorExpr->getType(),
21135 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
21136 /*CompareUnqualified=*/true)) ||
21137 (!IsPredefinedAllocator &&
21138 (AllocatorExpr->getType().isConstant(Context) ||
21139 !AllocatorExpr->isLValue()))) {
21140 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
21141 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
21142 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
21143 continue;
21144 }
21145 // OpenMP [2.12.5, target Construct]
21146 // Predefined allocators appearing in a uses_allocators clause cannot have
21147 // traits specified.
21148 if (IsPredefinedAllocator && D.AllocatorTraits) {
21149 Diag(D.AllocatorTraits->getExprLoc(),
21150 diag::err_omp_predefined_allocator_with_traits)
21151 << D.AllocatorTraits->getSourceRange();
21152 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
21153 << cast<NamedDecl>(DRE->getDecl())->getName()
21154 << D.Allocator->getSourceRange();
21155 continue;
21156 }
21157 // OpenMP [2.12.5, target Construct]
21158 // Non-predefined allocators appearing in a uses_allocators clause must
21159 // have traits specified.
21160 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
21161 Diag(D.Allocator->getExprLoc(),
21162 diag::err_omp_nonpredefined_allocator_without_traits);
21163 continue;
21164 }
21165 // No allocator traits - just convert it to rvalue.
21166 if (!D.AllocatorTraits)
21167 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
21168 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
21169 DRE->getDecl(),
21170 IsPredefinedAllocator
21171 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
21172 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
21173 }
21174 Expr *AllocatorTraitsExpr = nullptr;
21175 if (D.AllocatorTraits) {
21176 if (D.AllocatorTraits->isTypeDependent()) {
21177 AllocatorTraitsExpr = D.AllocatorTraits;
21178 } else {
21179 // OpenMP [2.12.5, target Construct]
21180 // Arrays that contain allocator traits that appear in a uses_allocators
21181 // clause must be constant arrays, have constant values and be defined
21182 // in the same scope as the construct in which the clause appears.
21183 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
21184 // Check that traits expr is a constant array.
21185 QualType TraitTy;
21186 if (const ArrayType *Ty =
21187 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
21188 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
21189 TraitTy = ConstArrayTy->getElementType();
21190 if (TraitTy.isNull() ||
21191 !(Context.hasSameUnqualifiedType(TraitTy,
21192 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
21193 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
21194 /*CompareUnqualified=*/true))) {
21195 Diag(D.AllocatorTraits->getExprLoc(),
21196 diag::err_omp_expected_array_alloctraits)
21197 << AllocatorTraitsExpr->getType();
21198 continue;
21199 }
21200 // Do not map by default allocator traits if it is a standalone
21201 // variable.
21202 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
21203 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
21204 DRE->getDecl(),
21205 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
21206 }
21207 }
21208 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
21209 NewD.Allocator = AllocatorExpr;
21210 NewD.AllocatorTraits = AllocatorTraitsExpr;
21211 NewD.LParenLoc = D.LParenLoc;
21212 NewD.RParenLoc = D.RParenLoc;
21213 }
21214 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
21215 NewData);
21216}
21217
21218OMPClause *Sema::ActOnOpenMPAffinityClause(
21219 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
21220 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
21221 SmallVector<Expr *, 8> Vars;
21222 for (Expr *RefExpr : Locators) {
21223 assert(RefExpr && "NULL expr in OpenMP shared clause.")((void)0);
21224 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
21225 // It will be analyzed later.
21226 Vars.push_back(RefExpr);
21227 continue;
21228 }
21229
21230 SourceLocation ELoc = RefExpr->getExprLoc();
21231 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
21232
21233 if (!SimpleExpr->isLValue()) {
21234 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21235 << 1 << 0 << RefExpr->getSourceRange();
21236 continue;
21237 }
21238
21239 ExprResult Res;
21240 {
21241 Sema::TentativeAnalysisScope Trap(*this);
21242 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
21243 }
21244 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21245 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21246 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21247 << 1 << 0 << RefExpr->getSourceRange();
21248 continue;
21249 }
21250 Vars.push_back(SimpleExpr);
21251 }
21252
21253 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
21254 EndLoc, Modifier, Vars);
21255}

/usr/include/c++/v1/__iterator/reverse_iterator.h

1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
11#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <type_traits>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROSpush_macro("min") push_macro("max")
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STDnamespace std { inline namespace __1 {
27
28template <class _Tp, class = void>
29struct __is_stashing_iterator : false_type {};
30
31template <class _Tp>
32struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
33 : true_type {};
34
35_LIBCPP_SUPPRESS_DEPRECATED_PUSHGCC diagnostic push GCC diagnostic ignored "-Wdeprecated" GCC
diagnostic ignored "-Wdeprecated-declarations"
36template <class _Iter>
37class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) reverse_iterator
38#if _LIBCPP_STD_VER14 <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
39 : public iterator<typename iterator_traits<_Iter>::iterator_category,
40 typename iterator_traits<_Iter>::value_type,
41 typename iterator_traits<_Iter>::difference_type,
42 typename iterator_traits<_Iter>::pointer,
43 typename iterator_traits<_Iter>::reference>
44#endif
45{
46_LIBCPP_SUPPRESS_DEPRECATED_POPGCC diagnostic pop
47private:
48#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
49 _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
50#endif
51
52 static_assert(!__is_stashing_iterator<_Iter>::value,
53 "The specified iterator type cannot be used with reverse_iterator; "
54 "Using stashing iterators with reverse_iterator causes undefined behavior");
55
56protected:
57 _Iter current;
58public:
59 typedef _Iter iterator_type;
60 typedef typename iterator_traits<_Iter>::difference_type difference_type;
61 typedef typename iterator_traits<_Iter>::reference reference;
62 typedef typename iterator_traits<_Iter>::pointer pointer;
63 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
64 random_access_iterator_tag,
65 typename iterator_traits<_Iter>::iterator_category> iterator_category;
66 typedef typename iterator_traits<_Iter>::value_type value_type;
67
68#if _LIBCPP_STD_VER14 > 17
69 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
70 random_access_iterator_tag,
71 bidirectional_iterator_tag> iterator_concept;
72#endif
73
74#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
75 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
76 reverse_iterator() : __t(), current() {}
77
78 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
79 explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
80
81 template <class _Up, class = _EnableIf<
82 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
83 > >
84 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
85 reverse_iterator(const reverse_iterator<_Up>& __u)
86 : __t(__u.base()), current(__u.base())
87 { }
88
89 template <class _Up, class = _EnableIf<
90 !is_same<_Up, _Iter>::value &&
91 is_convertible<_Up const&, _Iter>::value &&
92 is_assignable<_Up const&, _Iter>::value
93 > >
94 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
95 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
96 __t = current = __u.base();
97 return *this;
98 }
99#else
100 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
101 reverse_iterator() : current() {}
102
103 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
104 explicit reverse_iterator(_Iter __x) : current(__x) {}
105
106 template <class _Up, class = _EnableIf<
107 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
108 > >
109 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
110 reverse_iterator(const reverse_iterator<_Up>& __u)
111 : current(__u.base())
112 { }
113
114 template <class _Up, class = _EnableIf<
115 !is_same<_Up, _Iter>::value &&
116 is_convertible<_Up const&, _Iter>::value &&
117 is_assignable<_Up const&, _Iter>::value
118 > >
119 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
120 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
121 current = __u.base();
122 return *this;
123 }
124#endif
125 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
126 _Iter base() const {return current;}
127 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
128 reference operator*() const {_Iter __tmp = current; return *--__tmp;}
129 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
130 pointer operator->() const {return _VSTDstd::__1::addressof(operator*());}
131 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
132 reverse_iterator& operator++() {--current; return *this;}
133 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
134 reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
135 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
136 reverse_iterator& operator--() {++current; return *this;}
137 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
138 reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
139 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
140 reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
141 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
142 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
143 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
144 reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);}
145 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
146 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
147 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
148 reference operator[](difference_type __n) const {return *(*this + __n);}
149};
150
151template <class _Iter1, class _Iter2>
152inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
153bool
154operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
155{
156 return __x.base() == __y.base();
15
Assuming the condition is false
16
Returning zero, which participates in a condition later
157}
158
159template <class _Iter1, class _Iter2>
160inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
161bool
162operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
163{
164 return __x.base() > __y.base();
165}
166
167template <class _Iter1, class _Iter2>
168inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
169bool
170operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
171{
172 return __x.base() != __y.base();
173}
174
175template <class _Iter1, class _Iter2>
176inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
177bool
178operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
179{
180 return __x.base() < __y.base();
181}
182
183template <class _Iter1, class _Iter2>
184inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
185bool
186operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
187{
188 return __x.base() <= __y.base();
189}
190
191template <class _Iter1, class _Iter2>
192inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
193bool
194operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
195{
196 return __x.base() >= __y.base();
197}
198
199#ifndef _LIBCPP_CXX03_LANG
200template <class _Iter1, class _Iter2>
201inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
202auto
203operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
204-> decltype(__y.base() - __x.base())
205{
206 return __y.base() - __x.base();
207}
208#else
209template <class _Iter1, class _Iter2>
210inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
211typename reverse_iterator<_Iter1>::difference_type
212operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
213{
214 return __y.base() - __x.base();
215}
216#endif
217
218template <class _Iter>
219inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
220reverse_iterator<_Iter>
221operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
222{
223 return reverse_iterator<_Iter>(__x.base() - __n);
224}
225
226#if _LIBCPP_STD_VER14 > 11
227template <class _Iter>
228inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPR_AFTER_CXX14
229reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
230{
231 return reverse_iterator<_Iter>(__i);
232}
233#endif
234
235_LIBCPP_END_NAMESPACE_STD} }
236
237_LIBCPP_POP_MACROSpop_macro("min") pop_macro("max")
238
239#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H