Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/lib/Sema/SemaOpenMP.cpp
Warning:line 4557, column 5
Value stored to 'ErrorFound' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm -resource-dir /usr/lib/llvm-15/lib/clang/15.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/lib/Sema -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-15/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-04-20-140412-16051-1 -x c++ /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/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/SmallSet.h"
39#include "llvm/ADT/StringExtras.h"
40#include "llvm/Frontend/OpenMP/OMPAssume.h"
41#include "llvm/Frontend/OpenMP/OMPConstants.h"
42#include <set>
43
44using namespace clang;
45using namespace llvm::omp;
46
47//===----------------------------------------------------------------------===//
48// Stack of data-sharing attributes for variables
49//===----------------------------------------------------------------------===//
50
51static const Expr *checkMapClauseExpressionBase(
52 Sema &SemaRef, Expr *E,
53 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
54 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
55
56namespace {
57/// Default data sharing attributes, which can be applied to directive.
58enum DefaultDataSharingAttributes {
59 DSA_unspecified = 0, /// Data sharing attribute not specified.
60 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
61 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
62 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
63};
64
65/// Stack for tracking declarations used in OpenMP directives and
66/// clauses and their data-sharing attributes.
67class DSAStackTy {
68public:
69 struct DSAVarData {
70 OpenMPDirectiveKind DKind = OMPD_unknown;
71 OpenMPClauseKind CKind = OMPC_unknown;
72 unsigned Modifier = 0;
73 const Expr *RefExpr = nullptr;
74 DeclRefExpr *PrivateCopy = nullptr;
75 SourceLocation ImplicitDSALoc;
76 bool AppliedToPointee = false;
77 DSAVarData() = default;
78 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
79 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
80 SourceLocation ImplicitDSALoc, unsigned Modifier,
81 bool AppliedToPointee)
82 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
83 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
84 AppliedToPointee(AppliedToPointee) {}
85 };
86 using OperatorOffsetTy =
87 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
88 using DoacrossDependMapTy =
89 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
90 /// Kind of the declaration used in the uses_allocators clauses.
91 enum class UsesAllocatorsDeclKind {
92 /// Predefined allocator
93 PredefinedAllocator,
94 /// User-defined allocator
95 UserDefinedAllocator,
96 /// The declaration that represent allocator trait
97 AllocatorTrait,
98 };
99
100private:
101 struct DSAInfo {
102 OpenMPClauseKind Attributes = OMPC_unknown;
103 unsigned Modifier = 0;
104 /// Pointer to a reference expression and a flag which shows that the
105 /// variable is marked as lastprivate(true) or not (false).
106 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
107 DeclRefExpr *PrivateCopy = nullptr;
108 /// true if the attribute is applied to the pointee, not the variable
109 /// itself.
110 bool AppliedToPointee = false;
111 };
112 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
113 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
114 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
115 using LoopControlVariablesMapTy =
116 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
117 /// Struct that associates a component with the clause kind where they are
118 /// found.
119 struct MappedExprComponentTy {
120 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
121 OpenMPClauseKind Kind = OMPC_unknown;
122 };
123 using MappedExprComponentsTy =
124 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
125 using CriticalsWithHintsTy =
126 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
127 struct ReductionData {
128 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
129 SourceRange ReductionRange;
130 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
131 ReductionData() = default;
132 void set(BinaryOperatorKind BO, SourceRange RR) {
133 ReductionRange = RR;
134 ReductionOp = BO;
135 }
136 void set(const Expr *RefExpr, SourceRange RR) {
137 ReductionRange = RR;
138 ReductionOp = RefExpr;
139 }
140 };
141 using DeclReductionMapTy =
142 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
143 struct DefaultmapInfo {
144 OpenMPDefaultmapClauseModifier ImplicitBehavior =
145 OMPC_DEFAULTMAP_MODIFIER_unknown;
146 SourceLocation SLoc;
147 DefaultmapInfo() = default;
148 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
149 : ImplicitBehavior(M), SLoc(Loc) {}
150 };
151
152 struct SharingMapTy {
153 DeclSAMapTy SharingMap;
154 DeclReductionMapTy ReductionMap;
155 UsedRefMapTy AlignedMap;
156 UsedRefMapTy NontemporalMap;
157 MappedExprComponentsTy MappedExprComponents;
158 LoopControlVariablesMapTy LCVMap;
159 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
160 SourceLocation DefaultAttrLoc;
161 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
162 OpenMPDirectiveKind Directive = OMPD_unknown;
163 DeclarationNameInfo DirectiveName;
164 Scope *CurScope = nullptr;
165 DeclContext *Context = nullptr;
166 SourceLocation ConstructLoc;
167 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
168 /// get the data (loop counters etc.) about enclosing loop-based construct.
169 /// This data is required during codegen.
170 DoacrossDependMapTy DoacrossDepends;
171 /// First argument (Expr *) contains optional argument of the
172 /// 'ordered' clause, the second one is true if the regions has 'ordered'
173 /// clause, false otherwise.
174 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
175 unsigned AssociatedLoops = 1;
176 bool HasMutipleLoops = false;
177 const Decl *PossiblyLoopCounter = nullptr;
178 bool NowaitRegion = false;
179 bool UntiedRegion = false;
180 bool CancelRegion = false;
181 bool LoopStart = false;
182 bool BodyComplete = false;
183 SourceLocation PrevScanLocation;
184 SourceLocation PrevOrderedLocation;
185 SourceLocation InnerTeamsRegionLoc;
186 /// Reference to the taskgroup task_reduction reference expression.
187 Expr *TaskgroupReductionRef = nullptr;
188 llvm::DenseSet<QualType> MappedClassesQualTypes;
189 SmallVector<Expr *, 4> InnerUsedAllocators;
190 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
191 /// List of globals marked as declare target link in this target region
192 /// (isOpenMPTargetExecutionDirective(Directive) == true).
193 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
194 /// List of decls used in inclusive/exclusive clauses of the scan directive.
195 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
196 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
197 UsesAllocatorsDecls;
198 Expr *DeclareMapperVar = nullptr;
199 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
200 Scope *CurScope, SourceLocation Loc)
201 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
202 ConstructLoc(Loc) {}
203 SharingMapTy() = default;
204 };
205
206 using StackTy = SmallVector<SharingMapTy, 4>;
207
208 /// Stack of used declaration and their data-sharing attributes.
209 DeclSAMapTy Threadprivates;
210 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
211 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
212 /// true, if check for DSA must be from parent directive, false, if
213 /// from current directive.
214 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
215 Sema &SemaRef;
216 bool ForceCapturing = false;
217 /// true if all the variables in the target executable directives must be
218 /// captured by reference.
219 bool ForceCaptureByReferenceInTargetExecutable = false;
220 CriticalsWithHintsTy Criticals;
221 unsigned IgnoredStackElements = 0;
222
223 /// Iterators over the stack iterate in order from innermost to outermost
224 /// directive.
225 using const_iterator = StackTy::const_reverse_iterator;
226 const_iterator begin() const {
227 return Stack.empty() ? const_iterator()
228 : Stack.back().first.rbegin() + IgnoredStackElements;
229 }
230 const_iterator end() const {
231 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
232 }
233 using iterator = StackTy::reverse_iterator;
234 iterator begin() {
235 return Stack.empty() ? iterator()
236 : Stack.back().first.rbegin() + IgnoredStackElements;
237 }
238 iterator end() {
239 return Stack.empty() ? iterator() : Stack.back().first.rend();
240 }
241
242 // Convenience operations to get at the elements of the stack.
243
244 bool isStackEmpty() const {
245 return Stack.empty() ||
246 Stack.back().second != CurrentNonCapturingFunctionScope ||
247 Stack.back().first.size() <= IgnoredStackElements;
248 }
249 size_t getStackSize() const {
250 return isStackEmpty() ? 0
251 : Stack.back().first.size() - IgnoredStackElements;
252 }
253
254 SharingMapTy *getTopOfStackOrNull() {
255 size_t Size = getStackSize();
256 if (Size == 0)
257 return nullptr;
258 return &Stack.back().first[Size - 1];
259 }
260 const SharingMapTy *getTopOfStackOrNull() const {
261 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
262 }
263 SharingMapTy &getTopOfStack() {
264 assert(!isStackEmpty() && "no current directive")(static_cast <bool> (!isStackEmpty() && "no current directive"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"no current directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 264, __extension__ __PRETTY_FUNCTION__
))
;
265 return *getTopOfStackOrNull();
266 }
267 const SharingMapTy &getTopOfStack() const {
268 return const_cast<DSAStackTy &>(*this).getTopOfStack();
269 }
270
271 SharingMapTy *getSecondOnStackOrNull() {
272 size_t Size = getStackSize();
273 if (Size <= 1)
274 return nullptr;
275 return &Stack.back().first[Size - 2];
276 }
277 const SharingMapTy *getSecondOnStackOrNull() const {
278 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
279 }
280
281 /// Get the stack element at a certain level (previously returned by
282 /// \c getNestingLevel).
283 ///
284 /// Note that nesting levels count from outermost to innermost, and this is
285 /// the reverse of our iteration order where new inner levels are pushed at
286 /// the front of the stack.
287 SharingMapTy &getStackElemAtLevel(unsigned Level) {
288 assert(Level < getStackSize() && "no such stack element")(static_cast <bool> (Level < getStackSize() &&
"no such stack element") ? void (0) : __assert_fail ("Level < getStackSize() && \"no such stack element\""
, "clang/lib/Sema/SemaOpenMP.cpp", 288, __extension__ __PRETTY_FUNCTION__
))
;
289 return Stack.back().first[Level];
290 }
291 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
292 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
293 }
294
295 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
296
297 /// Checks if the variable is a local for OpenMP region.
298 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
299
300 /// Vector of previously declared requires directives
301 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
302 /// omp_allocator_handle_t type.
303 QualType OMPAllocatorHandleT;
304 /// omp_depend_t type.
305 QualType OMPDependT;
306 /// omp_event_handle_t type.
307 QualType OMPEventHandleT;
308 /// omp_alloctrait_t type.
309 QualType OMPAlloctraitT;
310 /// Expression for the predefined allocators.
311 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
312 nullptr};
313 /// Vector of previously encountered target directives
314 SmallVector<SourceLocation, 2> TargetLocations;
315 SourceLocation AtomicLocation;
316 /// Vector of declare variant construct traits.
317 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
318
319public:
320 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
321
322 /// Sets omp_allocator_handle_t type.
323 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
324 /// Gets omp_allocator_handle_t type.
325 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
326 /// Sets omp_alloctrait_t type.
327 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
328 /// Gets omp_alloctrait_t type.
329 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
330 /// Sets the given default allocator.
331 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
332 Expr *Allocator) {
333 OMPPredefinedAllocators[AllocatorKind] = Allocator;
334 }
335 /// Returns the specified default allocator.
336 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
337 return OMPPredefinedAllocators[AllocatorKind];
338 }
339 /// Sets omp_depend_t type.
340 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
341 /// Gets omp_depend_t type.
342 QualType getOMPDependT() const { return OMPDependT; }
343
344 /// Sets omp_event_handle_t type.
345 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
346 /// Gets omp_event_handle_t type.
347 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
348
349 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
350 OpenMPClauseKind getClauseParsingMode() const {
351 assert(isClauseParsingMode() && "Must be in clause parsing mode.")(static_cast <bool> (isClauseParsingMode() && "Must be in clause parsing mode."
) ? void (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 351, __extension__ __PRETTY_FUNCTION__
))
;
352 return ClauseKindMode;
353 }
354 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
355
356 bool isBodyComplete() const {
357 const SharingMapTy *Top = getTopOfStackOrNull();
358 return Top && Top->BodyComplete;
359 }
360 void setBodyComplete() { getTopOfStack().BodyComplete = true; }
361
362 bool isForceVarCapturing() const { return ForceCapturing; }
363 void setForceVarCapturing(bool V) { ForceCapturing = V; }
364
365 void setForceCaptureByReferenceInTargetExecutable(bool V) {
366 ForceCaptureByReferenceInTargetExecutable = V;
367 }
368 bool isForceCaptureByReferenceInTargetExecutable() const {
369 return ForceCaptureByReferenceInTargetExecutable;
370 }
371
372 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
373 Scope *CurScope, SourceLocation Loc) {
374 assert(!IgnoredStackElements &&(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 375, __extension__ __PRETTY_FUNCTION__
))
375 "cannot change stack while ignoring elements")(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 375, __extension__ __PRETTY_FUNCTION__
))
;
376 if (Stack.empty() ||
377 Stack.back().second != CurrentNonCapturingFunctionScope)
378 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
379 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
380 Stack.back().first.back().DefaultAttrLoc = Loc;
381 }
382
383 void pop() {
384 assert(!IgnoredStackElements &&(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 385, __extension__ __PRETTY_FUNCTION__
))
385 "cannot change stack while ignoring elements")(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 385, __extension__ __PRETTY_FUNCTION__
))
;
386 assert(!Stack.back().first.empty() &&(static_cast <bool> (!Stack.back().first.empty() &&
"Data-sharing attributes stack is empty!") ? void (0) : __assert_fail
("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 387, __extension__ __PRETTY_FUNCTION__
))
387 "Data-sharing attributes stack is empty!")(static_cast <bool> (!Stack.back().first.empty() &&
"Data-sharing attributes stack is empty!") ? void (0) : __assert_fail
("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 387, __extension__ __PRETTY_FUNCTION__
))
;
388 Stack.back().first.pop_back();
389 }
390
391 /// RAII object to temporarily leave the scope of a directive when we want to
392 /// logically operate in its parent.
393 class ParentDirectiveScope {
394 DSAStackTy &Self;
395 bool Active;
396
397 public:
398 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
399 : Self(Self), Active(false) {
400 if (Activate)
401 enable();
402 }
403 ~ParentDirectiveScope() { disable(); }
404 void disable() {
405 if (Active) {
406 --Self.IgnoredStackElements;
407 Active = false;
408 }
409 }
410 void enable() {
411 if (!Active) {
412 ++Self.IgnoredStackElements;
413 Active = true;
414 }
415 }
416 };
417
418 /// Marks that we're started loop parsing.
419 void loopInit() {
420 assert(isOpenMPLoopDirective(getCurrentDirective()) &&(static_cast <bool> (isOpenMPLoopDirective(getCurrentDirective
()) && "Expected loop-based directive.") ? void (0) :
__assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 421, __extension__ __PRETTY_FUNCTION__
))
421 "Expected loop-based directive.")(static_cast <bool> (isOpenMPLoopDirective(getCurrentDirective
()) && "Expected loop-based directive.") ? void (0) :
__assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 421, __extension__ __PRETTY_FUNCTION__
))
;
422 getTopOfStack().LoopStart = true;
423 }
424 /// Start capturing of the variables in the loop context.
425 void loopStart() {
426 assert(isOpenMPLoopDirective(getCurrentDirective()) &&(static_cast <bool> (isOpenMPLoopDirective(getCurrentDirective
()) && "Expected loop-based directive.") ? void (0) :
__assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 427, __extension__ __PRETTY_FUNCTION__
))
427 "Expected loop-based directive.")(static_cast <bool> (isOpenMPLoopDirective(getCurrentDirective
()) && "Expected loop-based directive.") ? void (0) :
__assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 427, __extension__ __PRETTY_FUNCTION__
))
;
428 getTopOfStack().LoopStart = false;
429 }
430 /// true, if variables are captured, false otherwise.
431 bool isLoopStarted() const {
432 assert(isOpenMPLoopDirective(getCurrentDirective()) &&(static_cast <bool> (isOpenMPLoopDirective(getCurrentDirective
()) && "Expected loop-based directive.") ? void (0) :
__assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 433, __extension__ __PRETTY_FUNCTION__
))
433 "Expected loop-based directive.")(static_cast <bool> (isOpenMPLoopDirective(getCurrentDirective
()) && "Expected loop-based directive.") ? void (0) :
__assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 433, __extension__ __PRETTY_FUNCTION__
))
;
434 return !getTopOfStack().LoopStart;
435 }
436 /// Marks (or clears) declaration as possibly loop counter.
437 void resetPossibleLoopCounter(const Decl *D = nullptr) {
438 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
439 }
440 /// Gets the possible loop counter decl.
441 const Decl *getPossiblyLoopCunter() const {
442 return getTopOfStack().PossiblyLoopCounter;
443 }
444 /// Start new OpenMP region stack in new non-capturing function.
445 void pushFunction() {
446 assert(!IgnoredStackElements &&(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 447, __extension__ __PRETTY_FUNCTION__
))
447 "cannot change stack while ignoring elements")(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 447, __extension__ __PRETTY_FUNCTION__
))
;
448 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
449 assert(!isa<CapturingScopeInfo>(CurFnScope))(static_cast <bool> (!isa<CapturingScopeInfo>(CurFnScope
)) ? void (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "clang/lib/Sema/SemaOpenMP.cpp", 449, __extension__ __PRETTY_FUNCTION__
))
;
450 CurrentNonCapturingFunctionScope = CurFnScope;
451 }
452 /// Pop region stack for non-capturing function.
453 void popFunction(const FunctionScopeInfo *OldFSI) {
454 assert(!IgnoredStackElements &&(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 455, __extension__ __PRETTY_FUNCTION__
))
455 "cannot change stack while ignoring elements")(static_cast <bool> (!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? void (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "clang/lib/Sema/SemaOpenMP.cpp", 455, __extension__ __PRETTY_FUNCTION__
))
;
456 if (!Stack.empty() && Stack.back().second == OldFSI) {
457 assert(Stack.back().first.empty())(static_cast <bool> (Stack.back().first.empty()) ? void
(0) : __assert_fail ("Stack.back().first.empty()", "clang/lib/Sema/SemaOpenMP.cpp"
, 457, __extension__ __PRETTY_FUNCTION__))
;
458 Stack.pop_back();
459 }
460 CurrentNonCapturingFunctionScope = nullptr;
461 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
462 if (!isa<CapturingScopeInfo>(FSI)) {
463 CurrentNonCapturingFunctionScope = FSI;
464 break;
465 }
466 }
467 }
468
469 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
470 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
471 }
472 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
473 getCriticalWithHint(const DeclarationNameInfo &Name) const {
474 auto I = Criticals.find(Name.getAsString());
475 if (I != Criticals.end())
476 return I->second;
477 return std::make_pair(nullptr, llvm::APSInt());
478 }
479 /// If 'aligned' declaration for given variable \a D was not seen yet,
480 /// add it and return NULL; otherwise return previous occurrence's expression
481 /// for diagnostics.
482 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
483 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
484 /// add it and return NULL; otherwise return previous occurrence's expression
485 /// for diagnostics.
486 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
487
488 /// Register specified variable as loop control variable.
489 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
490 /// Check if the specified variable is a loop control variable for
491 /// current region.
492 /// \return The index of the loop control variable in the list of associated
493 /// for-loops (from outer to inner).
494 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
495 /// Check if the specified variable is a loop control variable for
496 /// parent region.
497 /// \return The index of the loop control variable in the list of associated
498 /// for-loops (from outer to inner).
499 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
500 /// Check if the specified variable is a loop control variable for
501 /// current region.
502 /// \return The index of the loop control variable in the list of associated
503 /// for-loops (from outer to inner).
504 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
505 unsigned Level) const;
506 /// Get the loop control variable for the I-th loop (or nullptr) in
507 /// parent directive.
508 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
509
510 /// Marks the specified decl \p D as used in scan directive.
511 void markDeclAsUsedInScanDirective(ValueDecl *D) {
512 if (SharingMapTy *Stack = getSecondOnStackOrNull())
513 Stack->UsedInScanDirective.insert(D);
514 }
515
516 /// Checks if the specified declaration was used in the inner scan directive.
517 bool isUsedInScanDirective(ValueDecl *D) const {
518 if (const SharingMapTy *Stack = getTopOfStackOrNull())
519 return Stack->UsedInScanDirective.contains(D);
520 return false;
521 }
522
523 /// Adds explicit data sharing attribute to the specified declaration.
524 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
525 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
526 bool AppliedToPointee = false);
527
528 /// Adds additional information for the reduction items with the reduction id
529 /// represented as an operator.
530 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
531 BinaryOperatorKind BOK);
532 /// Adds additional information for the reduction items with the reduction id
533 /// represented as reduction identifier.
534 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
535 const Expr *ReductionRef);
536 /// Returns the location and reduction operation from the innermost parent
537 /// region for the given \p D.
538 const DSAVarData
539 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
540 BinaryOperatorKind &BOK,
541 Expr *&TaskgroupDescriptor) const;
542 /// Returns the location and reduction operation from the innermost parent
543 /// region for the given \p D.
544 const DSAVarData
545 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
546 const Expr *&ReductionRef,
547 Expr *&TaskgroupDescriptor) const;
548 /// Return reduction reference expression for the current taskgroup or
549 /// parallel/worksharing directives with task reductions.
550 Expr *getTaskgroupReductionRef() const {
551 assert((getTopOfStack().Directive == OMPD_taskgroup ||(static_cast <bool> ((getTopOfStack().Directive == OMPD_taskgroup
|| ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
!isOpenMPSimdDirective(getTopOfStack().Directive))) &&
"taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? void (0) : __assert_fail
("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 556, __extension__ __PRETTY_FUNCTION__
))
552 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(static_cast <bool> ((getTopOfStack().Directive == OMPD_taskgroup
|| ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
!isOpenMPSimdDirective(getTopOfStack().Directive))) &&
"taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? void (0) : __assert_fail
("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 556, __extension__ __PRETTY_FUNCTION__
))
553 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(static_cast <bool> ((getTopOfStack().Directive == OMPD_taskgroup
|| ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
!isOpenMPSimdDirective(getTopOfStack().Directive))) &&
"taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? void (0) : __assert_fail
("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 556, __extension__ __PRETTY_FUNCTION__
))
554 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(static_cast <bool> ((getTopOfStack().Directive == OMPD_taskgroup
|| ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
!isOpenMPSimdDirective(getTopOfStack().Directive))) &&
"taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? void (0) : __assert_fail
("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 556, __extension__ __PRETTY_FUNCTION__
))
555 "taskgroup reference expression requested for non taskgroup or "(static_cast <bool> ((getTopOfStack().Directive == OMPD_taskgroup
|| ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
!isOpenMPSimdDirective(getTopOfStack().Directive))) &&
"taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? void (0) : __assert_fail
("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 556, __extension__ __PRETTY_FUNCTION__
))
556 "parallel/worksharing directive.")(static_cast <bool> ((getTopOfStack().Directive == OMPD_taskgroup
|| ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
!isOpenMPSimdDirective(getTopOfStack().Directive))) &&
"taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? void (0) : __assert_fail
("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 556, __extension__ __PRETTY_FUNCTION__
))
;
557 return getTopOfStack().TaskgroupReductionRef;
558 }
559 /// Checks if the given \p VD declaration is actually a taskgroup reduction
560 /// descriptor variable at the \p Level of OpenMP regions.
561 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
562 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
563 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
564 ->getDecl() == VD;
565 }
566
567 /// Returns data sharing attributes from top of the stack for the
568 /// specified declaration.
569 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
570 /// Returns data-sharing attributes for the specified declaration.
571 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
572 /// Returns data-sharing attributes for the specified declaration.
573 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
574 /// Checks if the specified variables has data-sharing attributes which
575 /// match specified \a CPred predicate in any directive which matches \a DPred
576 /// predicate.
577 const DSAVarData
578 hasDSA(ValueDecl *D,
579 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
580 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
581 bool FromParent) const;
582 /// Checks if the specified variables has data-sharing attributes which
583 /// match specified \a CPred predicate in any innermost directive which
584 /// matches \a DPred predicate.
585 const DSAVarData
586 hasInnermostDSA(ValueDecl *D,
587 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
588 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
589 bool FromParent) const;
590 /// Checks if the specified variables has explicit data-sharing
591 /// attributes which match specified \a CPred predicate at the specified
592 /// OpenMP region.
593 bool
594 hasExplicitDSA(const ValueDecl *D,
595 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
596 unsigned Level, bool NotLastprivate = false) const;
597
598 /// Returns true if the directive at level \Level matches in the
599 /// specified \a DPred predicate.
600 bool hasExplicitDirective(
601 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
602 unsigned Level) const;
603
604 /// Finds a directive which matches specified \a DPred predicate.
605 bool hasDirective(
606 const llvm::function_ref<bool(
607 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
608 DPred,
609 bool FromParent) const;
610
611 /// Returns currently analyzed directive.
612 OpenMPDirectiveKind getCurrentDirective() const {
613 const SharingMapTy *Top = getTopOfStackOrNull();
614 return Top ? Top->Directive : OMPD_unknown;
615 }
616 /// Returns directive kind at specified level.
617 OpenMPDirectiveKind getDirective(unsigned Level) const {
618 assert(!isStackEmpty() && "No directive at specified level.")(static_cast <bool> (!isStackEmpty() && "No directive at specified level."
) ? void (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 618, __extension__ __PRETTY_FUNCTION__
))
;
619 return getStackElemAtLevel(Level).Directive;
620 }
621 /// Returns the capture region at the specified level.
622 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
623 unsigned OpenMPCaptureLevel) const {
624 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
625 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
626 return CaptureRegions[OpenMPCaptureLevel];
627 }
628 /// Returns parent directive.
629 OpenMPDirectiveKind getParentDirective() const {
630 const SharingMapTy *Parent = getSecondOnStackOrNull();
631 return Parent ? Parent->Directive : OMPD_unknown;
632 }
633
634 /// Add requires decl to internal vector
635 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
636
637 /// Checks if the defined 'requires' directive has specified type of clause.
638 template <typename ClauseType> 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 { return AtomicLocation; }
682
683 // Return previously encountered target region locations.
684 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
685 return TargetLocations;
686 }
687
688 /// Set default data sharing attribute to none.
689 void setDefaultDSANone(SourceLocation Loc) {
690 getTopOfStack().DefaultAttr = DSA_none;
691 getTopOfStack().DefaultAttrLoc = Loc;
692 }
693 /// Set default data sharing attribute to shared.
694 void setDefaultDSAShared(SourceLocation Loc) {
695 getTopOfStack().DefaultAttr = DSA_shared;
696 getTopOfStack().DefaultAttrLoc = Loc;
697 }
698 /// Set default data sharing attribute to firstprivate.
699 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
700 getTopOfStack().DefaultAttr = DSA_firstprivate;
701 getTopOfStack().DefaultAttrLoc = Loc;
702 }
703 /// Set default data mapping attribute to Modifier:Kind
704 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
705 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
706 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
707 DMI.ImplicitBehavior = M;
708 DMI.SLoc = Loc;
709 }
710 /// Check whether the implicit-behavior has been set in defaultmap
711 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
712 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
713 return getTopOfStack()
714 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
715 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
716 getTopOfStack()
717 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
718 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
719 getTopOfStack()
720 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
721 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
722 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
723 OMPC_DEFAULTMAP_MODIFIER_unknown;
724 }
725
726 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
727 return ConstructTraits;
728 }
729 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
730 bool ScopeEntry) {
731 if (ScopeEntry)
732 ConstructTraits.append(Traits.begin(), Traits.end());
733 else
734 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
735 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
736 assert(Top == Trait && "Something left a trait on the stack!")(static_cast <bool> (Top == Trait && "Something left a trait on the stack!"
) ? void (0) : __assert_fail ("Top == Trait && \"Something left a trait on the stack!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 736, __extension__ __PRETTY_FUNCTION__
))
;
737 (void)Trait;
738 (void)Top;
739 }
740 }
741
742 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
743 return getStackSize() <= Level ? DSA_unspecified
744 : getStackElemAtLevel(Level).DefaultAttr;
745 }
746 DefaultDataSharingAttributes getDefaultDSA() const {
747 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
748 }
749 SourceLocation getDefaultDSALocation() const {
750 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
751 }
752 OpenMPDefaultmapClauseModifier
753 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
754 return isStackEmpty()
755 ? OMPC_DEFAULTMAP_MODIFIER_unknown
756 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
757 }
758 OpenMPDefaultmapClauseModifier
759 getDefaultmapModifierAtLevel(unsigned Level,
760 OpenMPDefaultmapClauseKind Kind) const {
761 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
762 }
763 bool isDefaultmapCapturedByRef(unsigned Level,
764 OpenMPDefaultmapClauseKind Kind) const {
765 OpenMPDefaultmapClauseModifier M =
766 getDefaultmapModifierAtLevel(Level, Kind);
767 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
768 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
769 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
770 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
771 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
772 }
773 return true;
774 }
775 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
776 OpenMPDefaultmapClauseKind Kind) {
777 switch (Kind) {
778 case OMPC_DEFAULTMAP_scalar:
779 case OMPC_DEFAULTMAP_pointer:
780 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
781 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
782 (M == OMPC_DEFAULTMAP_MODIFIER_default);
783 case OMPC_DEFAULTMAP_aggregate:
784 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
785 default:
786 break;
787 }
788 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "clang/lib/Sema/SemaOpenMP.cpp", 788)
;
789 }
790 bool mustBeFirstprivateAtLevel(unsigned Level,
791 OpenMPDefaultmapClauseKind Kind) const {
792 OpenMPDefaultmapClauseModifier M =
793 getDefaultmapModifierAtLevel(Level, Kind);
794 return mustBeFirstprivateBase(M, Kind);
795 }
796 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
797 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
798 return mustBeFirstprivateBase(M, Kind);
799 }
800
801 /// Checks if the specified variable is a threadprivate.
802 bool isThreadPrivate(VarDecl *D) {
803 const DSAVarData DVar = getTopDSA(D, false);
804 return isOpenMPThreadPrivate(DVar.CKind);
805 }
806
807 /// Marks current region as ordered (it has an 'ordered' clause).
808 void setOrderedRegion(bool IsOrdered, const Expr *Param,
809 OMPOrderedClause *Clause) {
810 if (IsOrdered)
811 getTopOfStack().OrderedRegion.emplace(Param, Clause);
812 else
813 getTopOfStack().OrderedRegion.reset();
814 }
815 /// Returns true, if region is ordered (has associated 'ordered' clause),
816 /// false - otherwise.
817 bool isOrderedRegion() const {
818 if (const SharingMapTy *Top = getTopOfStackOrNull())
819 return Top->OrderedRegion.hasValue();
820 return false;
821 }
822 /// Returns optional parameter for the ordered region.
823 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
824 if (const SharingMapTy *Top = getTopOfStackOrNull())
825 if (Top->OrderedRegion.hasValue())
826 return Top->OrderedRegion.getValue();
827 return std::make_pair(nullptr, nullptr);
828 }
829 /// Returns true, if parent region is ordered (has associated
830 /// 'ordered' clause), false - otherwise.
831 bool isParentOrderedRegion() const {
832 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
833 return Parent->OrderedRegion.hasValue();
834 return false;
835 }
836 /// Returns optional parameter for the ordered region.
837 std::pair<const Expr *, OMPOrderedClause *>
838 getParentOrderedRegionParam() const {
839 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
840 if (Parent->OrderedRegion.hasValue())
841 return Parent->OrderedRegion.getValue();
842 return std::make_pair(nullptr, nullptr);
843 }
844 /// Marks current region as nowait (it has a 'nowait' clause).
845 void setNowaitRegion(bool IsNowait = true) {
846 getTopOfStack().NowaitRegion = IsNowait;
847 }
848 /// Returns true, if parent region is nowait (has associated
849 /// 'nowait' clause), false - otherwise.
850 bool isParentNowaitRegion() const {
851 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
852 return Parent->NowaitRegion;
853 return false;
854 }
855 /// Marks current region as untied (it has a 'untied' clause).
856 void setUntiedRegion(bool IsUntied = true) {
857 getTopOfStack().UntiedRegion = IsUntied;
858 }
859 /// Return true if current region is untied.
860 bool isUntiedRegion() const {
861 const SharingMapTy *Top = getTopOfStackOrNull();
862 return Top ? Top->UntiedRegion : false;
863 }
864 /// Marks parent region as cancel region.
865 void setParentCancelRegion(bool Cancel = true) {
866 if (SharingMapTy *Parent = getSecondOnStackOrNull())
867 Parent->CancelRegion |= Cancel;
868 }
869 /// Return true if current region has inner cancel construct.
870 bool isCancelRegion() const {
871 const SharingMapTy *Top = getTopOfStackOrNull();
872 return Top ? Top->CancelRegion : false;
873 }
874
875 /// Mark that parent region already has scan directive.
876 void setParentHasScanDirective(SourceLocation Loc) {
877 if (SharingMapTy *Parent = getSecondOnStackOrNull())
878 Parent->PrevScanLocation = Loc;
879 }
880 /// Return true if current region has inner cancel construct.
881 bool doesParentHasScanDirective() const {
882 const SharingMapTy *Top = getSecondOnStackOrNull();
883 return Top ? Top->PrevScanLocation.isValid() : false;
884 }
885 /// Return true if current region has inner cancel construct.
886 SourceLocation getParentScanDirectiveLoc() const {
887 const SharingMapTy *Top = getSecondOnStackOrNull();
888 return Top ? Top->PrevScanLocation : SourceLocation();
889 }
890 /// Mark that parent region already has ordered directive.
891 void setParentHasOrderedDirective(SourceLocation Loc) {
892 if (SharingMapTy *Parent = getSecondOnStackOrNull())
893 Parent->PrevOrderedLocation = Loc;
894 }
895 /// Return true if current region has inner ordered construct.
896 bool doesParentHasOrderedDirective() const {
897 const SharingMapTy *Top = getSecondOnStackOrNull();
898 return Top ? Top->PrevOrderedLocation.isValid() : false;
899 }
900 /// Returns the location of the previously specified ordered directive.
901 SourceLocation getParentOrderedDirectiveLoc() const {
902 const SharingMapTy *Top = getSecondOnStackOrNull();
903 return Top ? Top->PrevOrderedLocation : SourceLocation();
904 }
905
906 /// Set collapse value for the region.
907 void setAssociatedLoops(unsigned Val) {
908 getTopOfStack().AssociatedLoops = Val;
909 if (Val > 1)
910 getTopOfStack().HasMutipleLoops = true;
911 }
912 /// Return collapse value for region.
913 unsigned getAssociatedLoops() const {
914 const SharingMapTy *Top = getTopOfStackOrNull();
915 return Top ? Top->AssociatedLoops : 0;
916 }
917 /// Returns true if the construct is associated with multiple loops.
918 bool hasMutipleLoops() const {
919 const SharingMapTy *Top = getTopOfStackOrNull();
920 return Top ? Top->HasMutipleLoops : false;
921 }
922
923 /// Marks current target region as one with closely nested teams
924 /// region.
925 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
926 if (SharingMapTy *Parent = getSecondOnStackOrNull())
927 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
928 }
929 /// Returns true, if current region has closely nested teams region.
930 bool hasInnerTeamsRegion() const {
931 return getInnerTeamsRegionLoc().isValid();
932 }
933 /// Returns location of the nested teams region (if any).
934 SourceLocation getInnerTeamsRegionLoc() const {
935 const SharingMapTy *Top = getTopOfStackOrNull();
936 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
937 }
938
939 Scope *getCurScope() const {
940 const SharingMapTy *Top = getTopOfStackOrNull();
941 return Top ? Top->CurScope : nullptr;
942 }
943 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
944 SourceLocation getConstructLoc() const {
945 const SharingMapTy *Top = getTopOfStackOrNull();
946 return Top ? Top->ConstructLoc : SourceLocation();
947 }
948
949 /// Do the check specified in \a Check to all component lists and return true
950 /// if any issue is found.
951 bool checkMappableExprComponentListsForDecl(
952 const ValueDecl *VD, bool CurrentRegionOnly,
953 const llvm::function_ref<
954 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
955 OpenMPClauseKind)>
956 Check) const {
957 if (isStackEmpty())
958 return false;
959 auto SI = begin();
960 auto SE = end();
961
962 if (SI == SE)
963 return false;
964
965 if (CurrentRegionOnly)
966 SE = std::next(SI);
967 else
968 std::advance(SI, 1);
969
970 for (; SI != SE; ++SI) {
971 auto MI = SI->MappedExprComponents.find(VD);
972 if (MI != SI->MappedExprComponents.end())
973 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
974 MI->second.Components)
975 if (Check(L, MI->second.Kind))
976 return true;
977 }
978 return false;
979 }
980
981 /// Do the check specified in \a Check to all component lists at a given level
982 /// and return true if any issue is found.
983 bool checkMappableExprComponentListsForDeclAtLevel(
984 const ValueDecl *VD, unsigned Level,
985 const llvm::function_ref<
986 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
987 OpenMPClauseKind)>
988 Check) const {
989 if (getStackSize() <= Level)
990 return false;
991
992 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
993 auto MI = StackElem.MappedExprComponents.find(VD);
994 if (MI != StackElem.MappedExprComponents.end())
995 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
996 MI->second.Components)
997 if (Check(L, MI->second.Kind))
998 return true;
999 return false;
1000 }
1001
1002 /// Create a new mappable expression component list associated with a given
1003 /// declaration and initialize it with the provided list of components.
1004 void addMappableExpressionComponents(
1005 const ValueDecl *VD,
1006 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1007 OpenMPClauseKind WhereFoundClauseKind) {
1008 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1009 // Create new entry and append the new components there.
1010 MEC.Components.resize(MEC.Components.size() + 1);
1011 MEC.Components.back().append(Components.begin(), Components.end());
1012 MEC.Kind = WhereFoundClauseKind;
1013 }
1014
1015 unsigned getNestingLevel() const {
1016 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "clang/lib/Sema/SemaOpenMP.cpp", 1016, __extension__
__PRETTY_FUNCTION__))
;
1017 return getStackSize() - 1;
1018 }
1019 void addDoacrossDependClause(OMPDependClause *C,
1020 const OperatorOffsetTy &OpsOffs) {
1021 SharingMapTy *Parent = getSecondOnStackOrNull();
1022 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))(static_cast <bool> (Parent && isOpenMPWorksharingDirective
(Parent->Directive)) ? void (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)"
, "clang/lib/Sema/SemaOpenMP.cpp", 1022, __extension__ __PRETTY_FUNCTION__
))
;
1023 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1024 }
1025 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1026 getDoacrossDependClauses() const {
1027 const SharingMapTy &StackElem = getTopOfStack();
1028 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1029 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1030 return llvm::make_range(Ref.begin(), Ref.end());
1031 }
1032 return llvm::make_range(StackElem.DoacrossDepends.end(),
1033 StackElem.DoacrossDepends.end());
1034 }
1035
1036 // Store types of classes which have been explicitly mapped
1037 void addMappedClassesQualTypes(QualType QT) {
1038 SharingMapTy &StackElem = getTopOfStack();
1039 StackElem.MappedClassesQualTypes.insert(QT);
1040 }
1041
1042 // Return set of mapped classes types
1043 bool isClassPreviouslyMapped(QualType QT) const {
1044 const SharingMapTy &StackElem = getTopOfStack();
1045 return StackElem.MappedClassesQualTypes.contains(QT);
1046 }
1047
1048 /// Adds global declare target to the parent target region.
1049 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1050 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration((static_cast <bool> (*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration
( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
"Expected declare target link global.") ? void (0) : __assert_fail
("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1052, __extension__ __PRETTY_FUNCTION__
))
1051 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&(static_cast <bool> (*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration
( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
"Expected declare target link global.") ? void (0) : __assert_fail
("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1052, __extension__ __PRETTY_FUNCTION__
))
1052 "Expected declare target link global.")(static_cast <bool> (*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration
( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
"Expected declare target link global.") ? void (0) : __assert_fail
("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1052, __extension__ __PRETTY_FUNCTION__
))
;
1053 for (auto &Elem : *this) {
1054 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1055 Elem.DeclareTargetLinkVarDecls.push_back(E);
1056 return;
1057 }
1058 }
1059 }
1060
1061 /// Returns the list of globals with declare target link if current directive
1062 /// is target.
1063 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1064 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&(static_cast <bool> (isOpenMPTargetExecutionDirective(getCurrentDirective
()) && "Expected target executable directive.") ? void
(0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1065, __extension__ __PRETTY_FUNCTION__
))
1065 "Expected target executable directive.")(static_cast <bool> (isOpenMPTargetExecutionDirective(getCurrentDirective
()) && "Expected target executable directive.") ? void
(0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1065, __extension__ __PRETTY_FUNCTION__
))
;
1066 return getTopOfStack().DeclareTargetLinkVarDecls;
1067 }
1068
1069 /// Adds list of allocators expressions.
1070 void addInnerAllocatorExpr(Expr *E) {
1071 getTopOfStack().InnerUsedAllocators.push_back(E);
1072 }
1073 /// Return list of used allocators.
1074 ArrayRef<Expr *> getInnerAllocators() const {
1075 return getTopOfStack().InnerUsedAllocators;
1076 }
1077 /// Marks the declaration as implicitly firstprivate nin the task-based
1078 /// regions.
1079 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1080 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1081 }
1082 /// Checks if the decl is implicitly firstprivate in the task-based region.
1083 bool isImplicitTaskFirstprivate(Decl *D) const {
1084 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1085 }
1086
1087 /// Marks decl as used in uses_allocators clause as the allocator.
1088 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1089 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1090 }
1091 /// Checks if specified decl is used in uses allocator clause as the
1092 /// allocator.
1093 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1094 const Decl *D) const {
1095 const SharingMapTy &StackElem = getTopOfStack();
1096 auto I = StackElem.UsesAllocatorsDecls.find(D);
1097 if (I == StackElem.UsesAllocatorsDecls.end())
1098 return None;
1099 return I->getSecond();
1100 }
1101 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1102 const SharingMapTy &StackElem = getTopOfStack();
1103 auto I = StackElem.UsesAllocatorsDecls.find(D);
1104 if (I == StackElem.UsesAllocatorsDecls.end())
1105 return None;
1106 return I->getSecond();
1107 }
1108
1109 void addDeclareMapperVarRef(Expr *Ref) {
1110 SharingMapTy &StackElem = getTopOfStack();
1111 StackElem.DeclareMapperVar = Ref;
1112 }
1113 const Expr *getDeclareMapperVarRef() const {
1114 const SharingMapTy *Top = getTopOfStackOrNull();
1115 return Top ? Top->DeclareMapperVar : nullptr;
1116 }
1117};
1118
1119bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1120 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1121}
1122
1123bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1124 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1125 DKind == OMPD_unknown;
1126}
1127
1128} // namespace
1129
1130static const Expr *getExprAsWritten(const Expr *E) {
1131 if (const auto *FE = dyn_cast<FullExpr>(E))
1132 E = FE->getSubExpr();
1133
1134 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1135 E = MTE->getSubExpr();
1136
1137 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1138 E = Binder->getSubExpr();
1139
1140 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1141 E = ICE->getSubExprAsWritten();
1142 return E->IgnoreParens();
1143}
1144
1145static Expr *getExprAsWritten(Expr *E) {
1146 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1147}
1148
1149static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1150 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1151 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1152 D = ME->getMemberDecl();
1153 const auto *VD = dyn_cast<VarDecl>(D);
1154 const auto *FD = dyn_cast<FieldDecl>(D);
1155 if (VD != nullptr) {
1156 VD = VD->getCanonicalDecl();
1157 D = VD;
1158 } else {
1159 assert(FD)(static_cast <bool> (FD) ? void (0) : __assert_fail ("FD"
, "clang/lib/Sema/SemaOpenMP.cpp", 1159, __extension__ __PRETTY_FUNCTION__
))
;
1160 FD = FD->getCanonicalDecl();
1161 D = FD;
1162 }
1163 return D;
1164}
1165
1166static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1167 return const_cast<ValueDecl *>(
1168 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1169}
1170
1171DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1172 ValueDecl *D) const {
1173 D = getCanonicalDecl(D);
1174 auto *VD = dyn_cast<VarDecl>(D);
1175 const auto *FD = dyn_cast<FieldDecl>(D);
1176 DSAVarData DVar;
1177 if (Iter == end()) {
1178 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1179 // in a region but not in construct]
1180 // File-scope or namespace-scope variables referenced in called routines
1181 // in the region are shared unless they appear in a threadprivate
1182 // directive.
1183 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1184 DVar.CKind = OMPC_shared;
1185
1186 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1187 // in a region but not in construct]
1188 // Variables with static storage duration that are declared in called
1189 // routines in the region are shared.
1190 if (VD && VD->hasGlobalStorage())
1191 DVar.CKind = OMPC_shared;
1192
1193 // Non-static data members are shared by default.
1194 if (FD)
1195 DVar.CKind = OMPC_shared;
1196
1197 return DVar;
1198 }
1199
1200 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1201 // in a Construct, C/C++, predetermined, p.1]
1202 // Variables with automatic storage duration that are declared in a scope
1203 // inside the construct are private.
1204 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1205 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1206 DVar.CKind = OMPC_private;
1207 return DVar;
1208 }
1209
1210 DVar.DKind = Iter->Directive;
1211 // Explicitly specified attributes and local variables with predetermined
1212 // attributes.
1213 if (Iter->SharingMap.count(D)) {
1214 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1215 DVar.RefExpr = Data.RefExpr.getPointer();
1216 DVar.PrivateCopy = Data.PrivateCopy;
1217 DVar.CKind = Data.Attributes;
1218 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1219 DVar.Modifier = Data.Modifier;
1220 DVar.AppliedToPointee = Data.AppliedToPointee;
1221 return DVar;
1222 }
1223
1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1225 // in a Construct, C/C++, implicitly determined, p.1]
1226 // In a parallel or task construct, the data-sharing attributes of these
1227 // variables are determined by the default clause, if present.
1228 switch (Iter->DefaultAttr) {
1229 case DSA_shared:
1230 DVar.CKind = OMPC_shared;
1231 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1232 return DVar;
1233 case DSA_none:
1234 return DVar;
1235 case DSA_firstprivate:
1236 if (VD->getStorageDuration() == SD_Static &&
1237 VD->getDeclContext()->isFileContext()) {
1238 DVar.CKind = OMPC_unknown;
1239 } else {
1240 DVar.CKind = OMPC_firstprivate;
1241 }
1242 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1243 return DVar;
1244 case DSA_unspecified:
1245 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1246 // in a Construct, implicitly determined, p.2]
1247 // In a parallel construct, if no default clause is present, these
1248 // variables are shared.
1249 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1250 if ((isOpenMPParallelDirective(DVar.DKind) &&
1251 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1252 isOpenMPTeamsDirective(DVar.DKind)) {
1253 DVar.CKind = OMPC_shared;
1254 return DVar;
1255 }
1256
1257 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1258 // in a Construct, implicitly determined, p.4]
1259 // In a task construct, if no default clause is present, a variable that in
1260 // the enclosing context is determined to be shared by all implicit tasks
1261 // bound to the current team is shared.
1262 if (isOpenMPTaskingDirective(DVar.DKind)) {
1263 DSAVarData DVarTemp;
1264 const_iterator I = Iter, E = end();
1265 do {
1266 ++I;
1267 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1268 // Referenced in a Construct, implicitly determined, p.6]
1269 // In a task construct, if no default clause is present, a variable
1270 // whose data-sharing attribute is not determined by the rules above is
1271 // firstprivate.
1272 DVarTemp = getDSA(I, D);
1273 if (DVarTemp.CKind != OMPC_shared) {
1274 DVar.RefExpr = nullptr;
1275 DVar.CKind = OMPC_firstprivate;
1276 return DVar;
1277 }
1278 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1279 DVar.CKind =
1280 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1281 return DVar;
1282 }
1283 }
1284 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1285 // in a Construct, implicitly determined, p.3]
1286 // For constructs other than task, if no default clause is present, these
1287 // variables inherit their data-sharing attributes from the enclosing
1288 // context.
1289 return getDSA(++Iter, D);
1290}
1291
1292const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1293 const Expr *NewDE) {
1294 assert(!isStackEmpty() && "Data sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1294, __extension__ __PRETTY_FUNCTION__
))
;
1295 D = getCanonicalDecl(D);
1296 SharingMapTy &StackElem = getTopOfStack();
1297 auto It = StackElem.AlignedMap.find(D);
1298 if (It == StackElem.AlignedMap.end()) {
1299 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")(static_cast <bool> (NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? void (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1299, __extension__ __PRETTY_FUNCTION__
))
;
1300 StackElem.AlignedMap[D] = NewDE;
1301 return nullptr;
1302 }
1303 assert(It->second && "Unexpected nullptr expr in the aligned map")(static_cast <bool> (It->second && "Unexpected nullptr expr in the aligned map"
) ? void (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1303, __extension__ __PRETTY_FUNCTION__
))
;
1304 return It->second;
1305}
1306
1307const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1308 const Expr *NewDE) {
1309 assert(!isStackEmpty() && "Data sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1309, __extension__ __PRETTY_FUNCTION__
))
;
1310 D = getCanonicalDecl(D);
1311 SharingMapTy &StackElem = getTopOfStack();
1312 auto It = StackElem.NontemporalMap.find(D);
1313 if (It == StackElem.NontemporalMap.end()) {
1314 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")(static_cast <bool> (NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? void (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1314, __extension__ __PRETTY_FUNCTION__
))
;
1315 StackElem.NontemporalMap[D] = NewDE;
1316 return nullptr;
1317 }
1318 assert(It->second && "Unexpected nullptr expr in the aligned map")(static_cast <bool> (It->second && "Unexpected nullptr expr in the aligned map"
) ? void (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1318, __extension__ __PRETTY_FUNCTION__
))
;
1319 return It->second;
1320}
1321
1322void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1323 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1323, __extension__ __PRETTY_FUNCTION__
))
;
1324 D = getCanonicalDecl(D);
1325 SharingMapTy &StackElem = getTopOfStack();
1326 StackElem.LCVMap.try_emplace(
1327 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1328}
1329
1330const DSAStackTy::LCDeclInfo
1331DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1332 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1332, __extension__ __PRETTY_FUNCTION__
))
;
1333 D = getCanonicalDecl(D);
1334 const SharingMapTy &StackElem = getTopOfStack();
1335 auto It = StackElem.LCVMap.find(D);
1336 if (It != StackElem.LCVMap.end())
1337 return It->second;
1338 return {0, nullptr};
1339}
1340
1341const DSAStackTy::LCDeclInfo
1342DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1343 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1343, __extension__ __PRETTY_FUNCTION__
))
;
1344 D = getCanonicalDecl(D);
1345 for (unsigned I = Level + 1; I > 0; --I) {
1346 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1347 auto It = StackElem.LCVMap.find(D);
1348 if (It != StackElem.LCVMap.end())
1349 return It->second;
1350 }
1351 return {0, nullptr};
1352}
1353
1354const DSAStackTy::LCDeclInfo
1355DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1356 const SharingMapTy *Parent = getSecondOnStackOrNull();
1357 assert(Parent && "Data-sharing attributes stack is empty")(static_cast <bool> (Parent && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1357, __extension__ __PRETTY_FUNCTION__
))
;
1358 D = getCanonicalDecl(D);
1359 auto It = Parent->LCVMap.find(D);
1360 if (It != Parent->LCVMap.end())
1361 return It->second;
1362 return {0, nullptr};
1363}
1364
1365const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1366 const SharingMapTy *Parent = getSecondOnStackOrNull();
1367 assert(Parent && "Data-sharing attributes stack is empty")(static_cast <bool> (Parent && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1367, __extension__ __PRETTY_FUNCTION__
))
;
1368 if (Parent->LCVMap.size() < I)
1369 return nullptr;
1370 for (const auto &Pair : Parent->LCVMap)
1371 if (Pair.second.first == I)
1372 return Pair.first;
1373 return nullptr;
1374}
1375
1376void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1377 DeclRefExpr *PrivateCopy, unsigned Modifier,
1378 bool AppliedToPointee) {
1379 D = getCanonicalDecl(D);
1380 if (A == OMPC_threadprivate) {
1381 DSAInfo &Data = Threadprivates[D];
1382 Data.Attributes = A;
1383 Data.RefExpr.setPointer(E);
1384 Data.PrivateCopy = nullptr;
1385 Data.Modifier = Modifier;
1386 } else {
1387 DSAInfo &Data = getTopOfStack().SharingMap[D];
1388 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "clang/lib/Sema/SemaOpenMP.cpp", 1391, __extension__ __PRETTY_FUNCTION__
))
1389 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "clang/lib/Sema/SemaOpenMP.cpp", 1391, __extension__ __PRETTY_FUNCTION__
))
1390 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "clang/lib/Sema/SemaOpenMP.cpp", 1391, __extension__ __PRETTY_FUNCTION__
))
1391 (isLoopControlVariable(D).first && A == OMPC_private))(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "clang/lib/Sema/SemaOpenMP.cpp", 1391, __extension__ __PRETTY_FUNCTION__
))
;
1392 Data.Modifier = Modifier;
1393 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1394 Data.RefExpr.setInt(/*IntVal=*/true);
1395 return;
1396 }
1397 const bool IsLastprivate =
1398 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1399 Data.Attributes = A;
1400 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1401 Data.PrivateCopy = PrivateCopy;
1402 Data.AppliedToPointee = AppliedToPointee;
1403 if (PrivateCopy) {
1404 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1405 Data.Modifier = Modifier;
1406 Data.Attributes = A;
1407 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1408 Data.PrivateCopy = nullptr;
1409 Data.AppliedToPointee = AppliedToPointee;
1410 }
1411 }
1412}
1413
1414/// Build a variable declaration for OpenMP loop iteration variable.
1415static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1416 StringRef Name, const AttrVec *Attrs = nullptr,
1417 DeclRefExpr *OrigRef = nullptr) {
1418 DeclContext *DC = SemaRef.CurContext;
1419 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1420 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1421 auto *Decl =
1422 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1423 if (Attrs) {
1424 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1425 I != E; ++I)
1426 Decl->addAttr(*I);
1427 }
1428 Decl->setImplicit();
1429 if (OrigRef) {
1430 Decl->addAttr(
1431 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1432 }
1433 return Decl;
1434}
1435
1436static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1437 SourceLocation Loc,
1438 bool RefersToCapture = false) {
1439 D->setReferenced();
1440 D->markUsed(S.Context);
1441 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1442 SourceLocation(), D, RefersToCapture, Loc, Ty,
1443 VK_LValue);
1444}
1445
1446void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1447 BinaryOperatorKind BOK) {
1448 D = getCanonicalDecl(D);
1449 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1449, __extension__ __PRETTY_FUNCTION__
))
;
1450 assert((static_cast <bool> (getTopOfStack().SharingMap[D].Attributes
== OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1452, __extension__ __PRETTY_FUNCTION__
))
1451 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&(static_cast <bool> (getTopOfStack().SharingMap[D].Attributes
== OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1452, __extension__ __PRETTY_FUNCTION__
))
1452 "Additional reduction info may be specified only for reduction items.")(static_cast <bool> (getTopOfStack().SharingMap[D].Attributes
== OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1452, __extension__ __PRETTY_FUNCTION__
))
;
1453 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1454 assert(ReductionData.ReductionRange.isInvalid() &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1460, __extension__ __PRETTY_FUNCTION__
))
1455 (getTopOfStack().Directive == OMPD_taskgroup ||(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1460, __extension__ __PRETTY_FUNCTION__
))
1456 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1460, __extension__ __PRETTY_FUNCTION__
))
1457 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1460, __extension__ __PRETTY_FUNCTION__
))
1458 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1460, __extension__ __PRETTY_FUNCTION__
))
1459 "Additional reduction info may be specified only once for reduction "(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1460, __extension__ __PRETTY_FUNCTION__
))
1460 "items.")(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1460, __extension__ __PRETTY_FUNCTION__
))
;
1461 ReductionData.set(BOK, SR);
1462 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1463 if (!TaskgroupReductionRef) {
1464 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1465 SemaRef.Context.VoidPtrTy, ".task_red.");
1466 TaskgroupReductionRef =
1467 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1468 }
1469}
1470
1471void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1472 const Expr *ReductionRef) {
1473 D = getCanonicalDecl(D);
1474 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1474, __extension__ __PRETTY_FUNCTION__
))
;
1475 assert((static_cast <bool> (getTopOfStack().SharingMap[D].Attributes
== OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1477, __extension__ __PRETTY_FUNCTION__
))
1476 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&(static_cast <bool> (getTopOfStack().SharingMap[D].Attributes
== OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1477, __extension__ __PRETTY_FUNCTION__
))
1477 "Additional reduction info may be specified only for reduction items.")(static_cast <bool> (getTopOfStack().SharingMap[D].Attributes
== OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1477, __extension__ __PRETTY_FUNCTION__
))
;
1478 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1479 assert(ReductionData.ReductionRange.isInvalid() &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1485, __extension__ __PRETTY_FUNCTION__
))
1480 (getTopOfStack().Directive == OMPD_taskgroup ||(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1485, __extension__ __PRETTY_FUNCTION__
))
1481 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1485, __extension__ __PRETTY_FUNCTION__
))
1482 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1485, __extension__ __PRETTY_FUNCTION__
))
1483 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1485, __extension__ __PRETTY_FUNCTION__
))
1484 "Additional reduction info may be specified only once for reduction "(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1485, __extension__ __PRETTY_FUNCTION__
))
1485 "items.")(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && (getTopOfStack().Directive == OMPD_taskgroup ||
((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective
(getTopOfStack().Directive)) && !isOpenMPSimdDirective
(getTopOfStack().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1485, __extension__ __PRETTY_FUNCTION__
))
;
1486 ReductionData.set(ReductionRef, SR);
1487 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1488 if (!TaskgroupReductionRef) {
1489 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1490 SemaRef.Context.VoidPtrTy, ".task_red.");
1491 TaskgroupReductionRef =
1492 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1493 }
1494}
1495
1496const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1497 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1498 Expr *&TaskgroupDescriptor) const {
1499 D = getCanonicalDecl(D);
1500 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1500, __extension__ __PRETTY_FUNCTION__
))
;
1501 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1502 const DSAInfo &Data = I->SharingMap.lookup(D);
1503 if (Data.Attributes != OMPC_reduction ||
1504 Data.Modifier != OMPC_REDUCTION_task)
1505 continue;
1506 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1507 if (!ReductionData.ReductionOp ||
1508 ReductionData.ReductionOp.is<const Expr *>())
1509 return DSAVarData();
1510 SR = ReductionData.ReductionRange;
1511 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1512 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1514, __extension__ __PRETTY_FUNCTION__
))
1513 "expression for the descriptor is not "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1514, __extension__ __PRETTY_FUNCTION__
))
1514 "set.")(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1514, __extension__ __PRETTY_FUNCTION__
))
;
1515 TaskgroupDescriptor = I->TaskgroupReductionRef;
1516 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1517 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1518 /*AppliedToPointee=*/false);
1519 }
1520 return DSAVarData();
1521}
1522
1523const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1524 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1525 Expr *&TaskgroupDescriptor) const {
1526 D = getCanonicalDecl(D);
1527 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1527, __extension__ __PRETTY_FUNCTION__
))
;
1528 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1529 const DSAInfo &Data = I->SharingMap.lookup(D);
1530 if (Data.Attributes != OMPC_reduction ||
1531 Data.Modifier != OMPC_REDUCTION_task)
1532 continue;
1533 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1534 if (!ReductionData.ReductionOp ||
1535 !ReductionData.ReductionOp.is<const Expr *>())
1536 return DSAVarData();
1537 SR = ReductionData.ReductionRange;
1538 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1539 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1541, __extension__ __PRETTY_FUNCTION__
))
1540 "expression for the descriptor is not "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1541, __extension__ __PRETTY_FUNCTION__
))
1541 "set.")(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1541, __extension__ __PRETTY_FUNCTION__
))
;
1542 TaskgroupDescriptor = I->TaskgroupReductionRef;
1543 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1544 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1545 /*AppliedToPointee=*/false);
1546 }
1547 return DSAVarData();
1548}
1549
1550bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1551 D = D->getCanonicalDecl();
1552 for (const_iterator E = end(); I != E; ++I) {
1553 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1554 isOpenMPTargetExecutionDirective(I->Directive)) {
1555 if (I->CurScope) {
1556 Scope *TopScope = I->CurScope->getParent();
1557 Scope *CurScope = getCurScope();
1558 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1559 CurScope = CurScope->getParent();
1560 return CurScope != TopScope;
1561 }
1562 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1563 if (I->Context == DC)
1564 return true;
1565 return false;
1566 }
1567 }
1568 return false;
1569}
1570
1571static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1572 bool AcceptIfMutable = true,
1573 bool *IsClassType = nullptr) {
1574 ASTContext &Context = SemaRef.getASTContext();
1575 Type = Type.getNonReferenceType().getCanonicalType();
1576 bool IsConstant = Type.isConstant(Context);
1577 Type = Context.getBaseElementType(Type);
1578 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1579 ? Type->getAsCXXRecordDecl()
1580 : nullptr;
1581 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1582 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1583 RD = CTD->getTemplatedDecl();
1584 if (IsClassType)
1585 *IsClassType = RD;
1586 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1587 RD->hasDefinition() && RD->hasMutableFields());
1588}
1589
1590static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1591 QualType Type, OpenMPClauseKind CKind,
1592 SourceLocation ELoc,
1593 bool AcceptIfMutable = true,
1594 bool ListItemNotVar = false) {
1595 ASTContext &Context = SemaRef.getASTContext();
1596 bool IsClassType;
1597 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1598 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1599 : IsClassType ? diag::err_omp_const_not_mutable_variable
1600 : diag::err_omp_const_variable;
1601 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1602 if (!ListItemNotVar && D) {
1603 const VarDecl *VD = dyn_cast<VarDecl>(D);
1604 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1605 VarDecl::DeclarationOnly;
1606 SemaRef.Diag(D->getLocation(),
1607 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1608 << D;
1609 }
1610 return true;
1611 }
1612 return false;
1613}
1614
1615const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1616 bool FromParent) {
1617 D = getCanonicalDecl(D);
1618 DSAVarData DVar;
1619
1620 auto *VD = dyn_cast<VarDecl>(D);
1621 auto TI = Threadprivates.find(D);
1622 if (TI != Threadprivates.end()) {
1623 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1624 DVar.CKind = OMPC_threadprivate;
1625 DVar.Modifier = TI->getSecond().Modifier;
1626 return DVar;
1627 }
1628 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1629 DVar.RefExpr = buildDeclRefExpr(
1630 SemaRef, VD, D->getType().getNonReferenceType(),
1631 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1632 DVar.CKind = OMPC_threadprivate;
1633 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1634 return DVar;
1635 }
1636 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1637 // in a Construct, C/C++, predetermined, p.1]
1638 // Variables appearing in threadprivate directives are threadprivate.
1639 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1640 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1641 SemaRef.getLangOpts().OpenMPUseTLS &&
1642 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1643 (VD && VD->getStorageClass() == SC_Register &&
1644 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1645 DVar.RefExpr = buildDeclRefExpr(
1646 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1647 DVar.CKind = OMPC_threadprivate;
1648 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1649 return DVar;
1650 }
1651 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1652 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1653 !isLoopControlVariable(D).first) {
1654 const_iterator IterTarget =
1655 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1656 return isOpenMPTargetExecutionDirective(Data.Directive);
1657 });
1658 if (IterTarget != end()) {
1659 const_iterator ParentIterTarget = IterTarget + 1;
1660 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1661 if (isOpenMPLocal(VD, Iter)) {
1662 DVar.RefExpr =
1663 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1664 D->getLocation());
1665 DVar.CKind = OMPC_threadprivate;
1666 return DVar;
1667 }
1668 }
1669 if (!isClauseParsingMode() || IterTarget != begin()) {
1670 auto DSAIter = IterTarget->SharingMap.find(D);
1671 if (DSAIter != IterTarget->SharingMap.end() &&
1672 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1673 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1674 DVar.CKind = OMPC_threadprivate;
1675 return DVar;
1676 }
1677 const_iterator End = end();
1678 if (!SemaRef.isOpenMPCapturedByRef(D,
1679 std::distance(ParentIterTarget, End),
1680 /*OpenMPCaptureLevel=*/0)) {
1681 DVar.RefExpr =
1682 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1683 IterTarget->ConstructLoc);
1684 DVar.CKind = OMPC_threadprivate;
1685 return DVar;
1686 }
1687 }
1688 }
1689 }
1690
1691 if (isStackEmpty())
1692 // Not in OpenMP execution region and top scope was already checked.
1693 return DVar;
1694
1695 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1696 // in a Construct, C/C++, predetermined, p.4]
1697 // Static data members are shared.
1698 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1699 // in a Construct, C/C++, predetermined, p.7]
1700 // Variables with static storage duration that are declared in a scope
1701 // inside the construct are shared.
1702 if (VD && VD->isStaticDataMember()) {
1703 // Check for explicitly specified attributes.
1704 const_iterator I = begin();
1705 const_iterator EndI = end();
1706 if (FromParent && I != EndI)
1707 ++I;
1708 if (I != EndI) {
1709 auto It = I->SharingMap.find(D);
1710 if (It != I->SharingMap.end()) {
1711 const DSAInfo &Data = It->getSecond();
1712 DVar.RefExpr = Data.RefExpr.getPointer();
1713 DVar.PrivateCopy = Data.PrivateCopy;
1714 DVar.CKind = Data.Attributes;
1715 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1716 DVar.DKind = I->Directive;
1717 DVar.Modifier = Data.Modifier;
1718 DVar.AppliedToPointee = Data.AppliedToPointee;
1719 return DVar;
1720 }
1721 }
1722
1723 DVar.CKind = OMPC_shared;
1724 return DVar;
1725 }
1726
1727 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1728 // The predetermined shared attribute for const-qualified types having no
1729 // mutable members was removed after OpenMP 3.1.
1730 if (SemaRef.LangOpts.OpenMP <= 31) {
1731 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1732 // in a Construct, C/C++, predetermined, p.6]
1733 // Variables with const qualified type having no mutable member are
1734 // shared.
1735 if (isConstNotMutableType(SemaRef, D->getType())) {
1736 // Variables with const-qualified type having no mutable member may be
1737 // listed in a firstprivate clause, even if they are static data members.
1738 DSAVarData DVarTemp = hasInnermostDSA(
1739 D,
1740 [](OpenMPClauseKind C, bool) {
1741 return C == OMPC_firstprivate || C == OMPC_shared;
1742 },
1743 MatchesAlways, FromParent);
1744 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1745 return DVarTemp;
1746
1747 DVar.CKind = OMPC_shared;
1748 return DVar;
1749 }
1750 }
1751
1752 // Explicitly specified attributes and local variables with predetermined
1753 // attributes.
1754 const_iterator I = begin();
1755 const_iterator EndI = end();
1756 if (FromParent && I != EndI)
1757 ++I;
1758 if (I == EndI)
1759 return DVar;
1760 auto It = I->SharingMap.find(D);
1761 if (It != I->SharingMap.end()) {
1762 const DSAInfo &Data = It->getSecond();
1763 DVar.RefExpr = Data.RefExpr.getPointer();
1764 DVar.PrivateCopy = Data.PrivateCopy;
1765 DVar.CKind = Data.Attributes;
1766 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1767 DVar.DKind = I->Directive;
1768 DVar.Modifier = Data.Modifier;
1769 DVar.AppliedToPointee = Data.AppliedToPointee;
1770 }
1771
1772 return DVar;
1773}
1774
1775const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1776 bool FromParent) const {
1777 if (isStackEmpty()) {
1778 const_iterator I;
1779 return getDSA(I, D);
1780 }
1781 D = getCanonicalDecl(D);
1782 const_iterator StartI = begin();
1783 const_iterator EndI = end();
1784 if (FromParent && StartI != EndI)
1785 ++StartI;
1786 return getDSA(StartI, D);
1787}
1788
1789const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1790 unsigned Level) const {
1791 if (getStackSize() <= Level)
1792 return DSAVarData();
1793 D = getCanonicalDecl(D);
1794 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1795 return getDSA(StartI, D);
1796}
1797
1798const DSAStackTy::DSAVarData
1799DSAStackTy::hasDSA(ValueDecl *D,
1800 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1801 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1802 bool FromParent) const {
1803 if (isStackEmpty())
1804 return {};
1805 D = getCanonicalDecl(D);
1806 const_iterator I = begin();
1807 const_iterator EndI = end();
1808 if (FromParent && I != EndI)
1809 ++I;
1810 for (; I != EndI; ++I) {
1811 if (!DPred(I->Directive) &&
1812 !isImplicitOrExplicitTaskingRegion(I->Directive))
1813 continue;
1814 const_iterator NewI = I;
1815 DSAVarData DVar = getDSA(NewI, D);
1816 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1817 return DVar;
1818 }
1819 return {};
1820}
1821
1822const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1823 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1824 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1825 bool FromParent) const {
1826 if (isStackEmpty())
1827 return {};
1828 D = getCanonicalDecl(D);
1829 const_iterator StartI = begin();
1830 const_iterator EndI = end();
1831 if (FromParent && StartI != EndI)
1832 ++StartI;
1833 if (StartI == EndI || !DPred(StartI->Directive))
1834 return {};
1835 const_iterator NewI = StartI;
1836 DSAVarData DVar = getDSA(NewI, D);
1837 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1838 ? DVar
1839 : DSAVarData();
1840}
1841
1842bool DSAStackTy::hasExplicitDSA(
1843 const ValueDecl *D,
1844 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1845 unsigned Level, bool NotLastprivate) const {
1846 if (getStackSize() <= Level)
1847 return false;
1848 D = getCanonicalDecl(D);
1849 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1850 auto I = StackElem.SharingMap.find(D);
1851 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1852 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1853 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1854 return true;
1855 // Check predetermined rules for the loop control variables.
1856 auto LI = StackElem.LCVMap.find(D);
1857 if (LI != StackElem.LCVMap.end())
1858 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1859 return false;
1860}
1861
1862bool DSAStackTy::hasExplicitDirective(
1863 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1864 unsigned Level) const {
1865 if (getStackSize() <= Level)
1866 return false;
1867 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1868 return DPred(StackElem.Directive);
1869}
1870
1871bool DSAStackTy::hasDirective(
1872 const llvm::function_ref<bool(OpenMPDirectiveKind,
1873 const DeclarationNameInfo &, SourceLocation)>
1874 DPred,
1875 bool FromParent) const {
1876 // We look only in the enclosing region.
1877 size_t Skip = FromParent ? 2 : 1;
1878 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1879 I != E; ++I) {
1880 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1881 return true;
1882 }
1883 return false;
1884}
1885
1886void Sema::InitDataSharingAttributesStack() {
1887 VarDataSharingAttributesStack = new DSAStackTy(*this);
1888}
1889
1890#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1891
1892void Sema::pushOpenMPFunctionRegion() { DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction(); }
1893
1894void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1895 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1896}
1897
1898static bool isOpenMPDeviceDelayedContext(Sema &S) {
1899 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&(static_cast <bool> (S.LangOpts.OpenMP && S.LangOpts
.OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1900, __extension__ __PRETTY_FUNCTION__
))
1900 "Expected OpenMP device compilation.")(static_cast <bool> (S.LangOpts.OpenMP && S.LangOpts
.OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1900, __extension__ __PRETTY_FUNCTION__
))
;
1901 return !S.isInOpenMPTargetExecutionDirective();
1902}
1903
1904namespace {
1905/// Status of the function emission on the host/device.
1906enum class FunctionEmissionStatus {
1907 Emitted,
1908 Discarded,
1909 Unknown,
1910};
1911} // anonymous namespace
1912
1913Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1914 unsigned DiagID,
1915 FunctionDecl *FD) {
1916 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&(static_cast <bool> (LangOpts.OpenMP && LangOpts
.OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1917, __extension__ __PRETTY_FUNCTION__
))
1917 "Expected OpenMP device compilation.")(static_cast <bool> (LangOpts.OpenMP && LangOpts
.OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1917, __extension__ __PRETTY_FUNCTION__
))
;
1918
1919 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1920 if (FD) {
1921 FunctionEmissionStatus FES = getEmissionStatus(FD);
1922 switch (FES) {
1923 case FunctionEmissionStatus::Emitted:
1924 Kind = SemaDiagnosticBuilder::K_Immediate;
1925 break;
1926 case FunctionEmissionStatus::Unknown:
1927 // TODO: We should always delay diagnostics here in case a target
1928 // region is in a function we do not emit. However, as the
1929 // current diagnostics are associated with the function containing
1930 // the target region and we do not emit that one, we would miss out
1931 // on diagnostics for the target region itself. We need to anchor
1932 // the diagnostics with the new generated function *or* ensure we
1933 // emit diagnostics associated with the surrounding function.
1934 Kind = isOpenMPDeviceDelayedContext(*this)
1935 ? SemaDiagnosticBuilder::K_Deferred
1936 : SemaDiagnosticBuilder::K_Immediate;
1937 break;
1938 case FunctionEmissionStatus::TemplateDiscarded:
1939 case FunctionEmissionStatus::OMPDiscarded:
1940 Kind = SemaDiagnosticBuilder::K_Nop;
1941 break;
1942 case FunctionEmissionStatus::CUDADiscarded:
1943 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "clang/lib/Sema/SemaOpenMP.cpp", 1943)
;
1944 break;
1945 }
1946 }
1947
1948 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1949}
1950
1951Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1952 unsigned DiagID,
1953 FunctionDecl *FD) {
1954 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&(static_cast <bool> (LangOpts.OpenMP && !LangOpts
.OpenMPIsDevice && "Expected OpenMP host compilation."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1955, __extension__ __PRETTY_FUNCTION__
))
1955 "Expected OpenMP host compilation.")(static_cast <bool> (LangOpts.OpenMP && !LangOpts
.OpenMPIsDevice && "Expected OpenMP host compilation."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1955, __extension__ __PRETTY_FUNCTION__
))
;
1956
1957 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1958 if (FD) {
1959 FunctionEmissionStatus FES = getEmissionStatus(FD);
1960 switch (FES) {
1961 case FunctionEmissionStatus::Emitted:
1962 Kind = SemaDiagnosticBuilder::K_Immediate;
1963 break;
1964 case FunctionEmissionStatus::Unknown:
1965 Kind = SemaDiagnosticBuilder::K_Deferred;
1966 break;
1967 case FunctionEmissionStatus::TemplateDiscarded:
1968 case FunctionEmissionStatus::OMPDiscarded:
1969 case FunctionEmissionStatus::CUDADiscarded:
1970 Kind = SemaDiagnosticBuilder::K_Nop;
1971 break;
1972 }
1973 }
1974
1975 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1976}
1977
1978static OpenMPDefaultmapClauseKind
1979getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1980 if (LO.OpenMP <= 45) {
1981 if (VD->getType().getNonReferenceType()->isScalarType())
1982 return OMPC_DEFAULTMAP_scalar;
1983 return OMPC_DEFAULTMAP_aggregate;
1984 }
1985 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1986 return OMPC_DEFAULTMAP_pointer;
1987 if (VD->getType().getNonReferenceType()->isScalarType())
1988 return OMPC_DEFAULTMAP_scalar;
1989 return OMPC_DEFAULTMAP_aggregate;
1990}
1991
1992bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1993 unsigned OpenMPCaptureLevel) const {
1994 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "clang/lib/Sema/SemaOpenMP.cpp", 1994, __extension__ __PRETTY_FUNCTION__
))
;
1995
1996 ASTContext &Ctx = getASTContext();
1997 bool IsByRef = true;
1998
1999 // Find the directive that is associated with the provided scope.
2000 D = cast<ValueDecl>(D->getCanonicalDecl());
2001 QualType Ty = D->getType();
2002
2003 bool IsVariableUsedInMapClause = false;
2004 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2005 // This table summarizes how a given variable should be passed to the device
2006 // given its type and the clauses where it appears. This table is based on
2007 // the description in OpenMP 4.5 [2.10.4, target Construct] and
2008 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2009 //
2010 // =========================================================================
2011 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
2012 // | |(tofrom:scalar)| | pvt | | | |
2013 // =========================================================================
2014 // | scl | | | | - | | bycopy|
2015 // | scl | | - | x | - | - | bycopy|
2016 // | scl | | x | - | - | - | null |
2017 // | scl | x | | | - | | byref |
2018 // | scl | x | - | x | - | - | bycopy|
2019 // | scl | x | x | - | - | - | null |
2020 // | scl | | - | - | - | x | byref |
2021 // | scl | x | - | - | - | x | byref |
2022 //
2023 // | agg | n.a. | | | - | | byref |
2024 // | agg | n.a. | - | x | - | - | byref |
2025 // | agg | n.a. | x | - | - | - | null |
2026 // | agg | n.a. | - | - | - | x | byref |
2027 // | agg | n.a. | - | - | - | x[] | byref |
2028 //
2029 // | ptr | n.a. | | | - | | bycopy|
2030 // | ptr | n.a. | - | x | - | - | bycopy|
2031 // | ptr | n.a. | x | - | - | - | null |
2032 // | ptr | n.a. | - | - | - | x | byref |
2033 // | ptr | n.a. | - | - | - | x[] | bycopy|
2034 // | ptr | n.a. | - | - | x | | bycopy|
2035 // | ptr | n.a. | - | - | x | x | bycopy|
2036 // | ptr | n.a. | - | - | x | x[] | bycopy|
2037 // =========================================================================
2038 // Legend:
2039 // scl - scalar
2040 // ptr - pointer
2041 // agg - aggregate
2042 // x - applies
2043 // - - invalid in this combination
2044 // [] - mapped with an array section
2045 // byref - should be mapped by reference
2046 // byval - should be mapped by value
2047 // null - initialize a local variable to null on the device
2048 //
2049 // Observations:
2050 // - All scalar declarations that show up in a map clause have to be passed
2051 // by reference, because they may have been mapped in the enclosing data
2052 // environment.
2053 // - If the scalar value does not fit the size of uintptr, it has to be
2054 // passed by reference, regardless the result in the table above.
2055 // - For pointers mapped by value that have either an implicit map or an
2056 // array section, the runtime library may pass the NULL value to the
2057 // device instead of the value passed to it by the compiler.
2058
2059 if (Ty->isReferenceType())
2060 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2061
2062 // Locate map clauses and see if the variable being captured is referred to
2063 // in any of those clauses. Here we only care about variables, not fields,
2064 // because fields are part of aggregates.
2065 bool IsVariableAssociatedWithSection = false;
2066
2067 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2068 D, Level,
2069 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2070 D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2071 MapExprComponents,
2072 OpenMPClauseKind WhereFoundClauseKind) {
2073 // Only the map clause information influences how a variable is
2074 // captured. E.g. is_device_ptr does not require changing the default
2075 // behavior.
2076 if (WhereFoundClauseKind != OMPC_map)
2077 return false;
2078
2079 auto EI = MapExprComponents.rbegin();
2080 auto EE = MapExprComponents.rend();
2081
2082 assert(EI != EE && "Invalid map expression!")(static_cast <bool> (EI != EE && "Invalid map expression!"
) ? void (0) : __assert_fail ("EI != EE && \"Invalid map expression!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2082, __extension__ __PRETTY_FUNCTION__
))
;
2083
2084 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2085 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2086
2087 ++EI;
2088 if (EI == EE)
2089 return false;
2090
2091 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2092 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2093 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2094 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2095 IsVariableAssociatedWithSection = true;
2096 // There is nothing more we need to know about this variable.
2097 return true;
2098 }
2099
2100 // Keep looking for more map info.
2101 return false;
2102 });
2103
2104 if (IsVariableUsedInMapClause) {
2105 // If variable is identified in a map clause it is always captured by
2106 // reference except if it is a pointer that is dereferenced somehow.
2107 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2108 } else {
2109 // By default, all the data that has a scalar type is mapped by copy
2110 // (except for reduction variables).
2111 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2112 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2113 !Ty->isAnyPointerType()) ||
2114 !Ty->isScalarType() ||
2115 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2116 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2117 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2118 D,
2119 [](OpenMPClauseKind K, bool AppliedToPointee) {
2120 return K == OMPC_reduction && !AppliedToPointee;
2121 },
2122 Level);
2123 }
2124 }
2125
2126 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2127 IsByRef =
2128 ((IsVariableUsedInMapClause &&
2129 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2130 OMPD_target) ||
2131 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2132 D,
2133 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2134 return K == OMPC_firstprivate ||
2135 (K == OMPC_reduction && AppliedToPointee);
2136 },
2137 Level, /*NotLastprivate=*/true) ||
2138 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2139 // If the variable is artificial and must be captured by value - try to
2140 // capture by value.
2141 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2142 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2143 // If the variable is implicitly firstprivate and scalar - capture by
2144 // copy
2145 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2146 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2147 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2148 Level) &&
2149 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2150 }
2151
2152 // When passing data by copy, we need to make sure it fits the uintptr size
2153 // and alignment, because the runtime library only deals with uintptr types.
2154 // If it does not fit the uintptr size, we need to pass the data by reference
2155 // instead.
2156 if (!IsByRef &&
2157 (Ctx.getTypeSizeInChars(Ty) >
2158 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2159 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2160 IsByRef = true;
2161 }
2162
2163 return IsByRef;
2164}
2165
2166unsigned Sema::getOpenMPNestingLevel() const {
2167 assert(getLangOpts().OpenMP)(static_cast <bool> (getLangOpts().OpenMP) ? void (0) :
__assert_fail ("getLangOpts().OpenMP", "clang/lib/Sema/SemaOpenMP.cpp"
, 2167, __extension__ __PRETTY_FUNCTION__))
;
2168 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2169}
2170
2171bool Sema::isInOpenMPTaskUntiedContext() const {
2172 return isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2173 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUntiedRegion();
2174}
2175
2176bool Sema::isInOpenMPTargetExecutionDirective() const {
2177 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2178 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2179 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2180 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2181 SourceLocation) -> bool {
2182 return isOpenMPTargetExecutionDirective(K);
2183 },
2184 false);
2185}
2186
2187VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2188 unsigned StopAt) {
2189 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2189, __extension__ __PRETTY_FUNCTION__
))
;
2190 D = getCanonicalDecl(D);
2191
2192 auto *VD = dyn_cast<VarDecl>(D);
2193 // Do not capture constexpr variables.
2194 if (VD && VD->isConstexpr())
2195 return nullptr;
2196
2197 // If we want to determine whether the variable should be captured from the
2198 // perspective of the current capturing scope, and we've already left all the
2199 // capturing scopes of the top directive on the stack, check from the
2200 // perspective of its parent directive (if any) instead.
2201 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2202 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2203
2204 // If we are attempting to capture a global variable in a directive with
2205 // 'target' we return true so that this global is also mapped to the device.
2206 //
2207 if (VD && !VD->hasLocalStorage() &&
2208 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2209 if (isInOpenMPTargetExecutionDirective()) {
2210 DSAStackTy::DSAVarData DVarTop =
2211 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2212 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2213 return VD;
2214 // If the declaration is enclosed in a 'declare target' directive,
2215 // then it should not be captured.
2216 //
2217 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2218 return nullptr;
2219 CapturedRegionScopeInfo *CSI = nullptr;
2220 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2221 llvm::reverse(FunctionScopes),
2222 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2223 if (!isa<CapturingScopeInfo>(FSI))
2224 return nullptr;
2225 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2226 if (RSI->CapRegionKind == CR_OpenMP) {
2227 CSI = RSI;
2228 break;
2229 }
2230 }
2231 assert(CSI && "Failed to find CapturedRegionScopeInfo")(static_cast <bool> (CSI && "Failed to find CapturedRegionScopeInfo"
) ? void (0) : __assert_fail ("CSI && \"Failed to find CapturedRegionScopeInfo\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2231, __extension__ __PRETTY_FUNCTION__
))
;
2232 SmallVector<OpenMPDirectiveKind, 4> Regions;
2233 getOpenMPCaptureRegions(Regions,
2234 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2235 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2236 return VD;
2237 }
2238 if (isInOpenMPDeclareTargetContext()) {
2239 // Try to mark variable as declare target if it is used in capturing
2240 // regions.
2241 if (LangOpts.OpenMP <= 45 &&
2242 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2243 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2244 return nullptr;
2245 }
2246 }
2247
2248 if (CheckScopeInfo) {
2249 bool OpenMPFound = false;
2250 for (unsigned I = StopAt + 1; I > 0; --I) {
2251 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2252 if (!isa<CapturingScopeInfo>(FSI))
2253 return nullptr;
2254 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2255 if (RSI->CapRegionKind == CR_OpenMP) {
2256 OpenMPFound = true;
2257 break;
2258 }
2259 }
2260 if (!OpenMPFound)
2261 return nullptr;
2262 }
2263
2264 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2265 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2266 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2267 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2268 if (Info.first ||
2269 (VD && VD->hasLocalStorage() &&
2270 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2271 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2272 return VD ? VD : Info.second;
2273 DSAStackTy::DSAVarData DVarTop =
2274 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2275 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2276 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2277 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2278 // Threadprivate variables must not be captured.
2279 if (isOpenMPThreadPrivate(DVarTop.CKind))
2280 return nullptr;
2281 // The variable is not private or it is the variable in the directive with
2282 // default(none) clause and not used in any clause.
2283 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2284 D,
2285 [](OpenMPClauseKind C, bool AppliedToPointee) {
2286 return isOpenMPPrivate(C) && !AppliedToPointee;
2287 },
2288 [](OpenMPDirectiveKind) { return true; },
2289 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2290 // Global shared must not be captured.
2291 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2292 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2293 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2294 DVarTop.CKind == OMPC_shared))
2295 return nullptr;
2296 if (DVarPrivate.CKind != OMPC_unknown ||
2297 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2298 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2299 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2300 }
2301 return nullptr;
2302}
2303
2304void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2305 unsigned Level) const {
2306 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2307}
2308
2309void Sema::startOpenMPLoop() {
2310 assert(LangOpts.OpenMP && "OpenMP must be enabled.")(static_cast <bool> (LangOpts.OpenMP && "OpenMP must be enabled."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2310, __extension__ __PRETTY_FUNCTION__
))
;
2311 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2312 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2313}
2314
2315void Sema::startOpenMPCXXRangeFor() {
2316 assert(LangOpts.OpenMP && "OpenMP must be enabled.")(static_cast <bool> (LangOpts.OpenMP && "OpenMP must be enabled."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2316, __extension__ __PRETTY_FUNCTION__
))
;
2317 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2318 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2319 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2320 }
2321}
2322
2323OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2324 unsigned CapLevel) const {
2325 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2325, __extension__ __PRETTY_FUNCTION__
))
;
2326 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2327 bool IsTriviallyCopyable =
2328 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2329 !D->getType()
2330 .getNonReferenceType()
2331 .getCanonicalType()
2332 ->getAsCXXRecordDecl();
2333 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2334 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2335 getOpenMPCaptureRegions(CaptureRegions, DKind);
2336 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2337 (IsTriviallyCopyable ||
2338 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2339 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2340 D,
2341 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2342 Level, /*NotLastprivate=*/true))
2343 return OMPC_firstprivate;
2344 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2345 if (DVar.CKind != OMPC_shared &&
2346 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2347 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2348 return OMPC_firstprivate;
2349 }
2350 }
2351 }
2352 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2353 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2354 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2355 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2356 return OMPC_private;
2357 }
2358 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2359 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2360 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2361 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2362 Level) &&
2363 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2364 return OMPC_private;
2365 }
2366 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2367 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2368 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2369 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2370 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2371 Level))
2372 return OMPC_private;
2373 }
2374 // User-defined allocators are private since they must be defined in the
2375 // context of target region.
2376 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2377 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2378 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2379 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2380 return OMPC_private;
2381 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2382 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2383 Level) ||
2384 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2385 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2386 // Consider taskgroup reduction descriptor variable a private
2387 // to avoid possible capture in the region.
2388 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2389 [](OpenMPDirectiveKind K) {
2390 return K == OMPD_taskgroup ||
2391 ((isOpenMPParallelDirective(K) ||
2392 isOpenMPWorksharingDirective(K)) &&
2393 !isOpenMPSimdDirective(K));
2394 },
2395 Level) &&
2396 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2397 ? OMPC_private
2398 : OMPC_unknown;
2399}
2400
2401void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2402 unsigned Level) {
2403 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2403, __extension__ __PRETTY_FUNCTION__
))
;
2404 D = getCanonicalDecl(D);
2405 OpenMPClauseKind OMPC = OMPC_unknown;
2406 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2407 const unsigned NewLevel = I - 1;
2408 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2409 D,
2410 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2411 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2412 OMPC = K;
2413 return true;
2414 }
2415 return false;
2416 },
2417 NewLevel))
2418 break;
2419 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2420 D, NewLevel,
2421 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2422 OpenMPClauseKind) { return true; })) {
2423 OMPC = OMPC_map;
2424 break;
2425 }
2426 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2427 NewLevel)) {
2428 OMPC = OMPC_map;
2429 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2430 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2431 OMPC = OMPC_firstprivate;
2432 break;
2433 }
2434 }
2435 if (OMPC != OMPC_unknown)
2436 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2437}
2438
2439bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2440 unsigned CaptureLevel) const {
2441 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2441, __extension__ __PRETTY_FUNCTION__
))
;
2442 // Return true if the current level is no longer enclosed in a target region.
2443
2444 SmallVector<OpenMPDirectiveKind, 4> Regions;
2445 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2446 const auto *VD = dyn_cast<VarDecl>(D);
2447 return VD && !VD->hasLocalStorage() &&
2448 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2449 Level) &&
2450 Regions[CaptureLevel] != OMPD_task;
2451}
2452
2453bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2454 unsigned CaptureLevel) const {
2455 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2455, __extension__ __PRETTY_FUNCTION__
))
;
2456 // Return true if the current level is no longer enclosed in a target region.
2457
2458 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2459 if (!VD->hasLocalStorage()) {
2460 if (isInOpenMPTargetExecutionDirective())
2461 return true;
2462 DSAStackTy::DSAVarData TopDVar =
2463 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2464 unsigned NumLevels =
2465 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2466 if (Level == 0)
2467 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2468 do {
2469 --Level;
2470 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2471 if (DVar.CKind != OMPC_shared)
2472 return true;
2473 } while (Level > 0);
2474 }
2475 }
2476 return true;
2477}
2478
2479void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2480
2481void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2482 OMPTraitInfo &TI) {
2483 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2484}
2485
2486void Sema::ActOnOpenMPEndDeclareVariant() {
2487 assert(isInOpenMPDeclareVariantScope() &&(static_cast <bool> (isInOpenMPDeclareVariantScope() &&
"Not in OpenMP declare variant scope!") ? void (0) : __assert_fail
("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2488, __extension__ __PRETTY_FUNCTION__
))
2488 "Not in OpenMP declare variant scope!")(static_cast <bool> (isInOpenMPDeclareVariantScope() &&
"Not in OpenMP declare variant scope!") ? void (0) : __assert_fail
("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2488, __extension__ __PRETTY_FUNCTION__
))
;
2489
2490 OMPDeclareVariantScopes.pop_back();
2491}
2492
2493void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2494 const FunctionDecl *Callee,
2495 SourceLocation Loc) {
2496 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.")(static_cast <bool> (LangOpts.OpenMP && "Expected OpenMP compilation mode."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP compilation mode.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2496, __extension__ __PRETTY_FUNCTION__
))
;
2497 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2498 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2499 // Ignore host functions during device analyzis.
2500 if (LangOpts.OpenMPIsDevice &&
2501 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2502 return;
2503 // Ignore nohost functions during host analyzis.
2504 if (!LangOpts.OpenMPIsDevice && DevTy &&
2505 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2506 return;
2507 const FunctionDecl *FD = Callee->getMostRecentDecl();
2508 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2509 if (LangOpts.OpenMPIsDevice && DevTy &&
2510 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2511 // Diagnose host function called during device codegen.
2512 StringRef HostDevTy =
2513 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2514 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2515 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2516 diag::note_omp_marked_device_type_here)
2517 << HostDevTy;
2518 return;
2519 }
2520 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
2521 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2522 // Diagnose nohost function called during host codegen.
2523 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2524 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2525 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2526 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2527 diag::note_omp_marked_device_type_here)
2528 << NoHostDevTy;
2529 }
2530}
2531
2532void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2533 const DeclarationNameInfo &DirName,
2534 Scope *CurScope, SourceLocation Loc) {
2535 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2536 PushExpressionEvaluationContext(
2537 ExpressionEvaluationContext::PotentiallyEvaluated);
2538}
2539
2540void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2541 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2542}
2543
2544void Sema::EndOpenMPClause() {
2545 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2546 CleanupVarDeclMarking();
2547}
2548
2549static std::pair<ValueDecl *, bool>
2550getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2551 SourceRange &ERange, bool AllowArraySection = false);
2552
2553/// Check consistency of the reduction clauses.
2554static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2555 ArrayRef<OMPClause *> Clauses) {
2556 bool InscanFound = false;
2557 SourceLocation InscanLoc;
2558 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2559 // A reduction clause without the inscan reduction-modifier may not appear on
2560 // a construct on which a reduction clause with the inscan reduction-modifier
2561 // appears.
2562 for (OMPClause *C : Clauses) {
2563 if (C->getClauseKind() != OMPC_reduction)
2564 continue;
2565 auto *RC = cast<OMPReductionClause>(C);
2566 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2567 InscanFound = true;
2568 InscanLoc = RC->getModifierLoc();
2569 continue;
2570 }
2571 if (RC->getModifier() == OMPC_REDUCTION_task) {
2572 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2573 // A reduction clause with the task reduction-modifier may only appear on
2574 // a parallel construct, a worksharing construct or a combined or
2575 // composite construct for which any of the aforementioned constructs is a
2576 // constituent construct and simd or loop are not constituent constructs.
2577 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2578 if (!(isOpenMPParallelDirective(CurDir) ||
2579 isOpenMPWorksharingDirective(CurDir)) ||
2580 isOpenMPSimdDirective(CurDir))
2581 S.Diag(RC->getModifierLoc(),
2582 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2583 continue;
2584 }
2585 }
2586 if (InscanFound) {
2587 for (OMPClause *C : Clauses) {
2588 if (C->getClauseKind() != OMPC_reduction)
2589 continue;
2590 auto *RC = cast<OMPReductionClause>(C);
2591 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2592 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2593 ? RC->getBeginLoc()
2594 : RC->getModifierLoc(),
2595 diag::err_omp_inscan_reduction_expected);
2596 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2597 continue;
2598 }
2599 for (Expr *Ref : RC->varlists()) {
2600 assert(Ref && "NULL expr in OpenMP nontemporal clause.")(static_cast <bool> (Ref && "NULL expr in OpenMP nontemporal clause."
) ? void (0) : __assert_fail ("Ref && \"NULL expr in OpenMP nontemporal clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2600, __extension__ __PRETTY_FUNCTION__
))
;
2601 SourceLocation ELoc;
2602 SourceRange ERange;
2603 Expr *SimpleRefExpr = Ref;
2604 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2605 /*AllowArraySection=*/true);
2606 ValueDecl *D = Res.first;
2607 if (!D)
2608 continue;
2609 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2610 S.Diag(Ref->getExprLoc(),
2611 diag::err_omp_reduction_not_inclusive_exclusive)
2612 << Ref->getSourceRange();
2613 }
2614 }
2615 }
2616 }
2617}
2618
2619static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2620 ArrayRef<OMPClause *> Clauses);
2621static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2622 bool WithInit);
2623
2624static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2625 const ValueDecl *D,
2626 const DSAStackTy::DSAVarData &DVar,
2627 bool IsLoopIterVar = false);
2628
2629void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2630 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2631 // A variable of class type (or array thereof) that appears in a lastprivate
2632 // clause requires an accessible, unambiguous default constructor for the
2633 // class type, unless the list item is also specified in a firstprivate
2634 // clause.
2635 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2636 for (OMPClause *C : D->clauses()) {
2637 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2638 SmallVector<Expr *, 8> PrivateCopies;
2639 for (Expr *DE : Clause->varlists()) {
2640 if (DE->isValueDependent() || DE->isTypeDependent()) {
2641 PrivateCopies.push_back(nullptr);
2642 continue;
2643 }
2644 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2645 auto *VD = cast<VarDecl>(DRE->getDecl());
2646 QualType Type = VD->getType().getNonReferenceType();
2647 const DSAStackTy::DSAVarData DVar =
2648 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2649 if (DVar.CKind == OMPC_lastprivate) {
2650 // Generate helper private variable and initialize it with the
2651 // default value. The address of the original variable is replaced
2652 // by the address of the new private variable in CodeGen. This new
2653 // variable is not added to IdResolver, so the code in the OpenMP
2654 // region uses original variable for proper diagnostics.
2655 VarDecl *VDPrivate = buildVarDecl(
2656 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2657 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2658 ActOnUninitializedDecl(VDPrivate);
2659 if (VDPrivate->isInvalidDecl()) {
2660 PrivateCopies.push_back(nullptr);
2661 continue;
2662 }
2663 PrivateCopies.push_back(buildDeclRefExpr(
2664 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2665 } else {
2666 // The variable is also a firstprivate, so initialization sequence
2667 // for private copy is generated already.
2668 PrivateCopies.push_back(nullptr);
2669 }
2670 }
2671 Clause->setPrivateCopies(PrivateCopies);
2672 continue;
2673 }
2674 // Finalize nontemporal clause by handling private copies, if any.
2675 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2676 SmallVector<Expr *, 8> PrivateRefs;
2677 for (Expr *RefExpr : Clause->varlists()) {
2678 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 2678, __extension__ __PRETTY_FUNCTION__
))
;
2679 SourceLocation ELoc;
2680 SourceRange ERange;
2681 Expr *SimpleRefExpr = RefExpr;
2682 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2683 if (Res.second)
2684 // It will be analyzed later.
2685 PrivateRefs.push_back(RefExpr);
2686 ValueDecl *D = Res.first;
2687 if (!D)
2688 continue;
2689
2690 const DSAStackTy::DSAVarData DVar =
2691 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2692 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2693 : SimpleRefExpr);
2694 }
2695 Clause->setPrivateRefs(PrivateRefs);
2696 continue;
2697 }
2698 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2699 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2700 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2701 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2702 if (!DRE)
2703 continue;
2704 ValueDecl *VD = DRE->getDecl();
2705 if (!VD || !isa<VarDecl>(VD))
2706 continue;
2707 DSAStackTy::DSAVarData DVar =
2708 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2709 // OpenMP [2.12.5, target Construct]
2710 // Memory allocators that appear in a uses_allocators clause cannot
2711 // appear in other data-sharing attribute clauses or data-mapping
2712 // attribute clauses in the same construct.
2713 Expr *MapExpr = nullptr;
2714 if (DVar.RefExpr ||
2715 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2716 VD, /*CurrentRegionOnly=*/true,
2717 [VD, &MapExpr](
2718 OMPClauseMappableExprCommon::MappableExprComponentListRef
2719 MapExprComponents,
2720 OpenMPClauseKind C) {
2721 auto MI = MapExprComponents.rbegin();
2722 auto ME = MapExprComponents.rend();
2723 if (MI != ME &&
2724 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2725 VD->getCanonicalDecl()) {
2726 MapExpr = MI->getAssociatedExpression();
2727 return true;
2728 }
2729 return false;
2730 })) {
2731 Diag(D.Allocator->getExprLoc(),
2732 diag::err_omp_allocator_used_in_clauses)
2733 << D.Allocator->getSourceRange();
2734 if (DVar.RefExpr)
2735 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2736 else
2737 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2738 << MapExpr->getSourceRange();
2739 }
2740 }
2741 continue;
2742 }
2743 }
2744 // Check allocate clauses.
2745 if (!CurContext->isDependentContext())
2746 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2747 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2748 }
2749
2750 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2751 DiscardCleanupsInEvaluationContext();
2752 PopExpressionEvaluationContext();
2753}
2754
2755static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2756 Expr *NumIterations, Sema &SemaRef,
2757 Scope *S, DSAStackTy *Stack);
2758
2759namespace {
2760
2761class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2762private:
2763 Sema &SemaRef;
2764
2765public:
2766 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2767 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2768 NamedDecl *ND = Candidate.getCorrectionDecl();
2769 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2770 return VD->hasGlobalStorage() &&
2771 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2772 SemaRef.getCurScope());
2773 }
2774 return false;
2775 }
2776
2777 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2778 return std::make_unique<VarDeclFilterCCC>(*this);
2779 }
2780};
2781
2782class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2783private:
2784 Sema &SemaRef;
2785
2786public:
2787 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2788 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2789 NamedDecl *ND = Candidate.getCorrectionDecl();
2790 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2791 isa<FunctionDecl>(ND))) {
2792 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2793 SemaRef.getCurScope());
2794 }
2795 return false;
2796 }
2797
2798 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2799 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2800 }
2801};
2802
2803} // namespace
2804
2805ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2806 CXXScopeSpec &ScopeSpec,
2807 const DeclarationNameInfo &Id,
2808 OpenMPDirectiveKind Kind) {
2809 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2810 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2811
2812 if (Lookup.isAmbiguous())
2813 return ExprError();
2814
2815 VarDecl *VD;
2816 if (!Lookup.isSingleResult()) {
2817 VarDeclFilterCCC CCC(*this);
2818 if (TypoCorrection Corrected =
2819 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2820 CTK_ErrorRecovery)) {
2821 diagnoseTypo(Corrected,
2822 PDiag(Lookup.empty()
2823 ? diag::err_undeclared_var_use_suggest
2824 : diag::err_omp_expected_var_arg_suggest)
2825 << Id.getName());
2826 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2827 } else {
2828 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2829 : diag::err_omp_expected_var_arg)
2830 << Id.getName();
2831 return ExprError();
2832 }
2833 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2834 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2835 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2836 return ExprError();
2837 }
2838 Lookup.suppressDiagnostics();
2839
2840 // OpenMP [2.9.2, Syntax, C/C++]
2841 // Variables must be file-scope, namespace-scope, or static block-scope.
2842 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2843 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2844 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2845 bool IsDecl =
2846 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2847 Diag(VD->getLocation(),
2848 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2849 << VD;
2850 return ExprError();
2851 }
2852
2853 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2854 NamedDecl *ND = CanonicalVD;
2855 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2856 // A threadprivate directive for file-scope variables must appear outside
2857 // any definition or declaration.
2858 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2859 !getCurLexicalContext()->isTranslationUnit()) {
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.3]
2870 // A threadprivate directive for static class member variables must appear
2871 // in the class definition, in the same scope in which the member
2872 // variables are declared.
2873 if (CanonicalVD->isStaticDataMember() &&
2874 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2875 Diag(Id.getLoc(), diag::err_omp_var_scope)
2876 << getOpenMPDirectiveName(Kind) << VD;
2877 bool IsDecl =
2878 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2879 Diag(VD->getLocation(),
2880 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2881 << VD;
2882 return ExprError();
2883 }
2884 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2885 // A threadprivate directive for namespace-scope variables must appear
2886 // outside any definition or declaration other than the namespace
2887 // definition itself.
2888 if (CanonicalVD->getDeclContext()->isNamespace() &&
2889 (!getCurLexicalContext()->isFileContext() ||
2890 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2891 Diag(Id.getLoc(), diag::err_omp_var_scope)
2892 << getOpenMPDirectiveName(Kind) << VD;
2893 bool IsDecl =
2894 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2895 Diag(VD->getLocation(),
2896 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2897 << VD;
2898 return ExprError();
2899 }
2900 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2901 // A threadprivate directive for static block-scope variables must appear
2902 // in the scope of the variable and not in a nested scope.
2903 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2904 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2905 Diag(Id.getLoc(), diag::err_omp_var_scope)
2906 << getOpenMPDirectiveName(Kind) << VD;
2907 bool IsDecl =
2908 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2909 Diag(VD->getLocation(),
2910 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2911 << VD;
2912 return ExprError();
2913 }
2914
2915 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2916 // A threadprivate directive must lexically precede all references to any
2917 // of the variables in its list.
2918 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2919 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2920 Diag(Id.getLoc(), diag::err_omp_var_used)
2921 << getOpenMPDirectiveName(Kind) << VD;
2922 return ExprError();
2923 }
2924
2925 QualType ExprType = VD->getType().getNonReferenceType();
2926 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2927 SourceLocation(), VD,
2928 /*RefersToEnclosingVariableOrCapture=*/false,
2929 Id.getLoc(), ExprType, VK_LValue);
2930}
2931
2932Sema::DeclGroupPtrTy
2933Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2934 ArrayRef<Expr *> VarList) {
2935 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2936 CurContext->addDecl(D);
2937 return DeclGroupPtrTy::make(DeclGroupRef(D));
2938 }
2939 return nullptr;
2940}
2941
2942namespace {
2943class LocalVarRefChecker final
2944 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2945 Sema &SemaRef;
2946
2947public:
2948 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2949 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2950 if (VD->hasLocalStorage()) {
2951 SemaRef.Diag(E->getBeginLoc(),
2952 diag::err_omp_local_var_in_threadprivate_init)
2953 << E->getSourceRange();
2954 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2955 << VD << VD->getSourceRange();
2956 return true;
2957 }
2958 }
2959 return false;
2960 }
2961 bool VisitStmt(const Stmt *S) {
2962 for (const Stmt *Child : S->children()) {
2963 if (Child && Visit(Child))
2964 return true;
2965 }
2966 return false;
2967 }
2968 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2969};
2970} // namespace
2971
2972OMPThreadPrivateDecl *
2973Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2974 SmallVector<Expr *, 8> Vars;
2975 for (Expr *RefExpr : VarList) {
2976 auto *DE = cast<DeclRefExpr>(RefExpr);
2977 auto *VD = cast<VarDecl>(DE->getDecl());
2978 SourceLocation ILoc = DE->getExprLoc();
2979
2980 // Mark variable as used.
2981 VD->setReferenced();
2982 VD->markUsed(Context);
2983
2984 QualType QType = VD->getType();
2985 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2986 // It will be analyzed later.
2987 Vars.push_back(DE);
2988 continue;
2989 }
2990
2991 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2992 // A threadprivate variable must not have an incomplete type.
2993 if (RequireCompleteType(ILoc, VD->getType(),
2994 diag::err_omp_threadprivate_incomplete_type)) {
2995 continue;
2996 }
2997
2998 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2999 // A threadprivate variable must not have a reference type.
3000 if (VD->getType()->isReferenceType()) {
3001 Diag(ILoc, diag::err_omp_ref_type_arg)
3002 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3003 bool IsDecl =
3004 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3005 Diag(VD->getLocation(),
3006 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3007 << VD;
3008 continue;
3009 }
3010
3011 // Check if this is a TLS variable. If TLS is not being supported, produce
3012 // the corresponding diagnostic.
3013 if ((VD->getTLSKind() != VarDecl::TLS_None &&
3014 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3015 getLangOpts().OpenMPUseTLS &&
3016 getASTContext().getTargetInfo().isTLSSupported())) ||
3017 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3018 !VD->isLocalVarDecl())) {
3019 Diag(ILoc, diag::err_omp_var_thread_local)
3020 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3021 bool IsDecl =
3022 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3023 Diag(VD->getLocation(),
3024 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3025 << VD;
3026 continue;
3027 }
3028
3029 // Check if initial value of threadprivate variable reference variable with
3030 // local storage (it is not supported by runtime).
3031 if (const Expr *Init = VD->getAnyInitializer()) {
3032 LocalVarRefChecker Checker(*this);
3033 if (Checker.Visit(Init))
3034 continue;
3035 }
3036
3037 Vars.push_back(RefExpr);
3038 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3039 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3040 Context, SourceRange(Loc, Loc)));
3041 if (ASTMutationListener *ML = Context.getASTMutationListener())
3042 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3043 }
3044 OMPThreadPrivateDecl *D = nullptr;
3045 if (!Vars.empty()) {
3046 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3047 Vars);
3048 D->setAccess(AS_public);
3049 }
3050 return D;
3051}
3052
3053static OMPAllocateDeclAttr::AllocatorTypeTy
3054getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3055 if (!Allocator)
3056 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3057 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3058 Allocator->isInstantiationDependent() ||
3059 Allocator->containsUnexpandedParameterPack())
3060 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3061 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3062 const Expr *AE = Allocator->IgnoreParenImpCasts();
3063 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3064 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3065 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3066 llvm::FoldingSetNodeID AEId, DAEId;
3067 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3068 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3069 if (AEId == DAEId) {
3070 AllocatorKindRes = AllocatorKind;
3071 break;
3072 }
3073 }
3074 return AllocatorKindRes;
3075}
3076
3077static bool checkPreviousOMPAllocateAttribute(
3078 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3079 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3080 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3081 return false;
3082 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3083 Expr *PrevAllocator = A->getAllocator();
3084 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3085 getAllocatorKind(S, Stack, PrevAllocator);
3086 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3087 if (AllocatorsMatch &&
3088 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3089 Allocator && PrevAllocator) {
3090 const Expr *AE = Allocator->IgnoreParenImpCasts();
3091 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3092 llvm::FoldingSetNodeID AEId, PAEId;
3093 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3094 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3095 AllocatorsMatch = AEId == PAEId;
3096 }
3097 if (!AllocatorsMatch) {
3098 SmallString<256> AllocatorBuffer;
3099 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3100 if (Allocator)
3101 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3102 SmallString<256> PrevAllocatorBuffer;
3103 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3104 if (PrevAllocator)
3105 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3106 S.getPrintingPolicy());
3107
3108 SourceLocation AllocatorLoc =
3109 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3110 SourceRange AllocatorRange =
3111 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3112 SourceLocation PrevAllocatorLoc =
3113 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3114 SourceRange PrevAllocatorRange =
3115 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3116 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3117 << (Allocator ? 1 : 0) << AllocatorStream.str()
3118 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3119 << AllocatorRange;
3120 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3121 << PrevAllocatorRange;
3122 return true;
3123 }
3124 return false;
3125}
3126
3127static void
3128applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3129 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3130 Expr *Allocator, Expr *Alignment, SourceRange SR) {
3131 if (VD->hasAttr<OMPAllocateDeclAttr>())
3132 return;
3133 if (Alignment &&
3134 (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3135 Alignment->isInstantiationDependent() ||
3136 Alignment->containsUnexpandedParameterPack()))
3137 // Apply later when we have a usable value.
3138 return;
3139 if (Allocator &&
3140 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3141 Allocator->isInstantiationDependent() ||
3142 Allocator->containsUnexpandedParameterPack()))
3143 return;
3144 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3145 Allocator, Alignment, SR);
3146 VD->addAttr(A);
3147 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3148 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3149}
3150
3151Sema::DeclGroupPtrTy
3152Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3153 ArrayRef<OMPClause *> Clauses,
3154 DeclContext *Owner) {
3155 assert(Clauses.size() <= 2 && "Expected at most two clauses.")(static_cast <bool> (Clauses.size() <= 2 && "Expected at most two clauses."
) ? void (0) : __assert_fail ("Clauses.size() <= 2 && \"Expected at most two clauses.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 3155, __extension__ __PRETTY_FUNCTION__
))
;
3156 Expr *Alignment = nullptr;
3157 Expr *Allocator = nullptr;
3158 if (Clauses.empty()) {
3159 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3160 // allocate directives that appear in a target region must specify an
3161 // allocator clause unless a requires directive with the dynamic_allocators
3162 // clause is present in the same compilation unit.
3163 if (LangOpts.OpenMPIsDevice &&
3164 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3165 targetDiag(Loc, diag::err_expected_allocator_clause);
3166 } else {
3167 for (const OMPClause *C : Clauses)
3168 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3169 Allocator = AC->getAllocator();
3170 else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3171 Alignment = AC->getAlignment();
3172 else
3173 llvm_unreachable("Unexpected clause on allocate directive")::llvm::llvm_unreachable_internal("Unexpected clause on allocate directive"
, "clang/lib/Sema/SemaOpenMP.cpp", 3173)
;
3174 }
3175 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3176 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3177 SmallVector<Expr *, 8> Vars;
3178 for (Expr *RefExpr : VarList) {
3179 auto *DE = cast<DeclRefExpr>(RefExpr);
3180 auto *VD = cast<VarDecl>(DE->getDecl());
3181
3182 // Check if this is a TLS variable or global register.
3183 if (VD->getTLSKind() != VarDecl::TLS_None ||
3184 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3185 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3186 !VD->isLocalVarDecl()))
3187 continue;
3188
3189 // If the used several times in the allocate directive, the same allocator
3190 // must be used.
3191 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3192 AllocatorKind, Allocator))
3193 continue;
3194
3195 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3196 // If a list item has a static storage type, the allocator expression in the
3197 // allocator clause must be a constant expression that evaluates to one of
3198 // the predefined memory allocator values.
3199 if (Allocator && VD->hasGlobalStorage()) {
3200 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3201 Diag(Allocator->getExprLoc(),
3202 diag::err_omp_expected_predefined_allocator)
3203 << Allocator->getSourceRange();
3204 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3205 VarDecl::DeclarationOnly;
3206 Diag(VD->getLocation(),
3207 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3208 << VD;
3209 continue;
3210 }
3211 }
3212
3213 Vars.push_back(RefExpr);
3214 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3215 DE->getSourceRange());
3216 }
3217 if (Vars.empty())
3218 return nullptr;
3219 if (!Owner)
3220 Owner = getCurLexicalContext();
3221 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3222 D->setAccess(AS_public);
3223 Owner->addDecl(D);
3224 return DeclGroupPtrTy::make(DeclGroupRef(D));
3225}
3226
3227Sema::DeclGroupPtrTy
3228Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3229 ArrayRef<OMPClause *> ClauseList) {
3230 OMPRequiresDecl *D = nullptr;
3231 if (!CurContext->isFileContext()) {
3232 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3233 } else {
3234 D = CheckOMPRequiresDecl(Loc, ClauseList);
3235 if (D) {
3236 CurContext->addDecl(D);
3237 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3238 }
3239 }
3240 return DeclGroupPtrTy::make(DeclGroupRef(D));
3241}
3242
3243void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3244 OpenMPDirectiveKind DKind,
3245 ArrayRef<std::string> Assumptions,
3246 bool SkippedClauses) {
3247 if (!SkippedClauses && Assumptions.empty())
3248 Diag(Loc, diag::err_omp_no_clause_for_directive)
3249 << llvm::omp::getAllAssumeClauseOptions()
3250 << llvm::omp::getOpenMPDirectiveName(DKind);
3251
3252 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3253 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3254 OMPAssumeScoped.push_back(AA);
3255 return;
3256 }
3257
3258 // Global assumes without assumption clauses are ignored.
3259 if (Assumptions.empty())
3260 return;
3261
3262 assert(DKind == llvm::omp::Directive::OMPD_assumes &&(static_cast <bool> (DKind == llvm::omp::Directive::OMPD_assumes
&& "Unexpected omp assumption directive!") ? void (0
) : __assert_fail ("DKind == llvm::omp::Directive::OMPD_assumes && \"Unexpected omp assumption directive!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 3263, __extension__ __PRETTY_FUNCTION__
))
3263 "Unexpected omp assumption directive!")(static_cast <bool> (DKind == llvm::omp::Directive::OMPD_assumes
&& "Unexpected omp assumption directive!") ? void (0
) : __assert_fail ("DKind == llvm::omp::Directive::OMPD_assumes && \"Unexpected omp assumption directive!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 3263, __extension__ __PRETTY_FUNCTION__
))
;
3264 OMPAssumeGlobal.push_back(AA);
3265
3266 // The OMPAssumeGlobal scope above will take care of new declarations but
3267 // we also want to apply the assumption to existing ones, e.g., to
3268 // declarations in included headers. To this end, we traverse all existing
3269 // declaration contexts and annotate function declarations here.
3270 SmallVector<DeclContext *, 8> DeclContexts;
3271 auto *Ctx = CurContext;
3272 while (Ctx->getLexicalParent())
3273 Ctx = Ctx->getLexicalParent();
3274 DeclContexts.push_back(Ctx);
3275 while (!DeclContexts.empty()) {
3276 DeclContext *DC = DeclContexts.pop_back_val();
3277 for (auto *SubDC : DC->decls()) {
3278 if (SubDC->isInvalidDecl())
3279 continue;
3280 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3281 DeclContexts.push_back(CTD->getTemplatedDecl());
3282 llvm::append_range(DeclContexts, CTD->specializations());
3283 continue;
3284 }
3285 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3286 DeclContexts.push_back(DC);
3287 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3288 F->addAttr(AA);
3289 continue;
3290 }
3291 }
3292 }
3293}
3294
3295void Sema::ActOnOpenMPEndAssumesDirective() {
3296 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!")(static_cast <bool> (isInOpenMPAssumeScope() &&
"Not in OpenMP assumes scope!") ? void (0) : __assert_fail (
"isInOpenMPAssumeScope() && \"Not in OpenMP assumes scope!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 3296, __extension__ __PRETTY_FUNCTION__
))
;
3297 OMPAssumeScoped.pop_back();
3298}
3299
3300OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3301 ArrayRef<OMPClause *> ClauseList) {
3302 /// For target specific clauses, the requires directive cannot be
3303 /// specified after the handling of any of the target regions in the
3304 /// current compilation unit.
3305 ArrayRef<SourceLocation> TargetLocations =
3306 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3307 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3308 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3309 for (const OMPClause *CNew : ClauseList) {
3310 // Check if any of the requires clauses affect target regions.
3311 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3312 isa<OMPUnifiedAddressClause>(CNew) ||
3313 isa<OMPReverseOffloadClause>(CNew) ||
3314 isa<OMPDynamicAllocatorsClause>(CNew)) {
3315 Diag(Loc, diag::err_omp_directive_before_requires)
3316 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3317 for (SourceLocation TargetLoc : TargetLocations) {
3318 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3319 << "target";
3320 }
3321 } else if (!AtomicLoc.isInvalid() &&
3322 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3323 Diag(Loc, diag::err_omp_directive_before_requires)
3324 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3325 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3326 << "atomic";
3327 }
3328 }
3329 }
3330
3331 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3332 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3333 ClauseList);
3334 return nullptr;
3335}
3336
3337static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3338 const ValueDecl *D,
3339 const DSAStackTy::DSAVarData &DVar,
3340 bool IsLoopIterVar) {
3341 if (DVar.RefExpr) {
3342 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3343 << getOpenMPClauseName(DVar.CKind);
3344 return;
3345 }
3346 enum {
3347 PDSA_StaticMemberShared,
3348 PDSA_StaticLocalVarShared,
3349 PDSA_LoopIterVarPrivate,
3350 PDSA_LoopIterVarLinear,
3351 PDSA_LoopIterVarLastprivate,
3352 PDSA_ConstVarShared,
3353 PDSA_GlobalVarShared,
3354 PDSA_TaskVarFirstprivate,
3355 PDSA_LocalVarPrivate,
3356 PDSA_Implicit
3357 } Reason = PDSA_Implicit;
3358 bool ReportHint = false;
3359 auto ReportLoc = D->getLocation();
3360 auto *VD = dyn_cast<VarDecl>(D);
3361 if (IsLoopIterVar) {
3362 if (DVar.CKind == OMPC_private)
3363 Reason = PDSA_LoopIterVarPrivate;
3364 else if (DVar.CKind == OMPC_lastprivate)
3365 Reason = PDSA_LoopIterVarLastprivate;
3366 else
3367 Reason = PDSA_LoopIterVarLinear;
3368 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3369 DVar.CKind == OMPC_firstprivate) {
3370 Reason = PDSA_TaskVarFirstprivate;
3371 ReportLoc = DVar.ImplicitDSALoc;
3372 } else if (VD && VD->isStaticLocal())
3373 Reason = PDSA_StaticLocalVarShared;
3374 else if (VD && VD->isStaticDataMember())
3375 Reason = PDSA_StaticMemberShared;
3376 else if (VD && VD->isFileVarDecl())
3377 Reason = PDSA_GlobalVarShared;
3378 else if (D->getType().isConstant(SemaRef.getASTContext()))
3379 Reason = PDSA_ConstVarShared;
3380 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3381 ReportHint = true;
3382 Reason = PDSA_LocalVarPrivate;
3383 }
3384 if (Reason != PDSA_Implicit) {
3385 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3386 << Reason << ReportHint
3387 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3388 } else if (DVar.ImplicitDSALoc.isValid()) {
3389 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3390 << getOpenMPClauseName(DVar.CKind);
3391 }
3392}
3393
3394static OpenMPMapClauseKind
3395getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3396 bool IsAggregateOrDeclareTarget) {
3397 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3398 switch (M) {
3399 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3400 Kind = OMPC_MAP_alloc;
3401 break;
3402 case OMPC_DEFAULTMAP_MODIFIER_to:
3403 Kind = OMPC_MAP_to;
3404 break;
3405 case OMPC_DEFAULTMAP_MODIFIER_from:
3406 Kind = OMPC_MAP_from;
3407 break;
3408 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3409 Kind = OMPC_MAP_tofrom;
3410 break;
3411 case OMPC_DEFAULTMAP_MODIFIER_present:
3412 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3413 // If implicit-behavior is present, each variable referenced in the
3414 // construct in the category specified by variable-category is treated as if
3415 // it had been listed in a map clause with the map-type of alloc and
3416 // map-type-modifier of present.
3417 Kind = OMPC_MAP_alloc;
3418 break;
3419 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3420 case OMPC_DEFAULTMAP_MODIFIER_last:
3421 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "clang/lib/Sema/SemaOpenMP.cpp", 3421)
;
3422 case OMPC_DEFAULTMAP_MODIFIER_none:
3423 case OMPC_DEFAULTMAP_MODIFIER_default:
3424 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3425 // IsAggregateOrDeclareTarget could be true if:
3426 // 1. the implicit behavior for aggregate is tofrom
3427 // 2. it's a declare target link
3428 if (IsAggregateOrDeclareTarget) {
3429 Kind = OMPC_MAP_tofrom;
3430 break;
3431 }
3432 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "clang/lib/Sema/SemaOpenMP.cpp", 3432)
;
3433 }
3434 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known")(static_cast <bool> (Kind != OMPC_MAP_unknown &&
"Expect map kind to be known") ? void (0) : __assert_fail ("Kind != OMPC_MAP_unknown && \"Expect map kind to be known\""
, "clang/lib/Sema/SemaOpenMP.cpp", 3434, __extension__ __PRETTY_FUNCTION__
))
;
3435 return Kind;
3436}
3437
3438namespace {
3439class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3440 DSAStackTy *Stack;
3441 Sema &SemaRef;
3442 bool ErrorFound = false;
3443 bool TryCaptureCXXThisMembers = false;
3444 CapturedStmt *CS = nullptr;
3445 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3446 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3447 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3448 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3449 ImplicitMapModifier[DefaultmapKindNum];
3450 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3451 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3452
3453 void VisitSubCaptures(OMPExecutableDirective *S) {
3454 // Check implicitly captured variables.
3455 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3456 return;
3457 if (S->getDirectiveKind() == OMPD_atomic ||
3458 S->getDirectiveKind() == OMPD_critical ||
3459 S->getDirectiveKind() == OMPD_section ||
3460 S->getDirectiveKind() == OMPD_master ||
3461 S->getDirectiveKind() == OMPD_masked ||
3462 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3463 Visit(S->getAssociatedStmt());
3464 return;
3465 }
3466 visitSubCaptures(S->getInnermostCapturedStmt());
3467 // Try to capture inner this->member references to generate correct mappings
3468 // and diagnostics.
3469 if (TryCaptureCXXThisMembers ||
3470 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3471 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3472 [](const CapturedStmt::Capture &C) {
3473 return C.capturesThis();
3474 }))) {
3475 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3476 TryCaptureCXXThisMembers = true;
3477 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3478 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3479 }
3480 // In tasks firstprivates are not captured anymore, need to analyze them
3481 // explicitly.
3482 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3483 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3484 for (OMPClause *C : S->clauses())
3485 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3486 for (Expr *Ref : FC->varlists())
3487 Visit(Ref);
3488 }
3489 }
3490 }
3491
3492public:
3493 void VisitDeclRefExpr(DeclRefExpr *E) {
3494 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3495 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3496 E->isInstantiationDependent())
3497 return;
3498 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3499 // Check the datasharing rules for the expressions in the clauses.
3500 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3501 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr)) {
3502 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3503 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3504 Visit(CED->getInit());
3505 return;
3506 }
3507 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3508 // Do not analyze internal variables and do not enclose them into
3509 // implicit clauses.
3510 return;
3511 VD = VD->getCanonicalDecl();
3512 // Skip internally declared variables.
3513 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3514 !Stack->isImplicitTaskFirstprivate(VD))
3515 return;
3516 // Skip allocators in uses_allocators clauses.
3517 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3518 return;
3519
3520 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3521 // Check if the variable has explicit DSA set and stop analysis if it so.
3522 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3523 return;
3524
3525 // Skip internally declared static variables.
3526 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3527 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3528 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3529 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3530 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3531 !Stack->isImplicitTaskFirstprivate(VD))
3532 return;
3533
3534 SourceLocation ELoc = E->getExprLoc();
3535 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3536 // The default(none) clause requires that each variable that is referenced
3537 // in the construct, and does not have a predetermined data-sharing
3538 // attribute, must have its data-sharing attribute explicitly determined
3539 // by being listed in a data-sharing attribute clause.
3540 if (DVar.CKind == OMPC_unknown &&
3541 (Stack->getDefaultDSA() == DSA_none ||
3542 Stack->getDefaultDSA() == DSA_firstprivate) &&
3543 isImplicitOrExplicitTaskingRegion(DKind) &&
3544 VarsWithInheritedDSA.count(VD) == 0) {
3545 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3546 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3547 DSAStackTy::DSAVarData DVar =
3548 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3549 InheritedDSA = DVar.CKind == OMPC_unknown;
3550 }
3551 if (InheritedDSA)
3552 VarsWithInheritedDSA[VD] = E;
3553 return;
3554 }
3555
3556 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3557 // If implicit-behavior is none, each variable referenced in the
3558 // construct that does not have a predetermined data-sharing attribute
3559 // and does not appear in a to or link clause on a declare target
3560 // directive must be listed in a data-mapping attribute clause, a
3561 // data-haring attribute clause (including a data-sharing attribute
3562 // clause on a combined construct where target. is one of the
3563 // constituent constructs), or an is_device_ptr clause.
3564 OpenMPDefaultmapClauseKind ClauseKind =
3565 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3566 if (SemaRef.getLangOpts().OpenMP >= 50) {
3567 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3568 OMPC_DEFAULTMAP_MODIFIER_none;
3569 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3570 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3571 // Only check for data-mapping attribute and is_device_ptr here
3572 // since we have already make sure that the declaration does not
3573 // have a data-sharing attribute above
3574 if (!Stack->checkMappableExprComponentListsForDecl(
3575 VD, /*CurrentRegionOnly=*/true,
3576 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3577 MapExprComponents,
3578 OpenMPClauseKind) {
3579 auto MI = MapExprComponents.rbegin();
3580 auto ME = MapExprComponents.rend();
3581 return MI != ME && MI->getAssociatedDeclaration() == VD;
3582 })) {
3583 VarsWithInheritedDSA[VD] = E;
3584 return;
3585 }
3586 }
3587 }
3588 if (SemaRef.getLangOpts().OpenMP > 50) {
3589 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3590 OMPC_DEFAULTMAP_MODIFIER_present;
3591 if (IsModifierPresent) {
3592 if (llvm::find(ImplicitMapModifier[ClauseKind],
3593 OMPC_MAP_MODIFIER_present) ==
3594 std::end(ImplicitMapModifier[ClauseKind])) {
3595 ImplicitMapModifier[ClauseKind].push_back(
3596 OMPC_MAP_MODIFIER_present);
3597 }
3598 }
3599 }
3600
3601 if (isOpenMPTargetExecutionDirective(DKind) &&
3602 !Stack->isLoopControlVariable(VD).first) {
3603 if (!Stack->checkMappableExprComponentListsForDecl(
3604 VD, /*CurrentRegionOnly=*/true,
3605 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3606 StackComponents,
3607 OpenMPClauseKind) {
3608 if (SemaRef.LangOpts.OpenMP >= 50)
3609 return !StackComponents.empty();
3610 // Variable is used if it has been marked as an array, array
3611 // section, array shaping or the variable iself.
3612 return StackComponents.size() == 1 ||
3613 std::all_of(
3614 std::next(StackComponents.rbegin()),
3615 StackComponents.rend(),
3616 [](const OMPClauseMappableExprCommon::
3617 MappableComponent &MC) {
3618 return MC.getAssociatedDeclaration() ==
3619 nullptr &&
3620 (isa<OMPArraySectionExpr>(
3621 MC.getAssociatedExpression()) ||
3622 isa<OMPArrayShapingExpr>(
3623 MC.getAssociatedExpression()) ||
3624 isa<ArraySubscriptExpr>(
3625 MC.getAssociatedExpression()));
3626 });
3627 })) {
3628 bool IsFirstprivate = false;
3629 // By default lambdas are captured as firstprivates.
3630 if (const auto *RD =
3631 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3632 IsFirstprivate = RD->isLambda();
3633 IsFirstprivate =
3634 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3635 if (IsFirstprivate) {
3636 ImplicitFirstprivate.emplace_back(E);
3637 } else {
3638 OpenMPDefaultmapClauseModifier M =
3639 Stack->getDefaultmapModifier(ClauseKind);
3640 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3641 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3642 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3643 }
3644 return;
3645 }
3646 }
3647
3648 // OpenMP [2.9.3.6, Restrictions, p.2]
3649 // A list item that appears in a reduction clause of the innermost
3650 // enclosing worksharing or parallel construct may not be accessed in an
3651 // explicit task.
3652 DVar = Stack->hasInnermostDSA(
3653 VD,
3654 [](OpenMPClauseKind C, bool AppliedToPointee) {
3655 return C == OMPC_reduction && !AppliedToPointee;
3656 },
3657 [](OpenMPDirectiveKind K) {
3658 return isOpenMPParallelDirective(K) ||
3659 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3660 },
3661 /*FromParent=*/true);
3662 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3663 ErrorFound = true;
3664 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3665 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3666 return;
3667 }
3668
3669 // Define implicit data-sharing attributes for task.
3670 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3671 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3672 (Stack->getDefaultDSA() == DSA_firstprivate &&
3673 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3674 !Stack->isLoopControlVariable(VD).first) {
3675 ImplicitFirstprivate.push_back(E);
3676 return;
3677 }
3678
3679 // Store implicitly used globals with declare target link for parent
3680 // target.
3681 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3682 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3683 Stack->addToParentTargetRegionLinkGlobals(E);
3684 return;
3685 }
3686 }
3687 }
3688 void VisitMemberExpr(MemberExpr *E) {
3689 if (E->isTypeDependent() || E->isValueDependent() ||
3690 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3691 return;
3692 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3693 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3694 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3695 if (!FD)
3696 return;
3697 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3698 // Check if the variable has explicit DSA set and stop analysis if it
3699 // so.
3700 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3701 return;
3702
3703 if (isOpenMPTargetExecutionDirective(DKind) &&
3704 !Stack->isLoopControlVariable(FD).first &&
3705 !Stack->checkMappableExprComponentListsForDecl(
3706 FD, /*CurrentRegionOnly=*/true,
3707 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3708 StackComponents,
3709 OpenMPClauseKind) {
3710 return isa<CXXThisExpr>(
3711 cast<MemberExpr>(
3712 StackComponents.back().getAssociatedExpression())
3713 ->getBase()
3714 ->IgnoreParens());
3715 })) {
3716 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3717 // A bit-field cannot appear in a map clause.
3718 //
3719 if (FD->isBitField())
3720 return;
3721
3722 // Check to see if the member expression is referencing a class that
3723 // has already been explicitly mapped
3724 if (Stack->isClassPreviouslyMapped(TE->getType()))
3725 return;
3726
3727 OpenMPDefaultmapClauseModifier Modifier =
3728 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3729 OpenMPDefaultmapClauseKind ClauseKind =
3730 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3731 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3732 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3733 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3734 return;
3735 }
3736
3737 SourceLocation ELoc = E->getExprLoc();
3738 // OpenMP [2.9.3.6, Restrictions, p.2]
3739 // A list item that appears in a reduction clause of the innermost
3740 // enclosing worksharing or parallel construct may not be accessed in
3741 // an explicit task.
3742 DVar = Stack->hasInnermostDSA(
3743 FD,
3744 [](OpenMPClauseKind C, bool AppliedToPointee) {
3745 return C == OMPC_reduction && !AppliedToPointee;
3746 },
3747 [](OpenMPDirectiveKind K) {
3748 return isOpenMPParallelDirective(K) ||
3749 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3750 },
3751 /*FromParent=*/true);
3752 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3753 ErrorFound = true;
3754 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3755 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3756 return;
3757 }
3758
3759 // Define implicit data-sharing attributes for task.
3760 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3761 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3762 !Stack->isLoopControlVariable(FD).first) {
3763 // Check if there is a captured expression for the current field in the
3764 // region. Do not mark it as firstprivate unless there is no captured
3765 // expression.
3766 // TODO: try to make it firstprivate.
3767 if (DVar.CKind != OMPC_unknown)
3768 ImplicitFirstprivate.push_back(E);
3769 }
3770 return;
3771 }
3772 if (isOpenMPTargetExecutionDirective(DKind)) {
3773 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3774 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3775 Stack->getCurrentDirective(),
3776 /*NoDiagnose=*/true))
3777 return;
3778 const auto *VD = cast<ValueDecl>(
3779 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3780 if (!Stack->checkMappableExprComponentListsForDecl(
3781 VD, /*CurrentRegionOnly=*/true,
3782 [&CurComponents](
3783 OMPClauseMappableExprCommon::MappableExprComponentListRef
3784 StackComponents,
3785 OpenMPClauseKind) {
3786 auto CCI = CurComponents.rbegin();
3787 auto CCE = CurComponents.rend();
3788 for (const auto &SC : llvm::reverse(StackComponents)) {
3789 // Do both expressions have the same kind?
3790 if (CCI->getAssociatedExpression()->getStmtClass() !=
3791 SC.getAssociatedExpression()->getStmtClass())
3792 if (!((isa<OMPArraySectionExpr>(
3793 SC.getAssociatedExpression()) ||
3794 isa<OMPArrayShapingExpr>(
3795 SC.getAssociatedExpression())) &&
3796 isa<ArraySubscriptExpr>(
3797 CCI->getAssociatedExpression())))
3798 return false;
3799
3800 const Decl *CCD = CCI->getAssociatedDeclaration();
3801 const Decl *SCD = SC.getAssociatedDeclaration();
3802 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3803 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3804 if (SCD != CCD)
3805 return false;
3806 std::advance(CCI, 1);
3807 if (CCI == CCE)
3808 break;
3809 }
3810 return true;
3811 })) {
3812 Visit(E->getBase());
3813 }
3814 } else if (!TryCaptureCXXThisMembers) {
3815 Visit(E->getBase());
3816 }
3817 }
3818 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3819 for (OMPClause *C : S->clauses()) {
3820 // Skip analysis of arguments of private clauses for task|target
3821 // directives.
3822 if (isa_and_nonnull<OMPPrivateClause>(C))
3823 continue;
3824 // Skip analysis of arguments of implicitly defined firstprivate clause
3825 // for task|target directives.
3826 // Skip analysis of arguments of implicitly defined map clause for target
3827 // directives.
3828 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3829 C->isImplicit() &&
3830 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3831 for (Stmt *CC : C->children()) {
3832 if (CC)
3833 Visit(CC);
3834 }
3835 }
3836 }
3837 // Check implicitly captured variables.
3838 VisitSubCaptures(S);
3839 }
3840
3841 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
3842 // Loop transformation directives do not introduce data sharing
3843 VisitStmt(S);
3844 }
3845
3846 void VisitCallExpr(CallExpr *S) {
3847 for (Stmt *C : S->arguments()) {
3848 if (C) {
3849 // Check implicitly captured variables in the task-based directives to
3850 // check if they must be firstprivatized.
3851 Visit(C);
3852 }
3853 }
3854 if (Expr *Callee = S->getCallee())
3855 if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts()))
3856 Visit(CE->getBase());
3857 }
3858 void VisitStmt(Stmt *S) {
3859 for (Stmt *C : S->children()) {
3860 if (C) {
3861 // Check implicitly captured variables in the task-based directives to
3862 // check if they must be firstprivatized.
3863 Visit(C);
3864 }
3865 }
3866 }
3867
3868 void visitSubCaptures(CapturedStmt *S) {
3869 for (const CapturedStmt::Capture &Cap : S->captures()) {
3870 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3871 continue;
3872 VarDecl *VD = Cap.getCapturedVar();
3873 // Do not try to map the variable if it or its sub-component was mapped
3874 // already.
3875 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3876 Stack->checkMappableExprComponentListsForDecl(
3877 VD, /*CurrentRegionOnly=*/true,
3878 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3879 OpenMPClauseKind) { return true; }))
3880 continue;
3881 DeclRefExpr *DRE = buildDeclRefExpr(
3882 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3883 Cap.getLocation(), /*RefersToCapture=*/true);
3884 Visit(DRE);
3885 }
3886 }
3887 bool isErrorFound() const { return ErrorFound; }
3888 ArrayRef<Expr *> getImplicitFirstprivate() const {
3889 return ImplicitFirstprivate;
3890 }
3891 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3892 OpenMPMapClauseKind MK) const {
3893 return ImplicitMap[DK][MK];
3894 }
3895 ArrayRef<OpenMPMapModifierKind>
3896 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3897 return ImplicitMapModifier[Kind];
3898 }
3899 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3900 return VarsWithInheritedDSA;
3901 }
3902
3903 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3904 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3905 // Process declare target link variables for the target directives.
3906 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3907 for (DeclRefExpr *E : Stack->getLinkGlobals())
3908 Visit(E);
3909 }
3910 }
3911};
3912} // namespace
3913
3914static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
3915 OpenMPDirectiveKind DKind,
3916 bool ScopeEntry) {
3917 SmallVector<llvm::omp::TraitProperty, 8> Traits;
3918 if (isOpenMPTargetExecutionDirective(DKind))
3919 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
3920 if (isOpenMPTeamsDirective(DKind))
3921 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
3922 if (isOpenMPParallelDirective(DKind))
3923 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
3924 if (isOpenMPWorksharingDirective(DKind))
3925 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
3926 if (isOpenMPSimdDirective(DKind))
3927 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
3928 Stack->handleConstructTrait(Traits, ScopeEntry);
3929}
3930
3931void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3932 switch (DKind) {
3933 case OMPD_parallel:
3934 case OMPD_parallel_for:
3935 case OMPD_parallel_for_simd:
3936 case OMPD_parallel_sections:
3937 case OMPD_parallel_master:
3938 case OMPD_parallel_loop:
3939 case OMPD_teams:
3940 case OMPD_teams_distribute:
3941 case OMPD_teams_distribute_simd: {
3942 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3943 QualType KmpInt32PtrTy =
3944 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3945 Sema::CapturedParamNameType Params[] = {
3946 std::make_pair(".global_tid.", KmpInt32PtrTy),
3947 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3948 std::make_pair(StringRef(), QualType()) // __context with shared vars
3949 };
3950 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3951 Params);
3952 break;
3953 }
3954 case OMPD_target_teams:
3955 case OMPD_target_parallel:
3956 case OMPD_target_parallel_for:
3957 case OMPD_target_parallel_for_simd:
3958 case OMPD_target_teams_loop:
3959 case OMPD_target_parallel_loop:
3960 case OMPD_target_teams_distribute:
3961 case OMPD_target_teams_distribute_simd: {
3962 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3963 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3964 QualType KmpInt32PtrTy =
3965 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3966 QualType Args[] = {VoidPtrTy};
3967 FunctionProtoType::ExtProtoInfo EPI;
3968 EPI.Variadic = true;
3969 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3970 Sema::CapturedParamNameType Params[] = {
3971 std::make_pair(".global_tid.", KmpInt32Ty),
3972 std::make_pair(".part_id.", KmpInt32PtrTy),
3973 std::make_pair(".privates.", VoidPtrTy),
3974 std::make_pair(
3975 ".copy_fn.",
3976 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3977 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3978 std::make_pair(StringRef(), QualType()) // __context with shared vars
3979 };
3980 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3981 Params, /*OpenMPCaptureLevel=*/0);
3982 // Mark this captured region as inlined, because we don't use outlined
3983 // function directly.
3984 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3985 AlwaysInlineAttr::CreateImplicit(
3986 Context, {}, AttributeCommonInfo::AS_Keyword,
3987 AlwaysInlineAttr::Keyword_forceinline));
3988 Sema::CapturedParamNameType ParamsTarget[] = {
3989 std::make_pair(StringRef(), QualType()) // __context with shared vars
3990 };
3991 // Start a captured region for 'target' with no implicit parameters.
3992 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3993 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3994 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3995 std::make_pair(".global_tid.", KmpInt32PtrTy),
3996 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3997 std::make_pair(StringRef(), QualType()) // __context with shared vars
3998 };
3999 // Start a captured region for 'teams' or 'parallel'. Both regions have
4000 // the same implicit parameters.
4001 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4002 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4003 break;
4004 }
4005 case OMPD_target:
4006 case OMPD_target_simd: {
4007 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4008 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4009 QualType KmpInt32PtrTy =
4010 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4011 QualType Args[] = {VoidPtrTy};
4012 FunctionProtoType::ExtProtoInfo EPI;
4013 EPI.Variadic = true;
4014 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4015 Sema::CapturedParamNameType Params[] = {
4016 std::make_pair(".global_tid.", KmpInt32Ty),
4017 std::make_pair(".part_id.", KmpInt32PtrTy),
4018 std::make_pair(".privates.", VoidPtrTy),
4019 std::make_pair(
4020 ".copy_fn.",
4021 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4022 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4023 std::make_pair(StringRef(), QualType()) // __context with shared vars
4024 };
4025 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4026 Params, /*OpenMPCaptureLevel=*/0);
4027 // Mark this captured region as inlined, because we don't use outlined
4028 // function directly.
4029 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4030 AlwaysInlineAttr::CreateImplicit(
4031 Context, {}, AttributeCommonInfo::AS_Keyword,
4032 AlwaysInlineAttr::Keyword_forceinline));
4033 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4034 std::make_pair(StringRef(), QualType()),
4035 /*OpenMPCaptureLevel=*/1);
4036 break;
4037 }
4038 case OMPD_atomic:
4039 case OMPD_critical:
4040 case OMPD_section:
4041 case OMPD_master:
4042 case OMPD_masked:
4043 case OMPD_tile:
4044 case OMPD_unroll:
4045 break;
4046 case OMPD_loop:
4047 // TODO: 'loop' may require additional parameters depending on the binding.
4048 // Treat similar to OMPD_simd/OMPD_for for now.
4049 case OMPD_simd:
4050 case OMPD_for:
4051 case OMPD_for_simd:
4052 case OMPD_sections:
4053 case OMPD_single:
4054 case OMPD_taskgroup:
4055 case OMPD_distribute:
4056 case OMPD_distribute_simd:
4057 case OMPD_ordered:
4058 case OMPD_target_data:
4059 case OMPD_dispatch: {
4060 Sema::CapturedParamNameType Params[] = {
4061 std::make_pair(StringRef(), QualType()) // __context with shared vars
4062 };
4063 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4064 Params);
4065 break;
4066 }
4067 case OMPD_task: {
4068 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4069 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4070 QualType KmpInt32PtrTy =
4071 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4072 QualType Args[] = {VoidPtrTy};
4073 FunctionProtoType::ExtProtoInfo EPI;
4074 EPI.Variadic = true;
4075 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4076 Sema::CapturedParamNameType Params[] = {
4077 std::make_pair(".global_tid.", KmpInt32Ty),
4078 std::make_pair(".part_id.", KmpInt32PtrTy),
4079 std::make_pair(".privates.", VoidPtrTy),
4080 std::make_pair(
4081 ".copy_fn.",
4082 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4083 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4084 std::make_pair(StringRef(), QualType()) // __context with shared vars
4085 };
4086 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4087 Params);
4088 // Mark this captured region as inlined, because we don't use outlined
4089 // function directly.
4090 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4091 AlwaysInlineAttr::CreateImplicit(
4092 Context, {}, AttributeCommonInfo::AS_Keyword,
4093 AlwaysInlineAttr::Keyword_forceinline));
4094 break;
4095 }
4096 case OMPD_taskloop:
4097 case OMPD_taskloop_simd:
4098 case OMPD_master_taskloop:
4099 case OMPD_master_taskloop_simd: {
4100 QualType KmpInt32Ty =
4101 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4102 .withConst();
4103 QualType KmpUInt64Ty =
4104 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4105 .withConst();
4106 QualType KmpInt64Ty =
4107 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4108 .withConst();
4109 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4110 QualType KmpInt32PtrTy =
4111 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4112 QualType Args[] = {VoidPtrTy};
4113 FunctionProtoType::ExtProtoInfo EPI;
4114 EPI.Variadic = true;
4115 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4116 Sema::CapturedParamNameType Params[] = {
4117 std::make_pair(".global_tid.", KmpInt32Ty),
4118 std::make_pair(".part_id.", KmpInt32PtrTy),
4119 std::make_pair(".privates.", VoidPtrTy),
4120 std::make_pair(
4121 ".copy_fn.",
4122 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4123 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4124 std::make_pair(".lb.", KmpUInt64Ty),
4125 std::make_pair(".ub.", KmpUInt64Ty),
4126 std::make_pair(".st.", KmpInt64Ty),
4127 std::make_pair(".liter.", KmpInt32Ty),
4128 std::make_pair(".reductions.", VoidPtrTy),
4129 std::make_pair(StringRef(), QualType()) // __context with shared vars
4130 };
4131 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4132 Params);
4133 // Mark this captured region as inlined, because we don't use outlined
4134 // function directly.
4135 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4136 AlwaysInlineAttr::CreateImplicit(
4137 Context, {}, AttributeCommonInfo::AS_Keyword,
4138 AlwaysInlineAttr::Keyword_forceinline));
4139 break;
4140 }
4141 case OMPD_parallel_master_taskloop:
4142 case OMPD_parallel_master_taskloop_simd: {
4143 QualType KmpInt32Ty =
4144 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4145 .withConst();
4146 QualType KmpUInt64Ty =
4147 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4148 .withConst();
4149 QualType KmpInt64Ty =
4150 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4151 .withConst();
4152 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4153 QualType KmpInt32PtrTy =
4154 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4155 Sema::CapturedParamNameType ParamsParallel[] = {
4156 std::make_pair(".global_tid.", KmpInt32PtrTy),
4157 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4158 std::make_pair(StringRef(), QualType()) // __context with shared vars
4159 };
4160 // Start a captured region for 'parallel'.
4161 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4162 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4163 QualType Args[] = {VoidPtrTy};
4164 FunctionProtoType::ExtProtoInfo EPI;
4165 EPI.Variadic = true;
4166 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4167 Sema::CapturedParamNameType Params[] = {
4168 std::make_pair(".global_tid.", KmpInt32Ty),
4169 std::make_pair(".part_id.", KmpInt32PtrTy),
4170 std::make_pair(".privates.", VoidPtrTy),
4171 std::make_pair(
4172 ".copy_fn.",
4173 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4174 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4175 std::make_pair(".lb.", KmpUInt64Ty),
4176 std::make_pair(".ub.", KmpUInt64Ty),
4177 std::make_pair(".st.", KmpInt64Ty),
4178 std::make_pair(".liter.", KmpInt32Ty),
4179 std::make_pair(".reductions.", VoidPtrTy),
4180 std::make_pair(StringRef(), QualType()) // __context with shared vars
4181 };
4182 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4183 Params, /*OpenMPCaptureLevel=*/1);
4184 // Mark this captured region as inlined, because we don't use outlined
4185 // function directly.
4186 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4187 AlwaysInlineAttr::CreateImplicit(
4188 Context, {}, AttributeCommonInfo::AS_Keyword,
4189 AlwaysInlineAttr::Keyword_forceinline));
4190 break;
4191 }
4192 case OMPD_distribute_parallel_for_simd:
4193 case OMPD_distribute_parallel_for: {
4194 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4195 QualType KmpInt32PtrTy =
4196 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4197 Sema::CapturedParamNameType Params[] = {
4198 std::make_pair(".global_tid.", KmpInt32PtrTy),
4199 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4200 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4201 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4202 std::make_pair(StringRef(), QualType()) // __context with shared vars
4203 };
4204 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4205 Params);
4206 break;
4207 }
4208 case OMPD_target_teams_distribute_parallel_for:
4209 case OMPD_target_teams_distribute_parallel_for_simd: {
4210 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4211 QualType KmpInt32PtrTy =
4212 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4213 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4214
4215 QualType Args[] = {VoidPtrTy};
4216 FunctionProtoType::ExtProtoInfo EPI;
4217 EPI.Variadic = true;
4218 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4219 Sema::CapturedParamNameType Params[] = {
4220 std::make_pair(".global_tid.", KmpInt32Ty),
4221 std::make_pair(".part_id.", KmpInt32PtrTy),
4222 std::make_pair(".privates.", VoidPtrTy),
4223 std::make_pair(
4224 ".copy_fn.",
4225 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4226 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4227 std::make_pair(StringRef(), QualType()) // __context with shared vars
4228 };
4229 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4230 Params, /*OpenMPCaptureLevel=*/0);
4231 // Mark this captured region as inlined, because we don't use outlined
4232 // function directly.
4233 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4234 AlwaysInlineAttr::CreateImplicit(
4235 Context, {}, AttributeCommonInfo::AS_Keyword,
4236 AlwaysInlineAttr::Keyword_forceinline));
4237 Sema::CapturedParamNameType ParamsTarget[] = {
4238 std::make_pair(StringRef(), QualType()) // __context with shared vars
4239 };
4240 // Start a captured region for 'target' with no implicit parameters.
4241 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4242 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4243
4244 Sema::CapturedParamNameType ParamsTeams[] = {
4245 std::make_pair(".global_tid.", KmpInt32PtrTy),
4246 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4247 std::make_pair(StringRef(), QualType()) // __context with shared vars
4248 };
4249 // Start a captured region for 'target' with no implicit parameters.
4250 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4251 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4252
4253 Sema::CapturedParamNameType ParamsParallel[] = {
4254 std::make_pair(".global_tid.", KmpInt32PtrTy),
4255 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4256 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4257 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4258 std::make_pair(StringRef(), QualType()) // __context with shared vars
4259 };
4260 // Start a captured region for 'teams' or 'parallel'. Both regions have
4261 // the same implicit parameters.
4262 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4263 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4264 break;
4265 }
4266
4267 case OMPD_teams_loop: {
4268 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4269 QualType KmpInt32PtrTy =
4270 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4271
4272 Sema::CapturedParamNameType ParamsTeams[] = {
4273 std::make_pair(".global_tid.", KmpInt32PtrTy),
4274 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4275 std::make_pair(StringRef(), QualType()) // __context with shared vars
4276 };
4277 // Start a captured region for 'teams'.
4278 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4279 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4280 break;
4281 }
4282
4283 case OMPD_teams_distribute_parallel_for:
4284 case OMPD_teams_distribute_parallel_for_simd: {
4285 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4286 QualType KmpInt32PtrTy =
4287 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4288
4289 Sema::CapturedParamNameType ParamsTeams[] = {
4290 std::make_pair(".global_tid.", KmpInt32PtrTy),
4291 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4292 std::make_pair(StringRef(), QualType()) // __context with shared vars
4293 };
4294 // Start a captured region for 'target' with no implicit parameters.
4295 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4296 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4297
4298 Sema::CapturedParamNameType ParamsParallel[] = {
4299 std::make_pair(".global_tid.", KmpInt32PtrTy),
4300 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4301 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4302 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4303 std::make_pair(StringRef(), QualType()) // __context with shared vars
4304 };
4305 // Start a captured region for 'teams' or 'parallel'. Both regions have
4306 // the same implicit parameters.
4307 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4308 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4309 break;
4310 }
4311 case OMPD_target_update:
4312 case OMPD_target_enter_data:
4313 case OMPD_target_exit_data: {
4314 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4315 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4316 QualType KmpInt32PtrTy =
4317 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4318 QualType Args[] = {VoidPtrTy};
4319 FunctionProtoType::ExtProtoInfo EPI;
4320 EPI.Variadic = true;
4321 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4322 Sema::CapturedParamNameType Params[] = {
4323 std::make_pair(".global_tid.", KmpInt32Ty),
4324 std::make_pair(".part_id.", KmpInt32PtrTy),
4325 std::make_pair(".privates.", VoidPtrTy),
4326 std::make_pair(
4327 ".copy_fn.",
4328 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4329 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4330 std::make_pair(StringRef(), QualType()) // __context with shared vars
4331 };
4332 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4333 Params);
4334 // Mark this captured region as inlined, because we don't use outlined
4335 // function directly.
4336 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4337 AlwaysInlineAttr::CreateImplicit(
4338 Context, {}, AttributeCommonInfo::AS_Keyword,
4339 AlwaysInlineAttr::Keyword_forceinline));
4340 break;
4341 }
4342 case OMPD_threadprivate:
4343 case OMPD_allocate:
4344 case OMPD_taskyield:
4345 case OMPD_barrier:
4346 case OMPD_taskwait:
4347 case OMPD_cancellation_point:
4348 case OMPD_cancel:
4349 case OMPD_flush:
4350 case OMPD_depobj:
4351 case OMPD_scan:
4352 case OMPD_declare_reduction:
4353 case OMPD_declare_mapper:
4354 case OMPD_declare_simd:
4355 case OMPD_declare_target:
4356 case OMPD_end_declare_target:
4357 case OMPD_requires:
4358 case OMPD_declare_variant:
4359 case OMPD_begin_declare_variant:
4360 case OMPD_end_declare_variant:
4361 case OMPD_metadirective:
4362 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "clang/lib/Sema/SemaOpenMP.cpp", 4362)
;
4363 case OMPD_unknown:
4364 default:
4365 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 4365)
;
4366 }
4367 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setContext(CurContext);
4368 handleDeclareVariantConstructTrait(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, DKind, /* ScopeEntry */ true);
4369}
4370
4371int Sema::getNumberOfConstructScopes(unsigned Level) const {
4372 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4373}
4374
4375int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4376 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4377 getOpenMPCaptureRegions(CaptureRegions, DKind);
4378 return CaptureRegions.size();
4379}
4380
4381static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4382 Expr *CaptureExpr, bool WithInit,
4383 bool AsExpression) {
4384 assert(CaptureExpr)(static_cast <bool> (CaptureExpr) ? void (0) : __assert_fail
("CaptureExpr", "clang/lib/Sema/SemaOpenMP.cpp", 4384, __extension__
__PRETTY_FUNCTION__))
;
4385 ASTContext &C = S.getASTContext();
4386 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4387 QualType Ty = Init->getType();
4388 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4389 if (S.getLangOpts().CPlusPlus) {
4390 Ty = C.getLValueReferenceType(Ty);
4391 } else {
4392 Ty = C.getPointerType(Ty);
4393 ExprResult Res =
4394 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4395 if (!Res.isUsable())
4396 return nullptr;
4397 Init = Res.get();
4398 }
4399 WithInit = true;
4400 }
4401 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4402 CaptureExpr->getBeginLoc());
4403 if (!WithInit)
4404 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4405 S.CurContext->addHiddenDecl(CED);
4406 Sema::TentativeAnalysisScope Trap(S);
4407 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4408 return CED;
4409}
4410
4411static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4412 bool WithInit) {
4413 OMPCapturedExprDecl *CD;
4414 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4415 CD = cast<OMPCapturedExprDecl>(VD);
4416 else
4417 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4418 /*AsExpression=*/false);
4419 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4420 CaptureExpr->getExprLoc());
4421}
4422
4423static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4424 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4425 if (!Ref) {
4426 OMPCapturedExprDecl *CD = buildCaptureDecl(
4427 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4428 /*WithInit=*/true, /*AsExpression=*/true);
4429 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4430 CaptureExpr->getExprLoc());
4431 }
4432 ExprResult Res = Ref;
4433 if (!S.getLangOpts().CPlusPlus &&
4434 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4435 Ref->getType()->isPointerType()) {
4436 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4437 if (!Res.isUsable())
4438 return ExprError();
4439 }
4440 return S.DefaultLvalueConversion(Res.get());
4441}
4442
4443namespace {
4444// OpenMP directives parsed in this section are represented as a
4445// CapturedStatement with an associated statement. If a syntax error
4446// is detected during the parsing of the associated statement, the
4447// compiler must abort processing and close the CapturedStatement.
4448//
4449// Combined directives such as 'target parallel' have more than one
4450// nested CapturedStatements. This RAII ensures that we unwind out
4451// of all the nested CapturedStatements when an error is found.
4452class CaptureRegionUnwinderRAII {
4453private:
4454 Sema &S;
4455 bool &ErrorFound;
4456 OpenMPDirectiveKind DKind = OMPD_unknown;
4457
4458public:
4459 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4460 OpenMPDirectiveKind DKind)
4461 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4462 ~CaptureRegionUnwinderRAII() {
4463 if (ErrorFound) {
4464 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4465 while (--ThisCaptureLevel >= 0)
4466 S.ActOnCapturedRegionError();
4467 }
4468 }
4469};
4470} // namespace
4471
4472void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4473 // Capture variables captured by reference in lambdas for target-based
4474 // directives.
4475 if (!CurContext->isDependentContext() &&
4476 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4477 isOpenMPTargetDataManagementDirective(
4478 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4479 QualType Type = V->getType();
4480 if (const auto *RD = Type.getCanonicalType()
4481 .getNonReferenceType()
4482 ->getAsCXXRecordDecl()) {
4483 bool SavedForceCaptureByReferenceInTargetExecutable =
4484 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4485 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4486 /*V=*/true);
4487 if (RD->isLambda()) {
4488 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4489 FieldDecl *ThisCapture;
4490 RD->getCaptureFields(Captures, ThisCapture);
4491 for (const LambdaCapture &LC : RD->captures()) {
4492 if (LC.getCaptureKind() == LCK_ByRef) {
4493 VarDecl *VD = LC.getCapturedVar();
4494 DeclContext *VDC = VD->getDeclContext();
4495 if (!VDC->Encloses(CurContext))
4496 continue;
4497 MarkVariableReferenced(LC.getLocation(), VD);
4498 } else if (LC.getCaptureKind() == LCK_This) {
4499 QualType ThisTy = getCurrentThisType();
4500 if (!ThisTy.isNull() &&
4501 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4502 CheckCXXThisCapture(LC.getLocation());
4503 }
4504 }
4505 }
4506 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4507 SavedForceCaptureByReferenceInTargetExecutable);
4508 }
4509 }
4510}
4511
4512static bool checkOrderedOrderSpecified(Sema &S,
4513 const ArrayRef<OMPClause *> Clauses) {
4514 const OMPOrderedClause *Ordered = nullptr;
4515 const OMPOrderClause *Order = nullptr;
4516
4517 for (const OMPClause *Clause : Clauses) {
4518 if (Clause->getClauseKind() == OMPC_ordered)
4519 Ordered = cast<OMPOrderedClause>(Clause);
4520 else if (Clause->getClauseKind() == OMPC_order) {
4521 Order = cast<OMPOrderClause>(Clause);
4522 if (Order->getKind() != OMPC_ORDER_concurrent)
4523 Order = nullptr;
4524 }
4525 if (Ordered && Order)
4526 break;
4527 }
4528
4529 if (Ordered && Order) {
4530 S.Diag(Order->getKindKwLoc(),
4531 diag::err_omp_simple_clause_incompatible_with_ordered)
4532 << getOpenMPClauseName(OMPC_order)
4533 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4534 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4535 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4536 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4537 return true;
4538 }
4539 return false;
4540}
4541
4542StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4543 ArrayRef<OMPClause *> Clauses) {
4544 handleDeclareVariantConstructTrait(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(),
4545 /* ScopeEntry */ false);
4546 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4547 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4548 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4549 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master ||
4550 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_masked)
4551 return S;
4552
4553 bool ErrorFound = false;
4554 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4555 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4556 if (!S.isUsable()) {
4557 ErrorFound = true;
Value stored to 'ErrorFound' is never read
4558 return StmtError();
4559 }
4560
4561 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4562 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4563 OMPOrderedClause *OC = nullptr;
4564 OMPScheduleClause *SC = nullptr;
4565 SmallVector<const OMPLinearClause *, 4> LCs;
4566 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4567 // This is required for proper codegen.
4568 for (OMPClause *Clause : Clauses) {
4569 if (!LangOpts.OpenMPSimd &&
4570 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4571 Clause->getClauseKind() == OMPC_in_reduction) {
4572 // Capture taskgroup task_reduction descriptors inside the tasking regions
4573 // with the corresponding in_reduction items.
4574 auto *IRC = cast<OMPInReductionClause>(Clause);
4575 for (Expr *E : IRC->taskgroup_descriptors())
4576 if (E)
4577 MarkDeclarationsReferencedInExpr(E);
4578 }
4579 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4580 Clause->getClauseKind() == OMPC_copyprivate ||
4581 (getLangOpts().OpenMPUseTLS &&
4582 getASTContext().getTargetInfo().isTLSSupported() &&
4583 Clause->getClauseKind() == OMPC_copyin)) {
4584 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4585 // Mark all variables in private list clauses as used in inner region.
4586 for (Stmt *VarRef : Clause->children()) {
4587 if (auto *E = cast_or_null<Expr>(VarRef)) {
4588 MarkDeclarationsReferencedInExpr(E);
4589 }
4590 }
4591 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4592 } else if (isOpenMPLoopTransformationDirective(
4593 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4594 assert(CaptureRegions.empty() &&(static_cast <bool> (CaptureRegions.empty() && "No captured regions in loop transformation directives."
) ? void (0) : __assert_fail ("CaptureRegions.empty() && \"No captured regions in loop transformation directives.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 4595, __extension__ __PRETTY_FUNCTION__
))
4595 "No captured regions in loop transformation directives.")(static_cast <bool> (CaptureRegions.empty() && "No captured regions in loop transformation directives."
) ? void (0) : __assert_fail ("CaptureRegions.empty() && \"No captured regions in loop transformation directives.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 4595, __extension__ __PRETTY_FUNCTION__
))
;
4596 } else if (CaptureRegions.size() > 1 ||
4597 CaptureRegions.back() != OMPD_unknown) {
4598 if (auto *C = OMPClauseWithPreInit::get(Clause))
4599 PICs.push_back(C);
4600 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4601 if (Expr *E = C->getPostUpdateExpr())
4602 MarkDeclarationsReferencedInExpr(E);
4603 }
4604 }
4605 if (Clause->getClauseKind() == OMPC_schedule)
4606 SC = cast<OMPScheduleClause>(Clause);
4607 else if (Clause->getClauseKind() == OMPC_ordered)
4608 OC = cast<OMPOrderedClause>(Clause);
4609 else if (Clause->getClauseKind() == OMPC_linear)
4610 LCs.push_back(cast<OMPLinearClause>(Clause));
4611 }
4612 // Capture allocator expressions if used.
4613 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4614 MarkDeclarationsReferencedInExpr(E);
4615 // OpenMP, 2.7.1 Loop Construct, Restrictions
4616 // The nonmonotonic modifier cannot be specified if an ordered clause is
4617 // specified.
4618 if (SC &&
4619 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4620 SC->getSecondScheduleModifier() ==
4621 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4622 OC) {
4623 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4624 ? SC->getFirstScheduleModifierLoc()
4625 : SC->getSecondScheduleModifierLoc(),
4626 diag::err_omp_simple_clause_incompatible_with_ordered)
4627 << getOpenMPClauseName(OMPC_schedule)
4628 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4629 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4630 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4631 ErrorFound = true;
4632 }
4633 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4634 // If an order(concurrent) clause is present, an ordered clause may not appear
4635 // on the same directive.
4636 if (checkOrderedOrderSpecified(*this, Clauses))
4637 ErrorFound = true;
4638 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4639 for (const OMPLinearClause *C : LCs) {
4640 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4641 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4642 }
4643 ErrorFound = true;
4644 }
4645 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4646 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4647 OC->getNumForLoops()) {
4648 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4649 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4650 ErrorFound = true;
4651 }
4652 if (ErrorFound) {
4653 return StmtError();
4654 }
4655 StmtResult SR = S;
4656 unsigned CompletedRegions = 0;
4657 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4658 // Mark all variables in private list clauses as used in inner region.
4659 // Required for proper codegen of combined directives.
4660 // TODO: add processing for other clauses.
4661 if (ThisCaptureRegion != OMPD_unknown) {
4662 for (const clang::OMPClauseWithPreInit *C : PICs) {
4663 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4664 // Find the particular capture region for the clause if the
4665 // directive is a combined one with multiple capture regions.
4666 // If the directive is not a combined one, the capture region
4667 // associated with the clause is OMPD_unknown and is generated
4668 // only once.
4669 if (CaptureRegion == ThisCaptureRegion ||
4670 CaptureRegion == OMPD_unknown) {
4671 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4672 for (Decl *D : DS->decls())
4673 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4674 }
4675 }
4676 }
4677 }
4678 if (ThisCaptureRegion == OMPD_target) {
4679 // Capture allocator traits in the target region. They are used implicitly
4680 // and, thus, are not captured by default.
4681 for (OMPClause *C : Clauses) {
4682 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4683 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4684 ++I) {
4685 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4686 if (Expr *E = D.AllocatorTraits)
4687 MarkDeclarationsReferencedInExpr(E);
4688 }
4689 continue;
4690 }
4691 }
4692 }
4693 if (ThisCaptureRegion == OMPD_parallel) {
4694 // Capture temp arrays for inscan reductions and locals in aligned
4695 // clauses.
4696 for (OMPClause *C : Clauses) {
4697 if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4698 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4699 continue;
4700 for (Expr *E : RC->copy_array_temps())
4701 MarkDeclarationsReferencedInExpr(E);
4702 }
4703 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4704 for (Expr *E : AC->varlists())
4705 MarkDeclarationsReferencedInExpr(E);
4706 }
4707 }
4708 }
4709 if (++CompletedRegions == CaptureRegions.size())
4710 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4711 SR = ActOnCapturedRegionEnd(SR.get());
4712 }
4713 return SR;
4714}
4715
4716static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4717 OpenMPDirectiveKind CancelRegion,
4718 SourceLocation StartLoc) {
4719 // CancelRegion is only needed for cancel and cancellation_point.
4720 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4721 return false;
4722
4723 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4724 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4725 return false;
4726
4727 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4728 << getOpenMPDirectiveName(CancelRegion);
4729 return true;
4730}
4731
4732static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4733 OpenMPDirectiveKind CurrentRegion,
4734 const DeclarationNameInfo &CurrentName,
4735 OpenMPDirectiveKind CancelRegion,
4736 OpenMPBindClauseKind BindKind,
4737 SourceLocation StartLoc) {
4738 if (Stack->getCurScope()) {
4739 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4740 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4741 bool NestingProhibited = false;
4742 bool CloseNesting = true;
4743 bool OrphanSeen = false;
4744 enum {
4745 NoRecommend,
4746 ShouldBeInParallelRegion,
4747 ShouldBeInOrderedRegion,
4748 ShouldBeInTargetRegion,
4749 ShouldBeInTeamsRegion,
4750 ShouldBeInLoopSimdRegion,
4751 } Recommend = NoRecommend;
4752 if (isOpenMPSimdDirective(ParentRegion) &&
4753 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4754 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4755 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4756 CurrentRegion != OMPD_scan))) {
4757 // OpenMP [2.16, Nesting of Regions]
4758 // OpenMP constructs may not be nested inside a simd region.
4759 // OpenMP [2.8.1,simd Construct, Restrictions]
4760 // An ordered construct with the simd clause is the only OpenMP
4761 // construct that can appear in the simd region.
4762 // Allowing a SIMD construct nested in another SIMD construct is an
4763 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4764 // message.
4765 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4766 // The only OpenMP constructs that can be encountered during execution of
4767 // a simd region are the atomic construct, the loop construct, the simd
4768 // construct and the ordered construct with the simd clause.
4769 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4770 ? diag::err_omp_prohibited_region_simd
4771 : diag::warn_omp_nesting_simd)
4772 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4773 return CurrentRegion != OMPD_simd;
4774 }
4775 if (ParentRegion == OMPD_atomic) {
4776 // OpenMP [2.16, Nesting of Regions]
4777 // OpenMP constructs may not be nested inside an atomic region.
4778 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4779 return true;
4780 }
4781 if (CurrentRegion == OMPD_section) {
4782 // OpenMP [2.7.2, sections Construct, Restrictions]
4783 // Orphaned section directives are prohibited. That is, the section
4784 // directives must appear within the sections construct and must not be
4785 // encountered elsewhere in the sections region.
4786 if (ParentRegion != OMPD_sections &&
4787 ParentRegion != OMPD_parallel_sections) {
4788 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4789 << (ParentRegion != OMPD_unknown)
4790 << getOpenMPDirectiveName(ParentRegion);
4791 return true;
4792 }
4793 return false;
4794 }
4795 // Allow some constructs (except teams and cancellation constructs) to be
4796 // orphaned (they could be used in functions, called from OpenMP regions
4797 // with the required preconditions).
4798 if (ParentRegion == OMPD_unknown &&
4799 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4800 CurrentRegion != OMPD_cancellation_point &&
4801 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4802 return false;
4803 if (CurrentRegion == OMPD_cancellation_point ||
4804 CurrentRegion == OMPD_cancel) {
4805 // OpenMP [2.16, Nesting of Regions]
4806 // A cancellation point construct for which construct-type-clause is
4807 // taskgroup must be nested inside a task construct. A cancellation
4808 // point construct for which construct-type-clause is not taskgroup must
4809 // be closely nested inside an OpenMP construct that matches the type
4810 // specified in construct-type-clause.
4811 // A cancel construct for which construct-type-clause is taskgroup must be
4812 // nested inside a task construct. A cancel construct for which
4813 // construct-type-clause is not taskgroup must be closely nested inside an
4814 // OpenMP construct that matches the type specified in
4815 // construct-type-clause.
4816 NestingProhibited =
4817 !((CancelRegion == OMPD_parallel &&
4818 (ParentRegion == OMPD_parallel ||
4819 ParentRegion == OMPD_target_parallel)) ||
4820 (CancelRegion == OMPD_for &&
4821 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4822 ParentRegion == OMPD_target_parallel_for ||
4823 ParentRegion == OMPD_distribute_parallel_for ||
4824 ParentRegion == OMPD_teams_distribute_parallel_for ||
4825 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4826 (CancelRegion == OMPD_taskgroup &&
4827 (ParentRegion == OMPD_task ||
4828 (SemaRef.getLangOpts().OpenMP >= 50 &&
4829 (ParentRegion == OMPD_taskloop ||
4830 ParentRegion == OMPD_master_taskloop ||
4831 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4832 (CancelRegion == OMPD_sections &&
4833 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4834 ParentRegion == OMPD_parallel_sections)));
4835 OrphanSeen = ParentRegion == OMPD_unknown;
4836 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4837 // OpenMP 5.1 [2.22, Nesting of Regions]
4838 // A masked region may not be closely nested inside a worksharing, loop,
4839 // atomic, task, or taskloop region.
4840 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4841 isOpenMPGenericLoopDirective(ParentRegion) ||
4842 isOpenMPTaskingDirective(ParentRegion);
4843 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4844 // OpenMP [2.16, Nesting of Regions]
4845 // A critical region may not be nested (closely or otherwise) inside a
4846 // critical region with the same name. Note that this restriction is not
4847 // sufficient to prevent deadlock.
4848 SourceLocation PreviousCriticalLoc;
4849 bool DeadLock = Stack->hasDirective(
4850 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4851 const DeclarationNameInfo &DNI,
4852 SourceLocation Loc) {
4853 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4854 PreviousCriticalLoc = Loc;
4855 return true;
4856 }
4857 return false;
4858 },
4859 false /* skip top directive */);
4860 if (DeadLock) {
4861 SemaRef.Diag(StartLoc,
4862 diag::err_omp_prohibited_region_critical_same_name)
4863 << CurrentName.getName();
4864 if (PreviousCriticalLoc.isValid())
4865 SemaRef.Diag(PreviousCriticalLoc,
4866 diag::note_omp_previous_critical_region);
4867 return true;
4868 }
4869 } else if (CurrentRegion == OMPD_barrier) {
4870 // OpenMP 5.1 [2.22, Nesting of Regions]
4871 // A barrier region may not be closely nested inside a worksharing, loop,
4872 // task, taskloop, critical, ordered, atomic, or masked region.
4873 NestingProhibited =
4874 isOpenMPWorksharingDirective(ParentRegion) ||
4875 isOpenMPGenericLoopDirective(ParentRegion) ||
4876 isOpenMPTaskingDirective(ParentRegion) ||
4877 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4878 ParentRegion == OMPD_parallel_master ||
4879 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4880 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4881 !isOpenMPParallelDirective(CurrentRegion) &&
4882 !isOpenMPTeamsDirective(CurrentRegion)) {
4883 // OpenMP 5.1 [2.22, Nesting of Regions]
4884 // A loop region that binds to a parallel region or a worksharing region
4885 // may not be closely nested inside a worksharing, loop, task, taskloop,
4886 // critical, ordered, atomic, or masked region.
4887 NestingProhibited =
4888 isOpenMPWorksharingDirective(ParentRegion) ||
4889 isOpenMPGenericLoopDirective(ParentRegion) ||
4890 isOpenMPTaskingDirective(ParentRegion) ||
4891 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4892 ParentRegion == OMPD_parallel_master ||
4893 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4894 Recommend = ShouldBeInParallelRegion;
4895 } else if (CurrentRegion == OMPD_ordered) {
4896 // OpenMP [2.16, Nesting of Regions]
4897 // An ordered region may not be closely nested inside a critical,
4898 // atomic, or explicit task region.
4899 // An ordered region must be closely nested inside a loop region (or
4900 // parallel loop region) with an ordered clause.
4901 // OpenMP [2.8.1,simd Construct, Restrictions]
4902 // An ordered construct with the simd clause is the only OpenMP construct
4903 // that can appear in the simd region.
4904 NestingProhibited = ParentRegion == OMPD_critical ||
4905 isOpenMPTaskingDirective(ParentRegion) ||
4906 !(isOpenMPSimdDirective(ParentRegion) ||
4907 Stack->isParentOrderedRegion());
4908 Recommend = ShouldBeInOrderedRegion;
4909 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4910 // OpenMP [2.16, Nesting of Regions]
4911 // If specified, a teams construct must be contained within a target
4912 // construct.
4913 NestingProhibited =
4914 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4915 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4916 ParentRegion != OMPD_target);
4917 OrphanSeen = ParentRegion == OMPD_unknown;
4918 Recommend = ShouldBeInTargetRegion;
4919 } else if (CurrentRegion == OMPD_scan) {
4920 // OpenMP [2.16, Nesting of Regions]
4921 // If specified, a teams construct must be contained within a target
4922 // construct.
4923 NestingProhibited =
4924 SemaRef.LangOpts.OpenMP < 50 ||
4925 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4926 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4927 ParentRegion != OMPD_parallel_for_simd);
4928 OrphanSeen = ParentRegion == OMPD_unknown;
4929 Recommend = ShouldBeInLoopSimdRegion;
4930 }
4931 if (!NestingProhibited &&
4932 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4933 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4934 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4935 // OpenMP [5.1, 2.22, Nesting of Regions]
4936 // distribute, distribute simd, distribute parallel worksharing-loop,
4937 // distribute parallel worksharing-loop SIMD, loop, parallel regions,
4938 // including any parallel regions arising from combined constructs,
4939 // omp_get_num_teams() regions, and omp_get_team_num() regions are the
4940 // only OpenMP regions that may be strictly nested inside the teams
4941 // region.
4942 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4943 !isOpenMPDistributeDirective(CurrentRegion) &&
4944 CurrentRegion != OMPD_loop;
4945 Recommend = ShouldBeInParallelRegion;
4946 }
4947 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
4948 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
4949 // If the bind clause is present on the loop construct and binding is
4950 // teams then the corresponding loop region must be strictly nested inside
4951 // a teams region.
4952 NestingProhibited = BindKind == OMPC_BIND_teams &&
4953 ParentRegion != OMPD_teams &&
4954 ParentRegion != OMPD_target_teams;
4955 Recommend = ShouldBeInTeamsRegion;
4956 }
4957 if (!NestingProhibited &&
4958 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4959 // OpenMP 4.5 [2.17 Nesting of Regions]
4960 // The region associated with the distribute construct must be strictly
4961 // nested inside a teams region
4962 NestingProhibited =
4963 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4964 Recommend = ShouldBeInTeamsRegion;
4965 }
4966 if (!NestingProhibited &&
4967 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4968 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4969 // OpenMP 4.5 [2.17 Nesting of Regions]
4970 // If a target, target update, target data, target enter data, or
4971 // target exit data construct is encountered during execution of a
4972 // target region, the behavior is unspecified.
4973 NestingProhibited = Stack->hasDirective(
4974 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4975 SourceLocation) {
4976 if (isOpenMPTargetExecutionDirective(K)) {
4977 OffendingRegion = K;
4978 return true;
4979 }
4980 return false;
4981 },
4982 false /* don't skip top directive */);
4983 CloseNesting = false;
4984 }
4985 if (NestingProhibited) {
4986 if (OrphanSeen) {
4987 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4988 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4989 } else {
4990 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4991 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4992 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4993 }
4994 return true;
4995 }
4996 }
4997 return false;
4998}
4999
5000struct Kind2Unsigned {
5001 using argument_type = OpenMPDirectiveKind;
5002 unsigned operator()(argument_type DK) { return unsigned(DK); }
5003};
5004static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5005 ArrayRef<OMPClause *> Clauses,
5006 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5007 bool ErrorFound = false;
5008 unsigned NamedModifiersNumber = 0;
5009 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5010 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5011 SmallVector<SourceLocation, 4> NameModifierLoc;
5012 for (const OMPClause *C : Clauses) {
5013 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5014 // At most one if clause without a directive-name-modifier can appear on
5015 // the directive.
5016 OpenMPDirectiveKind CurNM = IC->getNameModifier();
5017 if (FoundNameModifiers[CurNM]) {
5018 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5019 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5020 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5021 ErrorFound = true;
5022 } else if (CurNM != OMPD_unknown) {
5023 NameModifierLoc.push_back(IC->getNameModifierLoc());
5024 ++NamedModifiersNumber;
5025 }
5026 FoundNameModifiers[CurNM] = IC;
5027 if (CurNM == OMPD_unknown)
5028 continue;
5029 // Check if the specified name modifier is allowed for the current
5030 // directive.
5031 // At most one if clause with the particular directive-name-modifier can
5032 // appear on the directive.
5033 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5034 S.Diag(IC->getNameModifierLoc(),
5035 diag::err_omp_wrong_if_directive_name_modifier)
5036 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5037 ErrorFound = true;
5038 }
5039 }
5040 }
5041 // If any if clause on the directive includes a directive-name-modifier then
5042 // all if clauses on the directive must include a directive-name-modifier.
5043 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5044 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5045 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5046 diag::err_omp_no_more_if_clause);
5047 } else {
5048 std::string Values;
5049 std::string Sep(", ");
5050 unsigned AllowedCnt = 0;
5051 unsigned TotalAllowedNum =
5052 AllowedNameModifiers.size() - NamedModifiersNumber;
5053 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5054 ++Cnt) {
5055 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5056 if (!FoundNameModifiers[NM]) {
5057 Values += "'";
5058 Values += getOpenMPDirectiveName(NM);
5059 Values += "'";
5060 if (AllowedCnt + 2 == TotalAllowedNum)
5061 Values += " or ";
5062 else if (AllowedCnt + 1 != TotalAllowedNum)
5063 Values += Sep;
5064 ++AllowedCnt;
5065 }
5066 }
5067 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5068 diag::err_omp_unnamed_if_clause)
5069 << (TotalAllowedNum > 1) << Values;
5070 }
5071 for (SourceLocation Loc : NameModifierLoc) {
5072 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5073 }
5074 ErrorFound = true;
5075 }
5076 return ErrorFound;
5077}
5078
5079static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5080 SourceLocation &ELoc,
5081 SourceRange &ERange,
5082 bool AllowArraySection) {
5083 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5084 RefExpr->containsUnexpandedParameterPack())
5085 return std::make_pair(nullptr, true);
5086
5087 // OpenMP [3.1, C/C++]
5088 // A list item is a variable name.
5089 // OpenMP [2.9.3.3, Restrictions, p.1]
5090 // A variable that is part of another variable (as an array or
5091 // structure element) cannot appear in a private clause.
5092 RefExpr = RefExpr->IgnoreParens();
5093 enum {
5094 NoArrayExpr = -1,
5095 ArraySubscript = 0,
5096 OMPArraySection = 1
5097 } IsArrayExpr = NoArrayExpr;
5098 if (AllowArraySection) {
5099 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5100 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5101 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5102 Base = TempASE->getBase()->IgnoreParenImpCasts();
5103 RefExpr = Base;
5104 IsArrayExpr = ArraySubscript;
5105 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5106 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5107 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5108 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5109 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5110 Base = TempASE->getBase()->IgnoreParenImpCasts();
5111 RefExpr = Base;
5112 IsArrayExpr = OMPArraySection;
5113 }
5114 }
5115 ELoc = RefExpr->getExprLoc();
5116 ERange = RefExpr->getSourceRange();
5117 RefExpr = RefExpr->IgnoreParenImpCasts();
5118 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5119 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5120 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5121 (S.getCurrentThisType().isNull() || !ME ||
5122 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5123 !isa<FieldDecl>(ME->getMemberDecl()))) {
5124 if (IsArrayExpr != NoArrayExpr) {
5125 S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5126 << IsArrayExpr << ERange;
5127 } else {
5128 S.Diag(ELoc,
5129 AllowArraySection
5130 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5131 : diag::err_omp_expected_var_name_member_expr)
5132 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5133 }
5134 return std::make_pair(nullptr, false);
5135 }
5136 return std::make_pair(
5137 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5138}
5139
5140namespace {
5141/// Checks if the allocator is used in uses_allocators clause to be allowed in
5142/// target regions.
5143class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5144 DSAStackTy *S = nullptr;
5145
5146public:
5147 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5148 return S->isUsesAllocatorsDecl(E->getDecl())
5149 .getValueOr(
5150 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5151 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5152 }
5153 bool VisitStmt(const Stmt *S) {
5154 for (const Stmt *Child : S->children()) {
5155 if (Child && Visit(Child))
5156 return true;
5157 }
5158 return false;
5159 }
5160 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5161};
5162} // namespace
5163
5164static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5165 ArrayRef<OMPClause *> Clauses) {
5166 assert(!S.CurContext->isDependentContext() &&(static_cast <bool> (!S.CurContext->isDependentContext
() && "Expected non-dependent context.") ? void (0) :
__assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5167, __extension__ __PRETTY_FUNCTION__
))
5167 "Expected non-dependent context.")(static_cast <bool> (!S.CurContext->isDependentContext
() && "Expected non-dependent context.") ? void (0) :
__assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5167, __extension__ __PRETTY_FUNCTION__
))
;
5168 auto AllocateRange =
5169 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5170 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5171 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5172 return isOpenMPPrivate(C->getClauseKind());
5173 });
5174 for (OMPClause *Cl : PrivateRange) {
5175 MutableArrayRef<Expr *>::iterator I, It, Et;
5176 if (Cl->getClauseKind() == OMPC_private) {
5177 auto *PC = cast<OMPPrivateClause>(Cl);
5178 I = PC->private_copies().begin();
5179 It = PC->varlist_begin();
5180 Et = PC->varlist_end();
5181 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5182 auto *PC = cast<OMPFirstprivateClause>(Cl);
5183 I = PC->private_copies().begin();
5184 It = PC->varlist_begin();
5185 Et = PC->varlist_end();
5186 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5187 auto *PC = cast<OMPLastprivateClause>(Cl);
5188 I = PC->private_copies().begin();
5189 It = PC->varlist_begin();
5190 Et = PC->varlist_end();
5191 } else if (Cl->getClauseKind() == OMPC_linear) {
5192 auto *PC = cast<OMPLinearClause>(Cl);
5193 I = PC->privates().begin();
5194 It = PC->varlist_begin();
5195 Et = PC->varlist_end();
5196 } else if (Cl->getClauseKind() == OMPC_reduction) {
5197 auto *PC = cast<OMPReductionClause>(Cl);
5198 I = PC->privates().begin();
5199 It = PC->varlist_begin();
5200 Et = PC->varlist_end();
5201 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5202 auto *PC = cast<OMPTaskReductionClause>(Cl);
5203 I = PC->privates().begin();
5204 It = PC->varlist_begin();
5205 Et = PC->varlist_end();
5206 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5207 auto *PC = cast<OMPInReductionClause>(Cl);
5208 I = PC->privates().begin();
5209 It = PC->varlist_begin();
5210 Et = PC->varlist_end();
5211 } else {
5212 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"clang/lib/Sema/SemaOpenMP.cpp", 5212)
;
5213 }
5214 for (Expr *E : llvm::make_range(It, Et)) {
5215 if (!*I) {
5216 ++I;
5217 continue;
5218 }
5219 SourceLocation ELoc;
5220 SourceRange ERange;
5221 Expr *SimpleRefExpr = E;
5222 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5223 /*AllowArraySection=*/true);
5224 DeclToCopy.try_emplace(Res.first,
5225 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5226 ++I;
5227 }
5228 }
5229 for (OMPClause *C : AllocateRange) {
5230 auto *AC = cast<OMPAllocateClause>(C);
5231 if (S.getLangOpts().OpenMP >= 50 &&
5232 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5233 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5234 AC->getAllocator()) {
5235 Expr *Allocator = AC->getAllocator();
5236 // OpenMP, 2.12.5 target Construct
5237 // Memory allocators that do not appear in a uses_allocators clause cannot
5238 // appear as an allocator in an allocate clause or be used in the target
5239 // region unless a requires directive with the dynamic_allocators clause
5240 // is present in the same compilation unit.
5241 AllocatorChecker Checker(Stack);
5242 if (Checker.Visit(Allocator))
5243 S.Diag(Allocator->getExprLoc(),
5244 diag::err_omp_allocator_not_in_uses_allocators)
5245 << Allocator->getSourceRange();
5246 }
5247 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5248 getAllocatorKind(S, Stack, AC->getAllocator());
5249 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5250 // For task, taskloop or target directives, allocation requests to memory
5251 // allocators with the trait access set to thread result in unspecified
5252 // behavior.
5253 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5254 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5255 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5256 S.Diag(AC->getAllocator()->getExprLoc(),
5257 diag::warn_omp_allocate_thread_on_task_target_directive)
5258 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5259 }
5260 for (Expr *E : AC->varlists()) {
5261 SourceLocation ELoc;
5262 SourceRange ERange;
5263 Expr *SimpleRefExpr = E;
5264 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5265 ValueDecl *VD = Res.first;
5266 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5267 if (!isOpenMPPrivate(Data.CKind)) {
5268 S.Diag(E->getExprLoc(),
5269 diag::err_omp_expected_private_copy_for_allocate);
5270 continue;
5271 }
5272 VarDecl *PrivateVD = DeclToCopy[VD];
5273 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5274 AllocatorKind, AC->getAllocator()))
5275 continue;
5276 // Placeholder until allocate clause supports align modifier.
5277 Expr *Alignment = nullptr;
5278 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5279 Alignment, E->getSourceRange());
5280 }
5281 }
5282}
5283
5284namespace {
5285/// Rewrite statements and expressions for Sema \p Actions CurContext.
5286///
5287/// Used to wrap already parsed statements/expressions into a new CapturedStmt
5288/// context. DeclRefExpr used inside the new context are changed to refer to the
5289/// captured variable instead.
5290class CaptureVars : public TreeTransform<CaptureVars> {
5291 using BaseTransform = TreeTransform<CaptureVars>;
5292
5293public:
5294 CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5295
5296 bool AlwaysRebuild() { return true; }
5297};
5298} // namespace
5299
5300static VarDecl *precomputeExpr(Sema &Actions,
5301 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5302 StringRef Name) {
5303 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5304 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5305 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5306 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5307 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5308 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5309 BodyStmts.push_back(NewDeclStmt);
5310 return NewVar;
5311}
5312
5313/// Create a closure that computes the number of iterations of a loop.
5314///
5315/// \param Actions The Sema object.
5316/// \param LogicalTy Type for the logical iteration number.
5317/// \param Rel Comparison operator of the loop condition.
5318/// \param StartExpr Value of the loop counter at the first iteration.
5319/// \param StopExpr Expression the loop counter is compared against in the loop
5320/// condition. \param StepExpr Amount of increment after each iteration.
5321///
5322/// \return Closure (CapturedStmt) of the distance calculation.
5323static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5324 BinaryOperator::Opcode Rel,
5325 Expr *StartExpr, Expr *StopExpr,
5326 Expr *StepExpr) {
5327 ASTContext &Ctx = Actions.getASTContext();
5328 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5329
5330 // Captured regions currently don't support return values, we use an
5331 // out-parameter instead. All inputs are implicit captures.
5332 // TODO: Instead of capturing each DeclRefExpr occurring in
5333 // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5334 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5335 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5336 {StringRef(), QualType()}};
5337 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5338
5339 Stmt *Body;
5340 {
5341 Sema::CompoundScopeRAII CompoundScope(Actions);
5342 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5343
5344 // Get the LValue expression for the result.
5345 ImplicitParamDecl *DistParam = CS->getParam(0);
5346 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5347 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5348
5349 SmallVector<Stmt *, 4> BodyStmts;
5350
5351 // Capture all referenced variable references.
5352 // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5353 // CapturedStmt, we could compute them before and capture the result, to be
5354 // used jointly with the LoopVar function.
5355 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5356 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5357 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5358 auto BuildVarRef = [&](VarDecl *VD) {
5359 return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5360 };
5361
5362 IntegerLiteral *Zero = IntegerLiteral::Create(
5363 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5364 IntegerLiteral *One = IntegerLiteral::Create(
5365 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5366 Expr *Dist;
5367 if (Rel == BO_NE) {
5368 // When using a != comparison, the increment can be +1 or -1. This can be
5369 // dynamic at runtime, so we need to check for the direction.
5370 Expr *IsNegStep = AssertSuccess(
5371 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5372
5373 // Positive increment.
5374 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5375 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5376 ForwardRange = AssertSuccess(
5377 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5378 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5379 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5380
5381 // Negative increment.
5382 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5383 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5384 BackwardRange = AssertSuccess(
5385 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5386 Expr *NegIncAmount = AssertSuccess(
5387 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5388 Expr *BackwardDist = AssertSuccess(
5389 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5390
5391 // Use the appropriate case.
5392 Dist = AssertSuccess(Actions.ActOnConditionalOp(
5393 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5394 } else {
5395 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&(static_cast <bool> ((Rel == BO_LT || Rel == BO_LE || Rel
== BO_GE || Rel == BO_GT) && "Expected one of these relational operators"
) ? void (0) : __assert_fail ("(Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && \"Expected one of these relational operators\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5396, __extension__ __PRETTY_FUNCTION__
))
5396 "Expected one of these relational operators")(static_cast <bool> ((Rel == BO_LT || Rel == BO_LE || Rel
== BO_GE || Rel == BO_GT) && "Expected one of these relational operators"
) ? void (0) : __assert_fail ("(Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && \"Expected one of these relational operators\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5396, __extension__ __PRETTY_FUNCTION__
))
;
5397
5398 // We can derive the direction from any other comparison operator. It is
5399 // non well-formed OpenMP if Step increments/decrements in the other
5400 // directions. Whether at least the first iteration passes the loop
5401 // condition.
5402 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5403 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5404
5405 // Compute the range between first and last counter value.
5406 Expr *Range;
5407 if (Rel == BO_GE || Rel == BO_GT)
5408 Range = AssertSuccess(Actions.BuildBinOp(
5409 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5410 else
5411 Range = AssertSuccess(Actions.BuildBinOp(
5412 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5413
5414 // Ensure unsigned range space.
5415 Range =
5416 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5417
5418 if (Rel == BO_LE || Rel == BO_GE) {
5419 // Add one to the range if the relational operator is inclusive.
5420 Range =
5421 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5422 }
5423
5424 // Divide by the absolute step amount. If the range is not a multiple of
5425 // the step size, rounding-up the effective upper bound ensures that the
5426 // last iteration is included.
5427 // Note that the rounding-up may cause an overflow in a temporry that
5428 // could be avoided, but would have occurred in a C-style for-loop as well.
5429 Expr *Divisor = BuildVarRef(NewStep);
5430 if (Rel == BO_GE || Rel == BO_GT)
5431 Divisor =
5432 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5433 Expr *DivisorMinusOne =
5434 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5435 Expr *RangeRoundUp = AssertSuccess(
5436 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5437 Dist = AssertSuccess(
5438 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5439
5440 // If there is not at least one iteration, the range contains garbage. Fix
5441 // to zero in this case.
5442 Dist = AssertSuccess(
5443 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5444 }
5445
5446 // Assign the result to the out-parameter.
5447 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5448 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5449 BodyStmts.push_back(ResultAssign);
5450
5451 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5452 }
5453
5454 return cast<CapturedStmt>(
5455 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5456}
5457
5458/// Create a closure that computes the loop variable from the logical iteration
5459/// number.
5460///
5461/// \param Actions The Sema object.
5462/// \param LoopVarTy Type for the loop variable used for result value.
5463/// \param LogicalTy Type for the logical iteration number.
5464/// \param StartExpr Value of the loop counter at the first iteration.
5465/// \param Step Amount of increment after each iteration.
5466/// \param Deref Whether the loop variable is a dereference of the loop
5467/// counter variable.
5468///
5469/// \return Closure (CapturedStmt) of the loop value calculation.
5470static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5471 QualType LogicalTy,
5472 DeclRefExpr *StartExpr, Expr *Step,
5473 bool Deref) {
5474 ASTContext &Ctx = Actions.getASTContext();
5475
5476 // Pass the result as an out-parameter. Passing as return value would require
5477 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5478 // invoke a copy constructor.
5479 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5480 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5481 {"Logical", LogicalTy},
5482 {StringRef(), QualType()}};
5483 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5484
5485 // Capture the initial iterator which represents the LoopVar value at the
5486 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5487 // it in every iteration, capture it by value before it is modified.
5488 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5489 bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5490 Sema::TryCapture_ExplicitByVal, {});
5491 (void)Invalid;
5492 assert(!Invalid && "Expecting capture-by-value to work.")(static_cast <bool> (!Invalid && "Expecting capture-by-value to work."
) ? void (0) : __assert_fail ("!Invalid && \"Expecting capture-by-value to work.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5492, __extension__ __PRETTY_FUNCTION__
))
;
5493
5494 Expr *Body;
5495 {
5496 Sema::CompoundScopeRAII CompoundScope(Actions);
5497 auto *CS = cast<CapturedDecl>(Actions.CurContext);
5498
5499 ImplicitParamDecl *TargetParam = CS->getParam(0);
5500 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5501 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5502 ImplicitParamDecl *IndvarParam = CS->getParam(1);
5503 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5504 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5505
5506 // Capture the Start expression.
5507 CaptureVars Recap(Actions);
5508 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5509 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5510
5511 Expr *Skip = AssertSuccess(
5512 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5513 // TODO: Explicitly cast to the iterator's difference_type instead of
5514 // relying on implicit conversion.
5515 Expr *Advanced =
5516 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5517
5518 if (Deref) {
5519 // For range-based for-loops convert the loop counter value to a concrete
5520 // loop variable value by dereferencing the iterator.
5521 Advanced =
5522 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5523 }
5524
5525 // Assign the result to the output parameter.
5526 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5527 BO_Assign, TargetRef, Advanced));
5528 }
5529 return cast<CapturedStmt>(
5530 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5531}
5532
5533StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5534 ASTContext &Ctx = getASTContext();
5535
5536 // Extract the common elements of ForStmt and CXXForRangeStmt:
5537 // Loop variable, repeat condition, increment
5538 Expr *Cond, *Inc;
5539 VarDecl *LIVDecl, *LUVDecl;
5540 if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5541 Stmt *Init = For->getInit();
5542 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5543 // For statement declares loop variable.
5544 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5545 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5546 // For statement reuses variable.
5547 assert(LCAssign->getOpcode() == BO_Assign &&(static_cast <bool> (LCAssign->getOpcode() == BO_Assign
&& "init part must be a loop variable assignment") ?
void (0) : __assert_fail ("LCAssign->getOpcode() == BO_Assign && \"init part must be a loop variable assignment\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5548, __extension__ __PRETTY_FUNCTION__
))
5548 "init part must be a loop variable assignment")(static_cast <bool> (LCAssign->getOpcode() == BO_Assign
&& "init part must be a loop variable assignment") ?
void (0) : __assert_fail ("LCAssign->getOpcode() == BO_Assign && \"init part must be a loop variable assignment\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5548, __extension__ __PRETTY_FUNCTION__
))
;
5549 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5550 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5551 } else
5552 llvm_unreachable("Cannot determine loop variable")::llvm::llvm_unreachable_internal("Cannot determine loop variable"
, "clang/lib/Sema/SemaOpenMP.cpp", 5552)
;
5553 LUVDecl = LIVDecl;
5554
5555 Cond = For->getCond();
5556 Inc = For->getInc();
5557 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5558 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5559 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5560 LUVDecl = RangeFor->getLoopVariable();
5561
5562 Cond = RangeFor->getCond();
5563 Inc = RangeFor->getInc();
5564 } else
5565 llvm_unreachable("unhandled kind of loop")::llvm::llvm_unreachable_internal("unhandled kind of loop", "clang/lib/Sema/SemaOpenMP.cpp"
, 5565)
;
5566
5567 QualType CounterTy = LIVDecl->getType();
5568 QualType LVTy = LUVDecl->getType();
5569
5570 // Analyze the loop condition.
5571 Expr *LHS, *RHS;
5572 BinaryOperator::Opcode CondRel;
5573 Cond = Cond->IgnoreImplicit();
5574 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5575 LHS = CondBinExpr->getLHS();
5576 RHS = CondBinExpr->getRHS();
5577 CondRel = CondBinExpr->getOpcode();
5578 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5579 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands")(static_cast <bool> (CondCXXOp->getNumArgs() == 2 &&
"Comparison should have 2 operands") ? void (0) : __assert_fail
("CondCXXOp->getNumArgs() == 2 && \"Comparison should have 2 operands\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5579, __extension__ __PRETTY_FUNCTION__
))
;
5580 LHS = CondCXXOp->getArg(0);
5581 RHS = CondCXXOp->getArg(1);
5582 switch (CondCXXOp->getOperator()) {
5583 case OO_ExclaimEqual:
5584 CondRel = BO_NE;
5585 break;
5586 case OO_Less:
5587 CondRel = BO_LT;
5588 break;
5589 case OO_LessEqual:
5590 CondRel = BO_LE;
5591 break;
5592 case OO_Greater:
5593 CondRel = BO_GT;
5594 break;
5595 case OO_GreaterEqual:
5596 CondRel = BO_GE;
5597 break;
5598 default:
5599 llvm_unreachable("unexpected iterator operator")::llvm::llvm_unreachable_internal("unexpected iterator operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5599)
;
5600 }
5601 } else
5602 llvm_unreachable("unexpected loop condition")::llvm::llvm_unreachable_internal("unexpected loop condition"
, "clang/lib/Sema/SemaOpenMP.cpp", 5602)
;
5603
5604 // Normalize such that the loop counter is on the LHS.
5605 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5606 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5607 std::swap(LHS, RHS);
5608 CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5609 }
5610 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5611
5612 // Decide the bit width for the logical iteration counter. By default use the
5613 // unsigned ptrdiff_t integer size (for iterators and pointers).
5614 // TODO: For iterators, use iterator::difference_type,
5615 // std::iterator_traits<>::difference_type or decltype(it - end).
5616 QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5617 if (CounterTy->isIntegerType()) {
5618 unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5619 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5620 }
5621
5622 // Analyze the loop increment.
5623 Expr *Step;
5624 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5625 int Direction;
5626 switch (IncUn->getOpcode()) {
5627 case UO_PreInc:
5628 case UO_PostInc:
5629 Direction = 1;
5630 break;
5631 case UO_PreDec:
5632 case UO_PostDec:
5633 Direction = -1;
5634 break;
5635 default:
5636 llvm_unreachable("unhandled unary increment operator")::llvm::llvm_unreachable_internal("unhandled unary increment operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5636)
;
5637 }
5638 Step = IntegerLiteral::Create(
5639 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5640 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5641 if (IncBin->getOpcode() == BO_AddAssign) {
5642 Step = IncBin->getRHS();
5643 } else if (IncBin->getOpcode() == BO_SubAssign) {
5644 Step =
5645 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5646 } else
5647 llvm_unreachable("unhandled binary increment operator")::llvm::llvm_unreachable_internal("unhandled binary increment operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5647)
;
5648 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5649 switch (CondCXXOp->getOperator()) {
5650 case OO_PlusPlus:
5651 Step = IntegerLiteral::Create(
5652 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5653 break;
5654 case OO_MinusMinus:
5655 Step = IntegerLiteral::Create(
5656 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5657 break;
5658 case OO_PlusEqual:
5659 Step = CondCXXOp->getArg(1);
5660 break;
5661 case OO_MinusEqual:
5662 Step = AssertSuccess(
5663 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5664 break;
5665 default:
5666 llvm_unreachable("unhandled overloaded increment operator")::llvm::llvm_unreachable_internal("unhandled overloaded increment operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5666)
;
5667 }
5668 } else
5669 llvm_unreachable("unknown increment expression")::llvm::llvm_unreachable_internal("unknown increment expression"
, "clang/lib/Sema/SemaOpenMP.cpp", 5669)
;
5670
5671 CapturedStmt *DistanceFunc =
5672 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5673 CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5674 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5675 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5676 {}, nullptr, nullptr, {}, nullptr);
5677 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5678 LoopVarFunc, LVRef);
5679}
5680
5681StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5682 // Handle a literal loop.
5683 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5684 return ActOnOpenMPCanonicalLoop(AStmt);
5685
5686 // If not a literal loop, it must be the result of a loop transformation.
5687 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5688 assert((static_cast <bool> (isOpenMPLoopTransformationDirective
(LoopTransform->getDirectiveKind()) && "Loop transformation directive expected"
) ? void (0) : __assert_fail ("isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && \"Loop transformation directive expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5690, __extension__ __PRETTY_FUNCTION__
))
5689 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&(static_cast <bool> (isOpenMPLoopTransformationDirective
(LoopTransform->getDirectiveKind()) && "Loop transformation directive expected"
) ? void (0) : __assert_fail ("isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && \"Loop transformation directive expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5690, __extension__ __PRETTY_FUNCTION__
))
5690 "Loop transformation directive expected")(static_cast <bool> (isOpenMPLoopTransformationDirective
(LoopTransform->getDirectiveKind()) && "Loop transformation directive expected"
) ? void (0) : __assert_fail ("isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && \"Loop transformation directive expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5690, __extension__ __PRETTY_FUNCTION__
))
;
5691 return LoopTransform;
5692}
5693
5694static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5695 CXXScopeSpec &MapperIdScopeSpec,
5696 const DeclarationNameInfo &MapperId,
5697 QualType Type,
5698 Expr *UnresolvedMapper);
5699
5700/// Perform DFS through the structure/class data members trying to find
5701/// member(s) with user-defined 'default' mapper and generate implicit map
5702/// clauses for such members with the found 'default' mapper.
5703static void
5704processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5705 SmallVectorImpl<OMPClause *> &Clauses) {
5706 // Check for the deault mapper for data members.
5707 if (S.getLangOpts().OpenMP < 50)
5708 return;
5709 SmallVector<OMPClause *, 4> ImplicitMaps;
5710 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5711 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5712 if (!C)
5713 continue;
5714 SmallVector<Expr *, 4> SubExprs;
5715 auto *MI = C->mapperlist_begin();
5716 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5717 ++I, ++MI) {
5718 // Expression is mapped using mapper - skip it.
5719 if (*MI)
5720 continue;
5721 Expr *E = *I;
5722 // Expression is dependent - skip it, build the mapper when it gets
5723 // instantiated.
5724 if (E->isTypeDependent() || E->isValueDependent() ||
5725 E->containsUnexpandedParameterPack())
5726 continue;
5727 // Array section - need to check for the mapping of the array section
5728 // element.
5729 QualType CanonType = E->getType().getCanonicalType();
5730 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5731 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5732 QualType BaseType =
5733 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5734 QualType ElemType;
5735 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5736 ElemType = ATy->getElementType();
5737 else
5738 ElemType = BaseType->getPointeeType();
5739 CanonType = ElemType;
5740 }
5741
5742 // DFS over data members in structures/classes.
5743 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5744 1, {CanonType, nullptr});
5745 llvm::DenseMap<const Type *, Expr *> Visited;
5746 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5747 1, {nullptr, 1});
5748 while (!Types.empty()) {
5749 QualType BaseType;
5750 FieldDecl *CurFD;
5751 std::tie(BaseType, CurFD) = Types.pop_back_val();
5752 while (ParentChain.back().second == 0)
5753 ParentChain.pop_back();
5754 --ParentChain.back().second;
5755 if (BaseType.isNull())
5756 continue;
5757 // Only structs/classes are allowed to have mappers.
5758 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5759 if (!RD)
5760 continue;
5761 auto It = Visited.find(BaseType.getTypePtr());
5762 if (It == Visited.end()) {
5763 // Try to find the associated user-defined mapper.
5764 CXXScopeSpec MapperIdScopeSpec;
5765 DeclarationNameInfo DefaultMapperId;
5766 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5767 &S.Context.Idents.get("default")));
5768 DefaultMapperId.setLoc(E->getExprLoc());
5769 ExprResult ER = buildUserDefinedMapperRef(
5770 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5771 BaseType, /*UnresolvedMapper=*/nullptr);
5772 if (ER.isInvalid())
5773 continue;
5774 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5775 }
5776 // Found default mapper.
5777 if (It->second) {
5778 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5779 VK_LValue, OK_Ordinary, E);
5780 OE->setIsUnique(/*V=*/true);
5781 Expr *BaseExpr = OE;
5782 for (const auto &P : ParentChain) {
5783 if (P.first) {
5784 BaseExpr = S.BuildMemberExpr(
5785 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5786 NestedNameSpecifierLoc(), SourceLocation(), P.first,
5787 DeclAccessPair::make(P.first, P.first->getAccess()),
5788 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5789 P.first->getType(), VK_LValue, OK_Ordinary);
5790 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5791 }
5792 }
5793 if (CurFD)
5794 BaseExpr = S.BuildMemberExpr(
5795 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5796 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5797 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5798 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5799 CurFD->getType(), VK_LValue, OK_Ordinary);
5800 SubExprs.push_back(BaseExpr);
5801 continue;
5802 }
5803 // Check for the "default" mapper for data members.
5804 bool FirstIter = true;
5805 for (FieldDecl *FD : RD->fields()) {
5806 if (!FD)
5807 continue;
5808 QualType FieldTy = FD->getType();
5809 if (FieldTy.isNull() ||
5810 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5811 continue;
5812 if (FirstIter) {
5813 FirstIter = false;
5814 ParentChain.emplace_back(CurFD, 1);
5815 } else {
5816 ++ParentChain.back().second;
5817 }
5818 Types.emplace_back(FieldTy, FD);
5819 }
5820 }
5821 }
5822 if (SubExprs.empty())
5823 continue;
5824 CXXScopeSpec MapperIdScopeSpec;
5825 DeclarationNameInfo MapperId;
5826 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5827 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5828 MapperIdScopeSpec, MapperId, C->getMapType(),
5829 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5830 SubExprs, OMPVarListLocTy()))
5831 Clauses.push_back(NewClause);
5832 }
5833}
5834
5835StmtResult Sema::ActOnOpenMPExecutableDirective(
5836 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5837 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5838 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5839 StmtResult Res = StmtError();
5840 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
5841 if (const OMPBindClause *BC =
5842 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
5843 BindKind = BC->getBindKind();
5844 // First check CancelRegion which is then used in checkNestingOfRegions.
5845 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5846 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5847 BindKind, StartLoc))
5848 return StmtError();
5849
5850 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5851 VarsWithInheritedDSAType VarsWithInheritedDSA;
5852 bool ErrorFound = false;
5853 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5854 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5855 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5856 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5857 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 5857, __extension__ __PRETTY_FUNCTION__
))
;
5858
5859 // Check default data sharing attributes for referenced variables.
5860 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5861 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5862 Stmt *S = AStmt;
5863 while (--ThisCaptureLevel >= 0)
5864 S = cast<CapturedStmt>(S)->getCapturedStmt();
5865 DSAChecker.Visit(S);
5866 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5867 !isOpenMPTaskingDirective(Kind)) {
5868 // Visit subcaptures to generate implicit clauses for captured vars.
5869 auto *CS = cast<CapturedStmt>(AStmt);
5870 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5871 getOpenMPCaptureRegions(CaptureRegions, Kind);
5872 // Ignore outer tasking regions for target directives.
5873 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5874 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5875 DSAChecker.visitSubCaptures(CS);
5876 }
5877 if (DSAChecker.isErrorFound())
5878 return StmtError();
5879 // Generate list of implicitly defined firstprivate variables.
5880 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5881
5882 SmallVector<Expr *, 4> ImplicitFirstprivates(
5883 DSAChecker.getImplicitFirstprivate().begin(),
5884 DSAChecker.getImplicitFirstprivate().end());
5885 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5886 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5887 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5888 ImplicitMapModifiers[DefaultmapKindNum];
5889 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5890 ImplicitMapModifiersLoc[DefaultmapKindNum];
5891 // Get the original location of present modifier from Defaultmap clause.
5892 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5893 for (OMPClause *C : Clauses) {
5894 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5895 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5896 PresentModifierLocs[DMC->getDefaultmapKind()] =
5897 DMC->getDefaultmapModifierLoc();
5898 }
5899 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5900 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5901 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5902 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5903 Kind, static_cast<OpenMPMapClauseKind>(I));
5904 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5905 }
5906 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5907 DSAChecker.getImplicitMapModifier(Kind);
5908 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5909 ImplicitModifier.end());
5910 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5911 ImplicitModifier.size(), PresentModifierLocs[VC]);
5912 }
5913 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5914 for (OMPClause *C : Clauses) {
5915 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5916 for (Expr *E : IRC->taskgroup_descriptors())
5917 if (E)
5918 ImplicitFirstprivates.emplace_back(E);
5919 }
5920 // OpenMP 5.0, 2.10.1 task Construct
5921 // [detach clause]... The event-handle will be considered as if it was
5922 // specified on a firstprivate clause.
5923 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5924 ImplicitFirstprivates.push_back(DC->getEventHandler());
5925 }
5926 if (!ImplicitFirstprivates.empty()) {
5927 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5928 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5929 SourceLocation())) {
5930 ClausesWithImplicit.push_back(Implicit);
5931 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5932 ImplicitFirstprivates.size();
5933 } else {
5934 ErrorFound = true;
5935 }
5936 }
5937 // OpenMP 5.0 [2.19.7]
5938 // If a list item appears in a reduction, lastprivate or linear
5939 // clause on a combined target construct then it is treated as
5940 // if it also appears in a map clause with a map-type of tofrom
5941 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
5942 isOpenMPTargetExecutionDirective(Kind)) {
5943 SmallVector<Expr *, 4> ImplicitExprs;
5944 for (OMPClause *C : Clauses) {
5945 if (auto *RC = dyn_cast<OMPReductionClause>(C))
5946 for (Expr *E : RC->varlists())
5947 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
5948 ImplicitExprs.emplace_back(E);
5949 }
5950 if (!ImplicitExprs.empty()) {
5951 ArrayRef<Expr *> Exprs = ImplicitExprs;
5952 CXXScopeSpec MapperIdScopeSpec;
5953 DeclarationNameInfo MapperId;
5954 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5955 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
5956 MapperId, OMPC_MAP_tofrom,
5957 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5958 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
5959 ClausesWithImplicit.emplace_back(Implicit);
5960 }
5961 }
5962 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5963 int ClauseKindCnt = -1;
5964 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5965 ++ClauseKindCnt;
5966 if (ImplicitMap.empty())
5967 continue;
5968 CXXScopeSpec MapperIdScopeSpec;
5969 DeclarationNameInfo MapperId;
5970 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5971 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5972 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5973 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5974 SourceLocation(), SourceLocation(), ImplicitMap,
5975 OMPVarListLocTy())) {
5976 ClausesWithImplicit.emplace_back(Implicit);
5977 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5978 ImplicitMap.size();
5979 } else {
5980 ErrorFound = true;
5981 }
5982 }
5983 }
5984 // Build expressions for implicit maps of data members with 'default'
5985 // mappers.
5986 if (LangOpts.OpenMP >= 50)
5987 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5988 ClausesWithImplicit);
5989 }
5990
5991 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5992 switch (Kind) {
5993 case OMPD_parallel:
5994 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5995 EndLoc);
5996 AllowedNameModifiers.push_back(OMPD_parallel);
5997 break;
5998 case OMPD_simd:
5999 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6000 VarsWithInheritedDSA);
6001 if (LangOpts.OpenMP >= 50)
6002 AllowedNameModifiers.push_back(OMPD_simd);
6003 break;
6004 case OMPD_tile:
6005 Res =
6006 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6007 break;
6008 case OMPD_unroll:
6009 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6010 EndLoc);
6011 break;
6012 case OMPD_for:
6013 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6014 VarsWithInheritedDSA);
6015 break;
6016 case OMPD_for_simd:
6017 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6018 EndLoc, VarsWithInheritedDSA);
6019 if (LangOpts.OpenMP >= 50)
6020 AllowedNameModifiers.push_back(OMPD_simd);
6021 break;
6022 case OMPD_sections:
6023 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6024 EndLoc);
6025 break;
6026 case OMPD_section:
6027 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp section' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6028, __extension__ __PRETTY_FUNCTION__
))
6028 "No clauses are allowed for 'omp section' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp section' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6028, __extension__ __PRETTY_FUNCTION__
))
;
6029 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6030 break;
6031 case OMPD_single:
6032 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6033 EndLoc);
6034 break;
6035 case OMPD_master:
6036 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp master' directive") ? void (
0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6037, __extension__ __PRETTY_FUNCTION__
))
6037 "No clauses are allowed for 'omp master' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp master' directive") ? void (
0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6037, __extension__ __PRETTY_FUNCTION__
))
;
6038 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6039 break;
6040 case OMPD_masked:
6041 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6042 EndLoc);
6043 break;
6044 case OMPD_critical:
6045 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6046 StartLoc, EndLoc);
6047 break;
6048 case OMPD_parallel_for:
6049 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6050 EndLoc, VarsWithInheritedDSA);
6051 AllowedNameModifiers.push_back(OMPD_parallel);
6052 break;
6053 case OMPD_parallel_for_simd:
6054 Res = ActOnOpenMPParallelForSimdDirective(
6055 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6056 AllowedNameModifiers.push_back(OMPD_parallel);
6057 if (LangOpts.OpenMP >= 50)
6058 AllowedNameModifiers.push_back(OMPD_simd);
6059 break;
6060 case OMPD_parallel_master:
6061 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6062 StartLoc, EndLoc);
6063 AllowedNameModifiers.push_back(OMPD_parallel);
6064 break;
6065 case OMPD_parallel_sections:
6066 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6067 StartLoc, EndLoc);
6068 AllowedNameModifiers.push_back(OMPD_parallel);
6069 break;
6070 case OMPD_task:
6071 Res =
6072 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6073 AllowedNameModifiers.push_back(OMPD_task);
6074 break;
6075 case OMPD_taskyield:
6076 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp taskyield' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6077, __extension__ __PRETTY_FUNCTION__
))
6077 "No clauses are allowed for 'omp taskyield' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp taskyield' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6077, __extension__ __PRETTY_FUNCTION__
))
;
6078 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6079, __extension__ __PRETTY_FUNCTION__
))
6079 "No associated statement allowed for 'omp taskyield' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6079, __extension__ __PRETTY_FUNCTION__
))
;
6080 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6081 break;
6082 case OMPD_barrier:
6083 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp barrier' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6084, __extension__ __PRETTY_FUNCTION__
))
6084 "No clauses are allowed for 'omp barrier' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp barrier' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6084, __extension__ __PRETTY_FUNCTION__
))
;
6085 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6086, __extension__ __PRETTY_FUNCTION__
))
6086 "No associated statement allowed for 'omp barrier' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6086, __extension__ __PRETTY_FUNCTION__
))
;
6087 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6088 break;
6089 case OMPD_taskwait:
6090 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6091, __extension__ __PRETTY_FUNCTION__
))
6091 "No associated statement allowed for 'omp taskwait' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6091, __extension__ __PRETTY_FUNCTION__
))
;
6092 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6093 break;
6094 case OMPD_taskgroup:
6095 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6096 EndLoc);
6097 break;
6098 case OMPD_flush:
6099 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6100, __extension__ __PRETTY_FUNCTION__
))
6100 "No associated statement allowed for 'omp flush' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6100, __extension__ __PRETTY_FUNCTION__
))
;
6101 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6102 break;
6103 case OMPD_depobj:
6104 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6105, __extension__ __PRETTY_FUNCTION__
))
6105 "No associated statement allowed for 'omp depobj' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6105, __extension__ __PRETTY_FUNCTION__
))
;
6106 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6107 break;
6108 case OMPD_scan:
6109 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp scan' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6110, __extension__ __PRETTY_FUNCTION__
))
6110 "No associated statement allowed for 'omp scan' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp scan' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6110, __extension__ __PRETTY_FUNCTION__
))
;
6111 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6112 break;
6113 case OMPD_ordered:
6114 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6115 EndLoc);
6116 break;
6117 case OMPD_atomic:
6118 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6119 EndLoc);
6120 break;
6121 case OMPD_teams:
6122 Res =
6123 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6124 break;
6125 case OMPD_target:
6126 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6127 EndLoc);
6128 AllowedNameModifiers.push_back(OMPD_target);
6129 break;
6130 case OMPD_target_parallel:
6131 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6132 StartLoc, EndLoc);
6133 AllowedNameModifiers.push_back(OMPD_target);
6134 AllowedNameModifiers.push_back(OMPD_parallel);
6135 break;
6136 case OMPD_target_parallel_for:
6137 Res = ActOnOpenMPTargetParallelForDirective(
6138 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6139 AllowedNameModifiers.push_back(OMPD_target);
6140 AllowedNameModifiers.push_back(OMPD_parallel);
6141 break;
6142 case OMPD_cancellation_point:
6143 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp cancellation point' directive"
) ? void (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6144, __extension__ __PRETTY_FUNCTION__
))
6144 "No clauses are allowed for 'omp cancellation point' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp cancellation point' directive"
) ? void (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6144, __extension__ __PRETTY_FUNCTION__
))
;
6145 assert(AStmt == nullptr && "No associated statement allowed for 'omp "(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? void (0) : __assert_fail (
"AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6146, __extension__ __PRETTY_FUNCTION__
))
6146 "cancellation point' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? void (0) : __assert_fail (
"AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6146, __extension__ __PRETTY_FUNCTION__
))
;
6147 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6148 break;
6149 case OMPD_cancel:
6150 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6151, __extension__ __PRETTY_FUNCTION__
))
6151 "No associated statement allowed for 'omp cancel' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6151, __extension__ __PRETTY_FUNCTION__
))
;
6152 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6153 CancelRegion);
6154 AllowedNameModifiers.push_back(OMPD_cancel);
6155 break;
6156 case OMPD_target_data:
6157 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6158 EndLoc);
6159 AllowedNameModifiers.push_back(OMPD_target_data);
6160 break;
6161 case OMPD_target_enter_data:
6162 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6163 EndLoc, AStmt);
6164 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6165 break;
6166 case OMPD_target_exit_data:
6167 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6168 EndLoc, AStmt);
6169 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6170 break;
6171 case OMPD_taskloop:
6172 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6173 EndLoc, VarsWithInheritedDSA);
6174 AllowedNameModifiers.push_back(OMPD_taskloop);
6175 break;
6176 case OMPD_taskloop_simd:
6177 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6178 EndLoc, VarsWithInheritedDSA);
6179 AllowedNameModifiers.push_back(OMPD_taskloop);
6180 if (LangOpts.OpenMP >= 50)
6181 AllowedNameModifiers.push_back(OMPD_simd);
6182 break;
6183 case OMPD_master_taskloop:
6184 Res = ActOnOpenMPMasterTaskLoopDirective(
6185 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6186 AllowedNameModifiers.push_back(OMPD_taskloop);
6187 break;
6188 case OMPD_master_taskloop_simd:
6189 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6190 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6191 AllowedNameModifiers.push_back(OMPD_taskloop);
6192 if (LangOpts.OpenMP >= 50)
6193 AllowedNameModifiers.push_back(OMPD_simd);
6194 break;
6195 case OMPD_parallel_master_taskloop:
6196 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6197 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6198 AllowedNameModifiers.push_back(OMPD_taskloop);
6199 AllowedNameModifiers.push_back(OMPD_parallel);
6200 break;
6201 case OMPD_parallel_master_taskloop_simd:
6202 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6203 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6204 AllowedNameModifiers.push_back(OMPD_taskloop);
6205 AllowedNameModifiers.push_back(OMPD_parallel);
6206 if (LangOpts.OpenMP >= 50)
6207 AllowedNameModifiers.push_back(OMPD_simd);
6208 break;
6209 case OMPD_distribute:
6210 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6211 EndLoc, VarsWithInheritedDSA);
6212 break;
6213 case OMPD_target_update:
6214 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6215 EndLoc, AStmt);
6216 AllowedNameModifiers.push_back(OMPD_target_update);
6217 break;
6218 case OMPD_distribute_parallel_for:
6219 Res = ActOnOpenMPDistributeParallelForDirective(
6220 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6221 AllowedNameModifiers.push_back(OMPD_parallel);
6222 break;
6223 case OMPD_distribute_parallel_for_simd:
6224 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6225 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6226 AllowedNameModifiers.push_back(OMPD_parallel);
6227 if (LangOpts.OpenMP >= 50)
6228 AllowedNameModifiers.push_back(OMPD_simd);
6229 break;
6230 case OMPD_distribute_simd:
6231 Res = ActOnOpenMPDistributeSimdDirective(
6232 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6233 if (LangOpts.OpenMP >= 50)
6234 AllowedNameModifiers.push_back(OMPD_simd);
6235 break;
6236 case OMPD_target_parallel_for_simd:
6237 Res = ActOnOpenMPTargetParallelForSimdDirective(
6238 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6239 AllowedNameModifiers.push_back(OMPD_target);
6240 AllowedNameModifiers.push_back(OMPD_parallel);
6241 if (LangOpts.OpenMP >= 50)
6242 AllowedNameModifiers.push_back(OMPD_simd);
6243 break;
6244 case OMPD_target_simd:
6245 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6246 EndLoc, VarsWithInheritedDSA);
6247 AllowedNameModifiers.push_back(OMPD_target);
6248 if (LangOpts.OpenMP >= 50)
6249 AllowedNameModifiers.push_back(OMPD_simd);
6250 break;
6251 case OMPD_teams_distribute:
6252 Res = ActOnOpenMPTeamsDistributeDirective(
6253 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6254 break;
6255 case OMPD_teams_distribute_simd:
6256 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6257 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6258 if (LangOpts.OpenMP >= 50)
6259 AllowedNameModifiers.push_back(OMPD_simd);
6260 break;
6261 case OMPD_teams_distribute_parallel_for_simd:
6262 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6263 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6264 AllowedNameModifiers.push_back(OMPD_parallel);
6265 if (LangOpts.OpenMP >= 50)
6266 AllowedNameModifiers.push_back(OMPD_simd);
6267 break;
6268 case OMPD_teams_distribute_parallel_for:
6269 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6270 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6271 AllowedNameModifiers.push_back(OMPD_parallel);
6272 break;
6273 case OMPD_target_teams:
6274 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6275 EndLoc);
6276 AllowedNameModifiers.push_back(OMPD_target);
6277 break;
6278 case OMPD_target_teams_distribute:
6279 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6280 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6281 AllowedNameModifiers.push_back(OMPD_target);
6282 break;
6283 case OMPD_target_teams_distribute_parallel_for:
6284 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6285 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6286 AllowedNameModifiers.push_back(OMPD_target);
6287 AllowedNameModifiers.push_back(OMPD_parallel);
6288 break;
6289 case OMPD_target_teams_distribute_parallel_for_simd:
6290 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6291 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6292 AllowedNameModifiers.push_back(OMPD_target);
6293 AllowedNameModifiers.push_back(OMPD_parallel);
6294 if (LangOpts.OpenMP >= 50)
6295 AllowedNameModifiers.push_back(OMPD_simd);
6296 break;
6297 case OMPD_target_teams_distribute_simd:
6298 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6299 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6300 AllowedNameModifiers.push_back(OMPD_target);
6301 if (LangOpts.OpenMP >= 50)
6302 AllowedNameModifiers.push_back(OMPD_simd);
6303 break;
6304 case OMPD_interop:
6305 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp interop' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp interop' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6306, __extension__ __PRETTY_FUNCTION__
))
6306 "No associated statement allowed for 'omp interop' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp interop' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp interop' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6306, __extension__ __PRETTY_FUNCTION__
))
;
6307 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6308 break;
6309 case OMPD_dispatch:
6310 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6311 EndLoc);
6312 break;
6313 case OMPD_loop:
6314 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6315 EndLoc, VarsWithInheritedDSA);
6316 break;
6317 case OMPD_teams_loop:
6318 Res = ActOnOpenMPTeamsGenericLoopDirective(
6319 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6320 break;
6321 case OMPD_target_teams_loop:
6322 Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6323 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6324 break;
6325 case OMPD_parallel_loop:
6326 Res = ActOnOpenMPParallelGenericLoopDirective(
6327 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6328 break;
6329 case OMPD_target_parallel_loop:
6330 Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6332 break;
6333 case OMPD_declare_target:
6334 case OMPD_end_declare_target:
6335 case OMPD_threadprivate:
6336 case OMPD_allocate:
6337 case OMPD_declare_reduction:
6338 case OMPD_declare_mapper:
6339 case OMPD_declare_simd:
6340 case OMPD_requires:
6341 case OMPD_declare_variant:
6342 case OMPD_begin_declare_variant:
6343 case OMPD_end_declare_variant:
6344 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "clang/lib/Sema/SemaOpenMP.cpp", 6344)
;
6345 case OMPD_unknown:
6346 default:
6347 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 6347)
;
6348 }
6349
6350 ErrorFound = Res.isInvalid() || ErrorFound;
6351
6352 // Check variables in the clauses if default(none) or
6353 // default(firstprivate) was specified.
6354 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6355 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6356 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
6357 for (OMPClause *C : Clauses) {
6358 switch (C->getClauseKind()) {
6359 case OMPC_num_threads:
6360 case OMPC_dist_schedule:
6361 // Do not analyse if no parent teams directive.
6362 if (isOpenMPTeamsDirective(Kind))
6363 break;
6364 continue;
6365 case OMPC_if:
6366 if (isOpenMPTeamsDirective(Kind) &&
6367 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6368 break;
6369 if (isOpenMPParallelDirective(Kind) &&
6370 isOpenMPTaskLoopDirective(Kind) &&
6371 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6372 break;
6373 continue;
6374 case OMPC_schedule:
6375 case OMPC_detach:
6376 break;
6377 case OMPC_grainsize:
6378 case OMPC_num_tasks:
6379 case OMPC_final:
6380 case OMPC_priority:
6381 case OMPC_novariants:
6382 case OMPC_nocontext:
6383 // Do not analyze if no parent parallel directive.
6384 if (isOpenMPParallelDirective(Kind))
6385 break;
6386 continue;
6387 case OMPC_ordered:
6388 case OMPC_device:
6389 case OMPC_num_teams:
6390 case OMPC_thread_limit:
6391 case OMPC_hint:
6392 case OMPC_collapse:
6393 case OMPC_safelen:
6394 case OMPC_simdlen:
6395 case OMPC_sizes:
6396 case OMPC_default:
6397 case OMPC_proc_bind:
6398 case OMPC_private:
6399 case OMPC_firstprivate:
6400 case OMPC_lastprivate:
6401 case OMPC_shared:
6402 case OMPC_reduction:
6403 case OMPC_task_reduction:
6404 case OMPC_in_reduction:
6405 case OMPC_linear:
6406 case OMPC_aligned:
6407 case OMPC_copyin:
6408 case OMPC_copyprivate:
6409 case OMPC_nowait:
6410 case OMPC_untied:
6411 case OMPC_mergeable:
6412 case OMPC_allocate:
6413 case OMPC_read:
6414 case OMPC_write:
6415 case OMPC_update:
6416 case OMPC_capture:
6417 case OMPC_compare:
6418 case OMPC_seq_cst:
6419 case OMPC_acq_rel:
6420 case OMPC_acquire:
6421 case OMPC_release:
6422 case OMPC_relaxed:
6423 case OMPC_depend:
6424 case OMPC_threads:
6425 case OMPC_simd:
6426 case OMPC_map:
6427 case OMPC_nogroup:
6428 case OMPC_defaultmap:
6429 case OMPC_to:
6430 case OMPC_from:
6431 case OMPC_use_device_ptr:
6432 case OMPC_use_device_addr:
6433 case OMPC_is_device_ptr:
6434 case OMPC_has_device_addr:
6435 case OMPC_nontemporal:
6436 case OMPC_order:
6437 case OMPC_destroy:
6438 case OMPC_inclusive:
6439 case OMPC_exclusive:
6440 case OMPC_uses_allocators:
6441 case OMPC_affinity:
6442 case OMPC_bind:
6443 continue;
6444 case OMPC_allocator:
6445 case OMPC_flush:
6446 case OMPC_depobj:
6447 case OMPC_threadprivate:
6448 case OMPC_uniform:
6449 case OMPC_unknown:
6450 case OMPC_unified_address:
6451 case OMPC_unified_shared_memory:
6452 case OMPC_reverse_offload:
6453 case OMPC_dynamic_allocators:
6454 case OMPC_atomic_default_mem_order:
6455 case OMPC_device_type:
6456 case OMPC_match:
6457 case OMPC_when:
6458 default:
6459 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "clang/lib/Sema/SemaOpenMP.cpp"
, 6459)
;
6460 }
6461 for (Stmt *CC : C->children()) {
6462 if (CC)
6463 DSAChecker.Visit(CC);
6464 }
6465 }
6466 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6467 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6468 }
6469 for (const auto &P : VarsWithInheritedDSA) {
6470 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6471 continue;
6472 ErrorFound = true;
6473 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6474 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6475 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6476 << P.first << P.second->getSourceRange();
6477 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6478 } else if (getLangOpts().OpenMP >= 50) {
6479 Diag(P.second->getExprLoc(),
6480 diag::err_omp_defaultmap_no_attr_for_variable)
6481 << P.first << P.second->getSourceRange();
6482 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
6483 diag::note_omp_defaultmap_attr_none);
6484 }
6485 }
6486
6487 if (!AllowedNameModifiers.empty())
6488 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6489 ErrorFound;
6490
6491 if (ErrorFound)
6492 return StmtError();
6493
6494 if (!CurContext->isDependentContext() &&
6495 isOpenMPTargetExecutionDirective(Kind) &&
6496 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6497 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6498 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6499 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6500 // Register target to DSA Stack.
6501 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
6502 }
6503
6504 return Res;
6505}
6506
6507Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6508 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6509 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6510 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6511 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6512 assert(Aligneds.size() == Alignments.size())(static_cast <bool> (Aligneds.size() == Alignments.size
()) ? void (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "clang/lib/Sema/SemaOpenMP.cpp", 6512, __extension__ __PRETTY_FUNCTION__
))
;
6513 assert(Linears.size() == LinModifiers.size())(static_cast <bool> (Linears.size() == LinModifiers.size
()) ? void (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "clang/lib/Sema/SemaOpenMP.cpp", 6513, __extension__ __PRETTY_FUNCTION__
))
;
6514 assert(Linears.size() == Steps.size())(static_cast <bool> (Linears.size() == Steps.size()) ? void
(0) : __assert_fail ("Linears.size() == Steps.size()", "clang/lib/Sema/SemaOpenMP.cpp"
, 6514, __extension__ __PRETTY_FUNCTION__))
;
6515 if (!DG || DG.get().isNull())
6516 return DeclGroupPtrTy();
6517
6518 const int SimdId = 0;
6519 if (!DG.get().isSingleDecl()) {
6520 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6521 << SimdId;
6522 return DG;
6523 }
6524 Decl *ADecl = DG.get().getSingleDecl();
6525 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6526 ADecl = FTD->getTemplatedDecl();
6527
6528 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6529 if (!FD) {
6530 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6531 return DeclGroupPtrTy();
6532 }
6533
6534 // OpenMP [2.8.2, declare simd construct, Description]
6535 // The parameter of the simdlen clause must be a constant positive integer
6536 // expression.
6537 ExprResult SL;
6538 if (Simdlen)
6539 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6540 // OpenMP [2.8.2, declare simd construct, Description]
6541 // The special this pointer can be used as if was one of the arguments to the
6542 // function in any of the linear, aligned, or uniform clauses.
6543 // The uniform clause declares one or more arguments to have an invariant
6544 // value for all concurrent invocations of the function in the execution of a
6545 // single SIMD loop.
6546 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6547 const Expr *UniformedLinearThis = nullptr;
6548 for (const Expr *E : Uniforms) {
6549 E = E->IgnoreParenImpCasts();
6550 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6551 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6552 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6553 FD->getParamDecl(PVD->getFunctionScopeIndex())
6554 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6555 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6556 continue;
6557 }
6558 if (isa<CXXThisExpr>(E)) {
6559 UniformedLinearThis = E;
6560 continue;
6561 }
6562 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6563 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6564 }
6565 // OpenMP [2.8.2, declare simd construct, Description]
6566 // The aligned clause declares that the object to which each list item points
6567 // is aligned to the number of bytes expressed in the optional parameter of
6568 // the aligned clause.
6569 // The special this pointer can be used as if was one of the arguments to the
6570 // function in any of the linear, aligned, or uniform clauses.
6571 // The type of list items appearing in the aligned clause must be array,
6572 // pointer, reference to array, or reference to pointer.
6573 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6574 const Expr *AlignedThis = nullptr;
6575 for (const Expr *E : Aligneds) {
6576 E = E->IgnoreParenImpCasts();
6577 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6578 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6579 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6580 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6581 FD->getParamDecl(PVD->getFunctionScopeIndex())
6582 ->getCanonicalDecl() == CanonPVD) {
6583 // OpenMP [2.8.1, simd construct, Restrictions]
6584 // A list-item cannot appear in more than one aligned clause.
6585 if (AlignedArgs.count(CanonPVD) > 0) {
6586 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6587 << 1 << getOpenMPClauseName(OMPC_aligned)
6588 << E->getSourceRange();
6589 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6590 diag::note_omp_explicit_dsa)
6591 << getOpenMPClauseName(OMPC_aligned);
6592 continue;
6593 }
6594 AlignedArgs[CanonPVD] = E;
6595 QualType QTy = PVD->getType()
6596 .getNonReferenceType()
6597 .getUnqualifiedType()
6598 .getCanonicalType();
6599 const Type *Ty = QTy.getTypePtrOrNull();
6600 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6601 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6602 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6603 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6604 }
6605 continue;
6606 }
6607 }
6608 if (isa<CXXThisExpr>(E)) {
6609 if (AlignedThis) {
6610 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6611 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6612 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6613 << getOpenMPClauseName(OMPC_aligned);
6614 }
6615 AlignedThis = E;
6616 continue;
6617 }
6618 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6619 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6620 }
6621 // The optional parameter of the aligned clause, alignment, must be a constant
6622 // positive integer expression. If no optional parameter is specified,
6623 // implementation-defined default alignments for SIMD instructions on the
6624 // target platforms are assumed.
6625 SmallVector<const Expr *, 4> NewAligns;
6626 for (Expr *E : Alignments) {
6627 ExprResult Align;
6628 if (E)
6629 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6630 NewAligns.push_back(Align.get());
6631 }
6632 // OpenMP [2.8.2, declare simd construct, Description]
6633 // The linear clause declares one or more list items to be private to a SIMD
6634 // lane and to have a linear relationship with respect to the iteration space
6635 // of a loop.
6636 // The special this pointer can be used as if was one of the arguments to the
6637 // function in any of the linear, aligned, or uniform clauses.
6638 // When a linear-step expression is specified in a linear clause it must be
6639 // either a constant integer expression or an integer-typed parameter that is
6640 // specified in a uniform clause on the directive.
6641 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6642 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6643 auto MI = LinModifiers.begin();
6644 for (const Expr *E : Linears) {
6645 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6646 ++MI;
6647 E = E->IgnoreParenImpCasts();
6648 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6649 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6650 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6651 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6652 FD->getParamDecl(PVD->getFunctionScopeIndex())
6653 ->getCanonicalDecl() == CanonPVD) {
6654 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6655 // A list-item cannot appear in more than one linear clause.
6656 if (LinearArgs.count(CanonPVD) > 0) {
6657 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6658 << getOpenMPClauseName(OMPC_linear)
6659 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6660 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6661 diag::note_omp_explicit_dsa)
6662 << getOpenMPClauseName(OMPC_linear);
6663 continue;
6664 }
6665 // Each argument can appear in at most one uniform or linear clause.
6666 if (UniformedArgs.count(CanonPVD) > 0) {
6667 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6668 << getOpenMPClauseName(OMPC_linear)
6669 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6670 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6671 diag::note_omp_explicit_dsa)
6672 << getOpenMPClauseName(OMPC_uniform);
6673 continue;
6674 }
6675 LinearArgs[CanonPVD] = E;
6676 if (E->isValueDependent() || E->isTypeDependent() ||
6677 E->isInstantiationDependent() ||
6678 E->containsUnexpandedParameterPack())
6679 continue;
6680 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6681 PVD->getOriginalType(),
6682 /*IsDeclareSimd=*/true);
6683 continue;
6684 }
6685 }
6686 if (isa<CXXThisExpr>(E)) {
6687 if (UniformedLinearThis) {
6688 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6689 << getOpenMPClauseName(OMPC_linear)
6690 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6691 << E->getSourceRange();
6692 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6693 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6694 : OMPC_linear);
6695 continue;
6696 }
6697 UniformedLinearThis = E;
6698 if (E->isValueDependent() || E->isTypeDependent() ||
6699 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6700 continue;
6701 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6702 E->getType(), /*IsDeclareSimd=*/true);
6703 continue;
6704 }
6705 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6706 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6707 }
6708 Expr *Step = nullptr;
6709 Expr *NewStep = nullptr;
6710 SmallVector<Expr *, 4> NewSteps;
6711 for (Expr *E : Steps) {
6712 // Skip the same step expression, it was checked already.
6713 if (Step == E || !E) {
6714 NewSteps.push_back(E ? NewStep : nullptr);
6715 continue;
6716 }
6717 Step = E;
6718 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6719 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6720 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6721 if (UniformedArgs.count(CanonPVD) == 0) {
6722 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6723 << Step->getSourceRange();
6724 } else if (E->isValueDependent() || E->isTypeDependent() ||
6725 E->isInstantiationDependent() ||
6726 E->containsUnexpandedParameterPack() ||
6727 CanonPVD->getType()->hasIntegerRepresentation()) {
6728 NewSteps.push_back(Step);
6729 } else {
6730 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6731 << Step->getSourceRange();
6732 }
6733 continue;
6734 }
6735 NewStep = Step;
6736 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6737 !Step->isInstantiationDependent() &&
6738 !Step->containsUnexpandedParameterPack()) {
6739 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6740 .get();
6741 if (NewStep)
6742 NewStep =
6743 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6744 }
6745 NewSteps.push_back(NewStep);
6746 }
6747 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6748 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6749 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6750 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6751 const_cast<Expr **>(Linears.data()), Linears.size(),
6752 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6753 NewSteps.data(), NewSteps.size(), SR);
6754 ADecl->addAttr(NewAttr);
6755 return DG;
6756}
6757
6758static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6759 QualType NewType) {
6760 assert(NewType->isFunctionProtoType() &&(static_cast <bool> (NewType->isFunctionProtoType() &&
"Expected function type with prototype.") ? void (0) : __assert_fail
("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6761, __extension__ __PRETTY_FUNCTION__
))
6761 "Expected function type with prototype.")(static_cast <bool> (NewType->isFunctionProtoType() &&
"Expected function type with prototype.") ? void (0) : __assert_fail
("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6761, __extension__ __PRETTY_FUNCTION__
))
;
6762 assert(FD->getType()->isFunctionNoProtoType() &&(static_cast <bool> (FD->getType()->isFunctionNoProtoType
() && "Expected function with type with no prototype."
) ? void (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6763, __extension__ __PRETTY_FUNCTION__
))
6763 "Expected function with type with no prototype.")(static_cast <bool> (FD->getType()->isFunctionNoProtoType
() && "Expected function with type with no prototype."
) ? void (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6763, __extension__ __PRETTY_FUNCTION__
))
;
6764 assert(FDWithProto->getType()->isFunctionProtoType() &&(static_cast <bool> (FDWithProto->getType()->isFunctionProtoType
() && "Expected function with prototype.") ? void (0)
: __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6765, __extension__ __PRETTY_FUNCTION__
))
6765 "Expected function with prototype.")(static_cast <bool> (FDWithProto->getType()->isFunctionProtoType
() && "Expected function with prototype.") ? void (0)
: __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6765, __extension__ __PRETTY_FUNCTION__
))
;
6766 // Synthesize parameters with the same types.
6767 FD->setType(NewType);
6768 SmallVector<ParmVarDecl *, 16> Params;
6769 for (const ParmVarDecl *P : FDWithProto->parameters()) {
6770 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6771 SourceLocation(), nullptr, P->getType(),
6772 /*TInfo=*/nullptr, SC_None, nullptr);
6773 Param->setScopeInfo(0, Params.size());
6774 Param->setImplicit();
6775 Params.push_back(Param);
6776 }
6777
6778 FD->setParams(Params);
6779}
6780
6781void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6782 if (D->isInvalidDecl())
6783 return;
6784 FunctionDecl *FD = nullptr;
6785 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6786 FD = UTemplDecl->getTemplatedDecl();
6787 else
6788 FD = cast<FunctionDecl>(D);
6789 assert(FD && "Expected a function declaration!")(static_cast <bool> (FD && "Expected a function declaration!"
) ? void (0) : __assert_fail ("FD && \"Expected a function declaration!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6789, __extension__ __PRETTY_FUNCTION__
))
;
6790
6791 // If we are instantiating templates we do *not* apply scoped assumptions but
6792 // only global ones. We apply scoped assumption to the template definition
6793 // though.
6794 if (!inTemplateInstantiation()) {
6795 for (AssumptionAttr *AA : OMPAssumeScoped)
6796 FD->addAttr(AA);
6797 }
6798 for (AssumptionAttr *AA : OMPAssumeGlobal)
6799 FD->addAttr(AA);
6800}
6801
6802Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6803 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6804
6805void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6806 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6807 SmallVectorImpl<FunctionDecl *> &Bases) {
6808 if (!D.getIdentifier())
6809 return;
6810
6811 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6812
6813 // Template specialization is an extension, check if we do it.
6814 bool IsTemplated = !TemplateParamLists.empty();
6815 if (IsTemplated &
6816 !DVScope.TI->isExtensionActive(
6817 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6818 return;
6819
6820 IdentifierInfo *BaseII = D.getIdentifier();
6821 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6822 LookupOrdinaryName);
6823 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6824
6825 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6826 QualType FType = TInfo->getType();
6827
6828 bool IsConstexpr =
6829 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6830 bool IsConsteval =
6831 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6832
6833 for (auto *Candidate : Lookup) {
6834 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6835 FunctionDecl *UDecl = nullptr;
6836 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
6837 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
6838 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
6839 UDecl = FTD->getTemplatedDecl();
6840 } else if (!IsTemplated)
6841 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6842 if (!UDecl)
6843 continue;
6844
6845 // Don't specialize constexpr/consteval functions with
6846 // non-constexpr/consteval functions.
6847 if (UDecl->isConstexpr() && !IsConstexpr)
6848 continue;
6849 if (UDecl->isConsteval() && !IsConsteval)
6850 continue;
6851
6852 QualType UDeclTy = UDecl->getType();
6853 if (!UDeclTy->isDependentType()) {
6854 QualType NewType = Context.mergeFunctionTypes(
6855 FType, UDeclTy, /* OfBlockPointer */ false,
6856 /* Unqualified */ false, /* AllowCXX */ true);
6857 if (NewType.isNull())
6858 continue;
6859 }
6860
6861 // Found a base!
6862 Bases.push_back(UDecl);
6863 }
6864
6865 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6866 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6867 // If no base was found we create a declaration that we use as base.
6868 if (Bases.empty() && UseImplicitBase) {
6869 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6870 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6871 BaseD->setImplicit(true);
6872 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6873 Bases.push_back(BaseTemplD->getTemplatedDecl());
6874 else
6875 Bases.push_back(cast<FunctionDecl>(BaseD));
6876 }
6877
6878 std::string MangledName;
6879 MangledName += D.getIdentifier()->getName();
6880 MangledName += getOpenMPVariantManglingSeparatorStr();
6881 MangledName += DVScope.NameSuffix;
6882 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6883
6884 VariantII.setMangledOpenMPVariantName(true);
6885 D.SetIdentifier(&VariantII, D.getBeginLoc());
6886}
6887
6888void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6889 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6890 // Do not mark function as is used to prevent its emission if this is the
6891 // only place where it is used.
6892 EnterExpressionEvaluationContext Unevaluated(
6893 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6894
6895 FunctionDecl *FD = nullptr;
6896 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6897 FD = UTemplDecl->getTemplatedDecl();
6898 else
6899 FD = cast<FunctionDecl>(D);
6900 auto *VariantFuncRef = DeclRefExpr::Create(
6901 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6902 /* RefersToEnclosingVariableOrCapture */ false,
6903 /* NameLoc */ FD->getLocation(), FD->getType(),
6904 ExprValueKind::VK_PRValue);
6905
6906 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6907 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6908 Context, VariantFuncRef, DVScope.TI,
6909 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
6910 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
6911 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
6912 for (FunctionDecl *BaseFD : Bases)
6913 BaseFD->addAttr(OMPDeclareVariantA);
6914}
6915
6916ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6917 SourceLocation LParenLoc,
6918 MultiExprArg ArgExprs,
6919 SourceLocation RParenLoc, Expr *ExecConfig) {
6920 // The common case is a regular call we do not want to specialize at all. Try
6921 // to make that case fast by bailing early.
6922 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6923 if (!CE)
6924 return Call;
6925
6926 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6927 if (!CalleeFnDecl)
6928 return Call;
6929
6930 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6931 return Call;
6932
6933 ASTContext &Context = getASTContext();
6934 std::function<void(StringRef)> DiagUnknownTrait = [this,
6935 CE](StringRef ISATrait) {
6936 // TODO Track the selector locations in a way that is accessible here to
6937 // improve the diagnostic location.
6938 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6939 << ISATrait;
6940 };
6941 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6942 getCurFunctionDecl(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructTraits());
6943
6944 QualType CalleeFnType = CalleeFnDecl->getType();
6945
6946 SmallVector<Expr *, 4> Exprs;
6947 SmallVector<VariantMatchInfo, 4> VMIs;
6948 while (CalleeFnDecl) {
6949 for (OMPDeclareVariantAttr *A :
6950 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6951 Expr *VariantRef = A->getVariantFuncRef();
6952
6953 VariantMatchInfo VMI;
6954 OMPTraitInfo &TI = A->getTraitInfo();
6955 TI.getAsVariantMatchInfo(Context, VMI);
6956 if (!isVariantApplicableInContext(VMI, OMPCtx,
6957 /* DeviceSetOnly */ false))
6958 continue;
6959
6960 VMIs.push_back(VMI);
6961 Exprs.push_back(VariantRef);
6962 }
6963
6964 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6965 }
6966
6967 ExprResult NewCall;
6968 do {
6969 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6970 if (BestIdx < 0)
6971 return Call;
6972 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6973 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6974
6975 {
6976 // Try to build a (member) call expression for the current best applicable
6977 // variant expression. We allow this to fail in which case we continue
6978 // with the next best variant expression. The fail case is part of the
6979 // implementation defined behavior in the OpenMP standard when it talks
6980 // about what differences in the function prototypes: "Any differences
6981 // that the specific OpenMP context requires in the prototype of the
6982 // variant from the base function prototype are implementation defined."
6983 // This wording is there to allow the specialized variant to have a
6984 // different type than the base function. This is intended and OK but if
6985 // we cannot create a call the difference is not in the "implementation
6986 // defined range" we allow.
6987 Sema::TentativeAnalysisScope Trap(*this);
6988
6989 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6990 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6991 BestExpr = MemberExpr::CreateImplicit(
6992 Context, MemberCall->getImplicitObjectArgument(),
6993 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6994 MemberCall->getValueKind(), MemberCall->getObjectKind());
6995 }
6996 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6997 ExecConfig);
6998 if (NewCall.isUsable()) {
6999 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7000 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7001 QualType NewType = Context.mergeFunctionTypes(
7002 CalleeFnType, NewCalleeFnDecl->getType(),
7003 /* OfBlockPointer */ false,
7004 /* Unqualified */ false, /* AllowCXX */ true);
7005 if (!NewType.isNull())
7006 break;
7007 // Don't use the call if the function type was not compatible.
7008 NewCall = nullptr;
7009 }
7010 }
7011 }
7012
7013 VMIs.erase(VMIs.begin() + BestIdx);
7014 Exprs.erase(Exprs.begin() + BestIdx);
7015 } while (!VMIs.empty());
7016
7017 if (!NewCall.isUsable())
7018 return Call;
7019 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7020}
7021
7022Optional<std::pair<FunctionDecl *, Expr *>>
7023Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7024 Expr *VariantRef, OMPTraitInfo &TI,
7025 unsigned NumAppendArgs,
7026 SourceRange SR) {
7027 if (!DG || DG.get().isNull())
7028 return None;
7029
7030 const int VariantId = 1;
7031 // Must be applied only to single decl.
7032 if (!DG.get().isSingleDecl()) {
7033 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7034 << VariantId << SR;
7035 return None;
7036 }
7037 Decl *ADecl = DG.get().getSingleDecl();
7038 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7039 ADecl = FTD->getTemplatedDecl();
7040
7041 // Decl must be a function.
7042 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7043 if (!FD) {
7044 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7045 << VariantId << SR;
7046 return None;
7047 }
7048
7049 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7050 // The 'target' attribute needs to be separately checked because it does
7051 // not always signify a multiversion function declaration.
7052 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7053 };
7054 // OpenMP is not compatible with multiversion function attributes.
7055 if (HasMultiVersionAttributes(FD)) {
7056 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7057 << SR;
7058 return None;
7059 }
7060
7061 // Allow #pragma omp declare variant only if the function is not used.
7062 if (FD->isUsed(false))
7063 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7064 << FD->getLocation();
7065
7066 // Check if the function was emitted already.
7067 const FunctionDecl *Definition;
7068 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7069 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7070 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7071 << FD->getLocation();
7072
7073 // The VariantRef must point to function.
7074 if (!VariantRef) {
7075 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7076 return None;
7077 }
7078
7079 auto ShouldDelayChecks = [](Expr *&E, bool) {
7080 return E && (E->isTypeDependent() || E->isValueDependent() ||
7081 E->containsUnexpandedParameterPack() ||
7082 E->isInstantiationDependent());
7083 };
7084 // Do not check templates, wait until instantiation.
7085 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7086 TI.anyScoreOrCondition(ShouldDelayChecks))
7087 return std::make_pair(FD, VariantRef);
7088
7089 // Deal with non-constant score and user condition expressions.
7090 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7091 bool IsScore) -> bool {
7092 if (!E || E->isIntegerConstantExpr(Context))
7093 return false;
7094
7095 if (IsScore) {
7096 // We warn on non-constant scores and pretend they were not present.
7097 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7098 << E;
7099 E = nullptr;
7100 } else {
7101 // We could replace a non-constant user condition with "false" but we
7102 // will soon need to handle these anyway for the dynamic version of
7103 // OpenMP context selectors.
7104 Diag(E->getExprLoc(),
7105 diag::err_omp_declare_variant_user_condition_not_constant)
7106 << E;
7107 }
7108 return true;
7109 };
7110 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7111 return None;
7112
7113 QualType AdjustedFnType = FD->getType();
7114 if (NumAppendArgs) {
7115 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7116 if (!PTy) {
7117 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7118 << SR;
7119 return None;
7120 }
7121 // Adjust the function type to account for an extra omp_interop_t for each
7122 // specified in the append_args clause.
7123 const TypeDecl *TD = nullptr;
7124 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7125 SR.getBegin(), Sema::LookupOrdinaryName);
7126 if (LookupName(Result, getCurScope())) {
7127 NamedDecl *ND = Result.getFoundDecl();
7128 TD = dyn_cast_or_null<TypeDecl>(ND);
7129 }
7130 if (!TD) {
7131 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7132 return None;
7133 }
7134 QualType InteropType = Context.getTypeDeclType(TD);
7135 if (PTy->isVariadic()) {
7136 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7137 return None;
7138 }
7139 llvm::SmallVector<QualType, 8> Params;
7140 Params.append(PTy->param_type_begin(), PTy->param_type_end());
7141 Params.insert(Params.end(), NumAppendArgs, InteropType);
7142 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7143 PTy->getExtProtoInfo());
7144 }
7145
7146 // Convert VariantRef expression to the type of the original function to
7147 // resolve possible conflicts.
7148 ExprResult VariantRefCast = VariantRef;
7149 if (LangOpts.CPlusPlus) {
7150 QualType FnPtrType;
7151 auto *Method = dyn_cast<CXXMethodDecl>(FD);
7152 if (Method && !Method->isStatic()) {
7153 const Type *ClassType =
7154 Context.getTypeDeclType(Method->getParent()).getTypePtr();
7155 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7156 ExprResult ER;
7157 {
7158 // Build adrr_of unary op to correctly handle type checks for member
7159 // functions.
7160 Sema::TentativeAnalysisScope Trap(*this);
7161 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7162 VariantRef);
7163 }
7164 if (!ER.isUsable()) {
7165 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7166 << VariantId << VariantRef->getSourceRange();
7167 return None;
7168 }
7169 VariantRef = ER.get();
7170 } else {
7171 FnPtrType = Context.getPointerType(AdjustedFnType);
7172 }
7173 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7174 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7175 ImplicitConversionSequence ICS = TryImplicitConversion(
7176 VariantRef, FnPtrType.getUnqualifiedType(),
7177 /*SuppressUserConversions=*/false, AllowedExplicit::None,
7178 /*InOverloadResolution=*/false,
7179 /*CStyle=*/false,
7180 /*AllowObjCWritebackConversion=*/false);
7181 if (ICS.isFailure()) {
7182 Diag(VariantRef->getExprLoc(),
7183 diag::err_omp_declare_variant_incompat_types)
7184 << VariantRef->getType()
7185 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7186 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7187 return None;
7188 }
7189 VariantRefCast = PerformImplicitConversion(
7190 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7191 if (!VariantRefCast.isUsable())
7192 return None;
7193 }
7194 // Drop previously built artificial addr_of unary op for member functions.
7195 if (Method && !Method->isStatic()) {
7196 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7197 if (auto *UO = dyn_cast<UnaryOperator>(
7198 PossibleAddrOfVariantRef->IgnoreImplicit()))
7199 VariantRefCast = UO->getSubExpr();
7200 }
7201 }
7202
7203 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7204 if (!ER.isUsable() ||
7205 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7206 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7207 << VariantId << VariantRef->getSourceRange();
7208 return None;
7209 }
7210
7211 // The VariantRef must point to function.
7212 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7213 if (!DRE) {
7214 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7215 << VariantId << VariantRef->getSourceRange();
7216 return None;
7217 }
7218 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7219 if (!NewFD) {
7220 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7221 << VariantId << VariantRef->getSourceRange();
7222 return None;
7223 }
7224
7225 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7226 Diag(VariantRef->getExprLoc(),
7227 diag::err_omp_declare_variant_same_base_function)
7228 << VariantRef->getSourceRange();
7229 return None;
7230 }
7231
7232 // Check if function types are compatible in C.
7233 if (!LangOpts.CPlusPlus) {
7234 QualType NewType =
7235 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7236 if (NewType.isNull()) {
7237 Diag(VariantRef->getExprLoc(),
7238 diag::err_omp_declare_variant_incompat_types)
7239 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7240 << VariantRef->getSourceRange();
7241 return None;
7242 }
7243 if (NewType->isFunctionProtoType()) {
7244 if (FD->getType()->isFunctionNoProtoType())
7245 setPrototype(*this, FD, NewFD, NewType);
7246 else if (NewFD->getType()->isFunctionNoProtoType())
7247 setPrototype(*this, NewFD, FD, NewType);
7248 }
7249 }
7250
7251 // Check if variant function is not marked with declare variant directive.
7252 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7253 Diag(VariantRef->getExprLoc(),
7254 diag::warn_omp_declare_variant_marked_as_declare_variant)
7255 << VariantRef->getSourceRange();
7256 SourceRange SR =
7257 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7258 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7259 return None;
7260 }
7261
7262 enum DoesntSupport {
7263 VirtFuncs = 1,
7264 Constructors = 3,
7265 Destructors = 4,
7266 DeletedFuncs = 5,
7267 DefaultedFuncs = 6,
7268 ConstexprFuncs = 7,
7269 ConstevalFuncs = 8,
7270 };
7271 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7272 if (CXXFD->isVirtual()) {
7273 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7274 << VirtFuncs;
7275 return None;
7276 }
7277
7278 if (isa<CXXConstructorDecl>(FD)) {
7279 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7280 << Constructors;
7281 return None;
7282 }
7283
7284 if (isa<CXXDestructorDecl>(FD)) {
7285 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7286 << Destructors;
7287 return None;
7288 }
7289 }
7290
7291 if (FD->isDeleted()) {
7292 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7293 << DeletedFuncs;
7294 return None;
7295 }
7296
7297 if (FD->isDefaulted()) {
7298 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7299 << DefaultedFuncs;
7300 return None;
7301 }
7302
7303 if (FD->isConstexpr()) {
7304 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7305 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7306 return None;
7307 }
7308
7309 // Check general compatibility.
7310 if (areMultiversionVariantFunctionsCompatible(
7311 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7312 PartialDiagnosticAt(SourceLocation(),
7313 PartialDiagnostic::NullDiagnostic()),
7314 PartialDiagnosticAt(
7315 VariantRef->getExprLoc(),
7316 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7317 PartialDiagnosticAt(VariantRef->getExprLoc(),
7318 PDiag(diag::err_omp_declare_variant_diff)
7319 << FD->getLocation()),
7320 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7321 /*CLinkageMayDiffer=*/true))
7322 return None;
7323 return std::make_pair(FD, cast<Expr>(DRE));
7324}
7325
7326void Sema::ActOnOpenMPDeclareVariantDirective(
7327 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7328 ArrayRef<Expr *> AdjustArgsNothing,
7329 ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7330 ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs,
7331 SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc,
7332 SourceRange SR) {
7333
7334 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7335 // An adjust_args clause or append_args clause can only be specified if the
7336 // dispatch selector of the construct selector set appears in the match
7337 // clause.
7338
7339 SmallVector<Expr *, 8> AllAdjustArgs;
7340 llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7341 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7342
7343 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7344 VariantMatchInfo VMI;
7345 TI.getAsVariantMatchInfo(Context, VMI);
7346 if (!llvm::is_contained(
7347 VMI.ConstructTraits,
7348 llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7349 if (!AllAdjustArgs.empty())
7350 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7351 << getOpenMPClauseName(OMPC_adjust_args);
7352 if (!AppendArgs.empty())
7353 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7354 << getOpenMPClauseName(OMPC_append_args);
7355 return;
7356 }
7357 }
7358
7359 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7360 // Each argument can only appear in a single adjust_args clause for each
7361 // declare variant directive.
7362 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7363
7364 for (Expr *E : AllAdjustArgs) {
7365 E = E->IgnoreParenImpCasts();
7366 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7367 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7368 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7369 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7370 FD->getParamDecl(PVD->getFunctionScopeIndex())
7371 ->getCanonicalDecl() == CanonPVD) {
7372 // It's a parameter of the function, check duplicates.
7373 if (!AdjustVars.insert(CanonPVD).second) {
7374 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7375 << PVD;
7376 return;
7377 }
7378 continue;
7379 }
7380 }
7381 }
7382 // Anything that is not a function parameter is an error.
7383 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7384 return;
7385 }
7386
7387 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7388 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7389 AdjustArgsNothing.size(),
7390 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7391 AdjustArgsNeedDevicePtr.size(),
7392 const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()),
7393 AppendArgs.size(), SR);
7394 FD->addAttr(NewAttr);
7395}
7396
7397StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7398 Stmt *AStmt,
7399 SourceLocation StartLoc,
7400 SourceLocation EndLoc) {
7401 if (!AStmt)
7402 return StmtError();
7403
7404 auto *CS = cast<CapturedStmt>(AStmt);
7405 // 1.2.2 OpenMP Language Terminology
7406 // Structured block - An executable statement with a single entry at the
7407 // top and a single exit at the bottom.
7408 // The point of exit cannot be a branch out of the structured block.
7409 // longjmp() and throw() must not violate the entry/exit criteria.
7410 CS->getCapturedDecl()->setNothrow();
7411
7412 setFunctionHasBranchProtectedScope();
7413
7414 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7415 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
7416 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7417}
7418
7419namespace {
7420/// Iteration space of a single for loop.
7421struct LoopIterationSpace final {
7422 /// True if the condition operator is the strict compare operator (<, > or
7423 /// !=).
7424 bool IsStrictCompare = false;
7425 /// Condition of the loop.
7426 Expr *PreCond = nullptr;
7427 /// This expression calculates the number of iterations in the loop.
7428 /// It is always possible to calculate it before starting the loop.
7429 Expr *NumIterations = nullptr;
7430 /// The loop counter variable.
7431 Expr *CounterVar = nullptr;
7432 /// Private loop counter variable.
7433 Expr *PrivateCounterVar = nullptr;
7434 /// This is initializer for the initial value of #CounterVar.
7435 Expr *CounterInit = nullptr;
7436 /// This is step for the #CounterVar used to generate its update:
7437 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7438 Expr *CounterStep = nullptr;
7439 /// Should step be subtracted?
7440 bool Subtract = false;
7441 /// Source range of the loop init.
7442 SourceRange InitSrcRange;
7443 /// Source range of the loop condition.
7444 SourceRange CondSrcRange;
7445 /// Source range of the loop increment.
7446 SourceRange IncSrcRange;
7447 /// Minimum value that can have the loop control variable. Used to support
7448 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7449 /// since only such variables can be used in non-loop invariant expressions.
7450 Expr *MinValue = nullptr;
7451 /// Maximum value that can have the loop control variable. Used to support
7452 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7453 /// since only such variables can be used in non-loop invariant expressions.
7454 Expr *MaxValue = nullptr;
7455 /// true, if the lower bound depends on the outer loop control var.
7456 bool IsNonRectangularLB = false;
7457 /// true, if the upper bound depends on the outer loop control var.
7458 bool IsNonRectangularUB = false;
7459 /// Index of the loop this loop depends on and forms non-rectangular loop
7460 /// nest.
7461 unsigned LoopDependentIdx = 0;
7462 /// Final condition for the non-rectangular loop nest support. It is used to
7463 /// check that the number of iterations for this particular counter must be
7464 /// finished.
7465 Expr *FinalCondition = nullptr;
7466};
7467
7468/// Helper class for checking canonical form of the OpenMP loops and
7469/// extracting iteration space of each loop in the loop nest, that will be used
7470/// for IR generation.
7471class OpenMPIterationSpaceChecker {
7472 /// Reference to Sema.
7473 Sema &SemaRef;
7474 /// Does the loop associated directive support non-rectangular loops?
7475 bool SupportsNonRectangular;
7476 /// Data-sharing stack.
7477 DSAStackTy &Stack;
7478 /// A location for diagnostics (when there is no some better location).
7479 SourceLocation DefaultLoc;
7480 /// A location for diagnostics (when increment is not compatible).
7481 SourceLocation ConditionLoc;
7482 /// A source location for referring to loop init later.
7483 SourceRange InitSrcRange;
7484 /// A source location for referring to condition later.
7485 SourceRange ConditionSrcRange;
7486 /// A source location for referring to increment later.
7487 SourceRange IncrementSrcRange;
7488 /// Loop variable.
7489 ValueDecl *LCDecl = nullptr;
7490 /// Reference to loop variable.
7491 Expr *LCRef = nullptr;
7492 /// Lower bound (initializer for the var).
7493 Expr *LB = nullptr;
7494 /// Upper bound.
7495 Expr *UB = nullptr;
7496 /// Loop step (increment).
7497 Expr *Step = nullptr;
7498 /// This flag is true when condition is one of:
7499 /// Var < UB
7500 /// Var <= UB
7501 /// UB > Var
7502 /// UB >= Var
7503 /// This will have no value when the condition is !=
7504 llvm::Optional<bool> TestIsLessOp;
7505 /// This flag is true when condition is strict ( < or > ).
7506 bool TestIsStrictOp = false;
7507 /// This flag is true when step is subtracted on each iteration.
7508 bool SubtractStep = false;
7509 /// The outer loop counter this loop depends on (if any).
7510 const ValueDecl *DepDecl = nullptr;
7511 /// Contains number of loop (starts from 1) on which loop counter init
7512 /// expression of this loop depends on.
7513 Optional<unsigned> InitDependOnLC;
7514 /// Contains number of loop (starts from 1) on which loop counter condition
7515 /// expression of this loop depends on.
7516 Optional<unsigned> CondDependOnLC;
7517 /// Checks if the provide statement depends on the loop counter.
7518 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7519 /// Original condition required for checking of the exit condition for
7520 /// non-rectangular loop.
7521 Expr *Condition = nullptr;
7522
7523public:
7524 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7525 DSAStackTy &Stack, SourceLocation DefaultLoc)
7526 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7527 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7528 /// Check init-expr for canonical loop form and save loop counter
7529 /// variable - #Var and its initialization value - #LB.
7530 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7531 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7532 /// for less/greater and for strict/non-strict comparison.
7533 bool checkAndSetCond(Expr *S);
7534 /// Check incr-expr for canonical loop form and return true if it
7535 /// does not conform, otherwise save loop step (#Step).
7536 bool checkAndSetInc(Expr *S);
7537 /// Return the loop counter variable.
7538 ValueDecl *getLoopDecl() const { return LCDecl; }
7539 /// Return the reference expression to loop counter variable.
7540 Expr *getLoopDeclRefExpr() const { return LCRef; }
7541 /// Source range of the loop init.
7542 SourceRange getInitSrcRange() const { return InitSrcRange; }
7543 /// Source range of the loop condition.
7544 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7545 /// Source range of the loop increment.
7546 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7547 /// True if the step should be subtracted.
7548 bool shouldSubtractStep() const { return SubtractStep; }
7549 /// True, if the compare operator is strict (<, > or !=).
7550 bool isStrictTestOp() const { return TestIsStrictOp; }
7551 /// Build the expression to calculate the number of iterations.
7552 Expr *buildNumIterations(
7553 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7554 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7555 /// Build the precondition expression for the loops.
7556 Expr *
7557 buildPreCond(Scope *S, Expr *Cond,
7558 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7559 /// Build reference expression to the counter be used for codegen.
7560 DeclRefExpr *
7561 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7562 DSAStackTy &DSA) const;
7563 /// Build reference expression to the private counter be used for
7564 /// codegen.
7565 Expr *buildPrivateCounterVar() const;
7566 /// Build initialization of the counter be used for codegen.
7567 Expr *buildCounterInit() const;
7568 /// Build step of the counter be used for codegen.
7569 Expr *buildCounterStep() const;
7570 /// Build loop data with counter value for depend clauses in ordered
7571 /// directives.
7572 Expr *
7573 buildOrderedLoopData(Scope *S, Expr *Counter,
7574 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7575 SourceLocation Loc, Expr *Inc = nullptr,
7576 OverloadedOperatorKind OOK = OO_Amp);
7577 /// Builds the minimum value for the loop counter.
7578 std::pair<Expr *, Expr *> buildMinMaxValues(
7579 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7580 /// Builds final condition for the non-rectangular loops.
7581 Expr *buildFinalCondition(Scope *S) const;
7582 /// Return true if any expression is dependent.
7583 bool dependent() const;
7584 /// Returns true if the initializer forms non-rectangular loop.
7585 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7586 /// Returns true if the condition forms non-rectangular loop.
7587 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7588 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7589 unsigned getLoopDependentIdx() const {
7590 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7591 }
7592
7593private:
7594 /// Check the right-hand side of an assignment in the increment
7595 /// expression.
7596 bool checkAndSetIncRHS(Expr *RHS);
7597 /// Helper to set loop counter variable and its initializer.
7598 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7599 bool EmitDiags);
7600 /// Helper to set upper bound.
7601 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7602 SourceRange SR, SourceLocation SL);
7603 /// Helper to set loop increment.
7604 bool setStep(Expr *NewStep, bool Subtract);
7605};
7606
7607bool OpenMPIterationSpaceChecker::dependent() const {
7608 if (!LCDecl) {
7609 assert(!LB && !UB && !Step)(static_cast <bool> (!LB && !UB && !Step
) ? void (0) : __assert_fail ("!LB && !UB && !Step"
, "clang/lib/Sema/SemaOpenMP.cpp", 7609, __extension__ __PRETTY_FUNCTION__
))
;
7610 return false;
7611 }
7612 return LCDecl->getType()->isDependentType() ||
7613 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7614 (Step && Step->isValueDependent());
7615}
7616
7617bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7618 Expr *NewLCRefExpr,
7619 Expr *NewLB, bool EmitDiags) {
7620 // State consistency checking to ensure correct usage.
7621 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&(static_cast <bool> (LCDecl == nullptr && LB ==
nullptr && LCRef == nullptr && UB == nullptr
&& Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? void (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "clang/lib/Sema/SemaOpenMP.cpp", 7622, __extension__ __PRETTY_FUNCTION__
))
7622 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)(static_cast <bool> (LCDecl == nullptr && LB ==
nullptr && LCRef == nullptr && UB == nullptr
&& Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? void (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "clang/lib/Sema/SemaOpenMP.cpp", 7622, __extension__ __PRETTY_FUNCTION__
))
;
7623 if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7624 return true;
7625 LCDecl = getCanonicalDecl(NewLCDecl);
7626 LCRef = NewLCRefExpr;
7627 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7628 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7629 if ((Ctor->isCopyOrMoveConstructor() ||
7630 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7631 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7632 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7633 LB = NewLB;
7634 if (EmitDiags)
7635 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7636 return false;
7637}
7638
7639bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7640 llvm::Optional<bool> LessOp,
7641 bool StrictOp, SourceRange SR,
7642 SourceLocation SL) {
7643 // State consistency checking to ensure correct usage.
7644 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&(static_cast <bool> (LCDecl != nullptr && LB !=
nullptr && UB == nullptr && Step == nullptr &&
!TestIsLessOp && !TestIsStrictOp) ? void (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "clang/lib/Sema/SemaOpenMP.cpp", 7645, __extension__ __PRETTY_FUNCTION__
))
7645 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)(static_cast <bool> (LCDecl != nullptr && LB !=
nullptr && UB == nullptr && Step == nullptr &&
!TestIsLessOp && !TestIsStrictOp) ? void (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "clang/lib/Sema/SemaOpenMP.cpp", 7645, __extension__ __PRETTY_FUNCTION__
))
;
7646 if (!NewUB || NewUB->containsErrors())
7647 return true;
7648 UB = NewUB;
7649 if (LessOp)
7650 TestIsLessOp = LessOp;
7651 TestIsStrictOp = StrictOp;
7652 ConditionSrcRange = SR;
7653 ConditionLoc = SL;
7654 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7655 return false;
7656}
7657
7658bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7659 // State consistency checking to ensure correct usage.
7660 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)(static_cast <bool> (LCDecl != nullptr && LB !=
nullptr && Step == nullptr) ? void (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && Step == nullptr"
, "clang/lib/Sema/SemaOpenMP.cpp", 7660, __extension__ __PRETTY_FUNCTION__
))
;
7661 if (!NewStep || NewStep->containsErrors())
7662 return true;
7663 if (!NewStep->isValueDependent()) {
7664 // Check that the step is integer expression.
7665 SourceLocation StepLoc = NewStep->getBeginLoc();
7666 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7667 StepLoc, getExprAsWritten(NewStep));
7668 if (Val.isInvalid())
7669 return true;
7670 NewStep = Val.get();
7671
7672 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7673 // If test-expr is of form var relational-op b and relational-op is < or
7674 // <= then incr-expr must cause var to increase on each iteration of the
7675 // loop. If test-expr is of form var relational-op b and relational-op is
7676 // > or >= then incr-expr must cause var to decrease on each iteration of
7677 // the loop.
7678 // If test-expr is of form b relational-op var and relational-op is < or
7679 // <= then incr-expr must cause var to decrease on each iteration of the
7680 // loop. If test-expr is of form b relational-op var and relational-op is
7681 // > or >= then incr-expr must cause var to increase on each iteration of
7682 // the loop.
7683 Optional<llvm::APSInt> Result =
7684 NewStep->getIntegerConstantExpr(SemaRef.Context);
7685 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7686 bool IsConstNeg =
7687 Result && Result->isSigned() && (Subtract != Result->isNegative());
7688 bool IsConstPos =
7689 Result && Result->isSigned() && (Subtract == Result->isNegative());
7690 bool IsConstZero = Result && !Result->getBoolValue();
7691
7692 // != with increment is treated as <; != with decrement is treated as >
7693 if (!TestIsLessOp.hasValue())
7694 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7695 if (UB &&
7696 (IsConstZero || (TestIsLessOp.getValue()
7697 ? (IsConstNeg || (IsUnsigned && Subtract))
7698 : (IsConstPos || (IsUnsigned && !Subtract))))) {
7699 SemaRef.Diag(NewStep->getExprLoc(),
7700 diag::err_omp_loop_incr_not_compatible)
7701 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7702 SemaRef.Diag(ConditionLoc,
7703 diag::note_omp_loop_cond_requres_compatible_incr)
7704 << TestIsLessOp.getValue() << ConditionSrcRange;
7705 return true;
7706 }
7707 if (TestIsLessOp.getValue() == Subtract) {
7708 NewStep =
7709 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7710 .get();
7711 Subtract = !Subtract;
7712 }
7713 }
7714
7715 Step = NewStep;
7716 SubtractStep = Subtract;
7717 return false;
7718}
7719
7720namespace {
7721/// Checker for the non-rectangular loops. Checks if the initializer or
7722/// condition expression references loop counter variable.
7723class LoopCounterRefChecker final
7724 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7725 Sema &SemaRef;
7726 DSAStackTy &Stack;
7727 const ValueDecl *CurLCDecl = nullptr;
7728 const ValueDecl *DepDecl = nullptr;
7729 const ValueDecl *PrevDepDecl = nullptr;
7730 bool IsInitializer = true;
7731 bool SupportsNonRectangular;
7732 unsigned BaseLoopId = 0;
7733 bool checkDecl(const Expr *E, const ValueDecl *VD) {
7734 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7735 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7736 << (IsInitializer ? 0 : 1);
7737 return false;
7738 }
7739 const auto &&Data = Stack.isLoopControlVariable(VD);
7740 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7741 // The type of the loop iterator on which we depend may not have a random
7742 // access iterator type.
7743 if (Data.first && VD->getType()->isRecordType()) {
7744 SmallString<128> Name;
7745 llvm::raw_svector_ostream OS(Name);
7746 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7747 /*Qualified=*/true);
7748 SemaRef.Diag(E->getExprLoc(),
7749 diag::err_omp_wrong_dependency_iterator_type)
7750 << OS.str();
7751 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7752 return false;
7753 }
7754 if (Data.first && !SupportsNonRectangular) {
7755 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7756 return false;
7757 }
7758 if (Data.first &&
7759 (DepDecl || (PrevDepDecl &&
7760 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7761 if (!DepDecl && PrevDepDecl)
7762 DepDecl = PrevDepDecl;
7763 SmallString<128> Name;
7764 llvm::raw_svector_ostream OS(Name);
7765 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7766 /*Qualified=*/true);
7767 SemaRef.Diag(E->getExprLoc(),
7768 diag::err_omp_invariant_or_linear_dependency)
7769 << OS.str();
7770 return false;
7771 }
7772 if (Data.first) {
7773 DepDecl = VD;
7774 BaseLoopId = Data.first;
7775 }
7776 return Data.first;
7777 }
7778
7779public:
7780 bool VisitDeclRefExpr(const DeclRefExpr *E) {
7781 const ValueDecl *VD = E->getDecl();
7782 if (isa<VarDecl>(VD))
7783 return checkDecl(E, VD);
7784 return false;
7785 }
7786 bool VisitMemberExpr(const MemberExpr *E) {
7787 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7788 const ValueDecl *VD = E->getMemberDecl();
7789 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7790 return checkDecl(E, VD);
7791 }
7792 return false;
7793 }
7794 bool VisitStmt(const Stmt *S) {
7795 bool Res = false;
7796 for (const Stmt *Child : S->children())
7797 Res = (Child && Visit(Child)) || Res;
7798 return Res;
7799 }
7800 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7801 const ValueDecl *CurLCDecl, bool IsInitializer,
7802 const ValueDecl *PrevDepDecl = nullptr,
7803 bool SupportsNonRectangular = true)
7804 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7805 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7806 SupportsNonRectangular(SupportsNonRectangular) {}
7807 unsigned getBaseLoopId() const {
7808 assert(CurLCDecl && "Expected loop dependency.")(static_cast <bool> (CurLCDecl && "Expected loop dependency."
) ? void (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 7808, __extension__ __PRETTY_FUNCTION__
))
;
7809 return BaseLoopId;
7810 }
7811 const ValueDecl *getDepDecl() const {
7812 assert(CurLCDecl && "Expected loop dependency.")(static_cast <bool> (CurLCDecl && "Expected loop dependency."
) ? void (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 7812, __extension__ __PRETTY_FUNCTION__
))
;
7813 return DepDecl;
7814 }
7815};
7816} // namespace
7817
7818Optional<unsigned>
7819OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7820 bool IsInitializer) {
7821 // Check for the non-rectangular loops.
7822 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7823 DepDecl, SupportsNonRectangular);
7824 if (LoopStmtChecker.Visit(S)) {
7825 DepDecl = LoopStmtChecker.getDepDecl();
7826 return LoopStmtChecker.getBaseLoopId();
7827 }
7828 return llvm::None;
7829}
7830
7831bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7832 // Check init-expr for canonical loop form and save loop counter
7833 // variable - #Var and its initialization value - #LB.
7834 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7835 // var = lb
7836 // integer-type var = lb
7837 // random-access-iterator-type var = lb
7838 // pointer-type var = lb
7839 //
7840 if (!S) {
7841 if (EmitDiags) {
7842 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7843 }
7844 return true;
7845 }
7846 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7847 if (!ExprTemp->cleanupsHaveSideEffects())
7848 S = ExprTemp->getSubExpr();
7849
7850 InitSrcRange = S->getSourceRange();
7851 if (Expr *E = dyn_cast<Expr>(S))
7852 S = E->IgnoreParens();
7853 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7854 if (BO->getOpcode() == BO_Assign) {
7855 Expr *LHS = BO->getLHS()->IgnoreParens();
7856 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7857 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7858 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7859 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7860 EmitDiags);
7861 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7862 }
7863 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7864 if (ME->isArrow() &&
7865 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7866 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7867 EmitDiags);
7868 }
7869 }
7870 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7871 if (DS->isSingleDecl()) {
7872 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7873 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7874 // Accept non-canonical init form here but emit ext. warning.
7875 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7876 SemaRef.Diag(S->getBeginLoc(),
7877 diag::ext_omp_loop_not_canonical_init)
7878 << S->getSourceRange();
7879 return setLCDeclAndLB(
7880 Var,
7881 buildDeclRefExpr(SemaRef, Var,
7882 Var->getType().getNonReferenceType(),
7883 DS->getBeginLoc()),
7884 Var->getInit(), EmitDiags);
7885 }
7886 }
7887 }
7888 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7889 if (CE->getOperator() == OO_Equal) {
7890 Expr *LHS = CE->getArg(0);
7891 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7892 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7893 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7894 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7895 EmitDiags);
7896 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7897 }
7898 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7899 if (ME->isArrow() &&
7900 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7901 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7902 EmitDiags);
7903 }
7904 }
7905 }
7906
7907 if (dependent() || SemaRef.CurContext->isDependentContext())
7908 return false;
7909 if (EmitDiags) {
7910 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7911 << S->getSourceRange();
7912 }
7913 return true;
7914}
7915
7916/// Ignore parenthesizes, implicit casts, copy constructor and return the
7917/// variable (which may be the loop variable) if possible.
7918static const ValueDecl *getInitLCDecl(const Expr *E) {
7919 if (!E)
7920 return nullptr;
7921 E = getExprAsWritten(E);
7922 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7923 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7924 if ((Ctor->isCopyOrMoveConstructor() ||
7925 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7926 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7927 E = CE->getArg(0)->IgnoreParenImpCasts();
7928 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7929 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7930 return getCanonicalDecl(VD);
7931 }
7932 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7933 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7934 return getCanonicalDecl(ME->getMemberDecl());
7935 return nullptr;
7936}
7937
7938bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7939 // Check test-expr for canonical form, save upper-bound UB, flags for
7940 // less/greater and for strict/non-strict comparison.
7941 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7942 // var relational-op b
7943 // b relational-op var
7944 //
7945 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7946 if (!S) {
7947 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7948 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7949 return true;
7950 }
7951 Condition = S;
7952 S = getExprAsWritten(S);
7953 SourceLocation CondLoc = S->getBeginLoc();
7954 auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
7955 BinaryOperatorKind Opcode, const Expr *LHS,
7956 const Expr *RHS, SourceRange SR,
7957 SourceLocation OpLoc) -> llvm::Optional<bool> {
7958 if (BinaryOperator::isRelationalOp(Opcode)) {
7959 if (getInitLCDecl(LHS) == LCDecl)
7960 return setUB(const_cast<Expr *>(RHS),
7961 (Opcode == BO_LT || Opcode == BO_LE),
7962 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7963 if (getInitLCDecl(RHS) == LCDecl)
7964 return setUB(const_cast<Expr *>(LHS),
7965 (Opcode == BO_GT || Opcode == BO_GE),
7966 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7967 } else if (IneqCondIsCanonical && Opcode == BO_NE) {
7968 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
7969 /*LessOp=*/llvm::None,
7970 /*StrictOp=*/true, SR, OpLoc);
7971 }
7972 return llvm::None;
7973 };
7974 llvm::Optional<bool> Res;
7975 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
7976 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
7977 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
7978 RBO->getOperatorLoc());
7979 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7980 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
7981 BO->getSourceRange(), BO->getOperatorLoc());
7982 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7983 if (CE->getNumArgs() == 2) {
7984 Res = CheckAndSetCond(
7985 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
7986 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
7987 }
7988 }
7989 if (Res.hasValue())
7990 return *Res;
7991 if (dependent() || SemaRef.CurContext->isDependentContext())
7992 return false;
7993 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7994 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7995 return true;
7996}
7997
7998bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7999 // RHS of canonical loop form increment can be:
8000 // var + incr
8001 // incr + var
8002 // var - incr
8003 //
8004 RHS = RHS->IgnoreParenImpCasts();
8005 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8006 if (BO->isAdditiveOp()) {
8007 bool IsAdd = BO->getOpcode() == BO_Add;
8008 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8009 return setStep(BO->getRHS(), !IsAdd);
8010 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8011 return setStep(BO->getLHS(), /*Subtract=*/false);
8012 }
8013 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8014 bool IsAdd = CE->getOperator() == OO_Plus;
8015 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8016 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8017 return setStep(CE->getArg(1), !IsAdd);
8018 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8019 return setStep(CE->getArg(0), /*Subtract=*/false);
8020 }
8021 }
8022 if (dependent() || SemaRef.CurContext->isDependentContext())
8023 return false;
8024 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8025 << RHS->getSourceRange() << LCDecl;
8026 return true;
8027}
8028
8029bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8030 // Check incr-expr for canonical loop form and return true if it
8031 // does not conform.
8032 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8033 // ++var
8034 // var++
8035 // --var
8036 // var--
8037 // var += incr
8038 // var -= incr
8039 // var = var + incr
8040 // var = incr + var
8041 // var = var - incr
8042 //
8043 if (!S) {
8044 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8045 return true;
8046 }
8047 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8048 if (!ExprTemp->cleanupsHaveSideEffects())
8049 S = ExprTemp->getSubExpr();
8050
8051 IncrementSrcRange = S->getSourceRange();
8052 S = S->IgnoreParens();
8053 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8054 if (UO->isIncrementDecrementOp() &&
8055 getInitLCDecl(UO->getSubExpr()) == LCDecl)
8056 return setStep(SemaRef
8057 .ActOnIntegerConstant(UO->getBeginLoc(),
8058 (UO->isDecrementOp() ? -1 : 1))
8059 .get(),
8060 /*Subtract=*/false);
8061 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8062 switch (BO->getOpcode()) {
8063 case BO_AddAssign:
8064 case BO_SubAssign:
8065 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8066 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8067 break;
8068 case BO_Assign:
8069 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8070 return checkAndSetIncRHS(BO->getRHS());
8071 break;
8072 default:
8073 break;
8074 }
8075 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8076 switch (CE->getOperator()) {
8077 case OO_PlusPlus:
8078 case OO_MinusMinus:
8079 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8080 return setStep(SemaRef
8081 .ActOnIntegerConstant(
8082 CE->getBeginLoc(),
8083 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8084 .get(),
8085 /*Subtract=*/false);
8086 break;
8087 case OO_PlusEqual:
8088 case OO_MinusEqual:
8089 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8090 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8091 break;
8092 case OO_Equal:
8093 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8094 return checkAndSetIncRHS(CE->getArg(1));
8095 break;
8096 default:
8097 break;
8098 }
8099 }
8100 if (dependent() || SemaRef.CurContext->isDependentContext())
8101 return false;
8102 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8103 << S->getSourceRange() << LCDecl;
8104 return true;
8105}
8106
8107static ExprResult
8108tryBuildCapture(Sema &SemaRef, Expr *Capture,
8109 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8110 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8111 return Capture;
8112 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8113 return SemaRef.PerformImplicitConversion(
8114 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8115 /*AllowExplicit=*/true);
8116 auto I = Captures.find(Capture);
8117 if (I != Captures.end())
8118 return buildCapture(SemaRef, Capture, I->second);
8119 DeclRefExpr *Ref = nullptr;
8120 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
8121 Captures[Capture] = Ref;
8122 return Res;
8123}
8124
8125/// Calculate number of iterations, transforming to unsigned, if number of
8126/// iterations may be larger than the original type.
8127static Expr *
8128calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8129 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8130 bool TestIsStrictOp, bool RoundToStep,
8131 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8132 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8133 if (!NewStep.isUsable())
8134 return nullptr;
8135 llvm::APSInt LRes, SRes;
8136 bool IsLowerConst = false, IsStepConst = false;
8137 if (Optional<llvm::APSInt> Res =
8138 Lower->getIntegerConstantExpr(SemaRef.Context)) {
8139 LRes = *Res;
8140 IsLowerConst = true;
8141 }
8142 if (Optional<llvm::APSInt> Res =
8143 Step->getIntegerConstantExpr(SemaRef.Context)) {
8144 SRes = *Res;
8145 IsStepConst = true;
8146 }
8147 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8148 ((!TestIsStrictOp && LRes.isNonNegative()) ||
8149 (TestIsStrictOp && LRes.isStrictlyPositive()));
8150 bool NeedToReorganize = false;
8151 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8152 if (!NoNeedToConvert && IsLowerConst &&
8153 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8154 NoNeedToConvert = true;
8155 if (RoundToStep) {
8156 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8157 ? LRes.getBitWidth()
8158 : SRes.getBitWidth();
8159 LRes = LRes.extend(BW + 1);
8160 LRes.setIsSigned(true);
8161 SRes = SRes.extend(BW + 1);
8162 SRes.setIsSigned(true);
8163 LRes -= SRes;
8164 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8165 LRes = LRes.trunc(BW);
8166 }
8167 if (TestIsStrictOp) {
8168 unsigned BW = LRes.getBitWidth();
8169 LRes = LRes.extend(BW + 1);
8170 LRes.setIsSigned(true);
8171 ++LRes;
8172 NoNeedToConvert =
8173 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8174 // truncate to the original bitwidth.
8175 LRes = LRes.trunc(BW);
8176 }
8177 NeedToReorganize = NoNeedToConvert;
8178 }
8179 llvm::APSInt URes;
8180 bool IsUpperConst = false;
8181 if (Optional<llvm::APSInt> Res =
8182 Upper->getIntegerConstantExpr(SemaRef.Context)) {
8183 URes = *Res;
8184 IsUpperConst = true;
8185 }
8186 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8187 (!RoundToStep || IsStepConst)) {
8188 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8189 : URes.getBitWidth();
8190 LRes = LRes.extend(BW + 1);
8191 LRes.setIsSigned(true);
8192 URes = URes.extend(BW + 1);
8193 URes.setIsSigned(true);
8194 URes -= LRes;
8195 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8196 NeedToReorganize = NoNeedToConvert;
8197 }
8198 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8199 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8200 // unsigned.
8201 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8202 !LCTy->isDependentType() && LCTy->isIntegerType()) {
8203 QualType LowerTy = Lower->getType();
8204 QualType UpperTy = Upper->getType();
8205 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8206 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8207 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8208 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8209 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8210 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8211 Upper =
8212 SemaRef
8213 .PerformImplicitConversion(
8214 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8215 CastType, Sema::AA_Converting)
8216 .get();
8217 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8218 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8219 }
8220 }
8221 if (!Lower || !Upper || NewStep.isInvalid())
8222 return nullptr;
8223
8224 ExprResult Diff;
8225 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8226 // 1]).
8227 if (NeedToReorganize) {
8228 Diff = Lower;
8229
8230 if (RoundToStep) {
8231 // Lower - Step
8232 Diff =
8233 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8234 if (!Diff.isUsable())
8235 return nullptr;
8236 }
8237
8238 // Lower - Step [+ 1]
8239 if (TestIsStrictOp)
8240 Diff = SemaRef.BuildBinOp(
8241 S, DefaultLoc, BO_Add, Diff.get(),
8242 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8243 if (!Diff.isUsable())
8244 return nullptr;
8245
8246 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8247 if (!Diff.isUsable())
8248 return nullptr;
8249
8250 // Upper - (Lower - Step [+ 1]).
8251 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8252 if (!Diff.isUsable())
8253 return nullptr;
8254 } else {
8255 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8256
8257 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8258 // BuildBinOp already emitted error, this one is to point user to upper
8259 // and lower bound, and to tell what is passed to 'operator-'.
8260 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8261 << Upper->getSourceRange() << Lower->getSourceRange();
8262 return nullptr;
8263 }
8264
8265 if (!Diff.isUsable())
8266 return nullptr;
8267
8268 // Upper - Lower [- 1]
8269 if (TestIsStrictOp)
8270 Diff = SemaRef.BuildBinOp(
8271 S, DefaultLoc, BO_Sub, Diff.get(),
8272 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8273 if (!Diff.isUsable())
8274 return nullptr;
8275
8276 if (RoundToStep) {
8277 // Upper - Lower [- 1] + Step
8278 Diff =
8279 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8280 if (!Diff.isUsable())
8281 return nullptr;
8282 }
8283 }
8284
8285 // Parentheses (for dumping/debugging purposes only).
8286 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8287 if (!Diff.isUsable())
8288 return nullptr;
8289
8290 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8291 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8292 if (!Diff.isUsable())
8293 return nullptr;
8294
8295 return Diff.get();
8296}
8297
8298/// Build the expression to calculate the number of iterations.
8299Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8300 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8301 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8302 QualType VarType = LCDecl->getType().getNonReferenceType();
8303 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8304 !SemaRef.getLangOpts().CPlusPlus)
8305 return nullptr;
8306 Expr *LBVal = LB;
8307 Expr *UBVal = UB;
8308 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8309 // max(LB(MinVal), LB(MaxVal))
8310 if (InitDependOnLC) {
8311 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8312 if (!IS.MinValue || !IS.MaxValue)
8313 return nullptr;
8314 // OuterVar = Min
8315 ExprResult MinValue =
8316 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8317 if (!MinValue.isUsable())
8318 return nullptr;
8319
8320 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8321 IS.CounterVar, MinValue.get());
8322 if (!LBMinVal.isUsable())
8323 return nullptr;
8324 // OuterVar = Min, LBVal
8325 LBMinVal =
8326 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8327 if (!LBMinVal.isUsable())
8328 return nullptr;
8329 // (OuterVar = Min, LBVal)
8330 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8331 if (!LBMinVal.isUsable())
8332 return nullptr;
8333
8334 // OuterVar = Max
8335 ExprResult MaxValue =
8336 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8337 if (!MaxValue.isUsable())
8338 return nullptr;
8339
8340 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8341 IS.CounterVar, MaxValue.get());
8342 if (!LBMaxVal.isUsable())
8343 return nullptr;
8344 // OuterVar = Max, LBVal
8345 LBMaxVal =
8346 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8347 if (!LBMaxVal.isUsable())
8348 return nullptr;
8349 // (OuterVar = Max, LBVal)
8350 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8351 if (!LBMaxVal.isUsable())
8352 return nullptr;
8353
8354 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8355 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8356 if (!LBMin || !LBMax)
8357 return nullptr;
8358 // LB(MinVal) < LB(MaxVal)
8359 ExprResult MinLessMaxRes =
8360 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8361 if (!MinLessMaxRes.isUsable())
8362 return nullptr;
8363 Expr *MinLessMax =
8364 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8365 if (!MinLessMax)
8366 return nullptr;
8367 if (TestIsLessOp.getValue()) {
8368 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8369 // LB(MaxVal))
8370 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8371 MinLessMax, LBMin, LBMax);
8372 if (!MinLB.isUsable())
8373 return nullptr;
8374 LBVal = MinLB.get();
8375 } else {
8376 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8377 // LB(MaxVal))
8378 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8379 MinLessMax, LBMax, LBMin);
8380 if (!MaxLB.isUsable())
8381 return nullptr;
8382 LBVal = MaxLB.get();
8383 }
8384 }
8385 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8386 // min(UB(MinVal), UB(MaxVal))
8387 if (CondDependOnLC) {
8388 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8389 if (!IS.MinValue || !IS.MaxValue)
8390 return nullptr;
8391 // OuterVar = Min
8392 ExprResult MinValue =
8393 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8394 if (!MinValue.isUsable())
8395 return nullptr;
8396
8397 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8398 IS.CounterVar, MinValue.get());
8399 if (!UBMinVal.isUsable())
8400 return nullptr;
8401 // OuterVar = Min, UBVal
8402 UBMinVal =
8403 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8404 if (!UBMinVal.isUsable())
8405 return nullptr;
8406 // (OuterVar = Min, UBVal)
8407 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8408 if (!UBMinVal.isUsable())
8409 return nullptr;
8410
8411 // OuterVar = Max
8412 ExprResult MaxValue =
8413 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8414 if (!MaxValue.isUsable())
8415 return nullptr;
8416
8417 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8418 IS.CounterVar, MaxValue.get());
8419 if (!UBMaxVal.isUsable())
8420 return nullptr;
8421 // OuterVar = Max, UBVal
8422 UBMaxVal =
8423 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8424 if (!UBMaxVal.isUsable())
8425 return nullptr;
8426 // (OuterVar = Max, UBVal)
8427 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8428 if (!UBMaxVal.isUsable())
8429 return nullptr;
8430
8431 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8432 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8433 if (!UBMin || !UBMax)
8434 return nullptr;
8435 // UB(MinVal) > UB(MaxVal)
8436 ExprResult MinGreaterMaxRes =
8437 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8438 if (!MinGreaterMaxRes.isUsable())
8439 return nullptr;
8440 Expr *MinGreaterMax =
8441 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8442 if (!MinGreaterMax)
8443 return nullptr;
8444 if (TestIsLessOp.getValue()) {
8445 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8446 // UB(MaxVal))
8447 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8448 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8449 if (!MaxUB.isUsable())
8450 return nullptr;
8451 UBVal = MaxUB.get();
8452 } else {
8453 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8454 // UB(MaxVal))
8455 ExprResult MinUB = SemaRef.ActOnConditionalOp(
8456 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8457 if (!MinUB.isUsable())
8458 return nullptr;
8459 UBVal = MinUB.get();
8460 }
8461 }
8462 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8463 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8464 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8465 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8466 if (!Upper || !Lower)
8467 return nullptr;
8468
8469 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8470 Step, VarType, TestIsStrictOp,
8471 /*RoundToStep=*/true, Captures);
8472 if (!Diff.isUsable())
8473 return nullptr;
8474
8475 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8476 QualType Type = Diff.get()->getType();
8477 ASTContext &C = SemaRef.Context;
8478 bool UseVarType = VarType->hasIntegerRepresentation() &&
8479 C.getTypeSize(Type) > C.getTypeSize(VarType);
8480 if (!Type->isIntegerType() || UseVarType) {
8481 unsigned NewSize =
8482 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8483 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8484 : Type->hasSignedIntegerRepresentation();
8485 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8486 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8487 Diff = SemaRef.PerformImplicitConversion(
8488 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8489 if (!Diff.isUsable())
8490 return nullptr;
8491 }
8492 }
8493 if (LimitedType) {
8494 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8495 if (NewSize != C.getTypeSize(Type)) {
8496 if (NewSize < C.getTypeSize(Type)) {
8497 assert(NewSize == 64 && "incorrect loop var size")(static_cast <bool> (NewSize == 64 && "incorrect loop var size"
) ? void (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8497, __extension__ __PRETTY_FUNCTION__
))
;
8498 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8499 << InitSrcRange << ConditionSrcRange;
8500 }
8501 QualType NewType = C.getIntTypeForBitwidth(
8502 NewSize, Type->hasSignedIntegerRepresentation() ||
8503 C.getTypeSize(Type) < NewSize);
8504 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8505 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8506 Sema::AA_Converting, true);
8507 if (!Diff.isUsable())
8508 return nullptr;
8509 }
8510 }
8511 }
8512
8513 return Diff.get();
8514}
8515
8516std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8517 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8518 // Do not build for iterators, they cannot be used in non-rectangular loop
8519 // nests.
8520 if (LCDecl->getType()->isRecordType())
8521 return std::make_pair(nullptr, nullptr);
8522 // If we subtract, the min is in the condition, otherwise the min is in the
8523 // init value.
8524 Expr *MinExpr = nullptr;
8525 Expr *MaxExpr = nullptr;
8526 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8527 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8528 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8529 : CondDependOnLC.hasValue();
8530 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8531 : InitDependOnLC.hasValue();
8532 Expr *Lower =
8533 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8534 Expr *Upper =
8535 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8536 if (!Upper || !Lower)
8537 return std::make_pair(nullptr, nullptr);
8538
8539 if (TestIsLessOp.getValue())
8540 MinExpr = Lower;
8541 else
8542 MaxExpr = Upper;
8543
8544 // Build minimum/maximum value based on number of iterations.
8545 QualType VarType = LCDecl->getType().getNonReferenceType();
8546
8547 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8548 Step, VarType, TestIsStrictOp,
8549 /*RoundToStep=*/false, Captures);
8550 if (!Diff.isUsable())
8551 return std::make_pair(nullptr, nullptr);
8552
8553 // ((Upper - Lower [- 1]) / Step) * Step
8554 // Parentheses (for dumping/debugging purposes only).
8555 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8556 if (!Diff.isUsable())
8557 return std::make_pair(nullptr, nullptr);
8558
8559 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8560 if (!NewStep.isUsable())
8561 return std::make_pair(nullptr, nullptr);
8562 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8563 if (!Diff.isUsable())
8564 return std::make_pair(nullptr, nullptr);
8565
8566 // Parentheses (for dumping/debugging purposes only).
8567 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8568 if (!Diff.isUsable())
8569 return std::make_pair(nullptr, nullptr);
8570
8571 // Convert to the ptrdiff_t, if original type is pointer.
8572 if (VarType->isAnyPointerType() &&
8573 !SemaRef.Context.hasSameType(
8574 Diff.get()->getType(),
8575 SemaRef.Context.getUnsignedPointerDiffType())) {
8576 Diff = SemaRef.PerformImplicitConversion(
8577 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8578 Sema::AA_Converting, /*AllowExplicit=*/true);
8579 }
8580 if (!Diff.isUsable())
8581 return std::make_pair(nullptr, nullptr);
8582
8583 if (TestIsLessOp.getValue()) {
8584 // MinExpr = Lower;
8585 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8586 Diff = SemaRef.BuildBinOp(
8587 S, DefaultLoc, BO_Add,
8588 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8589 Diff.get());
8590 if (!Diff.isUsable())
8591 return std::make_pair(nullptr, nullptr);
8592 } else {
8593 // MaxExpr = Upper;
8594 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8595 Diff = SemaRef.BuildBinOp(
8596 S, DefaultLoc, BO_Sub,
8597 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8598 Diff.get());
8599 if (!Diff.isUsable())
8600 return std::make_pair(nullptr, nullptr);
8601 }
8602
8603 // Convert to the original type.
8604 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8605 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8606 Sema::AA_Converting,
8607 /*AllowExplicit=*/true);
8608 if (!Diff.isUsable())
8609 return std::make_pair(nullptr, nullptr);
8610
8611 Sema::TentativeAnalysisScope Trap(SemaRef);
8612 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8613 if (!Diff.isUsable())
8614 return std::make_pair(nullptr, nullptr);
8615
8616 if (TestIsLessOp.getValue())
8617 MaxExpr = Diff.get();
8618 else
8619 MinExpr = Diff.get();
8620
8621 return std::make_pair(MinExpr, MaxExpr);
8622}
8623
8624Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8625 if (InitDependOnLC || CondDependOnLC)
8626 return Condition;
8627 return nullptr;
8628}
8629
8630Expr *OpenMPIterationSpaceChecker::buildPreCond(
8631 Scope *S, Expr *Cond,
8632 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8633 // Do not build a precondition when the condition/initialization is dependent
8634 // to prevent pessimistic early loop exit.
8635 // TODO: this can be improved by calculating min/max values but not sure that
8636 // it will be very effective.
8637 if (CondDependOnLC || InitDependOnLC)
8638 return SemaRef
8639 .PerformImplicitConversion(
8640 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8641 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8642 /*AllowExplicit=*/true)
8643 .get();
8644
8645 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8646 Sema::TentativeAnalysisScope Trap(SemaRef);
8647
8648 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8649 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8650 if (!NewLB.isUsable() || !NewUB.isUsable())
8651 return nullptr;
8652
8653 ExprResult CondExpr = SemaRef.BuildBinOp(
8654 S, DefaultLoc,
8655 TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE)
8656 : (TestIsStrictOp ? BO_GT : BO_GE),
8657 NewLB.get(), NewUB.get());
8658 if (CondExpr.isUsable()) {
8659 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8660 SemaRef.Context.BoolTy))
8661 CondExpr = SemaRef.PerformImplicitConversion(
8662 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8663 /*AllowExplicit=*/true);
8664 }
8665
8666 // Otherwise use original loop condition and evaluate it in runtime.
8667 return CondExpr.isUsable() ? CondExpr.get() : Cond;
8668}
8669
8670/// Build reference expression to the counter be used for codegen.
8671DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8672 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8673 DSAStackTy &DSA) const {
8674 auto *VD = dyn_cast<VarDecl>(LCDecl);
8675 if (!VD) {
8676 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8677 DeclRefExpr *Ref = buildDeclRefExpr(
8678 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8679 const DSAStackTy::DSAVarData Data =
8680 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8681 // If the loop control decl is explicitly marked as private, do not mark it
8682 // as captured again.
8683 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8684 Captures.insert(std::make_pair(LCRef, Ref));
8685 return Ref;
8686 }
8687 return cast<DeclRefExpr>(LCRef);
8688}
8689
8690Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8691 if (LCDecl && !LCDecl->isInvalidDecl()) {
8692 QualType Type = LCDecl->getType().getNonReferenceType();
8693 VarDecl *PrivateVar = buildVarDecl(
8694 SemaRef, DefaultLoc, Type, LCDecl->getName(),
8695 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8696 isa<VarDecl>(LCDecl)
8697 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8698 : nullptr);
8699 if (PrivateVar->isInvalidDecl())
8700 return nullptr;
8701 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8702 }
8703 return nullptr;
8704}
8705
8706/// Build initialization of the counter to be used for codegen.
8707Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8708
8709/// Build step of the counter be used for codegen.
8710Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8711
8712Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8713 Scope *S, Expr *Counter,
8714 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8715 Expr *Inc, OverloadedOperatorKind OOK) {
8716 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8717 if (!Cnt)
8718 return nullptr;
8719 if (Inc) {
8720 assert((OOK == OO_Plus || OOK == OO_Minus) &&(static_cast <bool> ((OOK == OO_Plus || OOK == OO_Minus
) && "Expected only + or - operations for depend clauses."
) ? void (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8721, __extension__ __PRETTY_FUNCTION__
))
8721 "Expected only + or - operations for depend clauses.")(static_cast <bool> ((OOK == OO_Plus || OOK == OO_Minus
) && "Expected only + or - operations for depend clauses."
) ? void (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8721, __extension__ __PRETTY_FUNCTION__
))
;
8722 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8723 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8724 if (!Cnt)
8725 return nullptr;
8726 }
8727 QualType VarType = LCDecl->getType().getNonReferenceType();
8728 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8729 !SemaRef.getLangOpts().CPlusPlus)
8730 return nullptr;
8731 // Upper - Lower
8732 Expr *Upper = TestIsLessOp.getValue()
8733 ? Cnt
8734 : tryBuildCapture(SemaRef, LB, Captures).get();
8735 Expr *Lower = TestIsLessOp.getValue()
8736 ? tryBuildCapture(SemaRef, LB, Captures).get()
8737 : Cnt;
8738 if (!Upper || !Lower)
8739 return nullptr;
8740
8741 ExprResult Diff = calculateNumIters(
8742 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8743 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8744 if (!Diff.isUsable())
8745 return nullptr;
8746
8747 return Diff.get();
8748}
8749} // namespace
8750
8751void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8752 assert(getLangOpts().OpenMP && "OpenMP is not active.")(static_cast <bool> (getLangOpts().OpenMP && "OpenMP is not active."
) ? void (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8752, __extension__ __PRETTY_FUNCTION__
))
;
8753 assert(Init && "Expected loop in canonical form.")(static_cast <bool> (Init && "Expected loop in canonical form."
) ? void (0) : __assert_fail ("Init && \"Expected loop in canonical form.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8753, __extension__ __PRETTY_FUNCTION__
))
;
8754 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
8755 if (AssociatedLoops > 0 &&
8756 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
8757 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
8758 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8759 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
8760 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8761 if (ValueDecl *D = ISC.getLoopDecl()) {
8762 auto *VD = dyn_cast<VarDecl>(D);
8763 DeclRefExpr *PrivateRef = nullptr;
8764 if (!VD) {
8765 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8766 VD = Private;
8767 } else {
8768 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8769 /*WithInit=*/false);
8770 VD = cast<VarDecl>(PrivateRef->getDecl());
8771 }
8772 }
8773 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
8774 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
8775 if (LD != D->getCanonicalDecl()) {
8776 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
8777 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8778 MarkDeclarationsReferencedInExpr(
8779 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8780 Var->getType().getNonLValueExprType(Context),
8781 ForLoc, /*RefersToCapture=*/true));
8782 }
8783 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
8784 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8785 // Referenced in a Construct, C/C++]. The loop iteration variable in the
8786 // associated for-loop of a simd construct with just one associated
8787 // for-loop may be listed in a linear clause with a constant-linear-step
8788 // that is the increment of the associated for-loop. The loop iteration
8789 // variable(s) in the associated for-loop(s) of a for or parallel for
8790 // construct may be listed in a private or lastprivate clause.
8791 DSAStackTy::DSAVarData DVar =
8792 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
8793 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8794 // is declared in the loop and it is predetermined as a private.
8795 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8796 OpenMPClauseKind PredeterminedCKind =
8797 isOpenMPSimdDirective(DKind)
8798 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8799 : OMPC_private;
8800 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8801 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8802 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8803 DVar.CKind != OMPC_private))) ||
8804 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8805 DKind == OMPD_master_taskloop ||
8806 DKind == OMPD_parallel_master_taskloop ||
8807 isOpenMPDistributeDirective(DKind)) &&
8808 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8809 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8810 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8811 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8812 << getOpenMPClauseName(DVar.CKind)
8813 << getOpenMPDirectiveName(DKind)
8814 << getOpenMPClauseName(PredeterminedCKind);
8815 if (DVar.RefExpr == nullptr)
8816 DVar.CKind = PredeterminedCKind;
8817 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
8818 /*IsLoopIterVar=*/true);
8819 } else if (LoopDeclRefExpr) {
8820 // Make the loop iteration variable private (for worksharing
8821 // constructs), linear (for simd directives with the only one
8822 // associated loop) or lastprivate (for simd directives with several
8823 // collapsed or ordered loops).
8824 if (DVar.CKind == OMPC_unknown)
8825 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8826 PrivateRef);
8827 }
8828 }
8829 }
8830 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
8831 }
8832}
8833
8834/// Called on a for stmt to check and extract its iteration space
8835/// for further processing (such as collapsing).
8836static bool checkOpenMPIterationSpace(
8837 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8838 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8839 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8840 Expr *OrderedLoopCountExpr,
8841 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8842 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8843 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8844 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8845 // OpenMP [2.9.1, Canonical Loop Form]
8846 // for (init-expr; test-expr; incr-expr) structured-block
8847 // for (range-decl: range-expr) structured-block
8848 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8849 S = CanonLoop->getLoopStmt();
8850 auto *For = dyn_cast_or_null<ForStmt>(S);
8851 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8852 // Ranged for is supported only in OpenMP 5.0.
8853 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8854 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8855 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8856 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8857 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8858 if (TotalNestedLoopCount > 1) {
8859 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8860 SemaRef.Diag(DSA.getConstructLoc(),
8861 diag::note_omp_collapse_ordered_expr)
8862 << 2 << CollapseLoopCountExpr->getSourceRange()
8863 << OrderedLoopCountExpr->getSourceRange();
8864 else if (CollapseLoopCountExpr)
8865 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8866 diag::note_omp_collapse_ordered_expr)
8867 << 0 << CollapseLoopCountExpr->getSourceRange();
8868 else
8869 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8870 diag::note_omp_collapse_ordered_expr)
8871 << 1 << OrderedLoopCountExpr->getSourceRange();
8872 }
8873 return true;
8874 }
8875 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&(static_cast <bool> (((For && For->getBody()
) || (CXXFor && CXXFor->getBody())) && "No loop body."
) ? void (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8876, __extension__ __PRETTY_FUNCTION__
))
8876 "No loop body.")(static_cast <bool> (((For && For->getBody()
) || (CXXFor && CXXFor->getBody())) && "No loop body."
) ? void (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8876, __extension__ __PRETTY_FUNCTION__
))
;
8877 // Postpone analysis in dependent contexts for ranged for loops.
8878 if (CXXFor && SemaRef.CurContext->isDependentContext())
8879 return false;
8880
8881 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8882 For ? For->getForLoc() : CXXFor->getForLoc());
8883
8884 // Check init.
8885 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8886 if (ISC.checkAndSetInit(Init))
8887 return true;
8888
8889 bool HasErrors = false;
8890
8891 // Check loop variable's type.
8892 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8893 // OpenMP [2.6, Canonical Loop Form]
8894 // Var is one of the following:
8895 // A variable of signed or unsigned integer type.
8896 // For C++, a variable of a random access iterator type.
8897 // For C, a variable of a pointer type.
8898 QualType VarType = LCDecl->getType().getNonReferenceType();
8899 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8900 !VarType->isPointerType() &&
8901 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8902 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8903 << SemaRef.getLangOpts().CPlusPlus;
8904 HasErrors = true;
8905 }
8906
8907 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8908 // a Construct
8909 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8910 // parallel for construct is (are) private.
8911 // The loop iteration variable in the associated for-loop of a simd
8912 // construct with just one associated for-loop is linear with a
8913 // constant-linear-step that is the increment of the associated for-loop.
8914 // Exclude loop var from the list of variables with implicitly defined data
8915 // sharing attributes.
8916 VarsWithImplicitDSA.erase(LCDecl);
8917
8918 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")(static_cast <bool> (isOpenMPLoopDirective(DKind) &&
"DSA for non-loop vars") ? void (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\""
, "clang/lib/Sema/SemaOpenMP.cpp", 8918, __extension__ __PRETTY_FUNCTION__
))
;
8919
8920 // Check test-expr.
8921 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8922
8923 // Check incr-expr.
8924 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8925 }
8926
8927 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8928 return HasErrors;
8929
8930 // Build the loop's iteration space representation.
8931 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8932 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8933 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8934 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8935 (isOpenMPWorksharingDirective(DKind) ||
8936 isOpenMPGenericLoopDirective(DKind) ||
8937 isOpenMPTaskLoopDirective(DKind) ||
8938 isOpenMPDistributeDirective(DKind) ||
8939 isOpenMPLoopTransformationDirective(DKind)),
8940 Captures);
8941 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8942 ISC.buildCounterVar(Captures, DSA);
8943 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8944 ISC.buildPrivateCounterVar();
8945 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8946 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8947 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8948 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8949 ISC.getConditionSrcRange();
8950 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8951 ISC.getIncrementSrcRange();
8952 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8953 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8954 ISC.isStrictTestOp();
8955 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8956 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8957 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8958 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8959 ISC.buildFinalCondition(DSA.getCurScope());
8960 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8961 ISC.doesInitDependOnLC();
8962 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8963 ISC.doesCondDependOnLC();
8964 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8965 ISC.getLoopDependentIdx();
8966
8967 HasErrors |=
8968 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8969 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8970 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8971 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8972 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8973 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8974 if (!HasErrors && DSA.isOrderedRegion()) {
8975 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8976 if (CurrentNestedLoopCount <
8977 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8978 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8979 CurrentNestedLoopCount,
8980 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8981 DSA.getOrderedRegionParam().second->setLoopCounter(
8982 CurrentNestedLoopCount,
8983 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8984 }
8985 }
8986 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8987 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8988 // Erroneous case - clause has some problems.
8989 continue;
8990 }
8991 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8992 Pair.second.size() <= CurrentNestedLoopCount) {
8993 // Erroneous case - clause has some problems.
8994 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8995 continue;
8996 }
8997 Expr *CntValue;
8998 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8999 CntValue = ISC.buildOrderedLoopData(
9000 DSA.getCurScope(),
9001 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9002 Pair.first->getDependencyLoc());
9003 else
9004 CntValue = ISC.buildOrderedLoopData(
9005 DSA.getCurScope(),
9006 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9007 Pair.first->getDependencyLoc(),
9008 Pair.second[CurrentNestedLoopCount].first,
9009 Pair.second[CurrentNestedLoopCount].second);
9010 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
9011 }
9012 }
9013
9014 return HasErrors;
9015}
9016
9017/// Build 'VarRef = Start.
9018static ExprResult
9019buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9020 ExprResult Start, bool IsNonRectangularLB,
9021 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9022 // Build 'VarRef = Start.
9023 ExprResult NewStart = IsNonRectangularLB
9024 ? Start.get()
9025 : tryBuildCapture(SemaRef, Start.get(), Captures);
9026 if (!NewStart.isUsable())
9027 return ExprError();
9028 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9029 VarRef.get()->getType())) {
9030 NewStart = SemaRef.PerformImplicitConversion(
9031 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9032 /*AllowExplicit=*/true);
9033 if (!NewStart.isUsable())
9034 return ExprError();
9035 }
9036
9037 ExprResult Init =
9038 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9039 return Init;
9040}
9041
9042/// Build 'VarRef = Start + Iter * Step'.
9043static ExprResult buildCounterUpdate(
9044 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9045 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9046 bool IsNonRectangularLB,
9047 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9048 // Add parentheses (for debugging purposes only).
9049 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9050 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9051 !Step.isUsable())
9052 return ExprError();
9053
9054 ExprResult NewStep = Step;
9055 if (Captures)
9056 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9057 if (NewStep.isInvalid())
9058 return ExprError();
9059 ExprResult Update =
9060 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9061 if (!Update.isUsable())
9062 return ExprError();
9063
9064 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9065 // 'VarRef = Start (+|-) Iter * Step'.
9066 if (!Start.isUsable())
9067 return ExprError();
9068 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9069 if (!NewStart.isUsable())
9070 return ExprError();
9071 if (Captures && !IsNonRectangularLB)
9072 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9073 if (NewStart.isInvalid())
9074 return ExprError();
9075
9076 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9077 ExprResult SavedUpdate = Update;
9078 ExprResult UpdateVal;
9079 if (VarRef.get()->getType()->isOverloadableType() ||
9080 NewStart.get()->getType()->isOverloadableType() ||
9081 Update.get()->getType()->isOverloadableType()) {
9082 Sema::TentativeAnalysisScope Trap(SemaRef);
9083
9084 Update =
9085 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9086 if (Update.isUsable()) {
9087 UpdateVal =
9088 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9089 VarRef.get(), SavedUpdate.get());
9090 if (UpdateVal.isUsable()) {
9091 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9092 UpdateVal.get());
9093 }
9094 }
9095 }
9096
9097 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9098 if (!Update.isUsable() || !UpdateVal.isUsable()) {
9099 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9100 NewStart.get(), SavedUpdate.get());
9101 if (!Update.isUsable())
9102 return ExprError();
9103
9104 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9105 VarRef.get()->getType())) {
9106 Update = SemaRef.PerformImplicitConversion(
9107 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9108 if (!Update.isUsable())
9109 return ExprError();
9110 }
9111
9112 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9113 }
9114 return Update;
9115}
9116
9117/// Convert integer expression \a E to make it have at least \a Bits
9118/// bits.
9119static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9120 if (E == nullptr)
9121 return ExprError();
9122 ASTContext &C = SemaRef.Context;
9123 QualType OldType = E->getType();
9124 unsigned HasBits = C.getTypeSize(OldType);
9125 if (HasBits >= Bits)
9126 return ExprResult(E);
9127 // OK to convert to signed, because new type has more bits than old.
9128 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9129 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9130 true);
9131}
9132
9133/// Check if the given expression \a E is a constant integer that fits
9134/// into \a Bits bits.
9135static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9136 if (E == nullptr)
9137 return false;
9138 if (Optional<llvm::APSInt> Result =
9139 E->getIntegerConstantExpr(SemaRef.Context))
9140 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9141 return false;
9142}
9143
9144/// Build preinits statement for the given declarations.
9145static Stmt *buildPreInits(ASTContext &Context,
9146 MutableArrayRef<Decl *> PreInits) {
9147 if (!PreInits.empty()) {
9148 return new (Context) DeclStmt(
9149 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9150 SourceLocation(), SourceLocation());
9151 }
9152 return nullptr;
9153}
9154
9155/// Build preinits statement for the given declarations.
9156static Stmt *
9157buildPreInits(ASTContext &Context,
9158 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9159 if (!Captures.empty()) {
9160 SmallVector<Decl *, 16> PreInits;
9161 for (const auto &Pair : Captures)
9162 PreInits.push_back(Pair.second->getDecl());
9163 return buildPreInits(Context, PreInits);
9164 }
9165 return nullptr;
9166}
9167
9168/// Build postupdate expression for the given list of postupdates expressions.
9169static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9170 Expr *PostUpdate = nullptr;
9171 if (!PostUpdates.empty()) {
9172 for (Expr *E : PostUpdates) {
9173 Expr *ConvE = S.BuildCStyleCastExpr(
9174 E->getExprLoc(),
9175 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9176 E->getExprLoc(), E)
9177 .get();
9178 PostUpdate = PostUpdate
9179 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9180 PostUpdate, ConvE)
9181 .get()
9182 : ConvE;
9183 }
9184 }
9185 return PostUpdate;
9186}
9187
9188/// Called on a for stmt to check itself and nested loops (if any).
9189/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9190/// number of collapsed loops otherwise.
9191static unsigned
9192checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9193 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9194 DSAStackTy &DSA,
9195 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9196 OMPLoopBasedDirective::HelperExprs &Built) {
9197 unsigned NestedLoopCount = 1;
9198 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9199 !isOpenMPLoopTransformationDirective(DKind);
9200
9201 if (CollapseLoopCountExpr) {
9202 // Found 'collapse' clause - calculate collapse number.
9203 Expr::EvalResult Result;
9204 if (!CollapseLoopCountExpr->isValueDependent() &&
9205 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9206 NestedLoopCount = Result.Val.getInt().getLimitedValue();
9207 } else {
9208 Built.clear(/*Size=*/1);
9209 return 1;
9210 }
9211 }
9212 unsigned OrderedLoopCount = 1;
9213 if (OrderedLoopCountExpr) {
9214 // Found 'ordered' clause - calculate collapse number.
9215 Expr::EvalResult EVResult;
9216 if (!OrderedLoopCountExpr->isValueDependent() &&
9217 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9218 SemaRef.getASTContext())) {
9219 llvm::APSInt Result = EVResult.Val.getInt();
9220 if (Result.getLimitedValue() < NestedLoopCount) {
9221 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9222 diag::err_omp_wrong_ordered_loop_count)
9223 << OrderedLoopCountExpr->getSourceRange();
9224 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9225 diag::note_collapse_loop_count)
9226 << CollapseLoopCountExpr->getSourceRange();
9227 }
9228 OrderedLoopCount = Result.getLimitedValue();
9229 } else {
9230 Built.clear(/*Size=*/1);
9231 return 1;
9232 }
9233 }
9234 // This is helper routine for loop directives (e.g., 'for', 'simd',
9235 // 'for simd', etc.).
9236 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9237 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9238 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9239 if (!OMPLoopBasedDirective::doForAllLoops(
9240 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9241 SupportsNonPerfectlyNested, NumLoops,
9242 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9243 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9244 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9245 if (checkOpenMPIterationSpace(
9246 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9247 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9248 VarsWithImplicitDSA, IterSpaces, Captures))
9249 return true;
9250 if (Cnt > 0 && Cnt >= NestedLoopCount &&
9251 IterSpaces[Cnt].CounterVar) {
9252 // Handle initialization of captured loop iterator variables.
9253 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9254 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9255 Captures[DRE] = DRE;
9256 }
9257 }
9258 return false;
9259 },
9260 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9261 Stmt *DependentPreInits = Transform->getPreInits();
9262 if (!DependentPreInits)
9263 return;
9264 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9265 auto *D = cast<VarDecl>(C);
9266 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9267 Transform->getBeginLoc());
9268 Captures[Ref] = Ref;
9269 }
9270 }))
9271 return 0;
9272
9273 Built.clear(/* size */ NestedLoopCount);
9274
9275 if (SemaRef.CurContext->isDependentContext())
9276 return NestedLoopCount;
9277
9278 // An example of what is generated for the following code:
9279 //
9280 // #pragma omp simd collapse(2) ordered(2)
9281 // for (i = 0; i < NI; ++i)
9282 // for (k = 0; k < NK; ++k)
9283 // for (j = J0; j < NJ; j+=2) {
9284 // <loop body>
9285 // }
9286 //
9287 // We generate the code below.
9288 // Note: the loop body may be outlined in CodeGen.
9289 // Note: some counters may be C++ classes, operator- is used to find number of
9290 // iterations and operator+= to calculate counter value.
9291 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9292 // or i64 is currently supported).
9293 //
9294 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9295 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9296 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9297 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9298 // // similar updates for vars in clauses (e.g. 'linear')
9299 // <loop body (using local i and j)>
9300 // }
9301 // i = NI; // assign final values of counters
9302 // j = NJ;
9303 //
9304
9305 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9306 // the iteration counts of the collapsed for loops.
9307 // Precondition tests if there is at least one iteration (all conditions are
9308 // true).
9309 auto PreCond = ExprResult(IterSpaces[0].PreCond);
9310 Expr *N0 = IterSpaces[0].NumIterations;
9311 ExprResult LastIteration32 =
9312 widenIterationCount(/*Bits=*/32,
9313 SemaRef
9314 .PerformImplicitConversion(
9315 N0->IgnoreImpCasts(), N0->getType(),
9316 Sema::AA_Converting, /*AllowExplicit=*/true)
9317 .get(),
9318 SemaRef);
9319 ExprResult LastIteration64 = widenIterationCount(
9320 /*Bits=*/64,
9321 SemaRef
9322 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9323 Sema::AA_Converting,
9324 /*AllowExplicit=*/true)
9325 .get(),
9326 SemaRef);
9327
9328 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9329 return NestedLoopCount;
9330
9331 ASTContext &C = SemaRef.Context;
9332 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9333
9334 Scope *CurScope = DSA.getCurScope();
9335 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9336 if (PreCond.isUsable()) {
9337 PreCond =
9338 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9339 PreCond.get(), IterSpaces[Cnt].PreCond);
9340 }
9341 Expr *N = IterSpaces[Cnt].NumIterations;
9342 SourceLocation Loc = N->getExprLoc();
9343 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9344 if (LastIteration32.isUsable())
9345 LastIteration32 = SemaRef.BuildBinOp(
9346 CurScope, Loc, BO_Mul, LastIteration32.get(),
9347 SemaRef
9348 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9349 Sema::AA_Converting,
9350 /*AllowExplicit=*/true)
9351 .get());
9352 if (LastIteration64.isUsable())
9353 LastIteration64 = SemaRef.BuildBinOp(
9354 CurScope, Loc, BO_Mul, LastIteration64.get(),
9355 SemaRef
9356 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9357 Sema::AA_Converting,
9358 /*AllowExplicit=*/true)
9359 .get());
9360 }
9361
9362 // Choose either the 32-bit or 64-bit version.
9363 ExprResult LastIteration = LastIteration64;
9364 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9365 (LastIteration32.isUsable() &&
9366 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9367 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9368 fitsInto(
9369 /*Bits=*/32,
9370 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9371 LastIteration64.get(), SemaRef))))
9372 LastIteration = LastIteration32;
9373 QualType VType = LastIteration.get()->getType();
9374 QualType RealVType = VType;
9375 QualType StrideVType = VType;
9376 if (isOpenMPTaskLoopDirective(DKind)) {
9377 VType =
9378 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9379 StrideVType =
9380 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9381 }
9382
9383 if (!LastIteration.isUsable())
9384 return 0;
9385
9386 // Save the number of iterations.
9387 ExprResult NumIterations = LastIteration;
9388 {
9389 LastIteration = SemaRef.BuildBinOp(
9390 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9391 LastIteration.get(),
9392 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9393 if (!LastIteration.isUsable())
9394 return 0;
9395 }
9396
9397 // Calculate the last iteration number beforehand instead of doing this on
9398 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9399 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9400 ExprResult CalcLastIteration;
9401 if (!IsConstant) {
9402 ExprResult SaveRef =
9403 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9404 LastIteration = SaveRef;
9405
9406 // Prepare SaveRef + 1.
9407 NumIterations = SemaRef.BuildBinOp(
9408 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9409 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9410 if (!NumIterations.isUsable())
9411 return 0;
9412 }
9413
9414 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9415
9416 // Build variables passed into runtime, necessary for worksharing directives.
9417 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9418 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9419 isOpenMPDistributeDirective(DKind) ||
9420 isOpenMPGenericLoopDirective(DKind) ||
9421 isOpenMPLoopTransformationDirective(DKind)) {
9422 // Lower bound variable, initialized with zero.
9423 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9424 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9425 SemaRef.AddInitializerToDecl(LBDecl,
9426 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9427 /*DirectInit*/ false);
9428
9429 // Upper bound variable, initialized with last iteration number.
9430 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9431 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9432 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9433 /*DirectInit*/ false);
9434
9435 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9436 // This will be used to implement clause 'lastprivate'.
9437 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9438 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9439 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9440 SemaRef.AddInitializerToDecl(ILDecl,
9441 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9442 /*DirectInit*/ false);
9443
9444 // Stride variable returned by runtime (we initialize it to 1 by default).
9445 VarDecl *STDecl =
9446 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9447 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9448 SemaRef.AddInitializerToDecl(STDecl,
9449 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9450 /*DirectInit*/ false);
9451
9452 // Build expression: UB = min(UB, LastIteration)
9453 // It is necessary for CodeGen of directives with static scheduling.
9454 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9455 UB.get(), LastIteration.get());
9456 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9457 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9458 LastIteration.get(), UB.get());
9459 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9460 CondOp.get());
9461 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9462
9463 // If we have a combined directive that combines 'distribute', 'for' or
9464 // 'simd' we need to be able to access the bounds of the schedule of the
9465 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9466 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9467 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9468 // Lower bound variable, initialized with zero.
9469 VarDecl *CombLBDecl =
9470 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9471 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9472 SemaRef.AddInitializerToDecl(
9473 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9474 /*DirectInit*/ false);
9475
9476 // Upper bound variable, initialized with last iteration number.
9477 VarDecl *CombUBDecl =
9478 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9479 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9480 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9481 /*DirectInit*/ false);
9482
9483 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9484 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9485 ExprResult CombCondOp =
9486 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9487 LastIteration.get(), CombUB.get());
9488 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9489 CombCondOp.get());
9490 CombEUB =
9491 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9492
9493 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9494 // We expect to have at least 2 more parameters than the 'parallel'
9495 // directive does - the lower and upper bounds of the previous schedule.
9496 assert(CD->getNumParams() >= 4 &&(static_cast <bool> (CD->getNumParams() >= 4 &&
"Unexpected number of parameters in loop combined directive"
) ? void (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9497, __extension__ __PRETTY_FUNCTION__
))
9497 "Unexpected number of parameters in loop combined directive")(static_cast <bool> (CD->getNumParams() >= 4 &&
"Unexpected number of parameters in loop combined directive"
) ? void (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9497, __extension__ __PRETTY_FUNCTION__
))
;
9498
9499 // Set the proper type for the bounds given what we learned from the
9500 // enclosed loops.
9501 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9502 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9503
9504 // Previous lower and upper bounds are obtained from the region
9505 // parameters.
9506 PrevLB =
9507 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9508 PrevUB =
9509 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9510 }
9511 }
9512
9513 // Build the iteration variable and its initialization before loop.
9514 ExprResult IV;
9515 ExprResult Init, CombInit;
9516 {
9517 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9518 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9519 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9520 isOpenMPGenericLoopDirective(DKind) ||
9521 isOpenMPTaskLoopDirective(DKind) ||
9522 isOpenMPDistributeDirective(DKind) ||
9523 isOpenMPLoopTransformationDirective(DKind))
9524 ? LB.get()
9525 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9526 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9527 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9528
9529 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9530 Expr *CombRHS =
9531 (isOpenMPWorksharingDirective(DKind) ||
9532 isOpenMPGenericLoopDirective(DKind) ||
9533 isOpenMPTaskLoopDirective(DKind) ||
9534 isOpenMPDistributeDirective(DKind))
9535 ? CombLB.get()
9536 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9537 CombInit =
9538 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9539 CombInit =
9540 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9541 }
9542 }
9543
9544 bool UseStrictCompare =
9545 RealVType->hasUnsignedIntegerRepresentation() &&
9546 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9547 return LIS.IsStrictCompare;
9548 });
9549 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9550 // unsigned IV)) for worksharing loops.
9551 SourceLocation CondLoc = AStmt->getBeginLoc();
9552 Expr *BoundUB = UB.get();
9553 if (UseStrictCompare) {
9554 BoundUB =
9555 SemaRef
9556 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9557 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9558 .get();
9559 BoundUB =
9560 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9561 }
9562 ExprResult Cond =
9563 (isOpenMPWorksharingDirective(DKind) ||
9564 isOpenMPGenericLoopDirective(DKind) ||
9565 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9566 isOpenMPLoopTransformationDirective(DKind))
9567 ? SemaRef.BuildBinOp(CurScope, CondLoc,
9568 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9569 BoundUB)
9570 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9571 NumIterations.get());
9572 ExprResult CombDistCond;
9573 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9574 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9575 NumIterations.get());
9576 }
9577
9578 ExprResult CombCond;
9579 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9580 Expr *BoundCombUB = CombUB.get();
9581 if (UseStrictCompare) {
9582 BoundCombUB =
9583 SemaRef
9584 .BuildBinOp(
9585 CurScope, CondLoc, BO_Add, BoundCombUB,
9586 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9587 .get();
9588 BoundCombUB =
9589 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9590 .get();
9591 }
9592 CombCond =
9593 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9594 IV.get(), BoundCombUB);
9595 }
9596 // Loop increment (IV = IV + 1)
9597 SourceLocation IncLoc = AStmt->getBeginLoc();
9598 ExprResult Inc =
9599 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9600 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9601 if (!Inc.isUsable())
9602 return 0;
9603 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9604 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9605 if (!Inc.isUsable())
9606 return 0;
9607
9608 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9609 // Used for directives with static scheduling.
9610 // In combined construct, add combined version that use CombLB and CombUB
9611 // base variables for the update
9612 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9613 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9614 isOpenMPGenericLoopDirective(DKind) ||
9615 isOpenMPDistributeDirective(DKind) ||
9616 isOpenMPLoopTransformationDirective(DKind)) {
9617 // LB + ST
9618 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9619 if (!NextLB.isUsable())
9620 return 0;
9621 // LB = LB + ST
9622 NextLB =
9623 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9624 NextLB =
9625 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9626 if (!NextLB.isUsable())
9627 return 0;
9628 // UB + ST
9629 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9630 if (!NextUB.isUsable())
9631 return 0;
9632 // UB = UB + ST
9633 NextUB =
9634 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9635 NextUB =
9636 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9637 if (!NextUB.isUsable())
9638 return 0;
9639 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9640 CombNextLB =
9641 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9642 if (!NextLB.isUsable())
9643 return 0;
9644 // LB = LB + ST
9645 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9646 CombNextLB.get());
9647 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9648 /*DiscardedValue*/ false);
9649 if (!CombNextLB.isUsable())
9650 return 0;
9651 // UB + ST
9652 CombNextUB =
9653 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9654 if (!CombNextUB.isUsable())
9655 return 0;
9656 // UB = UB + ST
9657 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9658 CombNextUB.get());
9659 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9660 /*DiscardedValue*/ false);
9661 if (!CombNextUB.isUsable())
9662 return 0;
9663 }
9664 }
9665
9666 // Create increment expression for distribute loop when combined in a same
9667 // directive with for as IV = IV + ST; ensure upper bound expression based
9668 // on PrevUB instead of NumIterations - used to implement 'for' when found
9669 // in combination with 'distribute', like in 'distribute parallel for'
9670 SourceLocation DistIncLoc = AStmt->getBeginLoc();
9671 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9672 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9673 DistCond = SemaRef.BuildBinOp(
9674 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9675 assert(DistCond.isUsable() && "distribute cond expr was not built")(static_cast <bool> (DistCond.isUsable() && "distribute cond expr was not built"
) ? void (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9675, __extension__ __PRETTY_FUNCTION__
))
;
9676
9677 DistInc =
9678 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9679 assert(DistInc.isUsable() && "distribute inc expr was not built")(static_cast <bool> (DistInc.isUsable() && "distribute inc expr was not built"
) ? void (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9679, __extension__ __PRETTY_FUNCTION__
))
;
9680 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9681 DistInc.get());
9682 DistInc =
9683 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9684 assert(DistInc.isUsable() && "distribute inc expr was not built")(static_cast <bool> (DistInc.isUsable() && "distribute inc expr was not built"
) ? void (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9684, __extension__ __PRETTY_FUNCTION__
))
;
9685
9686 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9687 // construct
9688 ExprResult NewPrevUB = PrevUB;
9689 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9690 if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9691 PrevUB.get()->getType())) {
9692 NewPrevUB = SemaRef.BuildCStyleCastExpr(
9693 DistEUBLoc,
9694 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9695 DistEUBLoc, NewPrevUB.get());
9696 if (!NewPrevUB.isUsable())
9697 return 0;
9698 }
9699 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9700 UB.get(), NewPrevUB.get());
9701 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9702 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9703 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9704 CondOp.get());
9705 PrevEUB =
9706 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9707
9708 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9709 // parallel for is in combination with a distribute directive with
9710 // schedule(static, 1)
9711 Expr *BoundPrevUB = PrevUB.get();
9712 if (UseStrictCompare) {
9713 BoundPrevUB =
9714 SemaRef
9715 .BuildBinOp(
9716 CurScope, CondLoc, BO_Add, BoundPrevUB,
9717 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9718 .get();
9719 BoundPrevUB =
9720 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9721 .get();
9722 }
9723 ParForInDistCond =
9724 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9725 IV.get(), BoundPrevUB);
9726 }
9727
9728 // Build updates and final values of the loop counters.
9729 bool HasErrors = false;
9730 Built.Counters.resize(NestedLoopCount);
9731 Built.Inits.resize(NestedLoopCount);
9732 Built.Updates.resize(NestedLoopCount);
9733 Built.Finals.resize(NestedLoopCount);
9734 Built.DependentCounters.resize(NestedLoopCount);
9735 Built.DependentInits.resize(NestedLoopCount);
9736 Built.FinalsConditions.resize(NestedLoopCount);
9737 {
9738 // We implement the following algorithm for obtaining the
9739 // original loop iteration variable values based on the
9740 // value of the collapsed loop iteration variable IV.
9741 //
9742 // Let n+1 be the number of collapsed loops in the nest.
9743 // Iteration variables (I0, I1, .... In)
9744 // Iteration counts (N0, N1, ... Nn)
9745 //
9746 // Acc = IV;
9747 //
9748 // To compute Ik for loop k, 0 <= k <= n, generate:
9749 // Prod = N(k+1) * N(k+2) * ... * Nn;
9750 // Ik = Acc / Prod;
9751 // Acc -= Ik * Prod;
9752 //
9753 ExprResult Acc = IV;
9754 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9755 LoopIterationSpace &IS = IterSpaces[Cnt];
9756 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9757 ExprResult Iter;
9758
9759 // Compute prod
9760 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9761 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
9762 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9763 IterSpaces[K].NumIterations);
9764
9765 // Iter = Acc / Prod
9766 // If there is at least one more inner loop to avoid
9767 // multiplication by 1.
9768 if (Cnt + 1 < NestedLoopCount)
9769 Iter =
9770 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
9771 else
9772 Iter = Acc;
9773 if (!Iter.isUsable()) {
9774 HasErrors = true;
9775 break;
9776 }
9777
9778 // Update Acc:
9779 // Acc -= Iter * Prod
9780 // Check if there is at least one more inner loop to avoid
9781 // multiplication by 1.
9782 if (Cnt + 1 < NestedLoopCount)
9783 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
9784 Prod.get());
9785 else
9786 Prod = Iter;
9787 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
9788
9789 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9790 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9791 DeclRefExpr *CounterVar = buildDeclRefExpr(
9792 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9793 /*RefersToCapture=*/true);
9794 ExprResult Init =
9795 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9796 IS.CounterInit, IS.IsNonRectangularLB, Captures);
9797 if (!Init.isUsable()) {
9798 HasErrors = true;
9799 break;
9800 }
9801 ExprResult Update = buildCounterUpdate(
9802 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9803 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9804 if (!Update.isUsable()) {
9805 HasErrors = true;
9806 break;
9807 }
9808
9809 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9810 ExprResult Final =
9811 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9812 IS.CounterInit, IS.NumIterations, IS.CounterStep,
9813 IS.Subtract, IS.IsNonRectangularLB, &Captures);
9814 if (!Final.isUsable()) {
9815 HasErrors = true;
9816 break;
9817 }
9818
9819 if (!Update.isUsable() || !Final.isUsable()) {
9820 HasErrors = true;
9821 break;
9822 }
9823 // Save results
9824 Built.Counters[Cnt] = IS.CounterVar;
9825 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9826 Built.Inits[Cnt] = Init.get();
9827 Built.Updates[Cnt] = Update.get();
9828 Built.Finals[Cnt] = Final.get();
9829 Built.DependentCounters[Cnt] = nullptr;
9830 Built.DependentInits[Cnt] = nullptr;
9831 Built.FinalsConditions[Cnt] = nullptr;
9832 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9833 Built.DependentCounters[Cnt] =
9834 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9835 Built.DependentInits[Cnt] =
9836 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9837 Built.FinalsConditions[Cnt] = IS.FinalCondition;
9838 }
9839 }
9840 }
9841
9842 if (HasErrors)
9843 return 0;
9844
9845 // Save results
9846 Built.IterationVarRef = IV.get();
9847 Built.LastIteration = LastIteration.get();
9848 Built.NumIterations = NumIterations.get();
9849 Built.CalcLastIteration = SemaRef
9850 .ActOnFinishFullExpr(CalcLastIteration.get(),
9851 /*DiscardedValue=*/false)
9852 .get();
9853 Built.PreCond = PreCond.get();
9854 Built.PreInits = buildPreInits(C, Captures);
9855 Built.Cond = Cond.get();
9856 Built.Init = Init.get();
9857 Built.Inc = Inc.get();
9858 Built.LB = LB.get();
9859 Built.UB = UB.get();
9860 Built.IL = IL.get();
9861 Built.ST = ST.get();
9862 Built.EUB = EUB.get();
9863 Built.NLB = NextLB.get();
9864 Built.NUB = NextUB.get();
9865 Built.PrevLB = PrevLB.get();
9866 Built.PrevUB = PrevUB.get();
9867 Built.DistInc = DistInc.get();
9868 Built.PrevEUB = PrevEUB.get();
9869 Built.DistCombinedFields.LB = CombLB.get();
9870 Built.DistCombinedFields.UB = CombUB.get();
9871 Built.DistCombinedFields.EUB = CombEUB.get();
9872 Built.DistCombinedFields.Init = CombInit.get();
9873 Built.DistCombinedFields.Cond = CombCond.get();
9874 Built.DistCombinedFields.NLB = CombNextLB.get();
9875 Built.DistCombinedFields.NUB = CombNextUB.get();
9876 Built.DistCombinedFields.DistCond = CombDistCond.get();
9877 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9878
9879 return NestedLoopCount;
9880}
9881
9882static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9883 auto CollapseClauses =
9884 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9885 if (CollapseClauses.begin() != CollapseClauses.end())
9886 return (*CollapseClauses.begin())->getNumForLoops();
9887 return nullptr;
9888}
9889
9890static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9891 auto OrderedClauses =
9892 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9893 if (OrderedClauses.begin() != OrderedClauses.end())
9894 return (*OrderedClauses.begin())->getNumForLoops();
9895 return nullptr;
9896}
9897
9898static bool checkSimdlenSafelenSpecified(Sema &S,
9899 const ArrayRef<OMPClause *> Clauses) {
9900 const OMPSafelenClause *Safelen = nullptr;
9901 const OMPSimdlenClause *Simdlen = nullptr;
9902
9903 for (const OMPClause *Clause : Clauses) {
9904 if (Clause->getClauseKind() == OMPC_safelen)
9905 Safelen = cast<OMPSafelenClause>(Clause);
9906 else if (Clause->getClauseKind() == OMPC_simdlen)
9907 Simdlen = cast<OMPSimdlenClause>(Clause);
9908 if (Safelen && Simdlen)
9909 break;
9910 }
9911
9912 if (Simdlen && Safelen) {
9913 const Expr *SimdlenLength = Simdlen->getSimdlen();
9914 const Expr *SafelenLength = Safelen->getSafelen();
9915 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9916 SimdlenLength->isInstantiationDependent() ||
9917 SimdlenLength->containsUnexpandedParameterPack())
9918 return false;
9919 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9920 SafelenLength->isInstantiationDependent() ||
9921 SafelenLength->containsUnexpandedParameterPack())
9922 return false;
9923 Expr::EvalResult SimdlenResult, SafelenResult;
9924 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9925 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9926 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9927 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9928 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9929 // If both simdlen and safelen clauses are specified, the value of the
9930 // simdlen parameter must be less than or equal to the value of the safelen
9931 // parameter.
9932 if (SimdlenRes > SafelenRes) {
9933 S.Diag(SimdlenLength->getExprLoc(),
9934 diag::err_omp_wrong_simdlen_safelen_values)
9935 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9936 return true;
9937 }
9938 }
9939 return false;
9940}
9941
9942StmtResult
9943Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9944 SourceLocation StartLoc, SourceLocation EndLoc,
9945 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9946 if (!AStmt)
9947 return StmtError();
9948
9949 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9949, __extension__ __PRETTY_FUNCTION__
))
;
9950 OMPLoopBasedDirective::HelperExprs B;
9951 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9952 // define the nested loops number.
9953 unsigned NestedLoopCount = checkOpenMPLoop(
9954 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9955 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9956 if (NestedLoopCount == 0)
9957 return StmtError();
9958
9959 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9960, __extension__ __PRETTY_FUNCTION__
))
9960 "omp simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9960, __extension__ __PRETTY_FUNCTION__
))
;
9961
9962 if (!CurContext->isDependentContext()) {
9963 // Finalize the clauses that need pre-built expressions for CodeGen.
9964 for (OMPClause *C : Clauses) {
9965 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9966 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9967 B.NumIterations, *this, CurScope,
9968 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9969 return StmtError();
9970 }
9971 }
9972
9973 if (checkSimdlenSafelenSpecified(*this, Clauses))
9974 return StmtError();
9975
9976 setFunctionHasBranchProtectedScope();
9977 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9978 Clauses, AStmt, B);
9979}
9980
9981StmtResult
9982Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9983 SourceLocation StartLoc, SourceLocation EndLoc,
9984 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9985 if (!AStmt)
9986 return StmtError();
9987
9988 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9988, __extension__ __PRETTY_FUNCTION__
))
;
9989 OMPLoopBasedDirective::HelperExprs B;
9990 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9991 // define the nested loops number.
9992 unsigned NestedLoopCount = checkOpenMPLoop(
9993 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9994 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
9995 if (NestedLoopCount == 0)
9996 return StmtError();
9997
9998 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9999, __extension__ __PRETTY_FUNCTION__
))
9999 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 9999, __extension__ __PRETTY_FUNCTION__
))
;
10000
10001 if (!CurContext->isDependentContext()) {
10002 // Finalize the clauses that need pre-built expressions for CodeGen.
10003 for (OMPClause *C : Clauses) {
10004 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10005 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10006 B.NumIterations, *this, CurScope,
10007 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10008 return StmtError();
10009 }
10010 }
10011
10012 setFunctionHasBranchProtectedScope();
10013 return OMPForDirective::Create(
10014 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10015 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10016}
10017
10018StmtResult Sema::ActOnOpenMPForSimdDirective(
10019 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10020 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10021 if (!AStmt)
10022 return StmtError();
10023
10024 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10024, __extension__ __PRETTY_FUNCTION__
))
;
10025 OMPLoopBasedDirective::HelperExprs B;
10026 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10027 // define the nested loops number.
10028 unsigned NestedLoopCount =
10029 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10030 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10031 VarsWithImplicitDSA, B);
10032 if (NestedLoopCount == 0)
10033 return StmtError();
10034
10035 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10036, __extension__ __PRETTY_FUNCTION__
))
10036 "omp for simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10036, __extension__ __PRETTY_FUNCTION__
))
;
10037
10038 if (!CurContext->isDependentContext()) {
10039 // Finalize the clauses that need pre-built expressions for CodeGen.
10040 for (OMPClause *C : Clauses) {
10041 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10042 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10043 B.NumIterations, *this, CurScope,
10044 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10045 return StmtError();
10046 }
10047 }
10048
10049 if (checkSimdlenSafelenSpecified(*this, Clauses))
10050 return StmtError();
10051
10052 setFunctionHasBranchProtectedScope();
10053 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10054 Clauses, AStmt, B);
10055}
10056
10057StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10058 Stmt *AStmt,
10059 SourceLocation StartLoc,
10060 SourceLocation EndLoc) {
10061 if (!AStmt)
10062 return StmtError();
10063
10064 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10064, __extension__ __PRETTY_FUNCTION__
))
;
10065 auto BaseStmt = AStmt;
10066 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10067 BaseStmt = CS->getCapturedStmt();
10068 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10069 auto S = C->children();
10070 if (S.begin() == S.end())
10071 return StmtError();
10072 // All associated statements must be '#pragma omp section' except for
10073 // the first one.
10074 for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10075 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10076 if (SectionStmt)
10077 Diag(SectionStmt->getBeginLoc(),
10078 diag::err_omp_sections_substmt_not_section);
10079 return StmtError();
10080 }
10081 cast<OMPSectionDirective>(SectionStmt)
10082 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10083 }
10084 } else {
10085 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10086 return StmtError();
10087 }
10088
10089 setFunctionHasBranchProtectedScope();
10090
10091 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10092 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
10093 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10094}
10095
10096StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10097 SourceLocation StartLoc,
10098 SourceLocation EndLoc) {
10099 if (!AStmt)
10100 return StmtError();
10101
10102 setFunctionHasBranchProtectedScope();
10103 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10104
10105 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10106 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10107}
10108
10109static Expr *getDirectCallExpr(Expr *E) {
10110 E = E->IgnoreParenCasts()->IgnoreImplicit();
10111 if (auto *CE = dyn_cast<CallExpr>(E))
10112 if (CE->getDirectCallee())
10113 return E;
10114 return nullptr;
10115}
10116
10117StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10118 Stmt *AStmt,
10119 SourceLocation StartLoc,
10120 SourceLocation EndLoc) {
10121 if (!AStmt)
10122 return StmtError();
10123
10124 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10125
10126 // 5.1 OpenMP
10127 // expression-stmt : an expression statement with one of the following forms:
10128 // expression = target-call ( [expression-list] );
10129 // target-call ( [expression-list] );
10130
10131 SourceLocation TargetCallLoc;
10132
10133 if (!CurContext->isDependentContext()) {
10134 Expr *TargetCall = nullptr;
10135
10136 auto *E = dyn_cast<Expr>(S);
10137 if (!E) {
10138 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10139 return StmtError();
10140 }
10141
10142 E = E->IgnoreParenCasts()->IgnoreImplicit();
10143
10144 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10145 if (BO->getOpcode() == BO_Assign)
10146 TargetCall = getDirectCallExpr(BO->getRHS());
10147 } else {
10148 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10149 if (COCE->getOperator() == OO_Equal)
10150 TargetCall = getDirectCallExpr(COCE->getArg(1));
10151 if (!TargetCall)
10152 TargetCall = getDirectCallExpr(E);
10153 }
10154 if (!TargetCall) {
10155 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10156 return StmtError();
10157 }
10158 TargetCallLoc = TargetCall->getExprLoc();
10159 }
10160
10161 setFunctionHasBranchProtectedScope();
10162
10163 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10164 TargetCallLoc);
10165}
10166
10167static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10168 OpenMPDirectiveKind K,
10169 DSAStackTy *Stack) {
10170 bool ErrorFound = false;
10171 for (OMPClause *C : Clauses) {
10172 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10173 for (Expr *RefExpr : LPC->varlists()) {
10174 SourceLocation ELoc;
10175 SourceRange ERange;
10176 Expr *SimpleRefExpr = RefExpr;
10177 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10178 if (ValueDecl *D = Res.first) {
10179 auto &&Info = Stack->isLoopControlVariable(D);
10180 if (!Info.first) {
10181 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10182 << getOpenMPDirectiveName(K);
10183 ErrorFound = true;
10184 }
10185 }
10186 }
10187 }
10188 }
10189 return ErrorFound;
10190}
10191
10192StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10193 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10194 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10195 if (!AStmt)
10196 return StmtError();
10197
10198 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10199 // A list item may not appear in a lastprivate clause unless it is the
10200 // loop iteration variable of a loop that is associated with the construct.
10201 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10202 return StmtError();
10203
10204 auto *CS = cast<CapturedStmt>(AStmt);
10205 // 1.2.2 OpenMP Language Terminology
10206 // Structured block - An executable statement with a single entry at the
10207 // top and a single exit at the bottom.
10208 // The point of exit cannot be a branch out of the structured block.
10209 // longjmp() and throw() must not violate the entry/exit criteria.
10210 CS->getCapturedDecl()->setNothrow();
10211
10212 OMPLoopDirective::HelperExprs B;
10213 // In presence of clause 'collapse', it will define the nested loops number.
10214 unsigned NestedLoopCount = checkOpenMPLoop(
10215 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10216 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10217 if (NestedLoopCount == 0)
10218 return StmtError();
10219
10220 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10221, __extension__ __PRETTY_FUNCTION__
))
10221 "omp loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10221, __extension__ __PRETTY_FUNCTION__
))
;
10222
10223 setFunctionHasBranchProtectedScope();
10224 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10225 NestedLoopCount, Clauses, AStmt, B);
10226}
10227
10228StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10229 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10230 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10231 if (!AStmt)
10232 return StmtError();
10233
10234 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10235 // A list item may not appear in a lastprivate clause unless it is the
10236 // loop iteration variable of a loop that is associated with the construct.
10237 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10238 return StmtError();
10239
10240 auto *CS = cast<CapturedStmt>(AStmt);
10241 // 1.2.2 OpenMP Language Terminology
10242 // Structured block - An executable statement with a single entry at the
10243 // top and a single exit at the bottom.
10244 // The point of exit cannot be a branch out of the structured block.
10245 // longjmp() and throw() must not violate the entry/exit criteria.
10246 CS->getCapturedDecl()->setNothrow();
10247 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10248 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10249 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10250 // 1.2.2 OpenMP Language Terminology
10251 // Structured block - An executable statement with a single entry at the
10252 // top and a single exit at the bottom.
10253 // The point of exit cannot be a branch out of the structured block.
10254 // longjmp() and throw() must not violate the entry/exit criteria.
10255 CS->getCapturedDecl()->setNothrow();
10256 }
10257
10258 OMPLoopDirective::HelperExprs B;
10259 // In presence of clause 'collapse', it will define the nested loops number.
10260 unsigned NestedLoopCount =
10261 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10262 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10263 VarsWithImplicitDSA, B);
10264 if (NestedLoopCount == 0)
10265 return StmtError();
10266
10267 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10268, __extension__ __PRETTY_FUNCTION__
))
10268 "omp loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10268, __extension__ __PRETTY_FUNCTION__
))
;
10269
10270 setFunctionHasBranchProtectedScope();
10271 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10272
10273 return OMPTeamsGenericLoopDirective::Create(
10274 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10275}
10276
10277StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10278 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10279 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10280 if (!AStmt)
10281 return StmtError();
10282
10283 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10284 // A list item may not appear in a lastprivate clause unless it is the
10285 // loop iteration variable of a loop that is associated with the construct.
10286 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10287 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10288 return StmtError();
10289
10290 auto *CS = cast<CapturedStmt>(AStmt);
10291 // 1.2.2 OpenMP Language Terminology
10292 // Structured block - An executable statement with a single entry at the
10293 // top and a single exit at the bottom.
10294 // The point of exit cannot be a branch out of the structured block.
10295 // longjmp() and throw() must not violate the entry/exit criteria.
10296 CS->getCapturedDecl()->setNothrow();
10297 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10298 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10299 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10300 // 1.2.2 OpenMP Language Terminology
10301 // Structured block - An executable statement with a single entry at the
10302 // top and a single exit at the bottom.
10303 // The point of exit cannot be a branch out of the structured block.
10304 // longjmp() and throw() must not violate the entry/exit criteria.
10305 CS->getCapturedDecl()->setNothrow();
10306 }
10307
10308 OMPLoopDirective::HelperExprs B;
10309 // In presence of clause 'collapse', it will define the nested loops number.
10310 unsigned NestedLoopCount =
10311 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10312 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10313 VarsWithImplicitDSA, B);
10314 if (NestedLoopCount == 0)
10315 return StmtError();
10316
10317 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10318, __extension__ __PRETTY_FUNCTION__
))
10318 "omp loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10318, __extension__ __PRETTY_FUNCTION__
))
;
10319
10320 setFunctionHasBranchProtectedScope();
10321
10322 return OMPTargetTeamsGenericLoopDirective::Create(
10323 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10324}
10325
10326StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10328 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10329 if (!AStmt)
10330 return StmtError();
10331
10332 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10333 // A list item may not appear in a lastprivate clause unless it is the
10334 // loop iteration variable of a loop that is associated with the construct.
10335 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10336 return StmtError();
10337
10338 auto *CS = cast<CapturedStmt>(AStmt);
10339 // 1.2.2 OpenMP Language Terminology
10340 // Structured block - An executable statement with a single entry at the
10341 // top and a single exit at the bottom.
10342 // The point of exit cannot be a branch out of the structured block.
10343 // longjmp() and throw() must not violate the entry/exit criteria.
10344 CS->getCapturedDecl()->setNothrow();
10345 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10346 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10347 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10348 // 1.2.2 OpenMP Language Terminology
10349 // Structured block - An executable statement with a single entry at the
10350 // top and a single exit at the bottom.
10351 // The point of exit cannot be a branch out of the structured block.
10352 // longjmp() and throw() must not violate the entry/exit criteria.
10353 CS->getCapturedDecl()->setNothrow();
10354 }
10355
10356 OMPLoopDirective::HelperExprs B;
10357 // In presence of clause 'collapse', it will define the nested loops number.
10358 unsigned NestedLoopCount =
10359 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10360 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10361 VarsWithImplicitDSA, B);
10362 if (NestedLoopCount == 0)
10363 return StmtError();
10364
10365 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10366, __extension__ __PRETTY_FUNCTION__
))
10366 "omp loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10366, __extension__ __PRETTY_FUNCTION__
))
;
10367
10368 setFunctionHasBranchProtectedScope();
10369
10370 return OMPParallelGenericLoopDirective::Create(
10371 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10372}
10373
10374StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10375 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10376 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10377 if (!AStmt)
10378 return StmtError();
10379
10380 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10381 // A list item may not appear in a lastprivate clause unless it is the
10382 // loop iteration variable of a loop that is associated with the construct.
10383 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10384 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10385 return StmtError();
10386
10387 auto *CS = cast<CapturedStmt>(AStmt);
10388 // 1.2.2 OpenMP Language Terminology
10389 // Structured block - An executable statement with a single entry at the
10390 // top and a single exit at the bottom.
10391 // The point of exit cannot be a branch out of the structured block.
10392 // longjmp() and throw() must not violate the entry/exit criteria.
10393 CS->getCapturedDecl()->setNothrow();
10394 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10395 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10396 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10397 // 1.2.2 OpenMP Language Terminology
10398 // Structured block - An executable statement with a single entry at the
10399 // top and a single exit at the bottom.
10400 // The point of exit cannot be a branch out of the structured block.
10401 // longjmp() and throw() must not violate the entry/exit criteria.
10402 CS->getCapturedDecl()->setNothrow();
10403 }
10404
10405 OMPLoopDirective::HelperExprs B;
10406 // In presence of clause 'collapse', it will define the nested loops number.
10407 unsigned NestedLoopCount =
10408 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10409 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10410 VarsWithImplicitDSA, B);
10411 if (NestedLoopCount == 0)
10412 return StmtError();
10413
10414 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10415, __extension__ __PRETTY_FUNCTION__
))
10415 "omp loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10415, __extension__ __PRETTY_FUNCTION__
))
;
10416
10417 setFunctionHasBranchProtectedScope();
10418
10419 return OMPTargetParallelGenericLoopDirective::Create(
10420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10421}
10422
10423StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10424 Stmt *AStmt,
10425 SourceLocation StartLoc,
10426 SourceLocation EndLoc) {
10427 if (!AStmt)
10428 return StmtError();
10429
10430 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10430, __extension__ __PRETTY_FUNCTION__
))
;
10431
10432 setFunctionHasBranchProtectedScope();
10433
10434 // OpenMP [2.7.3, single Construct, Restrictions]
10435 // The copyprivate clause must not be used with the nowait clause.
10436 const OMPClause *Nowait = nullptr;
10437 const OMPClause *Copyprivate = nullptr;
10438 for (const OMPClause *Clause : Clauses) {
10439 if (Clause->getClauseKind() == OMPC_nowait)
10440 Nowait = Clause;
10441 else if (Clause->getClauseKind() == OMPC_copyprivate)
10442 Copyprivate = Clause;
10443 if (Copyprivate && Nowait) {
10444 Diag(Copyprivate->getBeginLoc(),
10445 diag::err_omp_single_copyprivate_with_nowait);
10446 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10447 return StmtError();
10448 }
10449 }
10450
10451 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10452}
10453
10454StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
10455 SourceLocation StartLoc,
10456 SourceLocation EndLoc) {
10457 if (!AStmt)
10458 return StmtError();
10459
10460 setFunctionHasBranchProtectedScope();
10461
10462 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
10463}
10464
10465StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
10466 Stmt *AStmt,
10467 SourceLocation StartLoc,
10468 SourceLocation EndLoc) {
10469 if (!AStmt)
10470 return StmtError();
10471
10472 setFunctionHasBranchProtectedScope();
10473
10474 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10475}
10476
10477StmtResult Sema::ActOnOpenMPCriticalDirective(
10478 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10479 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10480 if (!AStmt)
10481 return StmtError();
10482
10483 bool ErrorFound = false;
10484 llvm::APSInt Hint;
10485 SourceLocation HintLoc;
10486 bool DependentHint = false;
10487 for (const OMPClause *C : Clauses) {
10488 if (C->getClauseKind() == OMPC_hint) {
10489 if (!DirName.getName()) {
10490 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10491 ErrorFound = true;
10492 }
10493 Expr *E = cast<OMPHintClause>(C)->getHint();
10494 if (E->isTypeDependent() || E->isValueDependent() ||
10495 E->isInstantiationDependent()) {
10496 DependentHint = true;
10497 } else {
10498 Hint = E->EvaluateKnownConstInt(Context);
10499 HintLoc = C->getBeginLoc();
10500 }
10501 }
10502 }
10503 if (ErrorFound)
10504 return StmtError();
10505 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
10506 if (Pair.first && DirName.getName() && !DependentHint) {
10507 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10508 Diag(StartLoc, diag::err_omp_critical_with_hint);
10509 if (HintLoc.isValid())
10510 Diag(HintLoc, diag::note_omp_critical_hint_here)
10511 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10512 else
10513 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10514 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10515 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10516 << 1
10517 << toString(C->getHint()->EvaluateKnownConstInt(Context),
10518 /*Radix=*/10, /*Signed=*/false);
10519 } else {
10520 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10521 }
10522 }
10523 }
10524
10525 setFunctionHasBranchProtectedScope();
10526
10527 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10528 Clauses, AStmt);
10529 if (!Pair.first && DirName.getName() && !DependentHint)
10530 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
10531 return Dir;
10532}
10533
10534StmtResult Sema::ActOnOpenMPParallelForDirective(
10535 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10536 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10537 if (!AStmt)
10538 return StmtError();
10539
10540 auto *CS = cast<CapturedStmt>(AStmt);
10541 // 1.2.2 OpenMP Language Terminology
10542 // Structured block - An executable statement with a single entry at the
10543 // top and a single exit at the bottom.
10544 // The point of exit cannot be a branch out of the structured block.
10545 // longjmp() and throw() must not violate the entry/exit criteria.
10546 CS->getCapturedDecl()->setNothrow();
10547
10548 OMPLoopBasedDirective::HelperExprs B;
10549 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10550 // define the nested loops number.
10551 unsigned NestedLoopCount =
10552 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10553 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10554 VarsWithImplicitDSA, B);
10555 if (NestedLoopCount == 0)
10556 return StmtError();
10557
10558 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10559, __extension__ __PRETTY_FUNCTION__
))
10559 "omp parallel for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10559, __extension__ __PRETTY_FUNCTION__
))
;
10560
10561 if (!CurContext->isDependentContext()) {
10562 // Finalize the clauses that need pre-built expressions for CodeGen.
10563 for (OMPClause *C : Clauses) {
10564 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10565 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10566 B.NumIterations, *this, CurScope,
10567 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10568 return StmtError();
10569 }
10570 }
10571
10572 setFunctionHasBranchProtectedScope();
10573 return OMPParallelForDirective::Create(
10574 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10575 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10576}
10577
10578StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10579 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10580 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10581 if (!AStmt)
10582 return StmtError();
10583
10584 auto *CS = cast<CapturedStmt>(AStmt);
10585 // 1.2.2 OpenMP Language Terminology
10586 // Structured block - An executable statement with a single entry at the
10587 // top and a single exit at the bottom.
10588 // The point of exit cannot be a branch out of the structured block.
10589 // longjmp() and throw() must not violate the entry/exit criteria.
10590 CS->getCapturedDecl()->setNothrow();
10591
10592 OMPLoopBasedDirective::HelperExprs B;
10593 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10594 // define the nested loops number.
10595 unsigned NestedLoopCount =
10596 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10597 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10598 VarsWithImplicitDSA, B);
10599 if (NestedLoopCount == 0)
10600 return StmtError();
10601
10602 if (!CurContext->isDependentContext()) {
10603 // Finalize the clauses that need pre-built expressions for CodeGen.
10604 for (OMPClause *C : Clauses) {
10605 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10606 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10607 B.NumIterations, *this, CurScope,
10608 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10609 return StmtError();
10610 }
10611 }
10612
10613 if (checkSimdlenSafelenSpecified(*this, Clauses))
10614 return StmtError();
10615
10616 setFunctionHasBranchProtectedScope();
10617 return OMPParallelForSimdDirective::Create(
10618 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10619}
10620
10621StmtResult
10622Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10623 Stmt *AStmt, SourceLocation StartLoc,
10624 SourceLocation EndLoc) {
10625 if (!AStmt)
10626 return StmtError();
10627
10628 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10628, __extension__ __PRETTY_FUNCTION__
))
;
10629 auto *CS = cast<CapturedStmt>(AStmt);
10630 // 1.2.2 OpenMP Language Terminology
10631 // Structured block - An executable statement with a single entry at the
10632 // top and a single exit at the bottom.
10633 // The point of exit cannot be a branch out of the structured block.
10634 // longjmp() and throw() must not violate the entry/exit criteria.
10635 CS->getCapturedDecl()->setNothrow();
10636
10637 setFunctionHasBranchProtectedScope();
10638
10639 return OMPParallelMasterDirective::Create(
10640 Context, StartLoc, EndLoc, Clauses, AStmt,
10641 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10642}
10643
10644StmtResult
10645Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10646 Stmt *AStmt, SourceLocation StartLoc,
10647 SourceLocation EndLoc) {
10648 if (!AStmt)
10649 return StmtError();
10650
10651 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10651, __extension__ __PRETTY_FUNCTION__
))
;
10652 auto BaseStmt = AStmt;
10653 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10654 BaseStmt = CS->getCapturedStmt();
10655 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10656 auto S = C->children();
10657 if (S.begin() == S.end())
10658 return StmtError();
10659 // All associated statements must be '#pragma omp section' except for
10660 // the first one.
10661 for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10662 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10663 if (SectionStmt)
10664 Diag(SectionStmt->getBeginLoc(),
10665 diag::err_omp_parallel_sections_substmt_not_section);
10666 return StmtError();
10667 }
10668 cast<OMPSectionDirective>(SectionStmt)
10669 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10670 }
10671 } else {
10672 Diag(AStmt->getBeginLoc(),
10673 diag::err_omp_parallel_sections_not_compound_stmt);
10674 return StmtError();
10675 }
10676
10677 setFunctionHasBranchProtectedScope();
10678
10679 return OMPParallelSectionsDirective::Create(
10680 Context, StartLoc, EndLoc, Clauses, AStmt,
10681 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10682}
10683
10684/// Find and diagnose mutually exclusive clause kinds.
10685static bool checkMutuallyExclusiveClauses(
10686 Sema &S, ArrayRef<OMPClause *> Clauses,
10687 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10688 const OMPClause *PrevClause = nullptr;
10689 bool ErrorFound = false;
10690 for (const OMPClause *C : Clauses) {
10691 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10692 if (!PrevClause) {
10693 PrevClause = C;
10694 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10695 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10696 << getOpenMPClauseName(C->getClauseKind())
10697 << getOpenMPClauseName(PrevClause->getClauseKind());
10698 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10699 << getOpenMPClauseName(PrevClause->getClauseKind());
10700 ErrorFound = true;
10701 }
10702 }
10703 }
10704 return ErrorFound;
10705}
10706
10707StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10708 Stmt *AStmt, SourceLocation StartLoc,
10709 SourceLocation EndLoc) {
10710 if (!AStmt)
10711 return StmtError();
10712
10713 // OpenMP 5.0, 2.10.1 task Construct
10714 // If a detach clause appears on the directive, then a mergeable clause cannot
10715 // appear on the same directive.
10716 if (checkMutuallyExclusiveClauses(*this, Clauses,
10717 {OMPC_detach, OMPC_mergeable}))
10718 return StmtError();
10719
10720 auto *CS = cast<CapturedStmt>(AStmt);
10721 // 1.2.2 OpenMP Language Terminology
10722 // Structured block - An executable statement with a single entry at the
10723 // top and a single exit at the bottom.
10724 // The point of exit cannot be a branch out of the structured block.
10725 // longjmp() and throw() must not violate the entry/exit criteria.
10726 CS->getCapturedDecl()->setNothrow();
10727
10728 setFunctionHasBranchProtectedScope();
10729
10730 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10731 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10732}
10733
10734StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10735 SourceLocation EndLoc) {
10736 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10737}
10738
10739StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10740 SourceLocation EndLoc) {
10741 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10742}
10743
10744StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
10745 SourceLocation StartLoc,
10746 SourceLocation EndLoc) {
10747 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
10748}
10749
10750StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10751 Stmt *AStmt,
10752 SourceLocation StartLoc,
10753 SourceLocation EndLoc) {
10754 if (!AStmt)
10755 return StmtError();
10756
10757 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10757, __extension__ __PRETTY_FUNCTION__
))
;
10758
10759 setFunctionHasBranchProtectedScope();
10760
10761 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10762 AStmt,
10763 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10764}
10765
10766StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10767 SourceLocation StartLoc,
10768 SourceLocation EndLoc) {
10769 OMPFlushClause *FC = nullptr;
10770 OMPClause *OrderClause = nullptr;
10771 for (OMPClause *C : Clauses) {
10772 if (C->getClauseKind() == OMPC_flush)
10773 FC = cast<OMPFlushClause>(C);
10774 else
10775 OrderClause = C;
10776 }
10777 OpenMPClauseKind MemOrderKind = OMPC_unknown;
10778 SourceLocation MemOrderLoc;
10779 for (const OMPClause *C : Clauses) {
10780 if (C->getClauseKind() == OMPC_acq_rel ||
10781 C->getClauseKind() == OMPC_acquire ||
10782 C->getClauseKind() == OMPC_release) {
10783 if (MemOrderKind != OMPC_unknown) {
10784 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10785 << getOpenMPDirectiveName(OMPD_flush) << 1
10786 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10787 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10788 << getOpenMPClauseName(MemOrderKind);
10789 } else {
10790 MemOrderKind = C->getClauseKind();
10791 MemOrderLoc = C->getBeginLoc();
10792 }
10793 }
10794 }
10795 if (FC && OrderClause) {
10796 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10797 << getOpenMPClauseName(OrderClause->getClauseKind());
10798 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10799 << getOpenMPClauseName(OrderClause->getClauseKind());
10800 return StmtError();
10801 }
10802 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10803}
10804
10805StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10806 SourceLocation StartLoc,
10807 SourceLocation EndLoc) {
10808 if (Clauses.empty()) {
10809 Diag(StartLoc, diag::err_omp_depobj_expected);
10810 return StmtError();
10811 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10812 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10813 return StmtError();
10814 }
10815 // Only depobj expression and another single clause is allowed.
10816 if (Clauses.size() > 2) {
10817 Diag(Clauses[2]->getBeginLoc(),
10818 diag::err_omp_depobj_single_clause_expected);
10819 return StmtError();
10820 } else if (Clauses.size() < 1) {
10821 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10822 return StmtError();
10823 }
10824 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10825}
10826
10827StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10828 SourceLocation StartLoc,
10829 SourceLocation EndLoc) {
10830 // Check that exactly one clause is specified.
10831 if (Clauses.size() != 1) {
10832 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10833 diag::err_omp_scan_single_clause_expected);
10834 return StmtError();
10835 }
10836 // Check that scan directive is used in the scopeof the OpenMP loop body.
10837 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
10838 Scope *ParentS = S->getParent();
10839 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10840 !ParentS->getBreakParent()->isOpenMPLoopScope())
10841 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10842 << getOpenMPDirectiveName(OMPD_scan) << 5);
10843 }
10844 // Check that only one instance of scan directives is used in the same outer
10845 // region.
10846 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
10847 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10848 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
10849 diag::note_omp_previous_directive)
10850 << "scan";
10851 return StmtError();
10852 }
10853 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
10854 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10855}
10856
10857StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10858 Stmt *AStmt,
10859 SourceLocation StartLoc,
10860 SourceLocation EndLoc) {
10861 const OMPClause *DependFound = nullptr;
10862 const OMPClause *DependSourceClause = nullptr;
10863 const OMPClause *DependSinkClause = nullptr;
10864 bool ErrorFound = false;
10865 const OMPThreadsClause *TC = nullptr;
10866 const OMPSIMDClause *SC = nullptr;
10867 for (const OMPClause *C : Clauses) {
10868 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10869 DependFound = C;
10870 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10871 if (DependSourceClause) {
10872 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10873 << getOpenMPDirectiveName(OMPD_ordered)
10874 << getOpenMPClauseName(OMPC_depend) << 2;
10875 ErrorFound = true;
10876 } else {
10877 DependSourceClause = C;
10878 }
10879 if (DependSinkClause) {
10880 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10881 << 0;
10882 ErrorFound = true;
10883 }
10884 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10885 if (DependSourceClause) {
10886 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10887 << 1;
10888 ErrorFound = true;
10889 }
10890 DependSinkClause = C;
10891 }
10892 } else if (C->getClauseKind() == OMPC_threads) {
10893 TC = cast<OMPThreadsClause>(C);
10894 } else if (C->getClauseKind() == OMPC_simd) {
10895 SC = cast<OMPSIMDClause>(C);
10896 }
10897 }
10898 if (!ErrorFound && !SC &&
10899 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
10900 // OpenMP [2.8.1,simd Construct, Restrictions]
10901 // An ordered construct with the simd clause is the only OpenMP construct
10902 // that can appear in the simd region.
10903 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10904 << (LangOpts.OpenMP >= 50 ? 1 : 0);
10905 ErrorFound = true;
10906 } else if (DependFound && (TC || SC)) {
10907 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10908 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10909 ErrorFound = true;
10910 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10911 Diag(DependFound->getBeginLoc(),
10912 diag::err_omp_ordered_directive_without_param);
10913 ErrorFound = true;
10914 } else if (TC || Clauses.empty()) {
10915 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
10916 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10917 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10918 << (TC != nullptr);
10919 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10920 ErrorFound = true;
10921 }
10922 }
10923 if ((!AStmt && !DependFound) || ErrorFound)
10924 return StmtError();
10925
10926 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10927 // During execution of an iteration of a worksharing-loop or a loop nest
10928 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10929 // must not execute more than one ordered region corresponding to an ordered
10930 // construct without a depend clause.
10931 if (!DependFound) {
10932 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
10933 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10934 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
10935 diag::note_omp_previous_directive)
10936 << "ordered";
10937 return StmtError();
10938 }
10939 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
10940 }
10941
10942 if (AStmt) {
10943 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 10943, __extension__ __PRETTY_FUNCTION__
))
;
10944
10945 setFunctionHasBranchProtectedScope();
10946 }
10947
10948 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10949}
10950
10951namespace {
10952/// Helper class for checking expression in 'omp atomic [update]'
10953/// construct.
10954class OpenMPAtomicUpdateChecker {
10955 /// Error results for atomic update expressions.
10956 enum ExprAnalysisErrorCode {
10957 /// A statement is not an expression statement.
10958 NotAnExpression,
10959 /// Expression is not builtin binary or unary operation.
10960 NotABinaryOrUnaryExpression,
10961 /// Unary operation is not post-/pre- increment/decrement operation.
10962 NotAnUnaryIncDecExpression,
10963 /// An expression is not of scalar type.
10964 NotAScalarType,
10965 /// A binary operation is not an assignment operation.
10966 NotAnAssignmentOp,
10967 /// RHS part of the binary operation is not a binary expression.
10968 NotABinaryExpression,
10969 /// RHS part is not additive/multiplicative/shift/biwise binary
10970 /// expression.
10971 NotABinaryOperator,
10972 /// RHS binary operation does not have reference to the updated LHS
10973 /// part.
10974 NotAnUpdateExpression,
10975 /// No errors is found.
10976 NoError
10977 };
10978 /// Reference to Sema.
10979 Sema &SemaRef;
10980 /// A location for note diagnostics (when error is found).
10981 SourceLocation NoteLoc;
10982 /// 'x' lvalue part of the source atomic expression.
10983 Expr *X;
10984 /// 'expr' rvalue part of the source atomic expression.
10985 Expr *E;
10986 /// Helper expression of the form
10987 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10988 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10989 Expr *UpdateExpr;
10990 /// Is 'x' a LHS in a RHS part of full update expression. It is
10991 /// important for non-associative operations.
10992 bool IsXLHSInRHSPart;
10993 BinaryOperatorKind Op;
10994 SourceLocation OpLoc;
10995 /// true if the source expression is a postfix unary operation, false
10996 /// if it is a prefix unary operation.
10997 bool IsPostfixUpdate;
10998
10999public:
11000 OpenMPAtomicUpdateChecker(Sema &SemaRef)
11001 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11002 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11003 /// Check specified statement that it is suitable for 'atomic update'
11004 /// constructs and extract 'x', 'expr' and Operation from the original
11005 /// expression. If DiagId and NoteId == 0, then only check is performed
11006 /// without error notification.
11007 /// \param DiagId Diagnostic which should be emitted if error is found.
11008 /// \param NoteId Diagnostic note for the main error message.
11009 /// \return true if statement is not an update expression, false otherwise.
11010 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11011 /// Return the 'x' lvalue part of the source atomic expression.
11012 Expr *getX() const { return X; }
11013 /// Return the 'expr' rvalue part of the source atomic expression.
11014 Expr *getExpr() const { return E; }
11015 /// Return the update expression used in calculation of the updated
11016 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11017 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11018 Expr *getUpdateExpr() const { return UpdateExpr; }
11019 /// Return true if 'x' is LHS in RHS part of full update expression,
11020 /// false otherwise.
11021 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11022
11023 /// true if the source expression is a postfix unary operation, false
11024 /// if it is a prefix unary operation.
11025 bool isPostfixUpdate() const { return IsPostfixUpdate; }
11026
11027private:
11028 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11029 unsigned NoteId = 0);
11030};
11031
11032bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11033 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11034 ExprAnalysisErrorCode ErrorFound = NoError;
11035 SourceLocation ErrorLoc, NoteLoc;
11036 SourceRange ErrorRange, NoteRange;
11037 // Allowed constructs are:
11038 // x = x binop expr;
11039 // x = expr binop x;
11040 if (AtomicBinOp->getOpcode() == BO_Assign) {
11041 X = AtomicBinOp->getLHS();
11042 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11043 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11044 if (AtomicInnerBinOp->isMultiplicativeOp() ||
11045 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11046 AtomicInnerBinOp->isBitwiseOp()) {
11047 Op = AtomicInnerBinOp->getOpcode();
11048 OpLoc = AtomicInnerBinOp->getOperatorLoc();
11049 Expr *LHS = AtomicInnerBinOp->getLHS();
11050 Expr *RHS = AtomicInnerBinOp->getRHS();
11051 llvm::FoldingSetNodeID XId, LHSId, RHSId;
11052 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11053 /*Canonical=*/true);
11054 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11055 /*Canonical=*/true);
11056 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11057 /*Canonical=*/true);
11058 if (XId == LHSId) {
11059 E = RHS;
11060 IsXLHSInRHSPart = true;
11061 } else if (XId == RHSId) {
11062 E = LHS;
11063 IsXLHSInRHSPart = false;
11064 } else {
11065 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11066 ErrorRange = AtomicInnerBinOp->getSourceRange();
11067 NoteLoc = X->getExprLoc();
11068 NoteRange = X->getSourceRange();
11069 ErrorFound = NotAnUpdateExpression;
11070 }
11071 } else {
11072 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11073 ErrorRange = AtomicInnerBinOp->getSourceRange();
11074 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11075 NoteRange = SourceRange(NoteLoc, NoteLoc);
11076 ErrorFound = NotABinaryOperator;
11077 }
11078 } else {
11079 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11080 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11081 ErrorFound = NotABinaryExpression;
11082 }
11083 } else {
11084 ErrorLoc = AtomicBinOp->getExprLoc();
11085 ErrorRange = AtomicBinOp->getSourceRange();
11086 NoteLoc = AtomicBinOp->getOperatorLoc();
11087 NoteRange = SourceRange(NoteLoc, NoteLoc);
11088 ErrorFound = NotAnAssignmentOp;
11089 }
11090 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11091 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11092 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11093 return true;
11094 }
11095 if (SemaRef.CurContext->isDependentContext())
11096 E = X = UpdateExpr = nullptr;
11097 return ErrorFound != NoError;
11098}
11099
11100bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11101 unsigned NoteId) {
11102 ExprAnalysisErrorCode ErrorFound = NoError;
11103 SourceLocation ErrorLoc, NoteLoc;
11104 SourceRange ErrorRange, NoteRange;
11105 // Allowed constructs are:
11106 // x++;
11107 // x--;
11108 // ++x;
11109 // --x;
11110 // x binop= expr;
11111 // x = x binop expr;
11112 // x = expr binop x;
11113 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11114 AtomicBody = AtomicBody->IgnoreParenImpCasts();
11115 if (AtomicBody->getType()->isScalarType() ||
11116 AtomicBody->isInstantiationDependent()) {
11117 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11118 AtomicBody->IgnoreParenImpCasts())) {
11119 // Check for Compound Assignment Operation
11120 Op = BinaryOperator::getOpForCompoundAssignment(
11121 AtomicCompAssignOp->getOpcode());
11122 OpLoc = AtomicCompAssignOp->getOperatorLoc();
11123 E = AtomicCompAssignOp->getRHS();
11124 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11125 IsXLHSInRHSPart = true;
11126 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11127 AtomicBody->IgnoreParenImpCasts())) {
11128 // Check for Binary Operation
11129 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11130 return true;
11131 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11132 AtomicBody->IgnoreParenImpCasts())) {
11133 // Check for Unary Operation
11134 if (AtomicUnaryOp->isIncrementDecrementOp()) {
11135 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11136 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11137 OpLoc = AtomicUnaryOp->getOperatorLoc();
11138 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11139 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11140 IsXLHSInRHSPart = true;
11141 } else {
11142 ErrorFound = NotAnUnaryIncDecExpression;
11143 ErrorLoc = AtomicUnaryOp->getExprLoc();
11144 ErrorRange = AtomicUnaryOp->getSourceRange();
11145 NoteLoc = AtomicUnaryOp->getOperatorLoc();
11146 NoteRange = SourceRange(NoteLoc, NoteLoc);
11147 }
11148 } else if (!AtomicBody->isInstantiationDependent()) {
11149 ErrorFound = NotABinaryOrUnaryExpression;
11150 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11151 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11152 }
11153 } else {
11154 ErrorFound = NotAScalarType;
11155 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11156 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11157 }
11158 } else {
11159 ErrorFound = NotAnExpression;
11160 NoteLoc = ErrorLoc = S->getBeginLoc();
11161 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11162 }
11163 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11164 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11165 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11166 return true;
11167 }
11168 if (SemaRef.CurContext->isDependentContext())
11169 E = X = UpdateExpr = nullptr;
11170 if (ErrorFound == NoError && E && X) {
11171 // Build an update expression of form 'OpaqueValueExpr(x) binop
11172 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11173 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11174 auto *OVEX = new (SemaRef.getASTContext())
11175 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11176 auto *OVEExpr = new (SemaRef.getASTContext())
11177 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11178 ExprResult Update =
11179 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11180 IsXLHSInRHSPart ? OVEExpr : OVEX);
11181 if (Update.isInvalid())
11182 return true;
11183 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11184 Sema::AA_Casting);
11185 if (Update.isInvalid())
11186 return true;
11187 UpdateExpr = Update.get();
11188 }
11189 return ErrorFound != NoError;
11190}
11191
11192/// Get the node id of the fixed point of an expression \a S.
11193llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11194 llvm::FoldingSetNodeID Id;
11195 S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11196 return Id;
11197}
11198
11199/// Check if two expressions are same.
11200bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11201 const Expr *RHS) {
11202 return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11203}
11204
11205class OpenMPAtomicCompareChecker {
11206public:
11207 /// All kinds of errors that can occur in `atomic compare`
11208 enum ErrorTy {
11209 /// Empty compound statement.
11210 NoStmt = 0,
11211 /// More than one statement in a compound statement.
11212 MoreThanOneStmt,
11213 /// Not an assignment binary operator.
11214 NotAnAssignment,
11215 /// Not a conditional operator.
11216 NotCondOp,
11217 /// Wrong false expr. According to the spec, 'x' should be at the false
11218 /// expression of a conditional expression.
11219 WrongFalseExpr,
11220 /// The condition of a conditional expression is not a binary operator.
11221 NotABinaryOp,
11222 /// Invalid binary operator (not <, >, or ==).
11223 InvalidBinaryOp,
11224 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11225 InvalidComparison,
11226 /// X is not a lvalue.
11227 XNotLValue,
11228 /// Not a scalar.
11229 NotScalar,
11230 /// Not an integer.
11231 NotInteger,
11232 /// 'else' statement is not expected.
11233 UnexpectedElse,
11234 /// Not an equality operator.
11235 NotEQ,
11236 /// Invalid assignment (not v == x).
11237 InvalidAssignment,
11238 /// Not if statement
11239 NotIfStmt,
11240 /// More than two statements in a compund statement.
11241 MoreThanTwoStmts,
11242 /// Not a compound statement.
11243 NotCompoundStmt,
11244 /// No else statement.
11245 NoElse,
11246 /// Not 'if (r)'.
11247 InvalidCondition,
11248 /// No error.
11249 NoError,
11250 };
11251
11252 struct ErrorInfoTy {
11253 ErrorTy Error;
11254 SourceLocation ErrorLoc;
11255 SourceRange ErrorRange;
11256 SourceLocation NoteLoc;
11257 SourceRange NoteRange;
11258 };
11259
11260 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11261
11262 /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11263 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11264
11265 Expr *getX() const { return X; }
11266 Expr *getE() const { return E; }
11267 Expr *getD() const { return D; }
11268 Expr *getCond() const { return C; }
11269 bool isXBinopExpr() const { return IsXBinopExpr; }
11270
11271protected:
11272 /// Reference to ASTContext
11273 ASTContext &ContextRef;
11274 /// 'x' lvalue part of the source atomic expression.
11275 Expr *X = nullptr;
11276 /// 'expr' or 'e' rvalue part of the source atomic expression.
11277 Expr *E = nullptr;
11278 /// 'd' rvalue part of the source atomic expression.
11279 Expr *D = nullptr;
11280 /// 'cond' part of the source atomic expression. It is in one of the following
11281 /// forms:
11282 /// expr ordop x
11283 /// x ordop expr
11284 /// x == e
11285 /// e == x
11286 Expr *C = nullptr;
11287 /// True if the cond expr is in the form of 'x ordop expr'.
11288 bool IsXBinopExpr = true;
11289
11290 /// Check if it is a valid conditional update statement (cond-update-stmt).
11291 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11292
11293 /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11294 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11295
11296 /// Check if all captured values have right type.
11297 bool checkType(ErrorInfoTy &ErrorInfo) const;
11298
11299 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11300 bool ShouldBeLValue) {
11301 if (ShouldBeLValue && !E->isLValue()) {
11302 ErrorInfo.Error = ErrorTy::XNotLValue;
11303 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11304 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11305 return false;
11306 }
11307
11308 if (!E->isInstantiationDependent()) {
11309 QualType QTy = E->getType();
11310 if (!QTy->isScalarType()) {
11311 ErrorInfo.Error = ErrorTy::NotScalar;
11312 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11313 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11314 return false;
11315 }
11316
11317 if (!QTy->isIntegerType()) {
11318 ErrorInfo.Error = ErrorTy::NotInteger;
11319 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11320 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11321 return false;
11322 }
11323 }
11324
11325 return true;
11326 }
11327};
11328
11329bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11330 ErrorInfoTy &ErrorInfo) {
11331 auto *Then = S->getThen();
11332 if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11333 if (CS->body_empty()) {
11334 ErrorInfo.Error = ErrorTy::NoStmt;
11335 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11336 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11337 return false;
11338 }
11339 if (CS->size() > 1) {
11340 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11341 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11342 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11343 return false;
11344 }
11345 Then = CS->body_front();
11346 }
11347
11348 auto *BO = dyn_cast<BinaryOperator>(Then);
11349 if (!BO) {
11350 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11351 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11352 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11353 return false;
11354 }
11355 if (BO->getOpcode() != BO_Assign) {
11356 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11357 ErrorInfo.ErrorLoc = BO->getExprLoc();
11358 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11359 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11360 return false;
11361 }
11362
11363 X = BO->getLHS();
11364
11365 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11366 if (!Cond) {
11367 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11368 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11369 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11370 return false;
11371 }
11372
11373 switch (Cond->getOpcode()) {
11374 case BO_EQ: {
11375 C = Cond;
11376 D = BO->getRHS()->IgnoreImpCasts();
11377 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11378 E = Cond->getRHS()->IgnoreImpCasts();
11379 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11380 E = Cond->getLHS()->IgnoreImpCasts();
11381 } else {
11382 ErrorInfo.Error = ErrorTy::InvalidComparison;
11383 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11384 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11385 return false;
11386 }
11387 break;
11388 }
11389 case BO_LT:
11390 case BO_GT: {
11391 E = BO->getRHS()->IgnoreImpCasts();
11392 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11393 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11394 C = Cond;
11395 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11396 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11397 C = Cond;
11398 IsXBinopExpr = false;
11399 } else {
11400 ErrorInfo.Error = ErrorTy::InvalidComparison;
11401 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11402 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11403 return false;
11404 }
11405 break;
11406 }
11407 default:
11408 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11409 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11410 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11411 return false;
11412 }
11413
11414 if (S->getElse()) {
11415 ErrorInfo.Error = ErrorTy::UnexpectedElse;
11416 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11417 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11418 return false;
11419 }
11420
11421 return true;
11422}
11423
11424bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11425 ErrorInfoTy &ErrorInfo) {
11426 auto *BO = dyn_cast<BinaryOperator>(S);
11427 if (!BO) {
11428 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11429 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11430 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11431 return false;
11432 }
11433 if (BO->getOpcode() != BO_Assign) {
11434 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11435 ErrorInfo.ErrorLoc = BO->getExprLoc();
11436 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11437 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11438 return false;
11439 }
11440
11441 X = BO->getLHS();
11442
11443 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11444 if (!CO) {
11445 ErrorInfo.Error = ErrorTy::NotCondOp;
11446 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11447 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11448 return false;
11449 }
11450
11451 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11452 ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11453 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11454 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11455 CO->getFalseExpr()->getSourceRange();
11456 return false;
11457 }
11458
11459 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11460 if (!Cond) {
11461 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11462 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11463 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11464 CO->getCond()->getSourceRange();
11465 return false;
11466 }
11467
11468 switch (Cond->getOpcode()) {
11469 case BO_EQ: {
11470 C = Cond;
11471 D = CO->getTrueExpr()->IgnoreImpCasts();
11472 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11473 E = Cond->getRHS()->IgnoreImpCasts();
11474 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11475 E = Cond->getLHS()->IgnoreImpCasts();
11476 } else {
11477 ErrorInfo.Error = ErrorTy::InvalidComparison;
11478 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11479 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11480 return false;
11481 }
11482 break;
11483 }
11484 case BO_LT:
11485 case BO_GT: {
11486 E = CO->getTrueExpr()->IgnoreImpCasts();
11487 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11488 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11489 C = Cond;
11490 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11491 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11492 C = Cond;
11493 IsXBinopExpr = false;
11494 } else {
11495 ErrorInfo.Error = ErrorTy::InvalidComparison;
11496 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11497 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11498 return false;
11499 }
11500 break;
11501 }
11502 default:
11503 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11504 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11505 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11506 return false;
11507 }
11508
11509 return true;
11510}
11511
11512bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11513 // 'x' and 'e' cannot be nullptr
11514 assert(X && E && "X and E cannot be nullptr")(static_cast <bool> (X && E && "X and E cannot be nullptr"
) ? void (0) : __assert_fail ("X && E && \"X and E cannot be nullptr\""
, "clang/lib/Sema/SemaOpenMP.cpp", 11514, __extension__ __PRETTY_FUNCTION__
))
;
11515
11516 if (!CheckValue(X, ErrorInfo, true))
11517 return false;
11518
11519 if (!CheckValue(E, ErrorInfo, false))
11520 return false;
11521
11522 if (D && !CheckValue(D, ErrorInfo, false))
11523 return false;
11524
11525 return true;
11526}
11527
11528bool OpenMPAtomicCompareChecker::checkStmt(
11529 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11530 auto *CS = dyn_cast<CompoundStmt>(S);
11531 if (CS) {
11532 if (CS->body_empty()) {
11533 ErrorInfo.Error = ErrorTy::NoStmt;
11534 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11535 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11536 return false;
11537 }
11538
11539 if (CS->size() != 1) {
11540 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11541 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11542 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11543 return false;
11544 }
11545 S = CS->body_front();
11546 }
11547
11548 auto Res = false;
11549
11550 if (auto *IS = dyn_cast<IfStmt>(S)) {
11551 // Check if the statement is in one of the following forms
11552 // (cond-update-stmt):
11553 // if (expr ordop x) { x = expr; }
11554 // if (x ordop expr) { x = expr; }
11555 // if (x == e) { x = d; }
11556 Res = checkCondUpdateStmt(IS, ErrorInfo);
11557 } else {
11558 // Check if the statement is in one of the following forms (cond-expr-stmt):
11559 // x = expr ordop x ? expr : x;
11560 // x = x ordop expr ? expr : x;
11561 // x = x == e ? d : x;
11562 Res = checkCondExprStmt(S, ErrorInfo);
11563 }
11564
11565 if (!Res)
11566 return false;
11567
11568 return checkType(ErrorInfo);
11569}
11570
11571class OpenMPAtomicCompareCaptureChecker final
11572 : public OpenMPAtomicCompareChecker {
11573public:
11574 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
11575
11576 Expr *getV() const { return V; }
11577 Expr *getR() const { return R; }
11578 bool isFailOnly() const { return IsFailOnly; }
11579
11580 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11581 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11582
11583private:
11584 bool checkType(ErrorInfoTy &ErrorInfo);
11585
11586 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
11587 // form of 'conditional-update-capture-atomic' structured block on the v5.2
11588 // spec p.p. 82:
11589 // (1) { v = x; cond-update-stmt }
11590 // (2) { cond-update-stmt v = x; }
11591 // (3) if(x == e) { x = d; } else { v = x; }
11592 // (4) { r = x == e; if(r) { x = d; } }
11593 // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
11594
11595 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
11596 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
11597
11598 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
11599 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
11600 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
11601
11602 /// 'v' lvalue part of the source atomic expression.
11603 Expr *V = nullptr;
11604 /// 'r' lvalue part of the source atomic expression.
11605 Expr *R = nullptr;
11606 /// If 'v' is only updated when the comparison fails.
11607 bool IsFailOnly = false;
11608};
11609
11610bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
11611 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
11612 return false;
11613
11614 if (V && !CheckValue(V, ErrorInfo, true))
11615 return false;
11616
11617 if (R && !CheckValue(R, ErrorInfo, true))
11618 return false;
11619
11620 return true;
11621}
11622
11623bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
11624 ErrorInfoTy &ErrorInfo) {
11625 IsFailOnly = true;
11626
11627 auto *Then = S->getThen();
11628 if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11629 if (CS->body_empty()) {
11630 ErrorInfo.Error = ErrorTy::NoStmt;
11631 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11632 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11633 return false;
11634 }
11635 if (CS->size() > 1) {
11636 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11637 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11638 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11639 return false;
11640 }
11641 Then = CS->body_front();
11642 }
11643
11644 auto *BO = dyn_cast<BinaryOperator>(Then);
11645 if (!BO) {
11646 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11647 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11648 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11649 return false;
11650 }
11651 if (BO->getOpcode() != BO_Assign) {
11652 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11653 ErrorInfo.ErrorLoc = BO->getExprLoc();
11654 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11655 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11656 return false;
11657 }
11658
11659 X = BO->getLHS();
11660 D = BO->getRHS();
11661
11662 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11663 if (!Cond) {
11664 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11665 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11666 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11667 return false;
11668 }
11669 if (Cond->getOpcode() != BO_EQ) {
11670 ErrorInfo.Error = ErrorTy::NotEQ;
11671 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11672 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11673 return false;
11674 }
11675
11676 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11677 E = Cond->getRHS();
11678 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11679 E = Cond->getLHS();
11680 } else {
11681 ErrorInfo.Error = ErrorTy::InvalidComparison;
11682 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11683 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11684 return false;
11685 }
11686
11687 C = Cond;
11688
11689 if (!S->getElse()) {
11690 ErrorInfo.Error = ErrorTy::NoElse;
11691 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11692 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11693 return false;
11694 }
11695
11696 auto *Else = S->getElse();
11697 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
11698 if (CS->body_empty()) {
11699 ErrorInfo.Error = ErrorTy::NoStmt;
11700 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11701 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11702 return false;
11703 }
11704 if (CS->size() > 1) {
11705 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11706 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11707 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11708 return false;
11709 }
11710 Else = CS->body_front();
11711 }
11712
11713 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11714 if (!ElseBO) {
11715 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11716 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11717 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11718 return false;
11719 }
11720 if (ElseBO->getOpcode() != BO_Assign) {
11721 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11722 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11723 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
11724 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
11725 return false;
11726 }
11727
11728 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
11729 ErrorInfo.Error = ErrorTy::InvalidAssignment;
11730 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
11731 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11732 ElseBO->getRHS()->getSourceRange();
11733 return false;
11734 }
11735
11736 V = ElseBO->getLHS();
11737
11738 return checkType(ErrorInfo);
11739}
11740
11741bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
11742 ErrorInfoTy &ErrorInfo) {
11743 // We don't check here as they should be already done before call this
11744 // function.
11745 auto *CS = cast<CompoundStmt>(S);
11746 assert(CS->size() == 2 && "CompoundStmt size is not expected")(static_cast <bool> (CS->size() == 2 && "CompoundStmt size is not expected"
) ? void (0) : __assert_fail ("CS->size() == 2 && \"CompoundStmt size is not expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 11746, __extension__ __PRETTY_FUNCTION__
))
;
11747 auto *S1 = cast<BinaryOperator>(CS->body_front());
11748 auto *S2 = cast<IfStmt>(CS->body_back());
11749 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator")(static_cast <bool> (S1->getOpcode() == BO_Assign &&
"unexpected binary operator") ? void (0) : __assert_fail ("S1->getOpcode() == BO_Assign && \"unexpected binary operator\""
, "clang/lib/Sema/SemaOpenMP.cpp", 11749, __extension__ __PRETTY_FUNCTION__
))
;
11750
11751 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
11752 ErrorInfo.Error = ErrorTy::InvalidCondition;
11753 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
11754 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
11755 return false;
11756 }
11757
11758 R = S1->getLHS();
11759
11760 auto *Then = S2->getThen();
11761 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
11762 if (ThenCS->body_empty()) {
11763 ErrorInfo.Error = ErrorTy::NoStmt;
11764 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
11765 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
11766 return false;
11767 }
11768 if (ThenCS->size() > 1) {
11769 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11770 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
11771 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
11772 return false;
11773 }
11774 Then = ThenCS->body_front();
11775 }
11776
11777 auto *ThenBO = dyn_cast<BinaryOperator>(Then);
11778 if (!ThenBO) {
11779 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11780 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
11781 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
11782 return false;
11783 }
11784 if (ThenBO->getOpcode() != BO_Assign) {
11785 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11786 ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
11787 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
11788 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
11789 return false;
11790 }
11791
11792 X = ThenBO->getLHS();
11793 D = ThenBO->getRHS();
11794
11795 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
11796 if (BO->getOpcode() != BO_EQ) {
11797 ErrorInfo.Error = ErrorTy::NotEQ;
11798 ErrorInfo.ErrorLoc = BO->getExprLoc();
11799 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11800 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11801 return false;
11802 }
11803
11804 C = BO;
11805
11806 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
11807 E = BO->getRHS();
11808 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
11809 E = BO->getLHS();
11810 } else {
11811 ErrorInfo.Error = ErrorTy::InvalidComparison;
11812 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
11813 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11814 return false;
11815 }
11816
11817 if (S2->getElse()) {
11818 IsFailOnly = true;
11819
11820 auto *Else = S2->getElse();
11821 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
11822 if (ElseCS->body_empty()) {
11823 ErrorInfo.Error = ErrorTy::NoStmt;
11824 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
11825 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
11826 return false;
11827 }
11828 if (ElseCS->size() > 1) {
11829 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11830 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
11831 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
11832 return false;
11833 }
11834 Else = ElseCS->body_front();
11835 }
11836
11837 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11838 if (!ElseBO) {
11839 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11840 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11841 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11842 return false;
11843 }
11844 if (ElseBO->getOpcode() != BO_Assign) {
11845 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11846 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11847 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
11848 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
11849 return false;
11850 }
11851 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
11852 ErrorInfo.Error = ErrorTy::InvalidAssignment;
11853 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
11854 ErrorInfo.NoteLoc = X->getExprLoc();
11855 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
11856 ErrorInfo.NoteRange = X->getSourceRange();
11857 return false;
11858 }
11859
11860 V = ElseBO->getLHS();
11861 }
11862
11863 return checkType(ErrorInfo);
11864}
11865
11866bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
11867 ErrorInfoTy &ErrorInfo) {
11868 // if(x == e) { x = d; } else { v = x; }
11869 if (auto *IS = dyn_cast<IfStmt>(S))
11870 return checkForm3(IS, ErrorInfo);
11871
11872 auto *CS = dyn_cast<CompoundStmt>(S);
11873 if (!CS) {
11874 ErrorInfo.Error = ErrorTy::NotCompoundStmt;
11875 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11876 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11877 return false;
11878 }
11879 if (CS->body_empty()) {
11880 ErrorInfo.Error = ErrorTy::NoStmt;
11881 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11882 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11883 return false;
11884 }
11885
11886 // { if(x == e) { x = d; } else { v = x; } }
11887 if (CS->size() == 1) {
11888 auto *IS = dyn_cast<IfStmt>(CS->body_front());
11889 if (!IS) {
11890 ErrorInfo.Error = ErrorTy::NotIfStmt;
11891 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
11892 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11893 CS->body_front()->getSourceRange();
11894 return false;
11895 }
11896
11897 return checkForm3(IS, ErrorInfo);
11898 } else if (CS->size() == 2) {
11899 auto *S1 = CS->body_front();
11900 auto *S2 = CS->body_back();
11901
11902 Stmt *UpdateStmt = nullptr;
11903 Stmt *CondUpdateStmt = nullptr;
11904
11905 if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
11906 // { v = x; cond-update-stmt } or form 45.
11907 UpdateStmt = S1;
11908 CondUpdateStmt = S2;
11909 // Check if form 45.
11910 if (dyn_cast<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) &&
11911 dyn_cast<IfStmt>(S2))
11912 return checkForm45(CS, ErrorInfo);
11913 } else {
11914 // { cond-update-stmt v = x; }
11915 UpdateStmt = S2;
11916 CondUpdateStmt = S1;
11917 }
11918
11919 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
11920 auto *IS = dyn_cast<IfStmt>(CUS);
11921 if (!IS) {
11922 ErrorInfo.Error = ErrorTy::NotIfStmt;
11923 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
11924 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
11925 return false;
11926 }
11927
11928 if (!checkCondUpdateStmt(IS, ErrorInfo))
11929 return false;
11930
11931 return true;
11932 };
11933
11934 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
11935 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
11936 auto *BO = dyn_cast<BinaryOperator>(US);
11937 if (!BO) {
11938 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11939 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
11940 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
11941 return false;
11942 }
11943 if (BO->getOpcode() != BO_Assign) {
11944 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11945 ErrorInfo.ErrorLoc = BO->getExprLoc();
11946 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11947 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11948 return false;
11949 }
11950 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
11951 ErrorInfo.Error = ErrorTy::InvalidAssignment;
11952 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
11953 ErrorInfo.NoteLoc = this->X->getExprLoc();
11954 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
11955 ErrorInfo.NoteRange = this->X->getSourceRange();
11956 return false;
11957 }
11958
11959 this->V = BO->getLHS();
11960
11961 return true;
11962 };
11963
11964 if (!CheckCondUpdateStmt(CondUpdateStmt))
11965 return false;
11966 if (!CheckUpdateStmt(UpdateStmt))
11967 return false;
11968 } else {
11969 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
11970 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11971 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11972 return false;
11973 }
11974
11975 return checkType(ErrorInfo);
11976}
11977} // namespace
11978
11979StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
11980 Stmt *AStmt,
11981 SourceLocation StartLoc,
11982 SourceLocation EndLoc) {
11983 // Register location of the first atomic directive.
11984 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
11985 if (!AStmt)
11986 return StmtError();
11987
11988 // 1.2.2 OpenMP Language Terminology
11989 // Structured block - An executable statement with a single entry at the
11990 // top and a single exit at the bottom.
11991 // The point of exit cannot be a branch out of the structured block.
11992 // longjmp() and throw() must not violate the entry/exit criteria.
11993 OpenMPClauseKind AtomicKind = OMPC_unknown;
11994 SourceLocation AtomicKindLoc;
11995 OpenMPClauseKind MemOrderKind = OMPC_unknown;
11996 SourceLocation MemOrderLoc;
11997 bool MutexClauseEncountered = false;
11998 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
11999 for (const OMPClause *C : Clauses) {
12000 switch (C->getClauseKind()) {
12001 case OMPC_read:
12002 case OMPC_write:
12003 case OMPC_update:
12004 MutexClauseEncountered = true;
12005 LLVM_FALLTHROUGH[[gnu::fallthrough]];
12006 case OMPC_capture:
12007 case OMPC_compare: {
12008 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12009 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12010 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12011 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12012 << getOpenMPClauseName(AtomicKind);
12013 } else {
12014 AtomicKind = C->getClauseKind();
12015 AtomicKindLoc = C->getBeginLoc();
12016 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12017 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12018 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12019 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12020 << getOpenMPClauseName(AtomicKind);
12021 }
12022 }
12023 break;
12024 }
12025 case OMPC_seq_cst:
12026 case OMPC_acq_rel:
12027 case OMPC_acquire:
12028 case OMPC_release:
12029 case OMPC_relaxed: {
12030 if (MemOrderKind != OMPC_unknown) {
12031 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12032 << getOpenMPDirectiveName(OMPD_atomic) << 0
12033 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12034 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12035 << getOpenMPClauseName(MemOrderKind);
12036 } else {
12037 MemOrderKind = C->getClauseKind();
12038 MemOrderLoc = C->getBeginLoc();
12039 }
12040 break;
12041 }
12042 // The following clauses are allowed, but we don't need to do anything here.
12043 case OMPC_hint:
12044 break;
12045 default:
12046 llvm_unreachable("unknown clause is encountered")::llvm::llvm_unreachable_internal("unknown clause is encountered"
, "clang/lib/Sema/SemaOpenMP.cpp", 12046)
;
12047 }
12048 }
12049 bool IsCompareCapture = false;
12050 if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12051 EncounteredAtomicKinds.contains(OMPC_capture)) {
12052 IsCompareCapture = true;
12053 AtomicKind = OMPC_compare;
12054 }
12055 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12056 // If atomic-clause is read then memory-order-clause must not be acq_rel or
12057 // release.
12058 // If atomic-clause is write then memory-order-clause must not be acq_rel or
12059 // acquire.
12060 // If atomic-clause is update or not present then memory-order-clause must not
12061 // be acq_rel or acquire.
12062 if ((AtomicKind == OMPC_read &&
12063 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12064 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12065 AtomicKind == OMPC_unknown) &&
12066 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12067 SourceLocation Loc = AtomicKindLoc;
12068 if (AtomicKind == OMPC_unknown)
12069 Loc = StartLoc;
12070 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12071 << getOpenMPClauseName(AtomicKind)
12072 << (AtomicKind == OMPC_unknown ? 1 : 0)
12073 << getOpenMPClauseName(MemOrderKind);
12074 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12075 << getOpenMPClauseName(MemOrderKind);
12076 }
12077
12078 Stmt *Body = AStmt;
12079 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12080 Body = EWC->getSubExpr();
12081
12082 Expr *X = nullptr;
12083 Expr *V = nullptr;
12084 Expr *E = nullptr;
12085 Expr *UE = nullptr;
12086 Expr *D = nullptr;
12087 Expr *CE = nullptr;
12088 bool IsXLHSInRHSPart = false;
12089 bool IsPostfixUpdate = false;
12090 // OpenMP [2.12.6, atomic Construct]
12091 // In the next expressions:
12092 // * x and v (as applicable) are both l-value expressions with scalar type.
12093 // * During the execution of an atomic region, multiple syntactic
12094 // occurrences of x must designate the same storage location.
12095 // * Neither of v and expr (as applicable) may access the storage location
12096 // designated by x.
12097 // * Neither of x and expr (as applicable) may access the storage location
12098 // designated by v.
12099 // * expr is an expression with scalar type.
12100 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12101 // * binop, binop=, ++, and -- are not overloaded operators.
12102 // * The expression x binop expr must be numerically equivalent to x binop
12103 // (expr). This requirement is satisfied if the operators in expr have
12104 // precedence greater than binop, or by using parentheses around expr or
12105 // subexpressions of expr.
12106 // * The expression expr binop x must be numerically equivalent to (expr)
12107 // binop x. This requirement is satisfied if the operators in expr have
12108 // precedence equal to or greater than binop, or by using parentheses around
12109 // expr or subexpressions of expr.
12110 // * For forms that allow multiple occurrences of x, the number of times
12111 // that x is evaluated is unspecified.
12112 if (AtomicKind == OMPC_read) {
12113 enum {
12114 NotAnExpression,
12115 NotAnAssignmentOp,
12116 NotAScalarType,
12117 NotAnLValue,
12118 NoError
12119 } ErrorFound = NoError;
12120 SourceLocation ErrorLoc, NoteLoc;
12121 SourceRange ErrorRange, NoteRange;
12122 // If clause is read:
12123 // v = x;
12124 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12125 const auto *AtomicBinOp =
12126 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12127 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12128 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12129 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12130 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12131 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12132 if (!X->isLValue() || !V->isLValue()) {
12133 const Expr *NotLValueExpr = X->isLValue() ? V : X;
12134 ErrorFound = NotAnLValue;
12135 ErrorLoc = AtomicBinOp->getExprLoc();
12136 ErrorRange = AtomicBinOp->getSourceRange();
12137 NoteLoc = NotLValueExpr->getExprLoc();
12138 NoteRange = NotLValueExpr->getSourceRange();
12139 }
12140 } else if (!X->isInstantiationDependent() ||
12141 !V->isInstantiationDependent()) {
12142 const Expr *NotScalarExpr =
12143 (X->isInstantiationDependent() || X->getType()->isScalarType())
12144 ? V
12145 : X;
12146 ErrorFound = NotAScalarType;
12147 ErrorLoc = AtomicBinOp->getExprLoc();
12148 ErrorRange = AtomicBinOp->getSourceRange();
12149 NoteLoc = NotScalarExpr->getExprLoc();
12150 NoteRange = NotScalarExpr->getSourceRange();
12151 }
12152 } else if (!AtomicBody->isInstantiationDependent()) {
12153 ErrorFound = NotAnAssignmentOp;
12154 ErrorLoc = AtomicBody->getExprLoc();
12155 ErrorRange = AtomicBody->getSourceRange();
12156 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12157 : AtomicBody->getExprLoc();
12158 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12159 : AtomicBody->getSourceRange();
12160 }
12161 } else {
12162 ErrorFound = NotAnExpression;
12163 NoteLoc = ErrorLoc = Body->getBeginLoc();
12164 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12165 }
12166 if (ErrorFound != NoError) {
12167 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12168 << ErrorRange;
12169 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12170 << ErrorFound << NoteRange;
12171 return StmtError();
12172 }
12173 if (CurContext->isDependentContext())
12174 V = X = nullptr;
12175 } else if (AtomicKind == OMPC_write) {
12176 enum {
12177 NotAnExpression,
12178 NotAnAssignmentOp,
12179 NotAScalarType,
12180 NotAnLValue,
12181 NoError
12182 } ErrorFound = NoError;
12183 SourceLocation ErrorLoc, NoteLoc;
12184 SourceRange ErrorRange, NoteRange;
12185 // If clause is write:
12186 // x = expr;
12187 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12188 const auto *AtomicBinOp =
12189 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12190 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12191 X = AtomicBinOp->getLHS();
12192 E = AtomicBinOp->getRHS();
12193 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12194 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12195 if (!X->isLValue()) {
12196 ErrorFound = NotAnLValue;
12197 ErrorLoc = AtomicBinOp->getExprLoc();
12198 ErrorRange = AtomicBinOp->getSourceRange();
12199 NoteLoc = X->getExprLoc();
12200 NoteRange = X->getSourceRange();
12201 }
12202 } else if (!X->isInstantiationDependent() ||
12203 !E->isInstantiationDependent()) {
12204 const Expr *NotScalarExpr =
12205 (X->isInstantiationDependent() || X->getType()->isScalarType())
12206 ? E
12207 : X;
12208 ErrorFound = NotAScalarType;
12209 ErrorLoc = AtomicBinOp->getExprLoc();
12210 ErrorRange = AtomicBinOp->getSourceRange();
12211 NoteLoc = NotScalarExpr->getExprLoc();
12212 NoteRange = NotScalarExpr->getSourceRange();
12213 }
12214 } else if (!AtomicBody->isInstantiationDependent()) {
12215 ErrorFound = NotAnAssignmentOp;
12216 ErrorLoc = AtomicBody->getExprLoc();
12217 ErrorRange = AtomicBody->getSourceRange();
12218 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12219 : AtomicBody->getExprLoc();
12220 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12221 : AtomicBody->getSourceRange();
12222 }
12223 } else {
12224 ErrorFound = NotAnExpression;
12225 NoteLoc = ErrorLoc = Body->getBeginLoc();
12226 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12227 }
12228 if (ErrorFound != NoError) {
12229 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12230 << ErrorRange;
12231 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12232 << ErrorFound << NoteRange;
12233 return StmtError();
12234 }
12235 if (CurContext->isDependentContext())
12236 E = X = nullptr;
12237 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12238 // If clause is update:
12239 // x++;
12240 // x--;
12241 // ++x;
12242 // --x;
12243 // x binop= expr;
12244 // x = x binop expr;
12245 // x = expr binop x;
12246 OpenMPAtomicUpdateChecker Checker(*this);
12247 if (Checker.checkStatement(
12248 Body,
12249 (AtomicKind == OMPC_update)
12250 ? diag::err_omp_atomic_update_not_expression_statement
12251 : diag::err_omp_atomic_not_expression_statement,
12252 diag::note_omp_atomic_update))
12253 return StmtError();
12254 if (!CurContext->isDependentContext()) {
12255 E = Checker.getExpr();
12256 X = Checker.getX();
12257 UE = Checker.getUpdateExpr();
12258 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12259 }
12260 } else if (AtomicKind == OMPC_capture) {
12261 enum {
12262 NotAnAssignmentOp,
12263 NotACompoundStatement,
12264 NotTwoSubstatements,
12265 NotASpecificExpression,
12266 NoError
12267 } ErrorFound = NoError;
12268 SourceLocation ErrorLoc, NoteLoc;
12269 SourceRange ErrorRange, NoteRange;
12270 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12271 // If clause is a capture:
12272 // v = x++;
12273 // v = x--;
12274 // v = ++x;
12275 // v = --x;
12276 // v = x binop= expr;
12277 // v = x = x binop expr;
12278 // v = x = expr binop x;
12279 const auto *AtomicBinOp =
12280 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12281 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12282 V = AtomicBinOp->getLHS();
12283 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12284 OpenMPAtomicUpdateChecker Checker(*this);
12285 if (Checker.checkStatement(
12286 Body, diag::err_omp_atomic_capture_not_expression_statement,
12287 diag::note_omp_atomic_update))
12288 return StmtError();
12289 E = Checker.getExpr();
12290 X = Checker.getX();
12291 UE = Checker.getUpdateExpr();
12292 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12293 IsPostfixUpdate = Checker.isPostfixUpdate();
12294 } else if (!AtomicBody->isInstantiationDependent()) {
12295 ErrorLoc = AtomicBody->getExprLoc();
12296 ErrorRange = AtomicBody->getSourceRange();
12297 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12298 : AtomicBody->getExprLoc();
12299 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12300 : AtomicBody->getSourceRange();
12301 ErrorFound = NotAnAssignmentOp;
12302 }
12303 if (ErrorFound != NoError) {
12304 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12305 << ErrorRange;
12306 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12307 return StmtError();
12308 }
12309 if (CurContext->isDependentContext())
12310 UE = V = E = X = nullptr;
12311 } else {
12312 // If clause is a capture:
12313 // { v = x; x = expr; }
12314 // { v = x; x++; }
12315 // { v = x; x--; }
12316 // { v = x; ++x; }
12317 // { v = x; --x; }
12318 // { v = x; x binop= expr; }
12319 // { v = x; x = x binop expr; }
12320 // { v = x; x = expr binop x; }
12321 // { x++; v = x; }
12322 // { x--; v = x; }
12323 // { ++x; v = x; }
12324 // { --x; v = x; }
12325 // { x binop= expr; v = x; }
12326 // { x = x binop expr; v = x; }
12327 // { x = expr binop x; v = x; }
12328 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12329 // Check that this is { expr1; expr2; }
12330 if (CS->size() == 2) {
12331 Stmt *First = CS->body_front();
12332 Stmt *Second = CS->body_back();
12333 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12334 First = EWC->getSubExpr()->IgnoreParenImpCasts();
12335 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12336 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12337 // Need to find what subexpression is 'v' and what is 'x'.
12338 OpenMPAtomicUpdateChecker Checker(*this);
12339 bool IsUpdateExprFound = !Checker.checkStatement(Second);
12340 BinaryOperator *BinOp = nullptr;
12341 if (IsUpdateExprFound) {
12342 BinOp = dyn_cast<BinaryOperator>(First);
12343 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12344 }
12345 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12346 // { v = x; x++; }
12347 // { v = x; x--; }
12348 // { v = x; ++x; }
12349 // { v = x; --x; }
12350 // { v = x; x binop= expr; }
12351 // { v = x; x = x binop expr; }
12352 // { v = x; x = expr binop x; }
12353 // Check that the first expression has form v = x.
12354 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12355 llvm::FoldingSetNodeID XId, PossibleXId;
12356 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12357 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12358 IsUpdateExprFound = XId == PossibleXId;
12359 if (IsUpdateExprFound) {
12360 V = BinOp->getLHS();
12361 X = Checker.getX();
12362 E = Checker.getExpr();
12363 UE = Checker.getUpdateExpr();
12364 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12365 IsPostfixUpdate = true;
12366 }
12367 }
12368 if (!IsUpdateExprFound) {
12369 IsUpdateExprFound = !Checker.checkStatement(First);
12370 BinOp = nullptr;
12371 if (IsUpdateExprFound) {
12372 BinOp = dyn_cast<BinaryOperator>(Second);
12373 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12374 }
12375 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12376 // { x++; v = x; }
12377 // { x--; v = x; }
12378 // { ++x; v = x; }
12379 // { --x; v = x; }
12380 // { x binop= expr; v = x; }
12381 // { x = x binop expr; v = x; }
12382 // { x = expr binop x; v = x; }
12383 // Check that the second expression has form v = x.
12384 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12385 llvm::FoldingSetNodeID XId, PossibleXId;
12386 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12387 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12388 IsUpdateExprFound = XId == PossibleXId;
12389 if (IsUpdateExprFound) {
12390 V = BinOp->getLHS();
12391 X = Checker.getX();
12392 E = Checker.getExpr();
12393 UE = Checker.getUpdateExpr();
12394 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12395 IsPostfixUpdate = false;
12396 }
12397 }
12398 }
12399 if (!IsUpdateExprFound) {
12400 // { v = x; x = expr; }
12401 auto *FirstExpr = dyn_cast<Expr>(First);
12402 auto *SecondExpr = dyn_cast<Expr>(Second);
12403 if (!FirstExpr || !SecondExpr ||
12404 !(FirstExpr->isInstantiationDependent() ||
12405 SecondExpr->isInstantiationDependent())) {
12406 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12407 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12408 ErrorFound = NotAnAssignmentOp;
12409 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12410 : First->getBeginLoc();
12411 NoteRange = ErrorRange = FirstBinOp
12412 ? FirstBinOp->getSourceRange()
12413 : SourceRange(ErrorLoc, ErrorLoc);
12414 } else {
12415 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12416 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12417 ErrorFound = NotAnAssignmentOp;
12418 NoteLoc = ErrorLoc = SecondBinOp
12419 ? SecondBinOp->getOperatorLoc()
12420 : Second->getBeginLoc();
12421 NoteRange = ErrorRange =
12422 SecondBinOp ? SecondBinOp->getSourceRange()
12423 : SourceRange(ErrorLoc, ErrorLoc);
12424 } else {
12425 Expr *PossibleXRHSInFirst =
12426 FirstBinOp->getRHS()->IgnoreParenImpCasts();
12427 Expr *PossibleXLHSInSecond =
12428 SecondBinOp->getLHS()->IgnoreParenImpCasts();
12429 llvm::FoldingSetNodeID X1Id, X2Id;
12430 PossibleXRHSInFirst->Profile(X1Id, Context,
12431 /*Canonical=*/true);
12432 PossibleXLHSInSecond->Profile(X2Id, Context,
12433 /*Canonical=*/true);
12434 IsUpdateExprFound = X1Id == X2Id;
12435 if (IsUpdateExprFound) {
12436 V = FirstBinOp->getLHS();
12437 X = SecondBinOp->getLHS();
12438 E = SecondBinOp->getRHS();
12439 UE = nullptr;
12440 IsXLHSInRHSPart = false;
12441 IsPostfixUpdate = true;
12442 } else {
12443 ErrorFound = NotASpecificExpression;
12444 ErrorLoc = FirstBinOp->getExprLoc();
12445 ErrorRange = FirstBinOp->getSourceRange();
12446 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12447 NoteRange = SecondBinOp->getRHS()->getSourceRange();
12448 }
12449 }
12450 }
12451 }
12452 }
12453 } else {
12454 NoteLoc = ErrorLoc = Body->getBeginLoc();
12455 NoteRange = ErrorRange =
12456 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12457 ErrorFound = NotTwoSubstatements;
12458 }
12459 } else {
12460 NoteLoc = ErrorLoc = Body->getBeginLoc();
12461 NoteRange = ErrorRange =
12462 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12463 ErrorFound = NotACompoundStatement;
12464 }
12465 }
12466 if (ErrorFound != NoError) {
12467 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12468 << ErrorRange;
12469 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12470 return StmtError();
12471 }
12472 if (CurContext->isDependentContext())
12473 UE = V = E = X = nullptr;
12474 } else if (AtomicKind == OMPC_compare) {
12475 if (IsCompareCapture) {
12476 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12477 OpenMPAtomicCompareCaptureChecker Checker(*this);
12478 if (!Checker.checkStmt(Body, ErrorInfo)) {
12479 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12480 << ErrorInfo.ErrorRange;
12481 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12482 << ErrorInfo.Error << ErrorInfo.NoteRange;
12483 return StmtError();
12484 }
12485 // TODO: We don't set X, D, E, etc. here because in code gen we will emit
12486 // error directly.
12487 } else {
12488 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12489 OpenMPAtomicCompareChecker Checker(*this);
12490 if (!Checker.checkStmt(Body, ErrorInfo)) {
12491 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12492 << ErrorInfo.ErrorRange;
12493 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12494 << ErrorInfo.Error << ErrorInfo.NoteRange;
12495 return StmtError();
12496 }
12497 X = Checker.getX();
12498 E = Checker.getE();
12499 D = Checker.getD();
12500 CE = Checker.getCond();
12501 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12502 IsXLHSInRHSPart = Checker.isXBinopExpr();
12503 }
12504 }
12505
12506 setFunctionHasBranchProtectedScope();
12507
12508 return OMPAtomicDirective::Create(
12509 Context, StartLoc, EndLoc, Clauses, AStmt,
12510 {X, V, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate});
12511}
12512
12513StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
12514 Stmt *AStmt,
12515 SourceLocation StartLoc,
12516 SourceLocation EndLoc) {
12517 if (!AStmt)
12518 return StmtError();
12519
12520 auto *CS = cast<CapturedStmt>(AStmt);
12521 // 1.2.2 OpenMP Language Terminology
12522 // Structured block - An executable statement with a single entry at the
12523 // top and a single exit at the bottom.
12524 // The point of exit cannot be a branch out of the structured block.
12525 // longjmp() and throw() must not violate the entry/exit criteria.
12526 CS->getCapturedDecl()->setNothrow();
12527 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
12528 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12529 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12530 // 1.2.2 OpenMP Language Terminology
12531 // Structured block - An executable statement with a single entry at the
12532 // top and a single exit at the bottom.
12533 // The point of exit cannot be a branch out of the structured block.
12534 // longjmp() and throw() must not violate the entry/exit criteria.
12535 CS->getCapturedDecl()->setNothrow();
12536 }
12537
12538 // OpenMP [2.16, Nesting of Regions]
12539 // If specified, a teams construct must be contained within a target
12540 // construct. That target construct must contain no statements or directives
12541 // outside of the teams construct.
12542 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
12543 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
12544 bool OMPTeamsFound = true;
12545 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
12546 auto I = CS->body_begin();
12547 while (I != CS->body_end()) {
12548 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12549 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
12550 OMPTeamsFound) {
12551
12552 OMPTeamsFound = false;
12553 break;
12554 }
12555 ++I;
12556 }
12557 assert(I != CS->body_end() && "Not found statement")(static_cast <bool> (I != CS->body_end() && "Not found statement"
) ? void (0) : __assert_fail ("I != CS->body_end() && \"Not found statement\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12557, __extension__ __PRETTY_FUNCTION__
))
;
12558 S = *I;
12559 } else {
12560 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
12561 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
12562 }
12563 if (!OMPTeamsFound) {
12564 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
12565 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
12566 diag::note_omp_nested_teams_construct_here);
12567 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
12568 << isa<OMPExecutableDirective>(S);
12569 return StmtError();
12570 }
12571 }
12572
12573 setFunctionHasBranchProtectedScope();
12574
12575 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12576}
12577
12578StmtResult
12579Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
12580 Stmt *AStmt, SourceLocation StartLoc,
12581 SourceLocation EndLoc) {
12582 if (!AStmt)
12583 return StmtError();
12584
12585 auto *CS = cast<CapturedStmt>(AStmt);
12586 // 1.2.2 OpenMP Language Terminology
12587 // Structured block - An executable statement with a single entry at the
12588 // top and a single exit at the bottom.
12589 // The point of exit cannot be a branch out of the structured block.
12590 // longjmp() and throw() must not violate the entry/exit criteria.
12591 CS->getCapturedDecl()->setNothrow();
12592 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
12593 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12594 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12595 // 1.2.2 OpenMP Language Terminology
12596 // Structured block - An executable statement with a single entry at the
12597 // top and a single exit at the bottom.
12598 // The point of exit cannot be a branch out of the structured block.
12599 // longjmp() and throw() must not violate the entry/exit criteria.
12600 CS->getCapturedDecl()->setNothrow();
12601 }
12602
12603 setFunctionHasBranchProtectedScope();
12604
12605 return OMPTargetParallelDirective::Create(
12606 Context, StartLoc, EndLoc, Clauses, AStmt,
12607 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12608}
12609
12610StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
12611 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12612 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12613 if (!AStmt)
12614 return StmtError();
12615
12616 auto *CS = cast<CapturedStmt>(AStmt);
12617 // 1.2.2 OpenMP Language Terminology
12618 // Structured block - An executable statement with a single entry at the
12619 // top and a single exit at the bottom.
12620 // The point of exit cannot be a branch out of the structured block.
12621 // longjmp() and throw() must not violate the entry/exit criteria.
12622 CS->getCapturedDecl()->setNothrow();
12623 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12624 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12625 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12626 // 1.2.2 OpenMP Language Terminology
12627 // Structured block - An executable statement with a single entry at the
12628 // top and a single exit at the bottom.
12629 // The point of exit cannot be a branch out of the structured block.
12630 // longjmp() and throw() must not violate the entry/exit criteria.
12631 CS->getCapturedDecl()->setNothrow();
12632 }
12633
12634 OMPLoopBasedDirective::HelperExprs B;
12635 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12636 // define the nested loops number.
12637 unsigned NestedLoopCount =
12638 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
12639 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12640 VarsWithImplicitDSA, B);
12641 if (NestedLoopCount == 0)
12642 return StmtError();
12643
12644 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12645, __extension__ __PRETTY_FUNCTION__
))
12645 "omp target parallel for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12645, __extension__ __PRETTY_FUNCTION__
))
;
12646
12647 if (!CurContext->isDependentContext()) {
12648 // Finalize the clauses that need pre-built expressions for CodeGen.
12649 for (OMPClause *C : Clauses) {
12650 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12651 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12652 B.NumIterations, *this, CurScope,
12653 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12654 return StmtError();
12655 }
12656 }
12657
12658 setFunctionHasBranchProtectedScope();
12659 return OMPTargetParallelForDirective::Create(
12660 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12661 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12662}
12663
12664/// Check for existence of a map clause in the list of clauses.
12665static bool hasClauses(ArrayRef<OMPClause *> Clauses,
12666 const OpenMPClauseKind K) {
12667 return llvm::any_of(
12668 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
12669}
12670
12671template <typename... Params>
12672static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
12673 const Params... ClauseTypes) {
12674 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
12675}
12676
12677/// Check if the variables in the mapping clause are externally visible.
12678static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
12679 for (const OMPClause *C : Clauses) {
12680 if (auto *TC = dyn_cast<OMPToClause>(C))
12681 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
12682 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12683 (VD->isExternallyVisible() &&
12684 VD->getVisibility() != HiddenVisibility);
12685 });
12686 else if (auto *FC = dyn_cast<OMPFromClause>(C))
12687 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
12688 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12689 (VD->isExternallyVisible() &&
12690 VD->getVisibility() != HiddenVisibility);
12691 });
12692 }
12693
12694 return true;
12695}
12696
12697StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
12698 Stmt *AStmt,
12699 SourceLocation StartLoc,
12700 SourceLocation EndLoc) {
12701 if (!AStmt)
12702 return StmtError();
12703
12704 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12704, __extension__ __PRETTY_FUNCTION__
))
;
12705
12706 // OpenMP [2.12.2, target data Construct, Restrictions]
12707 // At least one map, use_device_addr or use_device_ptr clause must appear on
12708 // the directive.
12709 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
12710 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
12711 StringRef Expected;
12712 if (LangOpts.OpenMP < 50)
12713 Expected = "'map' or 'use_device_ptr'";
12714 else
12715 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
12716 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12717 << Expected << getOpenMPDirectiveName(OMPD_target_data);
12718 return StmtError();
12719 }
12720
12721 setFunctionHasBranchProtectedScope();
12722
12723 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12724 AStmt);
12725}
12726
12727StmtResult
12728Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
12729 SourceLocation StartLoc,
12730 SourceLocation EndLoc, Stmt *AStmt) {
12731 if (!AStmt)
12732 return StmtError();
12733
12734 auto *CS = cast<CapturedStmt>(AStmt);
12735 // 1.2.2 OpenMP Language Terminology
12736 // Structured block - An executable statement with a single entry at the
12737 // top and a single exit at the bottom.
12738 // The point of exit cannot be a branch out of the structured block.
12739 // longjmp() and throw() must not violate the entry/exit criteria.
12740 CS->getCapturedDecl()->setNothrow();
12741 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
12742 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12743 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12744 // 1.2.2 OpenMP Language Terminology
12745 // Structured block - An executable statement with a single entry at the
12746 // top and a single exit at the bottom.
12747 // The point of exit cannot be a branch out of the structured block.
12748 // longjmp() and throw() must not violate the entry/exit criteria.
12749 CS->getCapturedDecl()->setNothrow();
12750 }
12751
12752 // OpenMP [2.10.2, Restrictions, p. 99]
12753 // At least one map clause must appear on the directive.
12754 if (!hasClauses(Clauses, OMPC_map)) {
12755 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12756 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
12757 return StmtError();
12758 }
12759
12760 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12761 AStmt);
12762}
12763
12764StmtResult
12765Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
12766 SourceLocation StartLoc,
12767 SourceLocation EndLoc, Stmt *AStmt) {
12768 if (!AStmt)
12769 return StmtError();
12770
12771 auto *CS = cast<CapturedStmt>(AStmt);
12772 // 1.2.2 OpenMP Language Terminology
12773 // Structured block - An executable statement with a single entry at the
12774 // top and a single exit at the bottom.
12775 // The point of exit cannot be a branch out of the structured block.
12776 // longjmp() and throw() must not violate the entry/exit criteria.
12777 CS->getCapturedDecl()->setNothrow();
12778 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
12779 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12780 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12781 // 1.2.2 OpenMP Language Terminology
12782 // Structured block - An executable statement with a single entry at the
12783 // top and a single exit at the bottom.
12784 // The point of exit cannot be a branch out of the structured block.
12785 // longjmp() and throw() must not violate the entry/exit criteria.
12786 CS->getCapturedDecl()->setNothrow();
12787 }
12788
12789 // OpenMP [2.10.3, Restrictions, p. 102]
12790 // At least one map clause must appear on the directive.
12791 if (!hasClauses(Clauses, OMPC_map)) {
12792 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12793 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
12794 return StmtError();
12795 }
12796
12797 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12798 AStmt);
12799}
12800
12801StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
12802 SourceLocation StartLoc,
12803 SourceLocation EndLoc,
12804 Stmt *AStmt) {
12805 if (!AStmt)
12806 return StmtError();
12807
12808 auto *CS = cast<CapturedStmt>(AStmt);
12809 // 1.2.2 OpenMP Language Terminology
12810 // Structured block - An executable statement with a single entry at the
12811 // top and a single exit at the bottom.
12812 // The point of exit cannot be a branch out of the structured block.
12813 // longjmp() and throw() must not violate the entry/exit criteria.
12814 CS->getCapturedDecl()->setNothrow();
12815 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
12816 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12817 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12818 // 1.2.2 OpenMP Language Terminology
12819 // Structured block - An executable statement with a single entry at the
12820 // top and a single exit at the bottom.
12821 // The point of exit cannot be a branch out of the structured block.
12822 // longjmp() and throw() must not violate the entry/exit criteria.
12823 CS->getCapturedDecl()->setNothrow();
12824 }
12825
12826 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
12827 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
12828 return StmtError();
12829 }
12830
12831 if (!isClauseMappable(Clauses)) {
12832 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
12833 return StmtError();
12834 }
12835
12836 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
12837 AStmt);
12838}
12839
12840StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
12841 Stmt *AStmt, SourceLocation StartLoc,
12842 SourceLocation EndLoc) {
12843 if (!AStmt)
12844 return StmtError();
12845
12846 auto *CS = cast<CapturedStmt>(AStmt);
12847 // 1.2.2 OpenMP Language Terminology
12848 // Structured block - An executable statement with a single entry at the
12849 // top and a single exit at the bottom.
12850 // The point of exit cannot be a branch out of the structured block.
12851 // longjmp() and throw() must not violate the entry/exit criteria.
12852 CS->getCapturedDecl()->setNothrow();
12853
12854 setFunctionHasBranchProtectedScope();
12855
12856 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
12857
12858 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12859}
12860
12861StmtResult
12862Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
12863 SourceLocation EndLoc,
12864 OpenMPDirectiveKind CancelRegion) {
12865 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
12866 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
12867 return StmtError();
12868 }
12869 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
12870 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
12871 return StmtError();
12872 }
12873 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
12874 CancelRegion);
12875}
12876
12877StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
12878 SourceLocation StartLoc,
12879 SourceLocation EndLoc,
12880 OpenMPDirectiveKind CancelRegion) {
12881 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
12882 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
12883 return StmtError();
12884 }
12885 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
12886 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
12887 return StmtError();
12888 }
12889 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
12890 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
12891 CancelRegion);
12892}
12893
12894static bool checkReductionClauseWithNogroup(Sema &S,
12895 ArrayRef<OMPClause *> Clauses) {
12896 const OMPClause *ReductionClause = nullptr;
12897 const OMPClause *NogroupClause = nullptr;
12898 for (const OMPClause *C : Clauses) {
12899 if (C->getClauseKind() == OMPC_reduction) {
12900 ReductionClause = C;
12901 if (NogroupClause)
12902 break;
12903 continue;
12904 }
12905 if (C->getClauseKind() == OMPC_nogroup) {
12906 NogroupClause = C;
12907 if (ReductionClause)
12908 break;
12909 continue;
12910 }
12911 }
12912 if (ReductionClause && NogroupClause) {
12913 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
12914 << SourceRange(NogroupClause->getBeginLoc(),
12915 NogroupClause->getEndLoc());
12916 return true;
12917 }
12918 return false;
12919}
12920
12921StmtResult Sema::ActOnOpenMPTaskLoopDirective(
12922 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12923 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12924 if (!AStmt)
12925 return StmtError();
12926
12927 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12927, __extension__ __PRETTY_FUNCTION__
))
;
12928 OMPLoopBasedDirective::HelperExprs B;
12929 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12930 // define the nested loops number.
12931 unsigned NestedLoopCount =
12932 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
12933 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12934 VarsWithImplicitDSA, B);
12935 if (NestedLoopCount == 0)
12936 return StmtError();
12937
12938 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12939, __extension__ __PRETTY_FUNCTION__
))
12939 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12939, __extension__ __PRETTY_FUNCTION__
))
;
12940
12941 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12942 // The grainsize clause and num_tasks clause are mutually exclusive and may
12943 // not appear on the same taskloop directive.
12944 if (checkMutuallyExclusiveClauses(*this, Clauses,
12945 {OMPC_grainsize, OMPC_num_tasks}))
12946 return StmtError();
12947 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12948 // If a reduction clause is present on the taskloop directive, the nogroup
12949 // clause must not be specified.
12950 if (checkReductionClauseWithNogroup(*this, Clauses))
12951 return StmtError();
12952
12953 setFunctionHasBranchProtectedScope();
12954 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
12955 NestedLoopCount, Clauses, AStmt, B,
12956 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
12957}
12958
12959StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
12960 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12961 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12962 if (!AStmt)
12963 return StmtError();
12964
12965 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12965, __extension__ __PRETTY_FUNCTION__
))
;
12966 OMPLoopBasedDirective::HelperExprs B;
12967 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12968 // define the nested loops number.
12969 unsigned NestedLoopCount =
12970 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
12971 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
12972 VarsWithImplicitDSA, B);
12973 if (NestedLoopCount == 0)
12974 return StmtError();
12975
12976 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12977, __extension__ __PRETTY_FUNCTION__
))
12977 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 12977, __extension__ __PRETTY_FUNCTION__
))
;
12978
12979 if (!CurContext->isDependentContext()) {
12980 // Finalize the clauses that need pre-built expressions for CodeGen.
12981 for (OMPClause *C : Clauses) {
12982 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12983 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12984 B.NumIterations, *this, CurScope,
12985 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12986 return StmtError();
12987 }
12988 }
12989
12990 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12991 // The grainsize clause and num_tasks clause are mutually exclusive and may
12992 // not appear on the same taskloop directive.
12993 if (checkMutuallyExclusiveClauses(*this, Clauses,
12994 {OMPC_grainsize, OMPC_num_tasks}))
12995 return StmtError();
12996 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12997 // If a reduction clause is present on the taskloop directive, the nogroup
12998 // clause must not be specified.
12999 if (checkReductionClauseWithNogroup(*this, Clauses))
13000 return StmtError();
13001 if (checkSimdlenSafelenSpecified(*this, Clauses))
13002 return StmtError();
13003
13004 setFunctionHasBranchProtectedScope();
13005 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13006 NestedLoopCount, Clauses, AStmt, B);
13007}
13008
13009StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13010 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13011 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13012 if (!AStmt)
13013 return StmtError();
13014
13015 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13015, __extension__ __PRETTY_FUNCTION__
))
;
13016 OMPLoopBasedDirective::HelperExprs B;
13017 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13018 // define the nested loops number.
13019 unsigned NestedLoopCount =
13020 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13021 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13022 VarsWithImplicitDSA, B);
13023 if (NestedLoopCount == 0)
13024 return StmtError();
13025
13026 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13027, __extension__ __PRETTY_FUNCTION__
))
13027 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13027, __extension__ __PRETTY_FUNCTION__
))
;
13028
13029 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13030 // The grainsize clause and num_tasks clause are mutually exclusive and may
13031 // not appear on the same taskloop directive.
13032 if (checkMutuallyExclusiveClauses(*this, Clauses,
13033 {OMPC_grainsize, OMPC_num_tasks}))
13034 return StmtError();
13035 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13036 // If a reduction clause is present on the taskloop directive, the nogroup
13037 // clause must not be specified.
13038 if (checkReductionClauseWithNogroup(*this, Clauses))
13039 return StmtError();
13040
13041 setFunctionHasBranchProtectedScope();
13042 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13043 NestedLoopCount, Clauses, AStmt, B,
13044 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13045}
13046
13047StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13048 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13049 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13050 if (!AStmt)
13051 return StmtError();
13052
13053 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13053, __extension__ __PRETTY_FUNCTION__
))
;
13054 OMPLoopBasedDirective::HelperExprs B;
13055 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13056 // define the nested loops number.
13057 unsigned NestedLoopCount =
13058 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13059 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13060 VarsWithImplicitDSA, B);
13061 if (NestedLoopCount == 0)
13062 return StmtError();
13063
13064 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13065, __extension__ __PRETTY_FUNCTION__
))
13065 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13065, __extension__ __PRETTY_FUNCTION__
))
;
13066
13067 if (!CurContext->isDependentContext()) {
13068 // Finalize the clauses that need pre-built expressions for CodeGen.
13069 for (OMPClause *C : Clauses) {
13070 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13071 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13072 B.NumIterations, *this, CurScope,
13073 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13074 return StmtError();
13075 }
13076 }
13077
13078 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13079 // The grainsize clause and num_tasks clause are mutually exclusive and may
13080 // not appear on the same taskloop directive.
13081 if (checkMutuallyExclusiveClauses(*this, Clauses,
13082 {OMPC_grainsize, OMPC_num_tasks}))
13083 return StmtError();
13084 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13085 // If a reduction clause is present on the taskloop directive, the nogroup
13086 // clause must not be specified.
13087 if (checkReductionClauseWithNogroup(*this, Clauses))
13088 return StmtError();
13089 if (checkSimdlenSafelenSpecified(*this, Clauses))
13090 return StmtError();
13091
13092 setFunctionHasBranchProtectedScope();
13093 return OMPMasterTaskLoopSimdDirective::Create(
13094 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13095}
13096
13097StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13098 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13099 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13100 if (!AStmt)
13101 return StmtError();
13102
13103 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13103, __extension__ __PRETTY_FUNCTION__
))
;
13104 auto *CS = cast<CapturedStmt>(AStmt);
13105 // 1.2.2 OpenMP Language Terminology
13106 // Structured block - An executable statement with a single entry at the
13107 // top and a single exit at the bottom.
13108 // The point of exit cannot be a branch out of the structured block.
13109 // longjmp() and throw() must not violate the entry/exit criteria.
13110 CS->getCapturedDecl()->setNothrow();
13111 for (int ThisCaptureLevel =
13112 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13113 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13114 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13115 // 1.2.2 OpenMP Language Terminology
13116 // Structured block - An executable statement with a single entry at the
13117 // top and a single exit at the bottom.
13118 // The point of exit cannot be a branch out of the structured block.
13119 // longjmp() and throw() must not violate the entry/exit criteria.
13120 CS->getCapturedDecl()->setNothrow();
13121 }
13122
13123 OMPLoopBasedDirective::HelperExprs B;
13124 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13125 // define the nested loops number.
13126 unsigned NestedLoopCount = checkOpenMPLoop(
13127 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13128 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13129 VarsWithImplicitDSA, B);
13130 if (NestedLoopCount == 0)
13131 return StmtError();
13132
13133 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13134, __extension__ __PRETTY_FUNCTION__
))
13134 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13134, __extension__ __PRETTY_FUNCTION__
))
;
13135
13136 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13137 // The grainsize clause and num_tasks clause are mutually exclusive and may
13138 // not appear on the same taskloop directive.
13139 if (checkMutuallyExclusiveClauses(*this, Clauses,
13140 {OMPC_grainsize, OMPC_num_tasks}))
13141 return StmtError();
13142 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13143 // If a reduction clause is present on the taskloop directive, the nogroup
13144 // clause must not be specified.
13145 if (checkReductionClauseWithNogroup(*this, Clauses))
13146 return StmtError();
13147
13148 setFunctionHasBranchProtectedScope();
13149 return OMPParallelMasterTaskLoopDirective::Create(
13150 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13151 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13152}
13153
13154StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13155 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13156 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13157 if (!AStmt)
13158 return StmtError();
13159
13160 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13160, __extension__ __PRETTY_FUNCTION__
))
;
13161 auto *CS = cast<CapturedStmt>(AStmt);
13162 // 1.2.2 OpenMP Language Terminology
13163 // Structured block - An executable statement with a single entry at the
13164 // top and a single exit at the bottom.
13165 // The point of exit cannot be a branch out of the structured block.
13166 // longjmp() and throw() must not violate the entry/exit criteria.
13167 CS->getCapturedDecl()->setNothrow();
13168 for (int ThisCaptureLevel =
13169 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13170 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13171 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13172 // 1.2.2 OpenMP Language Terminology
13173 // Structured block - An executable statement with a single entry at the
13174 // top and a single exit at the bottom.
13175 // The point of exit cannot be a branch out of the structured block.
13176 // longjmp() and throw() must not violate the entry/exit criteria.
13177 CS->getCapturedDecl()->setNothrow();
13178 }
13179
13180 OMPLoopBasedDirective::HelperExprs B;
13181 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13182 // define the nested loops number.
13183 unsigned NestedLoopCount = checkOpenMPLoop(
13184 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13185 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13186 VarsWithImplicitDSA, B);
13187 if (NestedLoopCount == 0)
13188 return StmtError();
13189
13190 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13191, __extension__ __PRETTY_FUNCTION__
))
13191 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13191, __extension__ __PRETTY_FUNCTION__
))
;
13192
13193 if (!CurContext->isDependentContext()) {
13194 // Finalize the clauses that need pre-built expressions for CodeGen.
13195 for (OMPClause *C : Clauses) {
13196 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13197 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13198 B.NumIterations, *this, CurScope,
13199 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13200 return StmtError();
13201 }
13202 }
13203
13204 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13205 // The grainsize clause and num_tasks clause are mutually exclusive and may
13206 // not appear on the same taskloop directive.
13207 if (checkMutuallyExclusiveClauses(*this, Clauses,
13208 {OMPC_grainsize, OMPC_num_tasks}))
13209 return StmtError();
13210 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13211 // If a reduction clause is present on the taskloop directive, the nogroup
13212 // clause must not be specified.
13213 if (checkReductionClauseWithNogroup(*this, Clauses))
13214 return StmtError();
13215 if (checkSimdlenSafelenSpecified(*this, Clauses))
13216 return StmtError();
13217
13218 setFunctionHasBranchProtectedScope();
13219 return OMPParallelMasterTaskLoopSimdDirective::Create(
13220 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13221}
13222
13223StmtResult Sema::ActOnOpenMPDistributeDirective(
13224 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13225 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13226 if (!AStmt)
13227 return StmtError();
13228
13229 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13229, __extension__ __PRETTY_FUNCTION__
))
;
13230 OMPLoopBasedDirective::HelperExprs B;
13231 // In presence of clause 'collapse' with number of loops, it will
13232 // define the nested loops number.
13233 unsigned NestedLoopCount =
13234 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
13235 nullptr /*ordered not a clause on distribute*/, AStmt,
13236 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
13237 if (NestedLoopCount == 0)
13238 return StmtError();
13239
13240 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13241, __extension__ __PRETTY_FUNCTION__
))
13241 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13241, __extension__ __PRETTY_FUNCTION__
))
;
13242
13243 setFunctionHasBranchProtectedScope();
13244 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
13245 NestedLoopCount, Clauses, AStmt, B);
13246}
13247
13248StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
13249 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13250 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13251 if (!AStmt)
13252 return StmtError();
13253
13254 auto *CS = cast<CapturedStmt>(AStmt);
13255 // 1.2.2 OpenMP Language Terminology
13256 // Structured block - An executable statement with a single entry at the
13257 // top and a single exit at the bottom.
13258 // The point of exit cannot be a branch out of the structured block.
13259 // longjmp() and throw() must not violate the entry/exit criteria.
13260 CS->getCapturedDecl()->setNothrow();
13261 for (int ThisCaptureLevel =
13262 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
13263 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13264 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13265 // 1.2.2 OpenMP Language Terminology
13266 // Structured block - An executable statement with a single entry at the
13267 // top and a single exit at the bottom.
13268 // The point of exit cannot be a branch out of the structured block.
13269 // longjmp() and throw() must not violate the entry/exit criteria.
13270 CS->getCapturedDecl()->setNothrow();
13271 }
13272
13273 OMPLoopBasedDirective::HelperExprs B;
13274 // In presence of clause 'collapse' with number of loops, it will
13275 // define the nested loops number.
13276 unsigned NestedLoopCount = checkOpenMPLoop(
13277 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13278 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13279 VarsWithImplicitDSA, B);
13280 if (NestedLoopCount == 0)
13281 return StmtError();
13282
13283 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13284, __extension__ __PRETTY_FUNCTION__
))
13284 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13284, __extension__ __PRETTY_FUNCTION__
))
;
13285
13286 setFunctionHasBranchProtectedScope();
13287 return OMPDistributeParallelForDirective::Create(
13288 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13289 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13290}
13291
13292StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
13293 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13294 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13295 if (!AStmt)
13296 return StmtError();
13297
13298 auto *CS = cast<CapturedStmt>(AStmt);
13299 // 1.2.2 OpenMP Language Terminology
13300 // Structured block - An executable statement with a single entry at the
13301 // top and a single exit at the bottom.
13302 // The point of exit cannot be a branch out of the structured block.
13303 // longjmp() and throw() must not violate the entry/exit criteria.
13304 CS->getCapturedDecl()->setNothrow();
13305 for (int ThisCaptureLevel =
13306 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
13307 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13308 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13309 // 1.2.2 OpenMP Language Terminology
13310 // Structured block - An executable statement with a single entry at the
13311 // top and a single exit at the bottom.
13312 // The point of exit cannot be a branch out of the structured block.
13313 // longjmp() and throw() must not violate the entry/exit criteria.
13314 CS->getCapturedDecl()->setNothrow();
13315 }
13316
13317 OMPLoopBasedDirective::HelperExprs B;
13318 // In presence of clause 'collapse' with number of loops, it will
13319 // define the nested loops number.
13320 unsigned NestedLoopCount = checkOpenMPLoop(
13321 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13322 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13323 VarsWithImplicitDSA, B);
13324 if (NestedLoopCount == 0)
13325 return StmtError();
13326
13327 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13328, __extension__ __PRETTY_FUNCTION__
))
13328 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13328, __extension__ __PRETTY_FUNCTION__
))
;
13329
13330 if (!CurContext->isDependentContext()) {
13331 // Finalize the clauses that need pre-built expressions for CodeGen.
13332 for (OMPClause *C : Clauses) {
13333 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13334 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13335 B.NumIterations, *this, CurScope,
13336 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13337 return StmtError();
13338 }
13339 }
13340
13341 if (checkSimdlenSafelenSpecified(*this, Clauses))
13342 return StmtError();
13343
13344 setFunctionHasBranchProtectedScope();
13345 return OMPDistributeParallelForSimdDirective::Create(
13346 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13347}
13348
13349StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
13350 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13351 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13352 if (!AStmt)
13353 return StmtError();
13354
13355 auto *CS = cast<CapturedStmt>(AStmt);
13356 // 1.2.2 OpenMP Language Terminology
13357 // Structured block - An executable statement with a single entry at the
13358 // top and a single exit at the bottom.
13359 // The point of exit cannot be a branch out of the structured block.
13360 // longjmp() and throw() must not violate the entry/exit criteria.
13361 CS->getCapturedDecl()->setNothrow();
13362 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
13363 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13364 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13365 // 1.2.2 OpenMP Language Terminology
13366 // Structured block - An executable statement with a single entry at the
13367 // top and a single exit at the bottom.
13368 // The point of exit cannot be a branch out of the structured block.
13369 // longjmp() and throw() must not violate the entry/exit criteria.
13370 CS->getCapturedDecl()->setNothrow();
13371 }
13372
13373 OMPLoopBasedDirective::HelperExprs B;
13374 // In presence of clause 'collapse' with number of loops, it will
13375 // define the nested loops number.
13376 unsigned NestedLoopCount =
13377 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
13378 nullptr /*ordered not a clause on distribute*/, CS, *this,
13379 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
13380 if (NestedLoopCount == 0)
13381 return StmtError();
13382
13383 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13384, __extension__ __PRETTY_FUNCTION__
))
13384 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13384, __extension__ __PRETTY_FUNCTION__
))
;
13385
13386 if (!CurContext->isDependentContext()) {
13387 // Finalize the clauses that need pre-built expressions for CodeGen.
13388 for (OMPClause *C : Clauses) {
13389 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13390 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13391 B.NumIterations, *this, CurScope,
13392 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13393 return StmtError();
13394 }
13395 }
13396
13397 if (checkSimdlenSafelenSpecified(*this, Clauses))
13398 return StmtError();
13399
13400 setFunctionHasBranchProtectedScope();
13401 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
13402 NestedLoopCount, Clauses, AStmt, B);
13403}
13404
13405StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
13406 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13407 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13408 if (!AStmt)
13409 return StmtError();
13410
13411 auto *CS = cast<CapturedStmt>(AStmt);
13412 // 1.2.2 OpenMP Language Terminology
13413 // Structured block - An executable statement with a single entry at the
13414 // top and a single exit at the bottom.
13415 // The point of exit cannot be a branch out of the structured block.
13416 // longjmp() and throw() must not violate the entry/exit criteria.
13417 CS->getCapturedDecl()->setNothrow();
13418 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13419 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13420 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13421 // 1.2.2 OpenMP Language Terminology
13422 // Structured block - An executable statement with a single entry at the
13423 // top and a single exit at the bottom.
13424 // The point of exit cannot be a branch out of the structured block.
13425 // longjmp() and throw() must not violate the entry/exit criteria.
13426 CS->getCapturedDecl()->setNothrow();
13427 }
13428
13429 OMPLoopBasedDirective::HelperExprs B;
13430 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13431 // define the nested loops number.
13432 unsigned NestedLoopCount = checkOpenMPLoop(
13433 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
13434 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA,
13435 B);
13436 if (NestedLoopCount == 0)
13437 return StmtError();
13438
13439 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13440, __extension__ __PRETTY_FUNCTION__
))
13440 "omp target parallel for simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13440, __extension__ __PRETTY_FUNCTION__
))
;
13441
13442 if (!CurContext->isDependentContext()) {
13443 // Finalize the clauses that need pre-built expressions for CodeGen.
13444 for (OMPClause *C : Clauses) {
13445 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13446 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13447 B.NumIterations, *this, CurScope,
13448 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13449 return StmtError();
13450 }
13451 }
13452 if (checkSimdlenSafelenSpecified(*this, Clauses))
13453 return StmtError();
13454
13455 setFunctionHasBranchProtectedScope();
13456 return OMPTargetParallelForSimdDirective::Create(
13457 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13458}
13459
13460StmtResult Sema::ActOnOpenMPTargetSimdDirective(
13461 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13462 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13463 if (!AStmt)
13464 return StmtError();
13465
13466 auto *CS = cast<CapturedStmt>(AStmt);
13467 // 1.2.2 OpenMP Language Terminology
13468 // Structured block - An executable statement with a single entry at the
13469 // top and a single exit at the bottom.
13470 // The point of exit cannot be a branch out of the structured block.
13471 // longjmp() and throw() must not violate the entry/exit criteria.
13472 CS->getCapturedDecl()->setNothrow();
13473 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
13474 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13475 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13476 // 1.2.2 OpenMP Language Terminology
13477 // Structured block - An executable statement with a single entry at the
13478 // top and a single exit at the bottom.
13479 // The point of exit cannot be a branch out of the structured block.
13480 // longjmp() and throw() must not violate the entry/exit criteria.
13481 CS->getCapturedDecl()->setNothrow();
13482 }
13483
13484 OMPLoopBasedDirective::HelperExprs B;
13485 // In presence of clause 'collapse' with number of loops, it will define the
13486 // nested loops number.
13487 unsigned NestedLoopCount =
13488 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
13489 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13490 VarsWithImplicitDSA, B);
13491 if (NestedLoopCount == 0)
13492 return StmtError();
13493
13494 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13495, __extension__ __PRETTY_FUNCTION__
))
13495 "omp target simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13495, __extension__ __PRETTY_FUNCTION__
))
;
13496
13497 if (!CurContext->isDependentContext()) {
13498 // Finalize the clauses that need pre-built expressions for CodeGen.
13499 for (OMPClause *C : Clauses) {
13500 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13501 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13502 B.NumIterations, *this, CurScope,
13503 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13504 return StmtError();
13505 }
13506 }
13507
13508 if (checkSimdlenSafelenSpecified(*this, Clauses))
13509 return StmtError();
13510
13511 setFunctionHasBranchProtectedScope();
13512 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
13513 NestedLoopCount, Clauses, AStmt, B);
13514}
13515
13516StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
13517 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13518 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13519 if (!AStmt)
13520 return StmtError();
13521
13522 auto *CS = cast<CapturedStmt>(AStmt);
13523 // 1.2.2 OpenMP Language Terminology
13524 // Structured block - An executable statement with a single entry at the
13525 // top and a single exit at the bottom.
13526 // The point of exit cannot be a branch out of the structured block.
13527 // longjmp() and throw() must not violate the entry/exit criteria.
13528 CS->getCapturedDecl()->setNothrow();
13529 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
13530 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13531 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13532 // 1.2.2 OpenMP Language Terminology
13533 // Structured block - An executable statement with a single entry at the
13534 // top and a single exit at the bottom.
13535 // The point of exit cannot be a branch out of the structured block.
13536 // longjmp() and throw() must not violate the entry/exit criteria.
13537 CS->getCapturedDecl()->setNothrow();
13538 }
13539
13540 OMPLoopBasedDirective::HelperExprs B;
13541 // In presence of clause 'collapse' with number of loops, it will
13542 // define the nested loops number.
13543 unsigned NestedLoopCount =
13544 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
13545 nullptr /*ordered not a clause on distribute*/, CS, *this,
13546 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
13547 if (NestedLoopCount == 0)
13548 return StmtError();
13549
13550 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13551, __extension__ __PRETTY_FUNCTION__
))
13551 "omp teams distribute loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13551, __extension__ __PRETTY_FUNCTION__
))
;
13552
13553 setFunctionHasBranchProtectedScope();
13554
13555 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
13556
13557 return OMPTeamsDistributeDirective::Create(
13558 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13559}
13560
13561StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
13562 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13563 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13564 if (!AStmt)
13565 return StmtError();
13566
13567 auto *CS = cast<CapturedStmt>(AStmt);
13568 // 1.2.2 OpenMP Language Terminology
13569 // Structured block - An executable statement with a single entry at the
13570 // top and a single exit at the bottom.
13571 // The point of exit cannot be a branch out of the structured block.
13572 // longjmp() and throw() must not violate the entry/exit criteria.
13573 CS->getCapturedDecl()->setNothrow();
13574 for (int ThisCaptureLevel =
13575 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
13576 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13577 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13578 // 1.2.2 OpenMP Language Terminology
13579 // Structured block - An executable statement with a single entry at the
13580 // top and a single exit at the bottom.
13581 // The point of exit cannot be a branch out of the structured block.
13582 // longjmp() and throw() must not violate the entry/exit criteria.
13583 CS->getCapturedDecl()->setNothrow();
13584 }
13585
13586 OMPLoopBasedDirective::HelperExprs B;
13587 // In presence of clause 'collapse' with number of loops, it will
13588 // define the nested loops number.
13589 unsigned NestedLoopCount = checkOpenMPLoop(
13590 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
13591 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13592 VarsWithImplicitDSA, B);
13593
13594 if (NestedLoopCount == 0)
13595 return StmtError();
13596
13597 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13598, __extension__ __PRETTY_FUNCTION__
))
13598 "omp teams distribute simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13598, __extension__ __PRETTY_FUNCTION__
))
;
13599
13600 if (!CurContext->isDependentContext()) {
13601 // Finalize the clauses that need pre-built expressions for CodeGen.
13602 for (OMPClause *C : Clauses) {
13603 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13604 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13605 B.NumIterations, *this, CurScope,
13606 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13607 return StmtError();
13608 }
13609 }
13610
13611 if (checkSimdlenSafelenSpecified(*this, Clauses))
13612 return StmtError();
13613
13614 setFunctionHasBranchProtectedScope();
13615
13616 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
13617
13618 return OMPTeamsDistributeSimdDirective::Create(
13619 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13620}
13621
13622StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
13623 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13624 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13625 if (!AStmt)
13626 return StmtError();
13627
13628 auto *CS = cast<CapturedStmt>(AStmt);
13629 // 1.2.2 OpenMP Language Terminology
13630 // Structured block - An executable statement with a single entry at the
13631 // top and a single exit at the bottom.
13632 // The point of exit cannot be a branch out of the structured block.
13633 // longjmp() and throw() must not violate the entry/exit criteria.
13634 CS->getCapturedDecl()->setNothrow();
13635
13636 for (int ThisCaptureLevel =
13637 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
13638 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13639 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13640 // 1.2.2 OpenMP Language Terminology
13641 // Structured block - An executable statement with a single entry at the
13642 // top and a single exit at the bottom.
13643 // The point of exit cannot be a branch out of the structured block.
13644 // longjmp() and throw() must not violate the entry/exit criteria.
13645 CS->getCapturedDecl()->setNothrow();
13646 }
13647
13648 OMPLoopBasedDirective::HelperExprs B;
13649 // In presence of clause 'collapse' with number of loops, it will
13650 // define the nested loops number.
13651 unsigned NestedLoopCount = checkOpenMPLoop(
13652 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13653 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13654 VarsWithImplicitDSA, B);
13655
13656 if (NestedLoopCount == 0)
13657 return StmtError();
13658
13659 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13660, __extension__ __PRETTY_FUNCTION__
))
13660 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13660, __extension__ __PRETTY_FUNCTION__
))
;
13661
13662 if (!CurContext->isDependentContext()) {
13663 // Finalize the clauses that need pre-built expressions for CodeGen.
13664 for (OMPClause *C : Clauses) {
13665 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13666 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13667 B.NumIterations, *this, CurScope,
13668 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13669 return StmtError();
13670 }
13671 }
13672
13673 if (checkSimdlenSafelenSpecified(*this, Clauses))
13674 return StmtError();
13675
13676 setFunctionHasBranchProtectedScope();
13677
13678 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
13679
13680 return OMPTeamsDistributeParallelForSimdDirective::Create(
13681 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13682}
13683
13684StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
13685 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13686 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13687 if (!AStmt)
13688 return StmtError();
13689
13690 auto *CS = cast<CapturedStmt>(AStmt);
13691 // 1.2.2 OpenMP Language Terminology
13692 // Structured block - An executable statement with a single entry at the
13693 // top and a single exit at the bottom.
13694 // The point of exit cannot be a branch out of the structured block.
13695 // longjmp() and throw() must not violate the entry/exit criteria.
13696 CS->getCapturedDecl()->setNothrow();
13697
13698 for (int ThisCaptureLevel =
13699 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
13700 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13701 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13702 // 1.2.2 OpenMP Language Terminology
13703 // Structured block - An executable statement with a single entry at the
13704 // top and a single exit at the bottom.
13705 // The point of exit cannot be a branch out of the structured block.
13706 // longjmp() and throw() must not violate the entry/exit criteria.
13707 CS->getCapturedDecl()->setNothrow();
13708 }
13709
13710 OMPLoopBasedDirective::HelperExprs B;
13711 // In presence of clause 'collapse' with number of loops, it will
13712 // define the nested loops number.
13713 unsigned NestedLoopCount = checkOpenMPLoop(
13714 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13715 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13716 VarsWithImplicitDSA, B);
13717
13718 if (NestedLoopCount == 0)
13719 return StmtError();
13720
13721 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13722, __extension__ __PRETTY_FUNCTION__
))
13722 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13722, __extension__ __PRETTY_FUNCTION__
))
;
13723
13724 setFunctionHasBranchProtectedScope();
13725
13726 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
13727
13728 return OMPTeamsDistributeParallelForDirective::Create(
13729 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13730 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13731}
13732
13733StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
13734 Stmt *AStmt,
13735 SourceLocation StartLoc,
13736 SourceLocation EndLoc) {
13737 if (!AStmt)
13738 return StmtError();
13739
13740 auto *CS = cast<CapturedStmt>(AStmt);
13741 // 1.2.2 OpenMP Language Terminology
13742 // Structured block - An executable statement with a single entry at the
13743 // top and a single exit at the bottom.
13744 // The point of exit cannot be a branch out of the structured block.
13745 // longjmp() and throw() must not violate the entry/exit criteria.
13746 CS->getCapturedDecl()->setNothrow();
13747
13748 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
13749 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13750 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13751 // 1.2.2 OpenMP Language Terminology
13752 // Structured block - An executable statement with a single entry at the
13753 // top and a single exit at the bottom.
13754 // The point of exit cannot be a branch out of the structured block.
13755 // longjmp() and throw() must not violate the entry/exit criteria.
13756 CS->getCapturedDecl()->setNothrow();
13757 }
13758 setFunctionHasBranchProtectedScope();
13759
13760 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
13761 AStmt);
13762}
13763
13764StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
13765 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13766 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13767 if (!AStmt)
13768 return StmtError();
13769
13770 auto *CS = cast<CapturedStmt>(AStmt);
13771 // 1.2.2 OpenMP Language Terminology
13772 // Structured block - An executable statement with a single entry at the
13773 // top and a single exit at the bottom.
13774 // The point of exit cannot be a branch out of the structured block.
13775 // longjmp() and throw() must not violate the entry/exit criteria.
13776 CS->getCapturedDecl()->setNothrow();
13777 for (int ThisCaptureLevel =
13778 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
13779 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13780 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13781 // 1.2.2 OpenMP Language Terminology
13782 // Structured block - An executable statement with a single entry at the
13783 // top and a single exit at the bottom.
13784 // The point of exit cannot be a branch out of the structured block.
13785 // longjmp() and throw() must not violate the entry/exit criteria.
13786 CS->getCapturedDecl()->setNothrow();
13787 }
13788
13789 OMPLoopBasedDirective::HelperExprs B;
13790 // In presence of clause 'collapse' with number of loops, it will
13791 // define the nested loops number.
13792 unsigned NestedLoopCount = checkOpenMPLoop(
13793 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
13794 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13795 VarsWithImplicitDSA, B);
13796 if (NestedLoopCount == 0)
13797 return StmtError();
13798
13799 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13800, __extension__ __PRETTY_FUNCTION__
))
13800 "omp target teams distribute loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13800, __extension__ __PRETTY_FUNCTION__
))
;
13801
13802 setFunctionHasBranchProtectedScope();
13803 return OMPTargetTeamsDistributeDirective::Create(
13804 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13805}
13806
13807StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
13808 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13809 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13810 if (!AStmt)
13811 return StmtError();
13812
13813 auto *CS = cast<CapturedStmt>(AStmt);
13814 // 1.2.2 OpenMP Language Terminology
13815 // Structured block - An executable statement with a single entry at the
13816 // top and a single exit at the bottom.
13817 // The point of exit cannot be a branch out of the structured block.
13818 // longjmp() and throw() must not violate the entry/exit criteria.
13819 CS->getCapturedDecl()->setNothrow();
13820 for (int ThisCaptureLevel =
13821 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
13822 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13823 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13824 // 1.2.2 OpenMP Language Terminology
13825 // Structured block - An executable statement with a single entry at the
13826 // top and a single exit at the bottom.
13827 // The point of exit cannot be a branch out of the structured block.
13828 // longjmp() and throw() must not violate the entry/exit criteria.
13829 CS->getCapturedDecl()->setNothrow();
13830 }
13831
13832 OMPLoopBasedDirective::HelperExprs B;
13833 // In presence of clause 'collapse' with number of loops, it will
13834 // define the nested loops number.
13835 unsigned NestedLoopCount = checkOpenMPLoop(
13836 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13837 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13838 VarsWithImplicitDSA, B);
13839 if (NestedLoopCount == 0)
13840 return StmtError();
13841
13842 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13843, __extension__ __PRETTY_FUNCTION__
))
13843 "omp target teams distribute parallel for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13843, __extension__ __PRETTY_FUNCTION__
))
;
13844
13845 if (!CurContext->isDependentContext()) {
13846 // Finalize the clauses that need pre-built expressions for CodeGen.
13847 for (OMPClause *C : Clauses) {
13848 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13849 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13850 B.NumIterations, *this, CurScope,
13851 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13852 return StmtError();
13853 }
13854 }
13855
13856 setFunctionHasBranchProtectedScope();
13857 return OMPTargetTeamsDistributeParallelForDirective::Create(
13858 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13859 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13860}
13861
13862StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
13863 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13864 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13865 if (!AStmt)
13866 return StmtError();
13867
13868 auto *CS = cast<CapturedStmt>(AStmt);
13869 // 1.2.2 OpenMP Language Terminology
13870 // Structured block - An executable statement with a single entry at the
13871 // top and a single exit at the bottom.
13872 // The point of exit cannot be a branch out of the structured block.
13873 // longjmp() and throw() must not violate the entry/exit criteria.
13874 CS->getCapturedDecl()->setNothrow();
13875 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
13876 OMPD_target_teams_distribute_parallel_for_simd);
13877 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13878 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13879 // 1.2.2 OpenMP Language Terminology
13880 // Structured block - An executable statement with a single entry at the
13881 // top and a single exit at the bottom.
13882 // The point of exit cannot be a branch out of the structured block.
13883 // longjmp() and throw() must not violate the entry/exit criteria.
13884 CS->getCapturedDecl()->setNothrow();
13885 }
13886
13887 OMPLoopBasedDirective::HelperExprs B;
13888 // In presence of clause 'collapse' with number of loops, it will
13889 // define the nested loops number.
13890 unsigned NestedLoopCount =
13891 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
13892 getCollapseNumberExpr(Clauses),
13893 nullptr /*ordered not a clause on distribute*/, CS, *this,
13894 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
13895 if (NestedLoopCount == 0)
13896 return StmtError();
13897
13898 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not "
"built") ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13900, __extension__ __PRETTY_FUNCTION__
))
13899 "omp target teams distribute parallel for simd loop exprs were not "(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not "
"built") ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13900, __extension__ __PRETTY_FUNCTION__
))
13900 "built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not "
"built") ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13900, __extension__ __PRETTY_FUNCTION__
))
;
13901
13902 if (!CurContext->isDependentContext()) {
13903 // Finalize the clauses that need pre-built expressions for CodeGen.
13904 for (OMPClause *C : Clauses) {
13905 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13906 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13907 B.NumIterations, *this, CurScope,
13908 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13909 return StmtError();
13910 }
13911 }
13912
13913 if (checkSimdlenSafelenSpecified(*this, Clauses))
13914 return StmtError();
13915
13916 setFunctionHasBranchProtectedScope();
13917 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
13918 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13919}
13920
13921StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
13922 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13923 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13924 if (!AStmt)
13925 return StmtError();
13926
13927 auto *CS = cast<CapturedStmt>(AStmt);
13928 // 1.2.2 OpenMP Language Terminology
13929 // Structured block - An executable statement with a single entry at the
13930 // top and a single exit at the bottom.
13931 // The point of exit cannot be a branch out of the structured block.
13932 // longjmp() and throw() must not violate the entry/exit criteria.
13933 CS->getCapturedDecl()->setNothrow();
13934 for (int ThisCaptureLevel =
13935 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
13936 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13937 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13938 // 1.2.2 OpenMP Language Terminology
13939 // Structured block - An executable statement with a single entry at the
13940 // top and a single exit at the bottom.
13941 // The point of exit cannot be a branch out of the structured block.
13942 // longjmp() and throw() must not violate the entry/exit criteria.
13943 CS->getCapturedDecl()->setNothrow();
13944 }
13945
13946 OMPLoopBasedDirective::HelperExprs B;
13947 // In presence of clause 'collapse' with number of loops, it will
13948 // define the nested loops number.
13949 unsigned NestedLoopCount = checkOpenMPLoop(
13950 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
13951 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13952 VarsWithImplicitDSA, B);
13953 if (NestedLoopCount == 0)
13954 return StmtError();
13955
13956 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13957, __extension__ __PRETTY_FUNCTION__
))
13957 "omp target teams distribute simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13957, __extension__ __PRETTY_FUNCTION__
))
;
13958
13959 if (!CurContext->isDependentContext()) {
13960 // Finalize the clauses that need pre-built expressions for CodeGen.
13961 for (OMPClause *C : Clauses) {
13962 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13963 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13964 B.NumIterations, *this, CurScope,
13965 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13966 return StmtError();
13967 }
13968 }
13969
13970 if (checkSimdlenSafelenSpecified(*this, Clauses))
13971 return StmtError();
13972
13973 setFunctionHasBranchProtectedScope();
13974 return OMPTargetTeamsDistributeSimdDirective::Create(
13975 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13976}
13977
13978bool Sema::checkTransformableLoopNest(
13979 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
13980 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
13981 Stmt *&Body,
13982 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
13983 &OriginalInits) {
13984 OriginalInits.emplace_back();
13985 bool Result = OMPLoopBasedDirective::doForAllLoops(
13986 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
13987 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
13988 Stmt *CurStmt) {
13989 VarsWithInheritedDSAType TmpDSA;
13990 unsigned SingleNumLoops =
13991 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13992 TmpDSA, LoopHelpers[Cnt]);
13993 if (SingleNumLoops == 0)
13994 return true;
13995 assert(SingleNumLoops == 1 && "Expect single loop iteration space")(static_cast <bool> (SingleNumLoops == 1 && "Expect single loop iteration space"
) ? void (0) : __assert_fail ("SingleNumLoops == 1 && \"Expect single loop iteration space\""
, "clang/lib/Sema/SemaOpenMP.cpp", 13995, __extension__ __PRETTY_FUNCTION__
))
;
13996 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
13997 OriginalInits.back().push_back(For->getInit());
13998 Body = For->getBody();
13999 } else {
14000 assert(isa<CXXForRangeStmt>(CurStmt) &&(static_cast <bool> (isa<CXXForRangeStmt>(CurStmt
) && "Expected canonical for or range-based for loops."
) ? void (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14001, __extension__ __PRETTY_FUNCTION__
))
14001 "Expected canonical for or range-based for loops.")(static_cast <bool> (isa<CXXForRangeStmt>(CurStmt
) && "Expected canonical for or range-based for loops."
) ? void (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14001, __extension__ __PRETTY_FUNCTION__
))
;
14002 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14003 OriginalInits.back().push_back(CXXFor->getBeginStmt());
14004 Body = CXXFor->getBody();
14005 }
14006 OriginalInits.emplace_back();
14007 return false;
14008 },
14009 [&OriginalInits](OMPLoopBasedDirective *Transform) {
14010 Stmt *DependentPreInits;
14011 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14012 DependentPreInits = Dir->getPreInits();
14013 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14014 DependentPreInits = Dir->getPreInits();
14015 else
14016 llvm_unreachable("Unhandled loop transformation")::llvm::llvm_unreachable_internal("Unhandled loop transformation"
, "clang/lib/Sema/SemaOpenMP.cpp", 14016)
;
14017 if (!DependentPreInits)
14018 return;
14019 llvm::append_range(OriginalInits.back(),
14020 cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14021 });
14022 assert(OriginalInits.back().empty() && "No preinit after innermost loop")(static_cast <bool> (OriginalInits.back().empty() &&
"No preinit after innermost loop") ? void (0) : __assert_fail
("OriginalInits.back().empty() && \"No preinit after innermost loop\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14022, __extension__ __PRETTY_FUNCTION__
))
;
14023 OriginalInits.pop_back();
14024 return Result;
14025}
14026
14027StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14028 Stmt *AStmt, SourceLocation StartLoc,
14029 SourceLocation EndLoc) {
14030 auto SizesClauses =
14031 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14032 if (SizesClauses.empty()) {
14033 // A missing 'sizes' clause is already reported by the parser.
14034 return StmtError();
14035 }
14036 const OMPSizesClause *SizesClause = *SizesClauses.begin();
14037 unsigned NumLoops = SizesClause->getNumSizes();
14038
14039 // Empty statement should only be possible if there already was an error.
14040 if (!AStmt)
14041 return StmtError();
14042
14043 // Verify and diagnose loop nest.
14044 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14045 Stmt *Body = nullptr;
14046 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14047 OriginalInits;
14048 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14049 OriginalInits))
14050 return StmtError();
14051
14052 // Delay tiling to when template is completely instantiated.
14053 if (CurContext->isDependentContext())
14054 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14055 NumLoops, AStmt, nullptr, nullptr);
14056
14057 SmallVector<Decl *, 4> PreInits;
14058
14059 // Create iteration variables for the generated loops.
14060 SmallVector<VarDecl *, 4> FloorIndVars;
14061 SmallVector<VarDecl *, 4> TileIndVars;
14062 FloorIndVars.resize(NumLoops);
14063 TileIndVars.resize(NumLoops);
14064 for (unsigned I = 0; I < NumLoops; ++I) {
14065 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14066
14067 assert(LoopHelper.Counters.size() == 1 &&(static_cast <bool> (LoopHelper.Counters.size() == 1 &&
"Expect single-dimensional loop iteration space") ? void (0)
: __assert_fail ("LoopHelper.Counters.size() == 1 && \"Expect single-dimensional loop iteration space\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14068, __extension__ __PRETTY_FUNCTION__
))
14068 "Expect single-dimensional loop iteration space")(static_cast <bool> (LoopHelper.Counters.size() == 1 &&
"Expect single-dimensional loop iteration space") ? void (0)
: __assert_fail ("LoopHelper.Counters.size() == 1 && \"Expect single-dimensional loop iteration space\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14068, __extension__ __PRETTY_FUNCTION__
))
;
14069 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14070 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14071 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14072 QualType CntTy = IterVarRef->getType();
14073
14074 // Iteration variable for the floor (i.e. outer) loop.
14075 {
14076 std::string FloorCntName =
14077 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14078 VarDecl *FloorCntDecl =
14079 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14080 FloorIndVars[I] = FloorCntDecl;
14081 }
14082
14083 // Iteration variable for the tile (i.e. inner) loop.
14084 {
14085 std::string TileCntName =
14086 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14087
14088 // Reuse the iteration variable created by checkOpenMPLoop. It is also
14089 // used by the expressions to derive the original iteration variable's
14090 // value from the logical iteration number.
14091 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14092 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
14093 TileIndVars[I] = TileCntDecl;
14094 }
14095 for (auto &P : OriginalInits[I]) {
14096 if (auto *D = P.dyn_cast<Decl *>())
14097 PreInits.push_back(D);
14098 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14099 PreInits.append(PI->decl_begin(), PI->decl_end());
14100 }
14101 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14102 PreInits.append(PI->decl_begin(), PI->decl_end());
14103 // Gather declarations for the data members used as counters.
14104 for (Expr *CounterRef : LoopHelper.Counters) {
14105 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14106 if (isa<OMPCapturedExprDecl>(CounterDecl))
14107 PreInits.push_back(CounterDecl);
14108 }
14109 }
14110
14111 // Once the original iteration values are set, append the innermost body.
14112 Stmt *Inner = Body;
14113
14114 // Create tile loops from the inside to the outside.
14115 for (int I = NumLoops - 1; I >= 0; --I) {
14116 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14117 Expr *NumIterations = LoopHelper.NumIterations;
14118 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14119 QualType CntTy = OrigCntVar->getType();
14120 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14121 Scope *CurScope = getCurScope();
14122
14123 // Commonly used variables.
14124 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
14125 OrigCntVar->getExprLoc());
14126 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14127 OrigCntVar->getExprLoc());
14128
14129 // For init-statement: auto .tile.iv = .floor.iv
14130 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
14131 /*DirectInit=*/false);
14132 Decl *CounterDecl = TileIndVars[I];
14133 StmtResult InitStmt = new (Context)
14134 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14135 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14136 if (!InitStmt.isUsable())
14137 return StmtError();
14138
14139 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
14140 // NumIterations)
14141 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14142 BO_Add, FloorIV, DimTileSize);
14143 if (!EndOfTile.isUsable())
14144 return StmtError();
14145 ExprResult IsPartialTile =
14146 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14147 NumIterations, EndOfTile.get());
14148 if (!IsPartialTile.isUsable())
14149 return StmtError();
14150 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
14151 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14152 IsPartialTile.get(), NumIterations, EndOfTile.get());
14153 if (!MinTileAndIterSpace.isUsable())
14154 return StmtError();
14155 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14156 BO_LT, TileIV, MinTileAndIterSpace.get());
14157 if (!CondExpr.isUsable())
14158 return StmtError();
14159
14160 // For incr-statement: ++.tile.iv
14161 ExprResult IncrStmt =
14162 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
14163 if (!IncrStmt.isUsable())
14164 return StmtError();
14165
14166 // Statements to set the original iteration variable's value from the
14167 // logical iteration number.
14168 // Generated for loop is:
14169 // Original_for_init;
14170 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
14171 // NumIterations); ++.tile.iv) {
14172 // Original_Body;
14173 // Original_counter_update;
14174 // }
14175 // FIXME: If the innermost body is an loop itself, inserting these
14176 // statements stops it being recognized as a perfectly nested loop (e.g.
14177 // for applying tiling again). If this is the case, sink the expressions
14178 // further into the inner loop.
14179 SmallVector<Stmt *, 4> BodyParts;
14180 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14181 BodyParts.push_back(Inner);
14182 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
14183 Inner->getEndLoc());
14184 Inner = new (Context)
14185 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14186 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14187 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14188 }
14189
14190 // Create floor loops from the inside to the outside.
14191 for (int I = NumLoops - 1; I >= 0; --I) {
14192 auto &LoopHelper = LoopHelpers[I];
14193 Expr *NumIterations = LoopHelper.NumIterations;
14194 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14195 QualType CntTy = OrigCntVar->getType();
14196 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14197 Scope *CurScope = getCurScope();
14198
14199 // Commonly used variables.
14200 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14201 OrigCntVar->getExprLoc());
14202
14203 // For init-statement: auto .floor.iv = 0
14204 AddInitializerToDecl(
14205 FloorIndVars[I],
14206 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14207 /*DirectInit=*/false);
14208 Decl *CounterDecl = FloorIndVars[I];
14209 StmtResult InitStmt = new (Context)
14210 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14211 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14212 if (!InitStmt.isUsable())
14213 return StmtError();
14214
14215 // For cond-expression: .floor.iv < NumIterations
14216 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14217 BO_LT, FloorIV, NumIterations);
14218 if (!CondExpr.isUsable())
14219 return StmtError();
14220
14221 // For incr-statement: .floor.iv += DimTileSize
14222 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
14223 BO_AddAssign, FloorIV, DimTileSize);
14224 if (!IncrStmt.isUsable())
14225 return StmtError();
14226
14227 Inner = new (Context)
14228 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14229 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14230 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14231 }
14232
14233 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
14234 AStmt, Inner,
14235 buildPreInits(Context, PreInits));
14236}
14237
14238StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
14239 Stmt *AStmt,
14240 SourceLocation StartLoc,
14241 SourceLocation EndLoc) {
14242 // Empty statement should only be possible if there already was an error.
14243 if (!AStmt)
14244 return StmtError();
14245
14246 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
14247 return StmtError();
14248
14249 const OMPFullClause *FullClause =
14250 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14251 const OMPPartialClause *PartialClause =
14252 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14253 assert(!(FullClause && PartialClause) &&(static_cast <bool> (!(FullClause && PartialClause
) && "mutual exclusivity must have been checked before"
) ? void (0) : __assert_fail ("!(FullClause && PartialClause) && \"mutual exclusivity must have been checked before\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14254, __extension__ __PRETTY_FUNCTION__
))
14254 "mutual exclusivity must have been checked before")(static_cast <bool> (!(FullClause && PartialClause
) && "mutual exclusivity must have been checked before"
) ? void (0) : __assert_fail ("!(FullClause && PartialClause) && \"mutual exclusivity must have been checked before\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14254, __extension__ __PRETTY_FUNCTION__
))
;
14255
14256 constexpr unsigned NumLoops = 1;
14257 Stmt *Body = nullptr;
14258 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
14259 NumLoops);
14260 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
14261 OriginalInits;
14262 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14263 Body, OriginalInits))
14264 return StmtError();
14265
14266 unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14267
14268 // Delay unrolling to when template is completely instantiated.
14269 if (CurContext->isDependentContext())
14270 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14271 NumGeneratedLoops, nullptr, nullptr);
14272
14273 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14274
14275 if (FullClause) {
14276 if (!VerifyPositiveIntegerConstantInClause(
14277 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14278 /*SuppressExprDiags=*/true)
14279 .isUsable()) {
14280 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14281 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14282 << "#pragma omp unroll full";
14283 return StmtError();
14284 }
14285 }
14286
14287 // The generated loop may only be passed to other loop-associated directive
14288 // when a partial clause is specified. Without the requirement it is
14289 // sufficient to generate loop unroll metadata at code-generation.
14290 if (NumGeneratedLoops == 0)
14291 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14292 NumGeneratedLoops, nullptr, nullptr);
14293
14294 // Otherwise, we need to provide a de-sugared/transformed AST that can be
14295 // associated with another loop directive.
14296 //
14297 // The canonical loop analysis return by checkTransformableLoopNest assumes
14298 // the following structure to be the same loop without transformations or
14299 // directives applied: \code OriginalInits; LoopHelper.PreInits;
14300 // LoopHelper.Counters;
14301 // for (; IV < LoopHelper.NumIterations; ++IV) {
14302 // LoopHelper.Updates;
14303 // Body;
14304 // }
14305 // \endcode
14306 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14307 // and referenced by LoopHelper.IterationVarRef.
14308 //
14309 // The unrolling directive transforms this into the following loop:
14310 // \code
14311 // OriginalInits; \
14312 // LoopHelper.PreInits; > NewPreInits
14313 // LoopHelper.Counters; /
14314 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14315 // #pragma clang loop unroll_count(Factor)
14316 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14317 // {
14318 // LoopHelper.Updates;
14319 // Body;
14320 // }
14321 // }
14322 // \endcode
14323 // where UIV is a new logical iteration counter. IV must be the same VarDecl
14324 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14325 // references it. If the partially unrolled loop is associated with another
14326 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14327 // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14328 // OpenMP canonical loop. The inner loop is not an associable canonical loop
14329 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14330 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14331 // property of the OMPLoopBasedDirective instead of statements in
14332 // CompoundStatement. This is to allow the loop to become a non-outermost loop
14333 // of a canonical loop nest where these PreInits are emitted before the
14334 // outermost directive.
14335
14336 // Determine the PreInit declarations.
14337 SmallVector<Decl *, 4> PreInits;
14338 assert(OriginalInits.size() == 1 &&(static_cast <bool> (OriginalInits.size() == 1 &&
"Expecting a single-dimensional loop iteration space") ? void
(0) : __assert_fail ("OriginalInits.size() == 1 && \"Expecting a single-dimensional loop iteration space\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14339, __extension__ __PRETTY_FUNCTION__
))
14339 "Expecting a single-dimensional loop iteration space")(static_cast <bool> (OriginalInits.size() == 1 &&
"Expecting a single-dimensional loop iteration space") ? void
(0) : __assert_fail ("OriginalInits.size() == 1 && \"Expecting a single-dimensional loop iteration space\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14339, __extension__ __PRETTY_FUNCTION__
))
;
14340 for (auto &P : OriginalInits[0]) {
14341 if (auto *D = P.dyn_cast<Decl *>())
14342 PreInits.push_back(D);
14343 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14344 PreInits.append(PI->decl_begin(), PI->decl_end());
14345 }
14346 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14347 PreInits.append(PI->decl_begin(), PI->decl_end());
14348 // Gather declarations for the data members used as counters.
14349 for (Expr *CounterRef : LoopHelper.Counters) {
14350 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14351 if (isa<OMPCapturedExprDecl>(CounterDecl))
14352 PreInits.push_back(CounterDecl);
14353 }
14354
14355 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14356 QualType IVTy = IterationVarRef->getType();
14357 assert(LoopHelper.Counters.size() == 1 &&(static_cast <bool> (LoopHelper.Counters.size() == 1 &&
"Expecting a single-dimensional loop iteration space") ? void
(0) : __assert_fail ("LoopHelper.Counters.size() == 1 && \"Expecting a single-dimensional loop iteration space\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14358, __extension__ __PRETTY_FUNCTION__
))
14358 "Expecting a single-dimensional loop iteration space")(static_cast <bool> (LoopHelper.Counters.size() == 1 &&
"Expecting a single-dimensional loop iteration space") ? void
(0) : __assert_fail ("LoopHelper.Counters.size() == 1 && \"Expecting a single-dimensional loop iteration space\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14358, __extension__ __PRETTY_FUNCTION__
))
;
14359 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14360
14361 // Determine the unroll factor.
14362 uint64_t Factor;
14363 SourceLocation FactorLoc;
14364 if (Expr *FactorVal = PartialClause->getFactor()) {
14365 Factor =
14366 FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue();
14367 FactorLoc = FactorVal->getExprLoc();
14368 } else {
14369 // TODO: Use a better profitability model.
14370 Factor = 2;
14371 }
14372 assert(Factor > 0 && "Expected positive unroll factor")(static_cast <bool> (Factor > 0 && "Expected positive unroll factor"
) ? void (0) : __assert_fail ("Factor > 0 && \"Expected positive unroll factor\""
, "clang/lib/Sema/SemaOpenMP.cpp", 14372, __extension__ __PRETTY_FUNCTION__
))
;
14373 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
14374 return IntegerLiteral::Create(
14375 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
14376 FactorLoc);
14377 };
14378
14379 // Iteration variable SourceLocations.
14380 SourceLocation OrigVarLoc = OrigVar->getExprLoc();
14381 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
14382 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
14383
14384 // Internal variable names.
14385 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14386 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
14387 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
14388 std::string InnerTripCountName =
14389 (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
14390
14391 // Create the iteration variable for the unrolled loop.
14392 VarDecl *OuterIVDecl =
14393 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
14394 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
14395 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
14396 };
14397
14398 // Iteration variable for the inner loop: Reuse the iteration variable created
14399 // by checkOpenMPLoop.
14400 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
14401 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
14402 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
14403 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
14404 };
14405
14406 // Make a copy of the NumIterations expression for each use: By the AST
14407 // constraints, every expression object in a DeclContext must be unique.
14408 CaptureVars CopyTransformer(*this);
14409 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
14410 return AssertSuccess(
14411 CopyTransformer.TransformExpr(LoopHelper.NumIterations));
14412 };
14413
14414 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
14415 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
14416 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
14417 StmtResult InnerInit = new (Context)
14418 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14419 if (!InnerInit.isUsable())
14420 return StmtError();
14421
14422 // Inner For cond-expression:
14423 // \code
14424 // .unroll_inner.iv < .unrolled.iv + Factor &&
14425 // .unroll_inner.iv < NumIterations
14426 // \endcode
14427 // This conjunction of two conditions allows ScalarEvolution to derive the
14428 // maximum trip count of the inner loop.
14429 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14430 BO_Add, MakeOuterRef(), MakeFactorExpr());
14431 if (!EndOfTile.isUsable())
14432 return StmtError();
14433 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14434 BO_LE, MakeInnerRef(), EndOfTile.get());
14435 if (!InnerCond1.isUsable())
14436 return StmtError();
14437 ExprResult InnerCond2 =
14438 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
14439 MakeNumIterations());
14440 if (!InnerCond2.isUsable())
14441 return StmtError();
14442 ExprResult InnerCond =
14443 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
14444 InnerCond1.get(), InnerCond2.get());
14445 if (!InnerCond.isUsable())
14446 return StmtError();
14447
14448 // Inner For incr-statement: ++.unroll_inner.iv
14449 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
14450 UO_PreInc, MakeInnerRef());
14451 if (!InnerIncr.isUsable())
14452 return StmtError();
14453
14454 // Inner For statement.
14455 SmallVector<Stmt *> InnerBodyStmts;
14456 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14457 InnerBodyStmts.push_back(Body);
14458 CompoundStmt *InnerBody = CompoundStmt::Create(
14459 Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
14460 ForStmt *InnerFor = new (Context)
14461 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
14462 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
14463 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14464
14465 // Unroll metadata for the inner loop.
14466 // This needs to take into account the remainder portion of the unrolled loop,
14467 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
14468 // supports multiple loop exits. Instead, unroll using a factor equivalent to
14469 // the maximum trip count, which will also generate a remainder loop. Just
14470 // `unroll(enable)` (which could have been useful if the user has not
14471 // specified a concrete factor; even though the outer loop cannot be
14472 // influenced anymore, would avoid more code bloat than necessary) will refuse
14473 // the loop because "Won't unroll; remainder loop could not be generated when
14474 // assuming runtime trip count". Even if it did work, it must not choose a
14475 // larger unroll factor than the maximum loop length, or it would always just
14476 // execute the remainder loop.
14477 LoopHintAttr *UnrollHintAttr =
14478 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
14479 LoopHintAttr::Numeric, MakeFactorExpr());
14480 AttributedStmt *InnerUnrolled =
14481 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
14482
14483 // Outer For init-statement: auto .unrolled.iv = 0
14484 AddInitializerToDecl(
14485 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14486 /*DirectInit=*/false);
14487 StmtResult OuterInit = new (Context)
14488 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14489 if (!OuterInit.isUsable())
14490 return StmtError();
14491
14492 // Outer For cond-expression: .unrolled.iv < NumIterations
14493 ExprResult OuterConde =
14494 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
14495 MakeNumIterations());
14496 if (!OuterConde.isUsable())
14497 return StmtError();
14498
14499 // Outer For incr-statement: .unrolled.iv += Factor
14500 ExprResult OuterIncr =
14501 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
14502 MakeOuterRef(), MakeFactorExpr());
14503 if (!OuterIncr.isUsable())
14504 return StmtError();
14505
14506 // Outer For statement.
14507 ForStmt *OuterFor = new (Context)
14508 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
14509 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
14510 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14511
14512 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14513 NumGeneratedLoops, OuterFor,
14514 buildPreInits(Context, PreInits));
14515}
14516
14517OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
14518 SourceLocation StartLoc,
14519 SourceLocation LParenLoc,
14520 SourceLocation EndLoc) {
14521 OMPClause *Res = nullptr;
14522 switch (Kind) {
14523 case OMPC_final:
14524 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
14525 break;
14526 case OMPC_num_threads:
14527 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
14528 break;
14529 case OMPC_safelen:
14530 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
14531 break;
14532 case OMPC_simdlen:
14533 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
14534 break;
14535 case OMPC_allocator:
14536 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
14537 break;
14538 case OMPC_collapse:
14539 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
14540 break;
14541 case OMPC_ordered:
14542 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
14543 break;
14544 case OMPC_num_teams:
14545 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
14546 break;
14547 case OMPC_thread_limit:
14548 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
14549 break;
14550 case OMPC_priority:
14551 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
14552 break;
14553 case OMPC_grainsize:
14554 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
14555 break;
14556 case OMPC_num_tasks:
14557 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
14558 break;
14559 case OMPC_hint:
14560 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
14561 break;
14562 case OMPC_depobj:
14563 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
14564 break;
14565 case OMPC_detach:
14566 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
14567 break;
14568 case OMPC_novariants:
14569 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
14570 break;
14571 case OMPC_nocontext:
14572 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
14573 break;
14574 case OMPC_filter:
14575 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
14576 break;
14577 case OMPC_partial:
14578 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
14579 break;
14580 case OMPC_align:
14581 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
14582 break;
14583 case OMPC_device:
14584 case OMPC_if:
14585 case OMPC_default:
14586 case OMPC_proc_bind:
14587 case OMPC_schedule:
14588 case OMPC_private:
14589 case OMPC_firstprivate:
14590 case OMPC_lastprivate:
14591 case OMPC_shared:
14592 case OMPC_reduction:
14593 case OMPC_task_reduction:
14594 case OMPC_in_reduction:
14595 case OMPC_linear:
14596 case OMPC_aligned:
14597 case OMPC_copyin:
14598 case OMPC_copyprivate:
14599 case OMPC_nowait:
14600 case OMPC_untied:
14601 case OMPC_mergeable:
14602 case OMPC_threadprivate:
14603 case OMPC_sizes:
14604 case OMPC_allocate:
14605 case OMPC_flush:
14606 case OMPC_read:
14607 case OMPC_write:
14608 case OMPC_update:
14609 case OMPC_capture:
14610 case OMPC_compare:
14611 case OMPC_seq_cst:
14612 case OMPC_acq_rel:
14613 case OMPC_acquire:
14614 case OMPC_release:
14615 case OMPC_relaxed:
14616 case OMPC_depend:
14617 case OMPC_threads:
14618 case OMPC_simd:
14619 case OMPC_map:
14620 case OMPC_nogroup:
14621 case OMPC_dist_schedule:
14622 case OMPC_defaultmap:
14623 case OMPC_unknown:
14624 case OMPC_uniform:
14625 case OMPC_to:
14626 case OMPC_from:
14627 case OMPC_use_device_ptr:
14628 case OMPC_use_device_addr:
14629 case OMPC_is_device_ptr:
14630 case OMPC_unified_address:
14631 case OMPC_unified_shared_memory:
14632 case OMPC_reverse_offload:
14633 case OMPC_dynamic_allocators:
14634 case OMPC_atomic_default_mem_order:
14635 case OMPC_device_type:
14636 case OMPC_match:
14637 case OMPC_nontemporal:
14638 case OMPC_order:
14639 case OMPC_destroy:
14640 case OMPC_inclusive:
14641 case OMPC_exclusive:
14642 case OMPC_uses_allocators:
14643 case OMPC_affinity:
14644 case OMPC_when:
14645 case OMPC_bind:
14646 default:
14647 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 14647)
;
14648 }
14649 return Res;
14650}
14651
14652// An OpenMP directive such as 'target parallel' has two captured regions:
14653// for the 'target' and 'parallel' respectively. This function returns
14654// the region in which to capture expressions associated with a clause.
14655// A return value of OMPD_unknown signifies that the expression should not
14656// be captured.
14657static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
14658 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
14659 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
14660 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14661 switch (CKind) {
14662 case OMPC_if:
14663 switch (DKind) {
14664 case OMPD_target_parallel_for_simd:
14665 if (OpenMPVersion >= 50 &&
14666 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14667 CaptureRegion = OMPD_parallel;
14668 break;
14669 }
14670 LLVM_FALLTHROUGH[[gnu::fallthrough]];
14671 case OMPD_target_parallel:
14672 case OMPD_target_parallel_for:
14673 case OMPD_target_parallel_loop:
14674 // If this clause applies to the nested 'parallel' region, capture within
14675 // the 'target' region, otherwise do not capture.
14676 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
14677 CaptureRegion = OMPD_target;
14678 break;
14679 case OMPD_target_teams_distribute_parallel_for_simd:
14680 if (OpenMPVersion >= 50 &&
14681 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14682 CaptureRegion = OMPD_parallel;
14683 break;
14684 }
14685 LLVM_FALLTHROUGH[[gnu::fallthrough]];
14686 case OMPD_target_teams_distribute_parallel_for:
14687 // If this clause applies to the nested 'parallel' region, capture within
14688 // the 'teams' region, otherwise do not capture.
14689 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
14690 CaptureRegion = OMPD_teams;
14691 break;
14692 case OMPD_teams_distribute_parallel_for_simd:
14693 if (OpenMPVersion >= 50 &&
14694 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14695 CaptureRegion = OMPD_parallel;
14696 break;
14697 }
14698 LLVM_FALLTHROUGH[[gnu::fallthrough]];
14699 case OMPD_teams_distribute_parallel_for:
14700 CaptureRegion = OMPD_teams;
14701 break;
14702 case OMPD_target_update:
14703 case OMPD_target_enter_data:
14704 case OMPD_target_exit_data:
14705 CaptureRegion = OMPD_task;
14706 break;
14707 case OMPD_parallel_master_taskloop:
14708 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
14709 CaptureRegion = OMPD_parallel;
14710 break;
14711 case OMPD_parallel_master_taskloop_simd:
14712 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
14713 NameModifier == OMPD_taskloop) {
14714 CaptureRegion = OMPD_parallel;
14715 break;
14716 }
14717 if (OpenMPVersion <= 45)
14718 break;
14719 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14720 CaptureRegion = OMPD_taskloop;
14721 break;
14722 case OMPD_parallel_for_simd:
14723 if (OpenMPVersion <= 45)
14724 break;
14725 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14726 CaptureRegion = OMPD_parallel;
14727 break;
14728 case OMPD_taskloop_simd:
14729 case OMPD_master_taskloop_simd:
14730 if (OpenMPVersion <= 45)
14731 break;
14732 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14733 CaptureRegion = OMPD_taskloop;
14734 break;
14735 case OMPD_distribute_parallel_for_simd:
14736 if (OpenMPVersion <= 45)
14737 break;
14738 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14739 CaptureRegion = OMPD_parallel;
14740 break;
14741 case OMPD_target_simd:
14742 if (OpenMPVersion >= 50 &&
14743 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
14744 CaptureRegion = OMPD_target;
14745 break;
14746 case OMPD_teams_distribute_simd:
14747 case OMPD_target_teams_distribute_simd:
14748 if (OpenMPVersion >= 50 &&
14749 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
14750 CaptureRegion = OMPD_teams;
14751 break;
14752 case OMPD_cancel:
14753 case OMPD_parallel:
14754 case OMPD_parallel_master:
14755 case OMPD_parallel_sections:
14756 case OMPD_parallel_for:
14757 case OMPD_parallel_loop:
14758 case OMPD_target:
14759 case OMPD_target_teams:
14760 case OMPD_target_teams_distribute:
14761 case OMPD_target_teams_loop:
14762 case OMPD_distribute_parallel_for:
14763 case OMPD_task:
14764 case OMPD_taskloop:
14765 case OMPD_master_taskloop:
14766 case OMPD_target_data:
14767 case OMPD_simd:
14768 case OMPD_for_simd:
14769 case OMPD_distribute_simd:
14770 // Do not capture if-clause expressions.
14771 break;
14772 case OMPD_threadprivate:
14773 case OMPD_allocate:
14774 case OMPD_taskyield:
14775 case OMPD_barrier:
14776 case OMPD_taskwait:
14777 case OMPD_cancellation_point:
14778 case OMPD_flush:
14779 case OMPD_depobj:
14780 case OMPD_scan:
14781 case OMPD_declare_reduction:
14782 case OMPD_declare_mapper:
14783 case OMPD_declare_simd:
14784 case OMPD_declare_variant:
14785 case OMPD_begin_declare_variant:
14786 case OMPD_end_declare_variant:
14787 case OMPD_declare_target:
14788 case OMPD_end_declare_target:
14789 case OMPD_loop:
14790 case OMPD_teams_loop:
14791 case OMPD_teams:
14792 case OMPD_tile:
14793 case OMPD_unroll:
14794 case OMPD_for:
14795 case OMPD_sections:
14796 case OMPD_section:
14797 case OMPD_single:
14798 case OMPD_master:
14799 case OMPD_masked:
14800 case OMPD_critical:
14801 case OMPD_taskgroup:
14802 case OMPD_distribute:
14803 case OMPD_ordered:
14804 case OMPD_atomic:
14805 case OMPD_teams_distribute:
14806 case OMPD_requires:
14807 case OMPD_metadirective:
14808 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 14808)
;
14809 case OMPD_unknown:
14810 default:
14811 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 14811)
;
14812 }
14813 break;
14814 case OMPC_num_threads:
14815 switch (DKind) {
14816 case OMPD_target_parallel:
14817 case OMPD_target_parallel_for:
14818 case OMPD_target_parallel_for_simd:
14819 case OMPD_target_parallel_loop:
14820 CaptureRegion = OMPD_target;
14821 break;
14822 case OMPD_teams_distribute_parallel_for:
14823 case OMPD_teams_distribute_parallel_for_simd:
14824 case OMPD_target_teams_distribute_parallel_for:
14825 case OMPD_target_teams_distribute_parallel_for_simd:
14826 CaptureRegion = OMPD_teams;
14827 break;
14828 case OMPD_parallel:
14829 case OMPD_parallel_master:
14830 case OMPD_parallel_sections:
14831 case OMPD_parallel_for:
14832 case OMPD_parallel_for_simd:
14833 case OMPD_parallel_loop:
14834 case OMPD_distribute_parallel_for:
14835 case OMPD_distribute_parallel_for_simd:
14836 case OMPD_parallel_master_taskloop:
14837 case OMPD_parallel_master_taskloop_simd:
14838 // Do not capture num_threads-clause expressions.
14839 break;
14840 case OMPD_target_data:
14841 case OMPD_target_enter_data:
14842 case OMPD_target_exit_data:
14843 case OMPD_target_update:
14844 case OMPD_target:
14845 case OMPD_target_simd:
14846 case OMPD_target_teams:
14847 case OMPD_target_teams_distribute:
14848 case OMPD_target_teams_distribute_simd:
14849 case OMPD_cancel:
14850 case OMPD_task:
14851 case OMPD_taskloop:
14852 case OMPD_taskloop_simd:
14853 case OMPD_master_taskloop:
14854 case OMPD_master_taskloop_simd:
14855 case OMPD_threadprivate:
14856 case OMPD_allocate:
14857 case OMPD_taskyield:
14858 case OMPD_barrier:
14859 case OMPD_taskwait:
14860 case OMPD_cancellation_point:
14861 case OMPD_flush:
14862 case OMPD_depobj:
14863 case OMPD_scan:
14864 case OMPD_declare_reduction:
14865 case OMPD_declare_mapper:
14866 case OMPD_declare_simd:
14867 case OMPD_declare_variant:
14868 case OMPD_begin_declare_variant:
14869 case OMPD_end_declare_variant:
14870 case OMPD_declare_target:
14871 case OMPD_end_declare_target:
14872 case OMPD_loop:
14873 case OMPD_teams_loop:
14874 case OMPD_target_teams_loop:
14875 case OMPD_teams:
14876 case OMPD_simd:
14877 case OMPD_tile:
14878 case OMPD_unroll:
14879 case OMPD_for:
14880 case OMPD_for_simd:
14881 case OMPD_sections:
14882 case OMPD_section:
14883 case OMPD_single:
14884 case OMPD_master:
14885 case OMPD_masked:
14886 case OMPD_critical:
14887 case OMPD_taskgroup:
14888 case OMPD_distribute:
14889 case OMPD_ordered:
14890 case OMPD_atomic:
14891 case OMPD_distribute_simd:
14892 case OMPD_teams_distribute:
14893 case OMPD_teams_distribute_simd:
14894 case OMPD_requires:
14895 case OMPD_metadirective:
14896 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 14896)
;
14897 case OMPD_unknown:
14898 default:
14899 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 14899)
;
14900 }
14901 break;
14902 case OMPC_num_teams:
14903 switch (DKind) {
14904 case OMPD_target_teams:
14905 case OMPD_target_teams_distribute:
14906 case OMPD_target_teams_distribute_simd:
14907 case OMPD_target_teams_distribute_parallel_for:
14908 case OMPD_target_teams_distribute_parallel_for_simd:
14909 case OMPD_target_teams_loop:
14910 CaptureRegion = OMPD_target;
14911 break;
14912 case OMPD_teams_distribute_parallel_for:
14913 case OMPD_teams_distribute_parallel_for_simd:
14914 case OMPD_teams:
14915 case OMPD_teams_distribute:
14916 case OMPD_teams_distribute_simd:
14917 case OMPD_teams_loop:
14918 // Do not capture num_teams-clause expressions.
14919 break;
14920 case OMPD_distribute_parallel_for:
14921 case OMPD_distribute_parallel_for_simd:
14922 case OMPD_task:
14923 case OMPD_taskloop:
14924 case OMPD_taskloop_simd:
14925 case OMPD_master_taskloop:
14926 case OMPD_master_taskloop_simd:
14927 case OMPD_parallel_master_taskloop:
14928 case OMPD_parallel_master_taskloop_simd:
14929 case OMPD_target_data:
14930 case OMPD_target_enter_data:
14931 case OMPD_target_exit_data:
14932 case OMPD_target_update:
14933 case OMPD_cancel:
14934 case OMPD_parallel:
14935 case OMPD_parallel_master:
14936 case OMPD_parallel_sections:
14937 case OMPD_parallel_for:
14938 case OMPD_parallel_for_simd:
14939 case OMPD_parallel_loop:
14940 case OMPD_target:
14941 case OMPD_target_simd:
14942 case OMPD_target_parallel:
14943 case OMPD_target_parallel_for:
14944 case OMPD_target_parallel_for_simd:
14945 case OMPD_target_parallel_loop:
14946 case OMPD_threadprivate:
14947 case OMPD_allocate:
14948 case OMPD_taskyield:
14949 case OMPD_barrier:
14950 case OMPD_taskwait:
14951 case OMPD_cancellation_point:
14952 case OMPD_flush:
14953 case OMPD_depobj:
14954 case OMPD_scan:
14955 case OMPD_declare_reduction:
14956 case OMPD_declare_mapper:
14957 case OMPD_declare_simd:
14958 case OMPD_declare_variant:
14959 case OMPD_begin_declare_variant:
14960 case OMPD_end_declare_variant:
14961 case OMPD_declare_target:
14962 case OMPD_end_declare_target:
14963 case OMPD_loop:
14964 case OMPD_simd:
14965 case OMPD_tile:
14966 case OMPD_unroll:
14967 case OMPD_for:
14968 case OMPD_for_simd:
14969 case OMPD_sections:
14970 case OMPD_section:
14971 case OMPD_single:
14972 case OMPD_master:
14973 case OMPD_masked:
14974 case OMPD_critical:
14975 case OMPD_taskgroup:
14976 case OMPD_distribute:
14977 case OMPD_ordered:
14978 case OMPD_atomic:
14979 case OMPD_distribute_simd:
14980 case OMPD_requires:
14981 case OMPD_metadirective:
14982 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 14982)
;
14983 case OMPD_unknown:
14984 default:
14985 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 14985)
;
14986 }
14987 break;
14988 case OMPC_thread_limit:
14989 switch (DKind) {
14990 case OMPD_target_teams:
14991 case OMPD_target_teams_distribute:
14992 case OMPD_target_teams_distribute_simd:
14993 case OMPD_target_teams_distribute_parallel_for:
14994 case OMPD_target_teams_distribute_parallel_for_simd:
14995 case OMPD_target_teams_loop:
14996 CaptureRegion = OMPD_target;
14997 break;
14998 case OMPD_teams_distribute_parallel_for:
14999 case OMPD_teams_distribute_parallel_for_simd:
15000 case OMPD_teams:
15001 case OMPD_teams_distribute:
15002 case OMPD_teams_distribute_simd:
15003 case OMPD_teams_loop:
15004 // Do not capture thread_limit-clause expressions.
15005 break;
15006 case OMPD_distribute_parallel_for:
15007 case OMPD_distribute_parallel_for_simd:
15008 case OMPD_task:
15009 case OMPD_taskloop:
15010 case OMPD_taskloop_simd:
15011 case OMPD_master_taskloop:
15012 case OMPD_master_taskloop_simd:
15013 case OMPD_parallel_master_taskloop:
15014 case OMPD_parallel_master_taskloop_simd:
15015 case OMPD_target_data:
15016 case OMPD_target_enter_data:
15017 case OMPD_target_exit_data:
15018 case OMPD_target_update:
15019 case OMPD_cancel:
15020 case OMPD_parallel:
15021 case OMPD_parallel_master:
15022 case OMPD_parallel_sections:
15023 case OMPD_parallel_for:
15024 case OMPD_parallel_for_simd:
15025 case OMPD_parallel_loop:
15026 case OMPD_target:
15027 case OMPD_target_simd:
15028 case OMPD_target_parallel:
15029 case OMPD_target_parallel_for:
15030 case OMPD_target_parallel_for_simd:
15031 case OMPD_target_parallel_loop:
15032 case OMPD_threadprivate:
15033 case OMPD_allocate:
15034 case OMPD_taskyield:
15035 case OMPD_barrier:
15036 case OMPD_taskwait:
15037 case OMPD_cancellation_point:
15038 case OMPD_flush:
15039 case OMPD_depobj:
15040 case OMPD_scan:
15041 case OMPD_declare_reduction:
15042 case OMPD_declare_mapper:
15043 case OMPD_declare_simd:
15044 case OMPD_declare_variant:
15045 case OMPD_begin_declare_variant:
15046 case OMPD_end_declare_variant:
15047 case OMPD_declare_target:
15048 case OMPD_end_declare_target:
15049 case OMPD_loop:
15050 case OMPD_simd:
15051 case OMPD_tile:
15052 case OMPD_unroll:
15053 case OMPD_for:
15054 case OMPD_for_simd:
15055 case OMPD_sections:
15056 case OMPD_section:
15057 case OMPD_single:
15058 case OMPD_master:
15059 case OMPD_masked:
15060 case OMPD_critical:
15061 case OMPD_taskgroup:
15062 case OMPD_distribute:
15063 case OMPD_ordered:
15064 case OMPD_atomic:
15065 case OMPD_distribute_simd:
15066 case OMPD_requires:
15067 case OMPD_metadirective:
15068 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15068)
;
15069 case OMPD_unknown:
15070 default:
15071 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15071)
;
15072 }
15073 break;
15074 case OMPC_schedule:
15075 switch (DKind) {
15076 case OMPD_parallel_for:
15077 case OMPD_parallel_for_simd:
15078 case OMPD_distribute_parallel_for:
15079 case OMPD_distribute_parallel_for_simd:
15080 case OMPD_teams_distribute_parallel_for:
15081 case OMPD_teams_distribute_parallel_for_simd:
15082 case OMPD_target_parallel_for:
15083 case OMPD_target_parallel_for_simd:
15084 case OMPD_target_teams_distribute_parallel_for:
15085 case OMPD_target_teams_distribute_parallel_for_simd:
15086 CaptureRegion = OMPD_parallel;
15087 break;
15088 case OMPD_for:
15089 case OMPD_for_simd:
15090 // Do not capture schedule-clause expressions.
15091 break;
15092 case OMPD_task:
15093 case OMPD_taskloop:
15094 case OMPD_taskloop_simd:
15095 case OMPD_master_taskloop:
15096 case OMPD_master_taskloop_simd:
15097 case OMPD_parallel_master_taskloop:
15098 case OMPD_parallel_master_taskloop_simd:
15099 case OMPD_target_data:
15100 case OMPD_target_enter_data:
15101 case OMPD_target_exit_data:
15102 case OMPD_target_update:
15103 case OMPD_teams:
15104 case OMPD_teams_distribute:
15105 case OMPD_teams_distribute_simd:
15106 case OMPD_target_teams_distribute:
15107 case OMPD_target_teams_distribute_simd:
15108 case OMPD_target:
15109 case OMPD_target_simd:
15110 case OMPD_target_parallel:
15111 case OMPD_cancel:
15112 case OMPD_parallel:
15113 case OMPD_parallel_master:
15114 case OMPD_parallel_sections:
15115 case OMPD_threadprivate:
15116 case OMPD_allocate:
15117 case OMPD_taskyield:
15118 case OMPD_barrier:
15119 case OMPD_taskwait:
15120 case OMPD_cancellation_point:
15121 case OMPD_flush:
15122 case OMPD_depobj:
15123 case OMPD_scan:
15124 case OMPD_declare_reduction:
15125 case OMPD_declare_mapper:
15126 case OMPD_declare_simd:
15127 case OMPD_declare_variant:
15128 case OMPD_begin_declare_variant:
15129 case OMPD_end_declare_variant:
15130 case OMPD_declare_target:
15131 case OMPD_end_declare_target:
15132 case OMPD_loop:
15133 case OMPD_teams_loop:
15134 case OMPD_target_teams_loop:
15135 case OMPD_parallel_loop:
15136 case OMPD_target_parallel_loop:
15137 case OMPD_simd:
15138 case OMPD_tile:
15139 case OMPD_unroll:
15140 case OMPD_sections:
15141 case OMPD_section:
15142 case OMPD_single:
15143 case OMPD_master:
15144 case OMPD_masked:
15145 case OMPD_critical:
15146 case OMPD_taskgroup:
15147 case OMPD_distribute:
15148 case OMPD_ordered:
15149 case OMPD_atomic:
15150 case OMPD_distribute_simd:
15151 case OMPD_target_teams:
15152 case OMPD_requires:
15153 case OMPD_metadirective:
15154 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15154)
;
15155 case OMPD_unknown:
15156 default:
15157 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15157)
;
15158 }
15159 break;
15160 case OMPC_dist_schedule:
15161 switch (DKind) {
15162 case OMPD_teams_distribute_parallel_for:
15163 case OMPD_teams_distribute_parallel_for_simd:
15164 case OMPD_teams_distribute:
15165 case OMPD_teams_distribute_simd:
15166 case OMPD_target_teams_distribute_parallel_for:
15167 case OMPD_target_teams_distribute_parallel_for_simd:
15168 case OMPD_target_teams_distribute:
15169 case OMPD_target_teams_distribute_simd:
15170 CaptureRegion = OMPD_teams;
15171 break;
15172 case OMPD_distribute_parallel_for:
15173 case OMPD_distribute_parallel_for_simd:
15174 case OMPD_distribute:
15175 case OMPD_distribute_simd:
15176 // Do not capture dist_schedule-clause expressions.
15177 break;
15178 case OMPD_parallel_for:
15179 case OMPD_parallel_for_simd:
15180 case OMPD_target_parallel_for_simd:
15181 case OMPD_target_parallel_for:
15182 case OMPD_task:
15183 case OMPD_taskloop:
15184 case OMPD_taskloop_simd:
15185 case OMPD_master_taskloop:
15186 case OMPD_master_taskloop_simd:
15187 case OMPD_parallel_master_taskloop:
15188 case OMPD_parallel_master_taskloop_simd:
15189 case OMPD_target_data:
15190 case OMPD_target_enter_data:
15191 case OMPD_target_exit_data:
15192 case OMPD_target_update:
15193 case OMPD_teams:
15194 case OMPD_target:
15195 case OMPD_target_simd:
15196 case OMPD_target_parallel:
15197 case OMPD_cancel:
15198 case OMPD_parallel:
15199 case OMPD_parallel_master:
15200 case OMPD_parallel_sections:
15201 case OMPD_threadprivate:
15202 case OMPD_allocate:
15203 case OMPD_taskyield:
15204 case OMPD_barrier:
15205 case OMPD_taskwait:
15206 case OMPD_cancellation_point:
15207 case OMPD_flush:
15208 case OMPD_depobj:
15209 case OMPD_scan:
15210 case OMPD_declare_reduction:
15211 case OMPD_declare_mapper:
15212 case OMPD_declare_simd:
15213 case OMPD_declare_variant:
15214 case OMPD_begin_declare_variant:
15215 case OMPD_end_declare_variant:
15216 case OMPD_declare_target:
15217 case OMPD_end_declare_target:
15218 case OMPD_loop:
15219 case OMPD_teams_loop:
15220 case OMPD_target_teams_loop:
15221 case OMPD_parallel_loop:
15222 case OMPD_target_parallel_loop:
15223 case OMPD_simd:
15224 case OMPD_tile:
15225 case OMPD_unroll:
15226 case OMPD_for:
15227 case OMPD_for_simd:
15228 case OMPD_sections:
15229 case OMPD_section:
15230 case OMPD_single:
15231 case OMPD_master:
15232 case OMPD_masked:
15233 case OMPD_critical:
15234 case OMPD_taskgroup:
15235 case OMPD_ordered:
15236 case OMPD_atomic:
15237 case OMPD_target_teams:
15238 case OMPD_requires:
15239 case OMPD_metadirective:
15240 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with dist_schedule clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15240)
;
15241 case OMPD_unknown:
15242 default:
15243 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15243)
;
15244 }
15245 break;
15246 case OMPC_device:
15247 switch (DKind) {
15248 case OMPD_target_update:
15249 case OMPD_target_enter_data:
15250 case OMPD_target_exit_data:
15251 case OMPD_target:
15252 case OMPD_target_simd:
15253 case OMPD_target_teams:
15254 case OMPD_target_parallel:
15255 case OMPD_target_teams_distribute:
15256 case OMPD_target_teams_distribute_simd:
15257 case OMPD_target_parallel_for:
15258 case OMPD_target_parallel_for_simd:
15259 case OMPD_target_parallel_loop:
15260 case OMPD_target_teams_distribute_parallel_for:
15261 case OMPD_target_teams_distribute_parallel_for_simd:
15262 case OMPD_target_teams_loop:
15263 case OMPD_dispatch:
15264 CaptureRegion = OMPD_task;
15265 break;
15266 case OMPD_target_data:
15267 case OMPD_interop:
15268 // Do not capture device-clause expressions.
15269 break;
15270 case OMPD_teams_distribute_parallel_for:
15271 case OMPD_teams_distribute_parallel_for_simd:
15272 case OMPD_teams:
15273 case OMPD_teams_distribute:
15274 case OMPD_teams_distribute_simd:
15275 case OMPD_distribute_parallel_for:
15276 case OMPD_distribute_parallel_for_simd:
15277 case OMPD_task:
15278 case OMPD_taskloop:
15279 case OMPD_taskloop_simd:
15280 case OMPD_master_taskloop:
15281 case OMPD_master_taskloop_simd:
15282 case OMPD_parallel_master_taskloop:
15283 case OMPD_parallel_master_taskloop_simd:
15284 case OMPD_cancel:
15285 case OMPD_parallel:
15286 case OMPD_parallel_master:
15287 case OMPD_parallel_sections:
15288 case OMPD_parallel_for:
15289 case OMPD_parallel_for_simd:
15290 case OMPD_threadprivate:
15291 case OMPD_allocate:
15292 case OMPD_taskyield:
15293 case OMPD_barrier:
15294 case OMPD_taskwait:
15295 case OMPD_cancellation_point:
15296 case OMPD_flush:
15297 case OMPD_depobj:
15298 case OMPD_scan:
15299 case OMPD_declare_reduction:
15300 case OMPD_declare_mapper:
15301 case OMPD_declare_simd:
15302 case OMPD_declare_variant:
15303 case OMPD_begin_declare_variant:
15304 case OMPD_end_declare_variant:
15305 case OMPD_declare_target:
15306 case OMPD_end_declare_target:
15307 case OMPD_loop:
15308 case OMPD_teams_loop:
15309 case OMPD_parallel_loop:
15310 case OMPD_simd:
15311 case OMPD_tile:
15312 case OMPD_unroll:
15313 case OMPD_for:
15314 case OMPD_for_simd:
15315 case OMPD_sections:
15316 case OMPD_section:
15317 case OMPD_single:
15318 case OMPD_master:
15319 case OMPD_masked:
15320 case OMPD_critical:
15321 case OMPD_taskgroup:
15322 case OMPD_distribute:
15323 case OMPD_ordered:
15324 case OMPD_atomic:
15325 case OMPD_distribute_simd:
15326 case OMPD_requires:
15327 case OMPD_metadirective:
15328 llvm_unreachable("Unexpected OpenMP directive with device-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with device-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15328)
;
15329 case OMPD_unknown:
15330 default:
15331 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15331)
;
15332 }
15333 break;
15334 case OMPC_grainsize:
15335 case OMPC_num_tasks:
15336 case OMPC_final:
15337 case OMPC_priority:
15338 switch (DKind) {
15339 case OMPD_task:
15340 case OMPD_taskloop:
15341 case OMPD_taskloop_simd:
15342 case OMPD_master_taskloop:
15343 case OMPD_master_taskloop_simd:
15344 break;
15345 case OMPD_parallel_master_taskloop:
15346 case OMPD_parallel_master_taskloop_simd:
15347 CaptureRegion = OMPD_parallel;
15348 break;
15349 case OMPD_target_update:
15350 case OMPD_target_enter_data:
15351 case OMPD_target_exit_data:
15352 case OMPD_target:
15353 case OMPD_target_simd:
15354 case OMPD_target_teams:
15355 case OMPD_target_parallel:
15356 case OMPD_target_teams_distribute:
15357 case OMPD_target_teams_distribute_simd:
15358 case OMPD_target_parallel_for:
15359 case OMPD_target_parallel_for_simd:
15360 case OMPD_target_teams_distribute_parallel_for:
15361 case OMPD_target_teams_distribute_parallel_for_simd:
15362 case OMPD_target_data:
15363 case OMPD_teams_distribute_parallel_for:
15364 case OMPD_teams_distribute_parallel_for_simd:
15365 case OMPD_teams:
15366 case OMPD_teams_distribute:
15367 case OMPD_teams_distribute_simd:
15368 case OMPD_distribute_parallel_for:
15369 case OMPD_distribute_parallel_for_simd:
15370 case OMPD_cancel:
15371 case OMPD_parallel:
15372 case OMPD_parallel_master:
15373 case OMPD_parallel_sections:
15374 case OMPD_parallel_for:
15375 case OMPD_parallel_for_simd:
15376 case OMPD_threadprivate:
15377 case OMPD_allocate:
15378 case OMPD_taskyield:
15379 case OMPD_barrier:
15380 case OMPD_taskwait:
15381 case OMPD_cancellation_point:
15382 case OMPD_flush:
15383 case OMPD_depobj:
15384 case OMPD_scan:
15385 case OMPD_declare_reduction:
15386 case OMPD_declare_mapper:
15387 case OMPD_declare_simd:
15388 case OMPD_declare_variant:
15389 case OMPD_begin_declare_variant:
15390 case OMPD_end_declare_variant:
15391 case OMPD_declare_target:
15392 case OMPD_end_declare_target:
15393 case OMPD_loop:
15394 case OMPD_teams_loop:
15395 case OMPD_target_teams_loop:
15396 case OMPD_parallel_loop:
15397 case OMPD_target_parallel_loop:
15398 case OMPD_simd:
15399 case OMPD_tile:
15400 case OMPD_unroll:
15401 case OMPD_for:
15402 case OMPD_for_simd:
15403 case OMPD_sections:
15404 case OMPD_section:
15405 case OMPD_single:
15406 case OMPD_master:
15407 case OMPD_masked:
15408 case OMPD_critical:
15409 case OMPD_taskgroup:
15410 case OMPD_distribute:
15411 case OMPD_ordered:
15412 case OMPD_atomic:
15413 case OMPD_distribute_simd:
15414 case OMPD_requires:
15415 case OMPD_metadirective:
15416 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15416)
;
15417 case OMPD_unknown:
15418 default:
15419 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15419)
;
15420 }
15421 break;
15422 case OMPC_novariants:
15423 case OMPC_nocontext:
15424 switch (DKind) {
15425 case OMPD_dispatch:
15426 CaptureRegion = OMPD_task;
15427 break;
15428 default:
15429 llvm_unreachable("Unexpected OpenMP directive")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive"
, "clang/lib/Sema/SemaOpenMP.cpp", 15429)
;
15430 }
15431 break;
15432 case OMPC_filter:
15433 // Do not capture filter-clause expressions.
15434 break;
15435 case OMPC_when:
15436 if (DKind == OMPD_metadirective) {
15437 CaptureRegion = OMPD_metadirective;
15438 } else if (DKind == OMPD_unknown) {
15439 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15439)
;
15440 } else {
15441 llvm_unreachable("Unexpected OpenMP directive with when clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with when clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15441)
;
15442 }
15443 break;
15444 case OMPC_firstprivate:
15445 case OMPC_lastprivate:
15446 case OMPC_reduction:
15447 case OMPC_task_reduction:
15448 case OMPC_in_reduction:
15449 case OMPC_linear:
15450 case OMPC_default:
15451 case OMPC_proc_bind:
15452 case OMPC_safelen:
15453 case OMPC_simdlen:
15454 case OMPC_sizes:
15455 case OMPC_allocator:
15456 case OMPC_collapse:
15457 case OMPC_private:
15458 case OMPC_shared:
15459 case OMPC_aligned:
15460 case OMPC_copyin:
15461 case OMPC_copyprivate:
15462 case OMPC_ordered:
15463 case OMPC_nowait:
15464 case OMPC_untied:
15465 case OMPC_mergeable:
15466 case OMPC_threadprivate:
15467 case OMPC_allocate:
15468 case OMPC_flush:
15469 case OMPC_depobj:
15470 case OMPC_read:
15471 case OMPC_write:
15472 case OMPC_update:
15473 case OMPC_capture:
15474 case OMPC_compare:
15475 case OMPC_seq_cst:
15476 case OMPC_acq_rel:
15477 case OMPC_acquire:
15478 case OMPC_release:
15479 case OMPC_relaxed:
15480 case OMPC_depend:
15481 case OMPC_threads:
15482 case OMPC_simd:
15483 case OMPC_map:
15484 case OMPC_nogroup:
15485 case OMPC_hint:
15486 case OMPC_defaultmap:
15487 case OMPC_unknown:
15488 case OMPC_uniform:
15489 case OMPC_to:
15490 case OMPC_from:
15491 case OMPC_use_device_ptr:
15492 case OMPC_use_device_addr:
15493 case OMPC_is_device_ptr:
15494 case OMPC_unified_address:
15495 case OMPC_unified_shared_memory:
15496 case OMPC_reverse_offload:
15497 case OMPC_dynamic_allocators:
15498 case OMPC_atomic_default_mem_order:
15499 case OMPC_device_type:
15500 case OMPC_match:
15501 case OMPC_nontemporal:
15502 case OMPC_order:
15503 case OMPC_destroy:
15504 case OMPC_detach:
15505 case OMPC_inclusive:
15506 case OMPC_exclusive:
15507 case OMPC_uses_allocators:
15508 case OMPC_affinity:
15509 case OMPC_bind:
15510 default:
15511 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "clang/lib/Sema/SemaOpenMP.cpp", 15511)
;
15512 }
15513 return CaptureRegion;
15514}
15515
15516OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
15517 Expr *Condition, SourceLocation StartLoc,
15518 SourceLocation LParenLoc,
15519 SourceLocation NameModifierLoc,
15520 SourceLocation ColonLoc,
15521 SourceLocation EndLoc) {
15522 Expr *ValExpr = Condition;
15523 Stmt *HelperValStmt = nullptr;
15524 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15525 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15526 !Condition->isInstantiationDependent() &&
15527 !Condition->containsUnexpandedParameterPack()) {
15528 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15529 if (Val.isInvalid())
15530 return nullptr;
15531
15532 ValExpr = Val.get();
15533
15534 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15535 CaptureRegion = getOpenMPCaptureRegionForClause(
15536 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
15537 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15538 ValExpr = MakeFullExpr(ValExpr).get();
15539 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15540 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15541 HelperValStmt = buildPreInits(Context, Captures);
15542 }
15543 }
15544
15545 return new (Context)
15546 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
15547 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
15548}
15549
15550OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
15551 SourceLocation StartLoc,
15552 SourceLocation LParenLoc,
15553 SourceLocation EndLoc) {
15554 Expr *ValExpr = Condition;
15555 Stmt *HelperValStmt = nullptr;
15556 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15557 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15558 !Condition->isInstantiationDependent() &&
15559 !Condition->containsUnexpandedParameterPack()) {
15560 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15561 if (Val.isInvalid())
15562 return nullptr;
15563
15564 ValExpr = MakeFullExpr(Val.get()).get();
15565
15566 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15567 CaptureRegion =
15568 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
15569 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15570 ValExpr = MakeFullExpr(ValExpr).get();
15571 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15572 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15573 HelperValStmt = buildPreInits(Context, Captures);
15574 }
15575 }
15576
15577 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
15578 StartLoc, LParenLoc, EndLoc);
15579}
15580
15581ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
15582 Expr *Op) {
15583 if (!Op)
15584 return ExprError();
15585
15586 class IntConvertDiagnoser : public ICEConvertDiagnoser {
15587 public:
15588 IntConvertDiagnoser()
15589 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
15590 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
15591 QualType T) override {
15592 return S.Diag(Loc, diag::err_omp_not_integral) << T;
15593 }
15594 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
15595 QualType T) override {
15596 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
15597 }
15598 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
15599 QualType T,
15600 QualType ConvTy) override {
15601 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
15602 }
15603 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
15604 QualType ConvTy) override {
15605 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15606 << ConvTy->isEnumeralType() << ConvTy;
15607 }
15608 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
15609 QualType T) override {
15610 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
15611 }
15612 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
15613 QualType ConvTy) override {
15614 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15615 << ConvTy->isEnumeralType() << ConvTy;
15616 }
15617 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
15618 QualType) override {
15619 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "clang/lib/Sema/SemaOpenMP.cpp", 15619)
;
15620 }
15621 } ConvertDiagnoser;
15622 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
15623}
15624
15625static bool
15626isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
15627 bool StrictlyPositive, bool BuildCapture = false,
15628 OpenMPDirectiveKind DKind = OMPD_unknown,
15629 OpenMPDirectiveKind *CaptureRegion = nullptr,
15630 Stmt **HelperValStmt = nullptr) {
15631 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
15632 !ValExpr->isInstantiationDependent()) {
15633 SourceLocation Loc = ValExpr->getExprLoc();
15634 ExprResult Value =
15635 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
15636 if (Value.isInvalid())
15637 return false;
15638
15639 ValExpr = Value.get();
15640 // The expression must evaluate to a non-negative integer value.
15641 if (Optional<llvm::APSInt> Result =
15642 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
15643 if (Result->isSigned() &&
15644 !((!StrictlyPositive && Result->isNonNegative()) ||
15645 (StrictlyPositive && Result->isStrictlyPositive()))) {
15646 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
15647 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15648 << ValExpr->getSourceRange();
15649 return false;
15650 }
15651 }
15652 if (!BuildCapture)
15653 return true;
15654 *CaptureRegion =
15655 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
15656 if (*CaptureRegion != OMPD_unknown &&
15657 !SemaRef.CurContext->isDependentContext()) {
15658 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
15659 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15660 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
15661 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
15662 }
15663 }
15664 return true;
15665}
15666
15667OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
15668 SourceLocation StartLoc,
15669 SourceLocation LParenLoc,
15670 SourceLocation EndLoc) {
15671 Expr *ValExpr = NumThreads;
15672 Stmt *HelperValStmt = nullptr;
15673
15674 // OpenMP [2.5, Restrictions]
15675 // The num_threads expression must evaluate to a positive integer value.
15676 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
15677 /*StrictlyPositive=*/true))
15678 return nullptr;
15679
15680 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15681 OpenMPDirectiveKind CaptureRegion =
15682 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
15683 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15684 ValExpr = MakeFullExpr(ValExpr).get();
15685 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15686 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15687 HelperValStmt = buildPreInits(Context, Captures);
15688 }
15689
15690 return new (Context) OMPNumThreadsClause(
15691 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15692}
15693
15694ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
15695 OpenMPClauseKind CKind,
15696 bool StrictlyPositive,
15697 bool SuppressExprDiags) {
15698 if (!E)
15699 return ExprError();
15700 if (E->isValueDependent() || E->isTypeDependent() ||
15701 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
15702 return E;
15703
15704 llvm::APSInt Result;
15705 ExprResult ICE;
15706 if (SuppressExprDiags) {
15707 // Use a custom diagnoser that suppresses 'note' diagnostics about the
15708 // expression.
15709 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
15710 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
15711 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
15712 SourceLocation Loc) override {
15713 llvm_unreachable("Diagnostic suppressed")::llvm::llvm_unreachable_internal("Diagnostic suppressed", "clang/lib/Sema/SemaOpenMP.cpp"
, 15713)
;
15714 }
15715 } Diagnoser;
15716 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
15717 } else {
15718 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
15719 }
15720 if (ICE.isInvalid())
15721 return ExprError();
15722
15723 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
15724 (!StrictlyPositive && !Result.isNonNegative())) {
15725 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
15726 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15727 << E->getSourceRange();
15728 return ExprError();
15729 }
15730 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
15731 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
15732 << E->getSourceRange();
15733 return ExprError();
15734 }
15735 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
15736 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
15737 else if (CKind == OMPC_ordered)
15738 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
15739 return ICE;
15740}
15741
15742OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
15743 SourceLocation LParenLoc,
15744 SourceLocation EndLoc) {
15745 // OpenMP [2.8.1, simd construct, Description]
15746 // The parameter of the safelen clause must be a constant
15747 // positive integer expression.
15748 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
15749 if (Safelen.isInvalid())
15750 return nullptr;
15751 return new (Context)
15752 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
15753}
15754
15755OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
15756 SourceLocation LParenLoc,
15757 SourceLocation EndLoc) {
15758 // OpenMP [2.8.1, simd construct, Description]
15759 // The parameter of the simdlen clause must be a constant
15760 // positive integer expression.
15761 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
15762 if (Simdlen.isInvalid())
15763 return nullptr;
15764 return new (Context)
15765 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
15766}
15767
15768/// Tries to find omp_allocator_handle_t type.
15769static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
15770 DSAStackTy *Stack) {
15771 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
15772 if (!OMPAllocatorHandleT.isNull())
15773 return true;
15774 // Build the predefined allocator expressions.
15775 bool ErrorFound = false;
15776 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
15777 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
15778 StringRef Allocator =
15779 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
15780 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
15781 auto *VD = dyn_cast_or_null<ValueDecl>(
15782 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
15783 if (!VD) {
15784 ErrorFound = true;
15785 break;
15786 }
15787 QualType AllocatorType =
15788 VD->getType().getNonLValueExprType(S.getASTContext());
15789 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
15790 if (!Res.isUsable()) {
15791 ErrorFound = true;
15792 break;
15793 }
15794 if (OMPAllocatorHandleT.isNull())
15795 OMPAllocatorHandleT = AllocatorType;
15796 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
15797 ErrorFound = true;
15798 break;
15799 }
15800 Stack->setAllocator(AllocatorKind, Res.get());
15801 }
15802 if (ErrorFound) {
15803 S.Diag(Loc, diag::err_omp_implied_type_not_found)
15804 << "omp_allocator_handle_t";
15805 return false;
15806 }
15807 OMPAllocatorHandleT.addConst();
15808 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
15809 return true;
15810}
15811
15812OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
15813 SourceLocation LParenLoc,
15814 SourceLocation EndLoc) {
15815 // OpenMP [2.11.3, allocate Directive, Description]
15816 // allocator is an expression of omp_allocator_handle_t type.
15817 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
15818 return nullptr;
15819
15820 ExprResult Allocator = DefaultLvalueConversion(A);
15821 if (Allocator.isInvalid())
15822 return nullptr;
15823 Allocator = PerformImplicitConversion(Allocator.get(),
15824 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
15825 Sema::AA_Initializing,
15826 /*AllowExplicit=*/true);
15827 if (Allocator.isInvalid())
15828 return nullptr;
15829 return new (Context)
15830 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
15831}
15832
15833OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
15834 SourceLocation StartLoc,
15835 SourceLocation LParenLoc,
15836 SourceLocation EndLoc) {
15837 // OpenMP [2.7.1, loop construct, Description]
15838 // OpenMP [2.8.1, simd construct, Description]
15839 // OpenMP [2.9.6, distribute construct, Description]
15840 // The parameter of the collapse clause must be a constant
15841 // positive integer expression.
15842 ExprResult NumForLoopsResult =
15843 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
15844 if (NumForLoopsResult.isInvalid())
15845 return nullptr;
15846 return new (Context)
15847 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
15848}
15849
15850OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
15851 SourceLocation EndLoc,
15852 SourceLocation LParenLoc,
15853 Expr *NumForLoops) {
15854 // OpenMP [2.7.1, loop construct, Description]
15855 // OpenMP [2.8.1, simd construct, Description]
15856 // OpenMP [2.9.6, distribute construct, Description]
15857 // The parameter of the ordered clause must be a constant
15858 // positive integer expression if any.
15859 if (NumForLoops && LParenLoc.isValid()) {
15860 ExprResult NumForLoopsResult =
15861 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
15862 if (NumForLoopsResult.isInvalid())
15863 return nullptr;
15864 NumForLoops = NumForLoopsResult.get();
15865 } else {
15866 NumForLoops = nullptr;
15867 }
15868 auto *Clause = OMPOrderedClause::Create(
15869 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
15870 StartLoc, LParenLoc, EndLoc);
15871 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
15872 return Clause;
15873}
15874
15875OMPClause *Sema::ActOnOpenMPSimpleClause(
15876 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
15877 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
15878 OMPClause *Res = nullptr;
15879 switch (Kind) {
15880 case OMPC_default:
15881 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
15882 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15883 break;
15884 case OMPC_proc_bind:
15885 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
15886 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15887 break;
15888 case OMPC_atomic_default_mem_order:
15889 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
15890 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
15891 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15892 break;
15893 case OMPC_order:
15894 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
15895 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15896 break;
15897 case OMPC_update:
15898 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
15899 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15900 break;
15901 case OMPC_bind:
15902 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
15903 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15904 break;
15905 case OMPC_if:
15906 case OMPC_final:
15907 case OMPC_num_threads:
15908 case OMPC_safelen:
15909 case OMPC_simdlen:
15910 case OMPC_sizes:
15911 case OMPC_allocator:
15912 case OMPC_collapse:
15913 case OMPC_schedule:
15914 case OMPC_private:
15915 case OMPC_firstprivate:
15916 case OMPC_lastprivate:
15917 case OMPC_shared:
15918 case OMPC_reduction:
15919 case OMPC_task_reduction:
15920 case OMPC_in_reduction:
15921 case OMPC_linear:
15922 case OMPC_aligned:
15923 case OMPC_copyin:
15924 case OMPC_copyprivate:
15925 case OMPC_ordered:
15926 case OMPC_nowait:
15927 case OMPC_untied:
15928 case OMPC_mergeable:
15929 case OMPC_threadprivate:
15930 case OMPC_allocate:
15931 case OMPC_flush:
15932 case OMPC_depobj:
15933 case OMPC_read:
15934 case OMPC_write:
15935 case OMPC_capture:
15936 case OMPC_compare:
15937 case OMPC_seq_cst:
15938 case OMPC_acq_rel:
15939 case OMPC_acquire:
15940 case OMPC_release:
15941 case OMPC_relaxed:
15942 case OMPC_depend:
15943 case OMPC_device:
15944 case OMPC_threads:
15945 case OMPC_simd:
15946 case OMPC_map:
15947 case OMPC_num_teams:
15948 case OMPC_thread_limit:
15949 case OMPC_priority:
15950 case OMPC_grainsize:
15951 case OMPC_nogroup:
15952 case OMPC_num_tasks:
15953 case OMPC_hint:
15954 case OMPC_dist_schedule:
15955 case OMPC_defaultmap:
15956 case OMPC_unknown:
15957 case OMPC_uniform:
15958 case OMPC_to:
15959 case OMPC_from:
15960 case OMPC_use_device_ptr:
15961 case OMPC_use_device_addr:
15962 case OMPC_is_device_ptr:
15963 case OMPC_has_device_addr:
15964 case OMPC_unified_address:
15965 case OMPC_unified_shared_memory:
15966 case OMPC_reverse_offload:
15967 case OMPC_dynamic_allocators:
15968 case OMPC_device_type:
15969 case OMPC_match:
15970 case OMPC_nontemporal:
15971 case OMPC_destroy:
15972 case OMPC_novariants:
15973 case OMPC_nocontext:
15974 case OMPC_detach:
15975 case OMPC_inclusive:
15976 case OMPC_exclusive:
15977 case OMPC_uses_allocators:
15978 case OMPC_affinity:
15979 case OMPC_when:
15980 default:
15981 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 15981)
;
15982 }
15983 return Res;
15984}
15985
15986static std::string
15987getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
15988 ArrayRef<unsigned> Exclude = llvm::None) {
15989 SmallString<256> Buffer;
15990 llvm::raw_svector_ostream Out(Buffer);
15991 unsigned Skipped = Exclude.size();
15992 auto S = Exclude.begin(), E = Exclude.end();
15993 for (unsigned I = First; I < Last; ++I) {
15994 if (std::find(S, E, I) != E) {
15995 --Skipped;
15996 continue;
15997 }
15998 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
15999 if (I + Skipped + 2 == Last)
16000 Out << " or ";
16001 else if (I + Skipped + 1 != Last)
16002 Out << ", ";
16003 }
16004 return std::string(Out.str());
16005}
16006
16007OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
16008 SourceLocation KindKwLoc,
16009 SourceLocation StartLoc,
16010 SourceLocation LParenLoc,
16011 SourceLocation EndLoc) {
16012 if (Kind == OMP_DEFAULT_unknown) {
16013 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16014 << getListOfPossibleValues(OMPC_default, /*First=*/0,
16015 /*Last=*/unsigned(OMP_DEFAULT_unknown))
16016 << getOpenMPClauseName(OMPC_default);
16017 return nullptr;
16018 }
16019
16020 switch (Kind) {
16021 case OMP_DEFAULT_none:
16022 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
16023 break;
16024 case OMP_DEFAULT_shared:
16025 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
16026 break;
16027 case OMP_DEFAULT_firstprivate:
16028 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
16029 break;
16030 default:
16031 llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 16031)
;
16032 }
16033
16034 return new (Context)
16035 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16036}
16037
16038OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
16039 SourceLocation KindKwLoc,
16040 SourceLocation StartLoc,
16041 SourceLocation LParenLoc,
16042 SourceLocation EndLoc) {
16043 if (Kind == OMP_PROC_BIND_unknown) {
16044 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16045 << getListOfPossibleValues(OMPC_proc_bind,
16046 /*First=*/unsigned(OMP_PROC_BIND_master),
16047 /*Last=*/
16048 unsigned(LangOpts.OpenMP > 50
16049 ? OMP_PROC_BIND_primary
16050 : OMP_PROC_BIND_spread) +
16051 1)
16052 << getOpenMPClauseName(OMPC_proc_bind);
16053 return nullptr;
16054 }
16055 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
16056 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16057 << getListOfPossibleValues(OMPC_proc_bind,
16058 /*First=*/unsigned(OMP_PROC_BIND_master),
16059 /*Last=*/
16060 unsigned(OMP_PROC_BIND_spread) + 1)
16061 << getOpenMPClauseName(OMPC_proc_bind);
16062 return new (Context)
16063 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16064}
16065
16066OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
16067 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
16068 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16069 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
16070 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16071 << getListOfPossibleValues(
16072 OMPC_atomic_default_mem_order, /*First=*/0,
16073 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
16074 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
16075 return nullptr;
16076 }
16077 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
16078 LParenLoc, EndLoc);
16079}
16080
16081OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
16082 SourceLocation KindKwLoc,
16083 SourceLocation StartLoc,
16084 SourceLocation LParenLoc,
16085 SourceLocation EndLoc) {
16086 if (Kind == OMPC_ORDER_unknown) {
16087 static_assert(OMPC_ORDER_unknown > 0,
16088 "OMPC_ORDER_unknown not greater than 0");
16089 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16090 << getListOfPossibleValues(OMPC_order, /*First=*/0,
16091 /*Last=*/OMPC_ORDER_unknown)
16092 << getOpenMPClauseName(OMPC_order);
16093 return nullptr;
16094 }
16095 return new (Context)
16096 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16097}
16098
16099OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
16100 SourceLocation KindKwLoc,
16101 SourceLocation StartLoc,
16102 SourceLocation LParenLoc,
16103 SourceLocation EndLoc) {
16104 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
16105 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16106 SmallVector<unsigned> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
16107 OMPC_DEPEND_depobj};
16108 if (LangOpts.OpenMP < 51)
16109 Except.push_back(OMPC_DEPEND_inoutset);
16110 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16111 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
16112 /*Last=*/OMPC_DEPEND_unknown, Except)
16113 << getOpenMPClauseName(OMPC_update);
16114 return nullptr;
16115 }
16116 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
16117 EndLoc);
16118}
16119
16120OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
16121 SourceLocation StartLoc,
16122 SourceLocation LParenLoc,
16123 SourceLocation EndLoc) {
16124 for (Expr *SizeExpr : SizeExprs) {
16125 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
16126 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
16127 if (!NumForLoopsResult.isUsable())
16128 return nullptr;
16129 }
16130
16131 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(SizeExprs.size());
16132 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16133 SizeExprs);
16134}
16135
16136OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
16137 SourceLocation EndLoc) {
16138 return OMPFullClause::Create(Context, StartLoc, EndLoc);
16139}
16140
16141OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
16142 SourceLocation StartLoc,
16143 SourceLocation LParenLoc,
16144 SourceLocation EndLoc) {
16145 if (FactorExpr) {
16146 // If an argument is specified, it must be a constant (or an unevaluated
16147 // template expression).
16148 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
16149 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
16150 if (FactorResult.isInvalid())
16151 return nullptr;
16152 FactorExpr = FactorResult.get();
16153 }
16154
16155 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16156 FactorExpr);
16157}
16158
16159OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
16160 SourceLocation LParenLoc,
16161 SourceLocation EndLoc) {
16162 ExprResult AlignVal;
16163 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
16164 if (AlignVal.isInvalid())
16165 return nullptr;
16166 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
16167 EndLoc);
16168}
16169
16170OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
16171 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
16172 SourceLocation StartLoc, SourceLocation LParenLoc,
16173 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
16174 SourceLocation EndLoc) {
16175 OMPClause *Res = nullptr;
16176 switch (Kind) {
16177 case OMPC_schedule:
16178 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
16179 assert(Argument.size() == NumberOfElements &&(static_cast <bool> (Argument.size() == NumberOfElements
&& ArgumentLoc.size() == NumberOfElements) ? void (0
) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "clang/lib/Sema/SemaOpenMP.cpp", 16180, __extension__ __PRETTY_FUNCTION__
))
16180 ArgumentLoc.size() == NumberOfElements)(static_cast <bool> (Argument.size() == NumberOfElements
&& ArgumentLoc.size() == NumberOfElements) ? void (0
) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "clang/lib/Sema/SemaOpenMP.cpp", 16180, __extension__ __PRETTY_FUNCTION__
))
;
16181 Res = ActOnOpenMPScheduleClause(
16182 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
16183 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
16184 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
16185 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
16186 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
16187 break;
16188 case OMPC_if:
16189 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)(static_cast <bool> (Argument.size() == 1 && ArgumentLoc
.size() == 1) ? void (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "clang/lib/Sema/SemaOpenMP.cpp", 16189, __extension__ __PRETTY_FUNCTION__
))
;
16190 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
16191 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
16192 DelimLoc, EndLoc);
16193 break;
16194 case OMPC_dist_schedule:
16195 Res = ActOnOpenMPDistScheduleClause(
16196 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
16197 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
16198 break;
16199 case OMPC_defaultmap:
16200 enum { Modifier, DefaultmapKind };
16201 Res = ActOnOpenMPDefaultmapClause(
16202 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
16203 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
16204 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
16205 EndLoc);
16206 break;
16207 case OMPC_device:
16208 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)(static_cast <bool> (Argument.size() == 1 && ArgumentLoc
.size() == 1) ? void (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "clang/lib/Sema/SemaOpenMP.cpp", 16208, __extension__ __PRETTY_FUNCTION__
))
;
16209 Res = ActOnOpenMPDeviceClause(
16210 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
16211 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16212 break;
16213 case OMPC_final:
16214 case OMPC_num_threads:
16215 case OMPC_safelen:
16216 case OMPC_simdlen:
16217 case OMPC_sizes:
16218 case OMPC_allocator:
16219 case OMPC_collapse:
16220 case OMPC_default:
16221 case OMPC_proc_bind:
16222 case OMPC_private:
16223 case OMPC_firstprivate:
16224 case OMPC_lastprivate:
16225 case OMPC_shared:
16226 case OMPC_reduction:
16227 case OMPC_task_reduction:
16228 case OMPC_in_reduction:
16229 case OMPC_linear:
16230 case OMPC_aligned:
16231 case OMPC_copyin:
16232 case OMPC_copyprivate:
16233 case OMPC_ordered:
16234 case OMPC_nowait:
16235 case OMPC_untied:
16236 case OMPC_mergeable:
16237 case OMPC_threadprivate:
16238 case OMPC_allocate:
16239 case OMPC_flush:
16240 case OMPC_depobj:
16241 case OMPC_read:
16242 case OMPC_write:
16243 case OMPC_update:
16244 case OMPC_capture:
16245 case OMPC_compare:
16246 case OMPC_seq_cst:
16247 case OMPC_acq_rel:
16248 case OMPC_acquire:
16249 case OMPC_release:
16250 case OMPC_relaxed:
16251 case OMPC_depend:
16252 case OMPC_threads:
16253 case OMPC_simd:
16254 case OMPC_map:
16255 case OMPC_num_teams:
16256 case OMPC_thread_limit:
16257 case OMPC_priority:
16258 case OMPC_grainsize:
16259 case OMPC_nogroup:
16260 case OMPC_num_tasks:
16261 case OMPC_hint:
16262 case OMPC_unknown:
16263 case OMPC_uniform:
16264 case OMPC_to:
16265 case OMPC_from:
16266 case OMPC_use_device_ptr:
16267 case OMPC_use_device_addr:
16268 case OMPC_is_device_ptr:
16269 case OMPC_has_device_addr:
16270 case OMPC_unified_address:
16271 case OMPC_unified_shared_memory:
16272 case OMPC_reverse_offload:
16273 case OMPC_dynamic_allocators:
16274 case OMPC_atomic_default_mem_order:
16275 case OMPC_device_type:
16276 case OMPC_match:
16277 case OMPC_nontemporal:
16278 case OMPC_order:
16279 case OMPC_destroy:
16280 case OMPC_novariants:
16281 case OMPC_nocontext:
16282 case OMPC_detach:
16283 case OMPC_inclusive:
16284 case OMPC_exclusive:
16285 case OMPC_uses_allocators:
16286 case OMPC_affinity:
16287 case OMPC_when:
16288 case OMPC_bind:
16289 default:
16290 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 16290)
;
16291 }
16292 return Res;
16293}
16294
16295static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
16296 OpenMPScheduleClauseModifier M2,
16297 SourceLocation M1Loc, SourceLocation M2Loc) {
16298 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
16299 SmallVector<unsigned, 2> Excluded;
16300 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
16301 Excluded.push_back(M2);
16302 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
16303 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
16304 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
16305 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
16306 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
16307 << getListOfPossibleValues(OMPC_schedule,
16308 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
16309 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16310 Excluded)
16311 << getOpenMPClauseName(OMPC_schedule);
16312 return true;
16313 }
16314 return false;
16315}
16316
16317OMPClause *Sema::ActOnOpenMPScheduleClause(
16318 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
16319 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16320 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
16321 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
16322 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
16323 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
16324 return nullptr;
16325 // OpenMP, 2.7.1, Loop Construct, Restrictions
16326 // Either the monotonic modifier or the nonmonotonic modifier can be specified
16327 // but not both.
16328 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
16329 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
16330 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
16331 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
16332 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
16333 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
16334 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
16335 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
16336 return nullptr;
16337 }
16338 if (Kind == OMPC_SCHEDULE_unknown) {
16339 std::string Values;
16340 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
16341 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
16342 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16343 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16344 Exclude);
16345 } else {
16346 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16347 /*Last=*/OMPC_SCHEDULE_unknown);
16348 }
16349 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16350 << Values << getOpenMPClauseName(OMPC_schedule);
16351 return nullptr;
16352 }
16353 // OpenMP, 2.7.1, Loop Construct, Restrictions
16354 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
16355 // schedule(guided).
16356 // OpenMP 5.0 does not have this restriction.
16357 if (LangOpts.OpenMP < 50 &&
16358 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
16359 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
16360 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
16361 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
16362 diag::err_omp_schedule_nonmonotonic_static);
16363 return nullptr;
16364 }
16365 Expr *ValExpr = ChunkSize;
16366 Stmt *HelperValStmt = nullptr;
16367 if (ChunkSize) {
16368 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16369 !ChunkSize->isInstantiationDependent() &&
16370 !ChunkSize->containsUnexpandedParameterPack()) {
16371 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
16372 ExprResult Val =
16373 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16374 if (Val.isInvalid())
16375 return nullptr;
16376
16377 ValExpr = Val.get();
16378
16379 // OpenMP [2.7.1, Restrictions]
16380 // chunk_size must be a loop invariant integer expression with a positive
16381 // value.
16382 if (Optional<llvm::APSInt> Result =
16383 ValExpr->getIntegerConstantExpr(Context)) {
16384 if (Result->isSigned() && !Result->isStrictlyPositive()) {
16385 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16386 << "schedule" << 1 << ChunkSize->getSourceRange();
16387 return nullptr;
16388 }
16389 } else if (getOpenMPCaptureRegionForClause(
16390 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
16391 LangOpts.OpenMP) != OMPD_unknown &&
16392 !CurContext->isDependentContext()) {
16393 ValExpr = MakeFullExpr(ValExpr).get();
16394 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16395 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16396 HelperValStmt = buildPreInits(Context, Captures);
16397 }
16398 }
16399 }
16400
16401 return new (Context)
16402 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
16403 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
16404}
16405
16406OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
16407 SourceLocation StartLoc,
16408 SourceLocation EndLoc) {
16409 OMPClause *Res = nullptr;
16410 switch (Kind) {
16411 case OMPC_ordered:
16412 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
16413 break;
16414 case OMPC_nowait:
16415 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
16416 break;
16417 case OMPC_untied:
16418 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
16419 break;
16420 case OMPC_mergeable:
16421 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
16422 break;
16423 case OMPC_read:
16424 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
16425 break;
16426 case OMPC_write:
16427 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
16428 break;
16429 case OMPC_update:
16430 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
16431 break;
16432 case OMPC_capture:
16433 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
16434 break;
16435 case OMPC_compare:
16436 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
16437 break;
16438 case OMPC_seq_cst:
16439 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
16440 break;
16441 case OMPC_acq_rel:
16442 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
16443 break;
16444 case OMPC_acquire:
16445 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
16446 break;
16447 case OMPC_release:
16448 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
16449 break;
16450 case OMPC_relaxed:
16451 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
16452 break;
16453 case OMPC_threads:
16454 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
16455 break;
16456 case OMPC_simd:
16457 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
16458 break;
16459 case OMPC_nogroup:
16460 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
16461 break;
16462 case OMPC_unified_address:
16463 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
16464 break;
16465 case OMPC_unified_shared_memory:
16466 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16467 break;
16468 case OMPC_reverse_offload:
16469 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
16470 break;
16471 case OMPC_dynamic_allocators:
16472 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
16473 break;
16474 case OMPC_destroy:
16475 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
16476 /*LParenLoc=*/SourceLocation(),
16477 /*VarLoc=*/SourceLocation(), EndLoc);
16478 break;
16479 case OMPC_full:
16480 Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
16481 break;
16482 case OMPC_partial:
16483 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
16484 break;
16485 case OMPC_if:
16486 case OMPC_final:
16487 case OMPC_num_threads:
16488 case OMPC_safelen:
16489 case OMPC_simdlen:
16490 case OMPC_sizes:
16491 case OMPC_allocator:
16492 case OMPC_collapse:
16493 case OMPC_schedule:
16494 case OMPC_private:
16495 case OMPC_firstprivate:
16496 case OMPC_lastprivate:
16497 case OMPC_shared:
16498 case OMPC_reduction:
16499 case OMPC_task_reduction:
16500 case OMPC_in_reduction:
16501 case OMPC_linear:
16502 case OMPC_aligned:
16503 case OMPC_copyin:
16504 case OMPC_copyprivate:
16505 case OMPC_default:
16506 case OMPC_proc_bind:
16507 case OMPC_threadprivate:
16508 case OMPC_allocate:
16509 case OMPC_flush:
16510 case OMPC_depobj:
16511 case OMPC_depend:
16512 case OMPC_device:
16513 case OMPC_map:
16514 case OMPC_num_teams:
16515 case OMPC_thread_limit:
16516 case OMPC_priority:
16517 case OMPC_grainsize:
16518 case OMPC_num_tasks:
16519 case OMPC_hint:
16520 case OMPC_dist_schedule:
16521 case OMPC_defaultmap:
16522 case OMPC_unknown:
16523 case OMPC_uniform:
16524 case OMPC_to:
16525 case OMPC_from:
16526 case OMPC_use_device_ptr:
16527 case OMPC_use_device_addr:
16528 case OMPC_is_device_ptr:
16529 case OMPC_has_device_addr:
16530 case OMPC_atomic_default_mem_order:
16531 case OMPC_device_type:
16532 case OMPC_match:
16533 case OMPC_nontemporal:
16534 case OMPC_order:
16535 case OMPC_novariants:
16536 case OMPC_nocontext:
16537 case OMPC_detach:
16538 case OMPC_inclusive:
16539 case OMPC_exclusive:
16540 case OMPC_uses_allocators:
16541 case OMPC_affinity:
16542 case OMPC_when:
16543 default:
16544 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 16544)
;
16545 }
16546 return Res;
16547}
16548
16549OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
16550 SourceLocation EndLoc) {
16551 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
16552 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
16553}
16554
16555OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
16556 SourceLocation EndLoc) {
16557 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setUntiedRegion();
16558 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
16559}
16560
16561OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
16562 SourceLocation EndLoc) {
16563 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
16564}
16565
16566OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
16567 SourceLocation EndLoc) {
16568 return new (Context) OMPReadClause(StartLoc, EndLoc);
16569}
16570
16571OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
16572 SourceLocation EndLoc) {
16573 return new (Context) OMPWriteClause(StartLoc, EndLoc);
16574}
16575
16576OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
16577 SourceLocation EndLoc) {
16578 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
16579}
16580
16581OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
16582 SourceLocation EndLoc) {
16583 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
16584}
16585
16586OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
16587 SourceLocation EndLoc) {
16588 return new (Context) OMPCompareClause(StartLoc, EndLoc);
16589}
16590
16591OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
16592 SourceLocation EndLoc) {
16593 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
16594}
16595
16596OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
16597 SourceLocation EndLoc) {
16598 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
16599}
16600
16601OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
16602 SourceLocation EndLoc) {
16603 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
16604}
16605
16606OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
16607 SourceLocation EndLoc) {
16608 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
16609}
16610
16611OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
16612 SourceLocation EndLoc) {
16613 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
16614}
16615
16616OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
16617 SourceLocation EndLoc) {
16618 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
16619}
16620
16621OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
16622 SourceLocation EndLoc) {
16623 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
16624}
16625
16626OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
16627 SourceLocation EndLoc) {
16628 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
16629}
16630
16631OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
16632 SourceLocation EndLoc) {
16633 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
16634}
16635
16636OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
16637 SourceLocation EndLoc) {
16638 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16639}
16640
16641OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
16642 SourceLocation EndLoc) {
16643 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
16644}
16645
16646OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
16647 SourceLocation EndLoc) {
16648 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
16649}
16650
16651StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
16652 SourceLocation StartLoc,
16653 SourceLocation EndLoc) {
16654
16655 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16656 // At least one action-clause must appear on a directive.
16657 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
16658 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
16659 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
16660 << Expected << getOpenMPDirectiveName(OMPD_interop);
16661 return StmtError();
16662 }
16663
16664 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16665 // A depend clause can only appear on the directive if a targetsync
16666 // interop-type is present or the interop-var was initialized with
16667 // the targetsync interop-type.
16668
16669 // If there is any 'init' clause diagnose if there is no 'init' clause with
16670 // interop-type of 'targetsync'. Cases involving other directives cannot be
16671 // diagnosed.
16672 const OMPDependClause *DependClause = nullptr;
16673 bool HasInitClause = false;
16674 bool IsTargetSync = false;
16675 for (const OMPClause *C : Clauses) {
16676 if (IsTargetSync)
16677 break;
16678 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
16679 HasInitClause = true;
16680 if (InitClause->getIsTargetSync())
16681 IsTargetSync = true;
16682 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
16683 DependClause = DC;
16684 }
16685 }
16686 if (DependClause && HasInitClause && !IsTargetSync) {
16687 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
16688 return StmtError();
16689 }
16690
16691 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16692 // Each interop-var may be specified for at most one action-clause of each
16693 // interop construct.
16694 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
16695 for (const OMPClause *C : Clauses) {
16696 OpenMPClauseKind ClauseKind = C->getClauseKind();
16697 const DeclRefExpr *DRE = nullptr;
16698 SourceLocation VarLoc;
16699
16700 if (ClauseKind == OMPC_init) {
16701 const auto *IC = cast<OMPInitClause>(C);
16702 VarLoc = IC->getVarLoc();
16703 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
16704 } else if (ClauseKind == OMPC_use) {
16705 const auto *UC = cast<OMPUseClause>(C);
16706 VarLoc = UC->getVarLoc();
16707 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
16708 } else if (ClauseKind == OMPC_destroy) {
16709 const auto *DC = cast<OMPDestroyClause>(C);
16710 VarLoc = DC->getVarLoc();
16711 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
16712 }
16713
16714 if (!DRE)
16715 continue;
16716
16717 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
16718 if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
16719 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
16720 return StmtError();
16721 }
16722 }
16723 }
16724
16725 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
16726}
16727
16728static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
16729 SourceLocation VarLoc,
16730 OpenMPClauseKind Kind) {
16731 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
16732 InteropVarExpr->isInstantiationDependent() ||
16733 InteropVarExpr->containsUnexpandedParameterPack())
16734 return true;
16735
16736 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
16737 if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
16738 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
16739 return false;
16740 }
16741
16742 // Interop variable should be of type omp_interop_t.
16743 bool HasError = false;
16744 QualType InteropType;
16745 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
16746 VarLoc, Sema::LookupOrdinaryName);
16747 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
16748 NamedDecl *ND = Result.getFoundDecl();
16749 if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
16750 InteropType = QualType(TD->getTypeForDecl(), 0);
16751 } else {
16752 HasError = true;
16753 }
16754 } else {
16755 HasError = true;
16756 }
16757
16758 if (HasError) {
16759 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
16760 << "omp_interop_t";
16761 return false;
16762 }
16763
16764 QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
16765 if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
16766 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
16767 return false;
16768 }
16769
16770 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16771 // The interop-var passed to init or destroy must be non-const.
16772 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
16773 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
16774 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
16775 << /*non-const*/ 1;
16776 return false;
16777 }
16778 return true;
16779}
16780
16781OMPClause *
16782Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
16783 bool IsTarget, bool IsTargetSync,
16784 SourceLocation StartLoc, SourceLocation LParenLoc,
16785 SourceLocation VarLoc, SourceLocation EndLoc) {
16786
16787 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
16788 return nullptr;
16789
16790 // Check prefer_type values. These foreign-runtime-id values are either
16791 // string literals or constant integral expressions.
16792 for (const Expr *E : PrefExprs) {
16793 if (E->isValueDependent() || E->isTypeDependent() ||
16794 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16795 continue;
16796 if (E->isIntegerConstantExpr(Context))
16797 continue;
16798 if (isa<StringLiteral>(E))
16799 continue;
16800 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
16801 return nullptr;
16802 }
16803
16804 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
16805 IsTargetSync, StartLoc, LParenLoc, VarLoc,
16806 EndLoc);
16807}
16808
16809OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
16810 SourceLocation LParenLoc,
16811 SourceLocation VarLoc,
16812 SourceLocation EndLoc) {
16813
16814 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
16815 return nullptr;
16816
16817 return new (Context)
16818 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16819}
16820
16821OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
16822 SourceLocation StartLoc,
16823 SourceLocation LParenLoc,
16824 SourceLocation VarLoc,
16825 SourceLocation EndLoc) {
16826 if (InteropVar &&
16827 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
16828 return nullptr;
16829
16830 return new (Context)
16831 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16832}
16833
16834OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
16835 SourceLocation StartLoc,
16836 SourceLocation LParenLoc,
16837 SourceLocation EndLoc) {
16838 Expr *ValExpr = Condition;
16839 Stmt *HelperValStmt = nullptr;
16840 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16841 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16842 !Condition->isInstantiationDependent() &&
16843 !Condition->containsUnexpandedParameterPack()) {
16844 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16845 if (Val.isInvalid())
16846 return nullptr;
16847
16848 ValExpr = MakeFullExpr(Val.get()).get();
16849
16850 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16851 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
16852 LangOpts.OpenMP);
16853 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16854 ValExpr = MakeFullExpr(ValExpr).get();
16855 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16856 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16857 HelperValStmt = buildPreInits(Context, Captures);
16858 }
16859 }
16860
16861 return new (Context) OMPNovariantsClause(
16862 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16863}
16864
16865OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
16866 SourceLocation StartLoc,
16867 SourceLocation LParenLoc,
16868 SourceLocation EndLoc) {
16869 Expr *ValExpr = Condition;
16870 Stmt *HelperValStmt = nullptr;
16871 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16872 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16873 !Condition->isInstantiationDependent() &&
16874 !Condition->containsUnexpandedParameterPack()) {
16875 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16876 if (Val.isInvalid())
16877 return nullptr;
16878
16879 ValExpr = MakeFullExpr(Val.get()).get();
16880
16881 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16882 CaptureRegion =
16883 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
16884 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16885 ValExpr = MakeFullExpr(ValExpr).get();
16886 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16887 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16888 HelperValStmt = buildPreInits(Context, Captures);
16889 }
16890 }
16891
16892 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
16893 StartLoc, LParenLoc, EndLoc);
16894}
16895
16896OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
16897 SourceLocation StartLoc,
16898 SourceLocation LParenLoc,
16899 SourceLocation EndLoc) {
16900 Expr *ValExpr = ThreadID;
16901 Stmt *HelperValStmt = nullptr;
16902
16903 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16904 OpenMPDirectiveKind CaptureRegion =
16905 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
16906 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16907 ValExpr = MakeFullExpr(ValExpr).get();
16908 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16909 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16910 HelperValStmt = buildPreInits(Context, Captures);
16911 }
16912
16913 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
16914 StartLoc, LParenLoc, EndLoc);
16915}
16916
16917OMPClause *Sema::ActOnOpenMPVarListClause(
16918 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
16919 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
16920 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
16921 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
16922 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
16923 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
16924 SourceLocation ExtraModifierLoc,
16925 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
16926 ArrayRef<SourceLocation> MotionModifiersLoc) {
16927 SourceLocation StartLoc = Locs.StartLoc;
16928 SourceLocation LParenLoc = Locs.LParenLoc;
16929 SourceLocation EndLoc = Locs.EndLoc;
16930 OMPClause *Res = nullptr;
16931 switch (Kind) {
16932 case OMPC_private:
16933 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16934 break;
16935 case OMPC_firstprivate:
16936 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16937 break;
16938 case OMPC_lastprivate:
16939 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_LASTPRIVATE_unknown && "Unexpected lastprivate modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16940, __extension__ __PRETTY_FUNCTION__
))
16940 "Unexpected lastprivate modifier.")(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_LASTPRIVATE_unknown && "Unexpected lastprivate modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16940, __extension__ __PRETTY_FUNCTION__
))
;
16941 Res = ActOnOpenMPLastprivateClause(
16942 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
16943 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
16944 break;
16945 case OMPC_shared:
16946 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
16947 break;
16948 case OMPC_reduction:
16949 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_REDUCTION_unknown && "Unexpected lastprivate modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16950, __extension__ __PRETTY_FUNCTION__
))
16950 "Unexpected lastprivate modifier.")(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_REDUCTION_unknown && "Unexpected lastprivate modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16950, __extension__ __PRETTY_FUNCTION__
))
;
16951 Res = ActOnOpenMPReductionClause(
16952 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
16953 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
16954 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
16955 break;
16956 case OMPC_task_reduction:
16957 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
16958 EndLoc, ReductionOrMapperIdScopeSpec,
16959 ReductionOrMapperId);
16960 break;
16961 case OMPC_in_reduction:
16962 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
16963 EndLoc, ReductionOrMapperIdScopeSpec,
16964 ReductionOrMapperId);
16965 break;
16966 case OMPC_linear:
16967 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_LINEAR_unknown && "Unexpected linear modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16968, __extension__ __PRETTY_FUNCTION__
))
16968 "Unexpected linear modifier.")(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_LINEAR_unknown && "Unexpected linear modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16968, __extension__ __PRETTY_FUNCTION__
))
;
16969 Res = ActOnOpenMPLinearClause(
16970 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
16971 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
16972 ColonLoc, EndLoc);
16973 break;
16974 case OMPC_aligned:
16975 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
16976 LParenLoc, ColonLoc, EndLoc);
16977 break;
16978 case OMPC_copyin:
16979 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
16980 break;
16981 case OMPC_copyprivate:
16982 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16983 break;
16984 case OMPC_flush:
16985 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
16986 break;
16987 case OMPC_depend:
16988 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_DEPEND_unknown && "Unexpected depend modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16989, __extension__ __PRETTY_FUNCTION__
))
16989 "Unexpected depend modifier.")(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_DEPEND_unknown && "Unexpected depend modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16989, __extension__ __PRETTY_FUNCTION__
))
;
16990 Res = ActOnOpenMPDependClause(
16991 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
16992 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
16993 break;
16994 case OMPC_map:
16995 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_MAP_unknown && "Unexpected map modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16996, __extension__ __PRETTY_FUNCTION__
))
16996 "Unexpected map modifier.")(static_cast <bool> (0 <= ExtraModifier && ExtraModifier
<= OMPC_MAP_unknown && "Unexpected map modifier."
) ? void (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16996, __extension__ __PRETTY_FUNCTION__
))
;
16997 Res = ActOnOpenMPMapClause(
16998 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
16999 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
17000 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
17001 break;
17002 case OMPC_to:
17003 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
17004 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
17005 ColonLoc, VarList, Locs);
17006 break;
17007 case OMPC_from:
17008 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
17009 ReductionOrMapperIdScopeSpec,
17010 ReductionOrMapperId, ColonLoc, VarList, Locs);
17011 break;
17012 case OMPC_use_device_ptr:
17013 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
17014 break;
17015 case OMPC_use_device_addr:
17016 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
17017 break;
17018 case OMPC_is_device_ptr:
17019 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
17020 break;
17021 case OMPC_has_device_addr:
17022 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
17023 break;
17024 case OMPC_allocate:
17025 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
17026 LParenLoc, ColonLoc, EndLoc);
17027 break;
17028 case OMPC_nontemporal:
17029 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
17030 break;
17031 case OMPC_inclusive:
17032 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17033 break;
17034 case OMPC_exclusive:
17035 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17036 break;
17037 case OMPC_affinity:
17038 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
17039 DepModOrTailExpr, VarList);
17040 break;
17041 case OMPC_if:
17042 case OMPC_depobj:
17043 case OMPC_final:
17044 case OMPC_num_threads:
17045 case OMPC_safelen:
17046 case OMPC_simdlen:
17047 case OMPC_sizes:
17048 case OMPC_allocator:
17049 case OMPC_collapse:
17050 case OMPC_default:
17051 case OMPC_proc_bind:
17052 case OMPC_schedule:
17053 case OMPC_ordered:
17054 case OMPC_nowait:
17055 case OMPC_untied:
17056 case OMPC_mergeable:
17057 case OMPC_threadprivate:
17058 case OMPC_read:
17059 case OMPC_write:
17060 case OMPC_update:
17061 case OMPC_capture:
17062 case OMPC_compare:
17063 case OMPC_seq_cst:
17064 case OMPC_acq_rel:
17065 case OMPC_acquire:
17066 case OMPC_release:
17067 case OMPC_relaxed:
17068 case OMPC_device:
17069 case OMPC_threads:
17070 case OMPC_simd:
17071 case OMPC_num_teams:
17072 case OMPC_thread_limit:
17073 case OMPC_priority:
17074 case OMPC_grainsize:
17075 case OMPC_nogroup:
17076 case OMPC_num_tasks:
17077 case OMPC_hint:
17078 case OMPC_dist_schedule:
17079 case OMPC_defaultmap:
17080 case OMPC_unknown:
17081 case OMPC_uniform:
17082 case OMPC_unified_address:
17083 case OMPC_unified_shared_memory:
17084 case OMPC_reverse_offload:
17085 case OMPC_dynamic_allocators:
17086 case OMPC_atomic_default_mem_order:
17087 case OMPC_device_type:
17088 case OMPC_match:
17089 case OMPC_order:
17090 case OMPC_destroy:
17091 case OMPC_novariants:
17092 case OMPC_nocontext:
17093 case OMPC_detach:
17094 case OMPC_uses_allocators:
17095 case OMPC_when:
17096 case OMPC_bind:
17097 default:
17098 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 17098)
;
17099 }
17100 return Res;
17101}
17102
17103ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
17104 ExprObjectKind OK, SourceLocation Loc) {
17105 ExprResult Res = BuildDeclRefExpr(
17106 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
17107 if (!Res.isUsable())
17108 return ExprError();
17109 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
17110 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
17111 if (!Res.isUsable())
17112 return ExprError();
17113 }
17114 if (VK != VK_LValue && Res.get()->isGLValue()) {
17115 Res = DefaultLvalueConversion(Res.get());
17116 if (!Res.isUsable())
17117 return ExprError();
17118 }
17119 return Res;
17120}
17121
17122OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
17123 SourceLocation StartLoc,
17124 SourceLocation LParenLoc,
17125 SourceLocation EndLoc) {
17126 SmallVector<Expr *, 8> Vars;
17127 SmallVector<Expr *, 8> PrivateCopies;
17128 for (Expr *RefExpr : VarList) {
17129 assert(RefExpr && "NULL expr in OpenMP private clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP private clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 17129, __extension__ __PRETTY_FUNCTION__
))
;
17130 SourceLocation ELoc;
17131 SourceRange ERange;
17132 Expr *SimpleRefExpr = RefExpr;
17133 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17134 if (Res.second) {
17135 // It will be analyzed later.
17136 Vars.push_back(RefExpr);
17137 PrivateCopies.push_back(nullptr);
17138 }
17139 ValueDecl *D = Res.first;
17140 if (!D)
17141 continue;
17142
17143 QualType Type = D->getType();
17144 auto *VD = dyn_cast<VarDecl>(D);
17145
17146 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17147 // A variable that appears in a private clause must not have an incomplete
17148 // type or a reference type.
17149 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
17150 continue;
17151 Type = Type.getNonReferenceType();
17152
17153 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17154 // A variable that is privatized must not have a const-qualified type
17155 // unless it is of class type with a mutable member. This restriction does
17156 // not apply to the firstprivate clause.
17157 //
17158 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
17159 // A variable that appears in a private clause must not have a
17160 // const-qualified type unless it is of class type with a mutable member.
17161 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
17162 continue;
17163
17164 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17165 // in a Construct]
17166 // Variables with the predetermined data-sharing attributes may not be
17167 // listed in data-sharing attributes clauses, except for the cases
17168 // listed below. For these exceptions only, listing a predetermined
17169 // variable in a data-sharing attribute clause is allowed and overrides
17170 // the variable's predetermined data-sharing attributes.
17171 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17172 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
17173 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17174 << getOpenMPClauseName(OMPC_private);
17175 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17176 continue;
17177 }
17178
17179 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17180 // Variably modified types are not supported for tasks.
17181 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
17182 isOpenMPTaskingDirective(CurrDir)) {
17183 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17184 << getOpenMPClauseName(OMPC_private) << Type
17185 << getOpenMPDirectiveName(CurrDir);
17186 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17187 VarDecl::DeclarationOnly;
17188 Diag(D->getLocation(),
17189 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17190 << D;
17191 continue;
17192 }
17193
17194 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17195 // A list item cannot appear in both a map clause and a data-sharing
17196 // attribute clause on the same construct
17197 //
17198 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17199 // A list item cannot appear in both a map clause and a data-sharing
17200 // attribute clause on the same construct unless the construct is a
17201 // combined construct.
17202 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
17203 CurrDir == OMPD_target) {
17204 OpenMPClauseKind ConflictKind;
17205 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
17206 VD, /*CurrentRegionOnly=*/true,
17207 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
17208 OpenMPClauseKind WhereFoundClauseKind) -> bool {
17209 ConflictKind = WhereFoundClauseKind;
17210 return true;
17211 })) {
17212 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17213 << getOpenMPClauseName(OMPC_private)
17214 << getOpenMPClauseName(ConflictKind)
17215 << getOpenMPDirectiveName(CurrDir);
17216 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17217 continue;
17218 }
17219 }
17220
17221 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
17222 // A variable of class type (or array thereof) that appears in a private
17223 // clause requires an accessible, unambiguous default constructor for the
17224 // class type.
17225 // Generate helper private variable and initialize it with the default
17226 // value. The address of the original variable is replaced by the address of
17227 // the new private variable in CodeGen. This new variable is not added to
17228 // IdResolver, so the code in the OpenMP region uses original variable for
17229 // proper diagnostics.
17230 Type = Type.getUnqualifiedType();
17231 VarDecl *VDPrivate =
17232 buildVarDecl(*this, ELoc, Type, D->getName(),
17233 D->hasAttrs() ? &D->getAttrs() : nullptr,
17234 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17235 ActOnUninitializedDecl(VDPrivate);
17236 if (VDPrivate->isInvalidDecl())
17237 continue;
17238 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17239 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
17240
17241 DeclRefExpr *Ref = nullptr;
17242 if (!VD && !CurContext->isDependentContext())
17243 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17244 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
17245 Vars.push_back((VD || CurContext->isDependentContext())
17246 ? RefExpr->IgnoreParens()
17247 : Ref);
17248 PrivateCopies.push_back(VDPrivateRefExpr);
17249 }
17250
17251 if (Vars.empty())
17252 return nullptr;
17253
17254 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17255 PrivateCopies);
17256}
17257
17258OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
17259 SourceLocation StartLoc,
17260 SourceLocation LParenLoc,
17261 SourceLocation EndLoc) {
17262 SmallVector<Expr *, 8> Vars;
17263 SmallVector<Expr *, 8> PrivateCopies;
17264 SmallVector<Expr *, 8> Inits;
17265 SmallVector<Decl *, 4> ExprCaptures;
17266 bool IsImplicitClause =
17267 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17268 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
17269
17270 for (Expr *RefExpr : VarList) {
17271 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP firstprivate clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 17271, __extension__ __PRETTY_FUNCTION__
))
;
17272 SourceLocation ELoc;
17273 SourceRange ERange;
17274 Expr *SimpleRefExpr = RefExpr;
17275 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17276 if (Res.second) {
17277 // It will be analyzed later.
17278 Vars.push_back(RefExpr);
17279 PrivateCopies.push_back(nullptr);
17280 Inits.push_back(nullptr);
17281 }
17282 ValueDecl *D = Res.first;
17283 if (!D)
17284 continue;
17285
17286 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
17287 QualType Type = D->getType();
17288 auto *VD = dyn_cast<VarDecl>(D);
17289
17290 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17291 // A variable that appears in a private clause must not have an incomplete
17292 // type or a reference type.
17293 if (RequireCompleteType(ELoc, Type,
17294 diag::err_omp_firstprivate_incomplete_type))
17295 continue;
17296 Type = Type.getNonReferenceType();
17297
17298 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
17299 // A variable of class type (or array thereof) that appears in a private
17300 // clause requires an accessible, unambiguous copy constructor for the
17301 // class type.
17302 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17303
17304 // If an implicit firstprivate variable found it was checked already.
17305 DSAStackTy::DSAVarData TopDVar;
17306 if (!IsImplicitClause) {
17307 DSAStackTy::DSAVarData DVar =
17308 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17309 TopDVar = DVar;
17310 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17311 bool IsConstant = ElemType.isConstant(Context);
17312 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
17313 // A list item that specifies a given variable may not appear in more
17314 // than one clause on the same directive, except that a variable may be
17315 // specified in both firstprivate and lastprivate clauses.
17316 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17317 // A list item may appear in a firstprivate or lastprivate clause but not
17318 // both.
17319 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
17320 (isOpenMPDistributeDirective(CurrDir) ||
17321 DVar.CKind != OMPC_lastprivate) &&
17322 DVar.RefExpr) {
17323 Diag(ELoc, diag::err_omp_wrong_dsa)
17324 << getOpenMPClauseName(DVar.CKind)
17325 << getOpenMPClauseName(OMPC_firstprivate);
17326 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17327 continue;
17328 }
17329
17330 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17331 // in a Construct]
17332 // Variables with the predetermined data-sharing attributes may not be
17333 // listed in data-sharing attributes clauses, except for the cases
17334 // listed below. For these exceptions only, listing a predetermined
17335 // variable in a data-sharing attribute clause is allowed and overrides
17336 // the variable's predetermined data-sharing attributes.
17337 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17338 // in a Construct, C/C++, p.2]
17339 // Variables with const-qualified type having no mutable member may be
17340 // listed in a firstprivate clause, even if they are static data members.
17341 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
17342 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
17343 Diag(ELoc, diag::err_omp_wrong_dsa)
17344 << getOpenMPClauseName(DVar.CKind)
17345 << getOpenMPClauseName(OMPC_firstprivate);
17346 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17347 continue;
17348 }
17349
17350 // OpenMP [2.9.3.4, Restrictions, p.2]
17351 // A list item that is private within a parallel region must not appear
17352 // in a firstprivate clause on a worksharing construct if any of the
17353 // worksharing regions arising from the worksharing construct ever bind
17354 // to any of the parallel regions arising from the parallel construct.
17355 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17356 // A list item that is private within a teams region must not appear in a
17357 // firstprivate clause on a distribute construct if any of the distribute
17358 // regions arising from the distribute construct ever bind to any of the
17359 // teams regions arising from the teams construct.
17360 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17361 // A list item that appears in a reduction clause of a teams construct
17362 // must not appear in a firstprivate clause on a distribute construct if
17363 // any of the distribute regions arising from the distribute construct
17364 // ever bind to any of the teams regions arising from the teams construct.
17365 if ((isOpenMPWorksharingDirective(CurrDir) ||
17366 isOpenMPDistributeDirective(CurrDir)) &&
17367 !isOpenMPParallelDirective(CurrDir) &&
17368 !isOpenMPTeamsDirective(CurrDir)) {
17369 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
17370 if (DVar.CKind != OMPC_shared &&
17371 (isOpenMPParallelDirective(DVar.DKind) ||
17372 isOpenMPTeamsDirective(DVar.DKind) ||
17373 DVar.DKind == OMPD_unknown)) {
17374 Diag(ELoc, diag::err_omp_required_access)
17375 << getOpenMPClauseName(OMPC_firstprivate)
17376 << getOpenMPClauseName(OMPC_shared);
17377 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17378 continue;
17379 }
17380 }
17381 // OpenMP [2.9.3.4, Restrictions, p.3]
17382 // A list item that appears in a reduction clause of a parallel construct
17383 // must not appear in a firstprivate clause on a worksharing or task
17384 // construct if any of the worksharing or task regions arising from the
17385 // worksharing or task construct ever bind to any of the parallel regions
17386 // arising from the parallel construct.
17387 // OpenMP [2.9.3.4, Restrictions, p.4]
17388 // A list item that appears in a reduction clause in worksharing
17389 // construct must not appear in a firstprivate clause in a task construct
17390 // encountered during execution of any of the worksharing regions arising
17391 // from the worksharing construct.
17392 if (isOpenMPTaskingDirective(CurrDir)) {
17393 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
17394 D,
17395 [](OpenMPClauseKind C, bool AppliedToPointee) {
17396 return C == OMPC_reduction && !AppliedToPointee;
17397 },
17398 [](OpenMPDirectiveKind K) {
17399 return isOpenMPParallelDirective(K) ||
17400 isOpenMPWorksharingDirective(K) ||
17401 isOpenMPTeamsDirective(K);
17402 },
17403 /*FromParent=*/true);
17404 if (DVar.CKind == OMPC_reduction &&
17405 (isOpenMPParallelDirective(DVar.DKind) ||
17406 isOpenMPWorksharingDirective(DVar.DKind) ||
17407 isOpenMPTeamsDirective(DVar.DKind))) {
17408 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
17409 << getOpenMPDirectiveName(DVar.DKind);
17410 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17411 continue;
17412 }
17413 }
17414
17415 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17416 // A list item cannot appear in both a map clause and a data-sharing
17417 // attribute clause on the same construct
17418 //
17419 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17420 // A list item cannot appear in both a map clause and a data-sharing
17421 // attribute clause on the same construct unless the construct is a
17422 // combined construct.
17423 if ((LangOpts.OpenMP <= 45 &&
17424 isOpenMPTargetExecutionDirective(CurrDir)) ||
17425 CurrDir == OMPD_target) {
17426 OpenMPClauseKind ConflictKind;
17427 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
17428 VD, /*CurrentRegionOnly=*/true,
17429 [&ConflictKind](
17430 OMPClauseMappableExprCommon::MappableExprComponentListRef,
17431 OpenMPClauseKind WhereFoundClauseKind) {
17432 ConflictKind = WhereFoundClauseKind;
17433 return true;
17434 })) {
17435 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17436 << getOpenMPClauseName(OMPC_firstprivate)
17437 << getOpenMPClauseName(ConflictKind)
17438 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
17439 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17440 continue;
17441 }
17442 }
17443 }
17444
17445 // Variably modified types are not supported for tasks.
17446 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
17447 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
17448 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17449 << getOpenMPClauseName(OMPC_firstprivate) << Type
17450 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
17451 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17452 VarDecl::DeclarationOnly;
17453 Diag(D->getLocation(),
17454 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17455 << D;
17456 continue;
17457 }
17458
17459 Type = Type.getUnqualifiedType();
17460 VarDecl *VDPrivate =
17461 buildVarDecl(*this, ELoc, Type, D->getName(),
17462 D->hasAttrs() ? &D->getAttrs() : nullptr,
17463 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17464 // Generate helper private variable and initialize it with the value of the
17465 // original variable. The address of the original variable is replaced by
17466 // the address of the new private variable in the CodeGen. This new variable
17467 // is not added to IdResolver, so the code in the OpenMP region uses
17468 // original variable for proper diagnostics and variable capturing.
17469 Expr *VDInitRefExpr = nullptr;
17470 // For arrays generate initializer for single element and replace it by the
17471 // original array element in CodeGen.
17472 if (Type->isArrayType()) {
17473 VarDecl *VDInit =
17474 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
17475 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
17476 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
17477 ElemType = ElemType.getUnqualifiedType();
17478 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
17479 ".firstprivate.temp");
17480 InitializedEntity Entity =
17481 InitializedEntity::InitializeVariable(VDInitTemp);
17482 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
17483
17484 InitializationSequence InitSeq(*this, Entity, Kind, Init);
17485 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
17486 if (Result.isInvalid())
17487 VDPrivate->setInvalidDecl();
17488 else
17489 VDPrivate->setInit(Result.getAs<Expr>());
17490 // Remove temp variable declaration.
17491 Context.Deallocate(VDInitTemp);
17492 } else {
17493 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
17494 ".firstprivate.temp");
17495 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
17496 RefExpr->getExprLoc());
17497 AddInitializerToDecl(VDPrivate,
17498 DefaultLvalueConversion(VDInitRefExpr).get(),
17499 /*DirectInit=*/false);
17500 }
17501 if (VDPrivate->isInvalidDecl()) {
17502 if (IsImplicitClause) {
17503 Diag(RefExpr->getExprLoc(),
17504 diag::note_omp_task_predetermined_firstprivate_here);
17505 }
17506 continue;
17507 }
17508 CurContext->addDecl(VDPrivate);
17509 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17510 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
17511 RefExpr->getExprLoc());
17512 DeclRefExpr *Ref = nullptr;
17513 if (!VD && !CurContext->isDependentContext()) {
17514 if (TopDVar.CKind == OMPC_lastprivate) {
17515 Ref = TopDVar.PrivateCopy;
17516 } else {
17517 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17518 if (!isOpenMPCapturedDecl(D))
17519 ExprCaptures.push_back(Ref->getDecl());
17520 }
17521 }
17522 if (!IsImplicitClause)
17523 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
17524 Vars.push_back((VD || CurContext->isDependentContext())
17525 ? RefExpr->IgnoreParens()
17526 : Ref);
17527 PrivateCopies.push_back(VDPrivateRefExpr);
17528 Inits.push_back(VDInitRefExpr);
17529 }
17530
17531 if (Vars.empty())
17532 return nullptr;
17533
17534 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17535 Vars, PrivateCopies, Inits,
17536 buildPreInits(Context, ExprCaptures));
17537}
17538
17539OMPClause *Sema::ActOnOpenMPLastprivateClause(
17540 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
17541 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
17542 SourceLocation LParenLoc, SourceLocation EndLoc) {
17543 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
17544 assert(ColonLoc.isValid() && "Colon location must be valid.")(static_cast <bool> (ColonLoc.isValid() && "Colon location must be valid."
) ? void (0) : __assert_fail ("ColonLoc.isValid() && \"Colon location must be valid.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 17544, __extension__ __PRETTY_FUNCTION__
))
;
17545 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
17546 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
17547 /*Last=*/OMPC_LASTPRIVATE_unknown)
17548 << getOpenMPClauseName(OMPC_lastprivate);
17549 return nullptr;
17550 }
17551
17552 SmallVector<Expr *, 8> Vars;
17553 SmallVector<Expr *, 8> SrcExprs;
17554 SmallVector<Expr *, 8> DstExprs;
17555 SmallVector<Expr *, 8> AssignmentOps;
17556 SmallVector<Decl *, 4> ExprCaptures;
17557 SmallVector<Expr *, 4> ExprPostUpdates;
17558 for (Expr *RefExpr : VarList) {
17559 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 17559, __extension__ __PRETTY_FUNCTION__
))
;
17560 SourceLocation ELoc;
17561 SourceRange ERange;
17562 Expr *SimpleRefExpr = RefExpr;
17563 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17564 if (Res.second) {
17565 // It will be analyzed later.
17566 Vars.push_back(RefExpr);
17567 SrcExprs.push_back(nullptr);
17568 DstExprs.push_back(nullptr);
17569 AssignmentOps.push_back(nullptr);
17570 }
17571 ValueDecl *D = Res.first;
17572 if (!D)
17573 continue;
17574
17575 QualType Type = D->getType();
17576 auto *VD = dyn_cast<VarDecl>(D);
17577
17578 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
17579 // A variable that appears in a lastprivate clause must not have an
17580 // incomplete type or a reference type.
17581 if (RequireCompleteType(ELoc, Type,
17582 diag::err_omp_lastprivate_incomplete_type))
17583 continue;
17584 Type = Type.getNonReferenceType();
17585
17586 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17587 // A variable that is privatized must not have a const-qualified type
17588 // unless it is of class type with a mutable member. This restriction does
17589 // not apply to the firstprivate clause.
17590 //
17591 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
17592 // A variable that appears in a lastprivate clause must not have a
17593 // const-qualified type unless it is of class type with a mutable member.
17594 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
17595 continue;
17596
17597 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
17598 // A list item that appears in a lastprivate clause with the conditional
17599 // modifier must be a scalar variable.
17600 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
17601 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
17602 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17603 VarDecl::DeclarationOnly;
17604 Diag(D->getLocation(),
17605 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17606 << D;
17607 continue;
17608 }
17609
17610 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17611 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
17612 // in a Construct]
17613 // Variables with the predetermined data-sharing attributes may not be
17614 // listed in data-sharing attributes clauses, except for the cases
17615 // listed below.
17616 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17617 // A list item may appear in a firstprivate or lastprivate clause but not
17618 // both.
17619 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17620 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
17621 (isOpenMPDistributeDirective(CurrDir) ||
17622 DVar.CKind != OMPC_firstprivate) &&
17623 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
17624 Diag(ELoc, diag::err_omp_wrong_dsa)
17625 << getOpenMPClauseName(DVar.CKind)
17626 << getOpenMPClauseName(OMPC_lastprivate);
17627 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17628 continue;
17629 }
17630
17631 // OpenMP [2.14.3.5, Restrictions, p.2]
17632 // A list item that is private within a parallel region, or that appears in
17633 // the reduction clause of a parallel construct, must not appear in a
17634 // lastprivate clause on a worksharing construct if any of the corresponding
17635 // worksharing regions ever binds to any of the corresponding parallel
17636 // regions.
17637 DSAStackTy::DSAVarData TopDVar = DVar;
17638 if (isOpenMPWorksharingDirective(CurrDir) &&
17639 !isOpenMPParallelDirective(CurrDir) &&
17640 !isOpenMPTeamsDirective(CurrDir)) {
17641 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
17642 if (DVar.CKind != OMPC_shared) {
17643 Diag(ELoc, diag::err_omp_required_access)
17644 << getOpenMPClauseName(OMPC_lastprivate)
17645 << getOpenMPClauseName(OMPC_shared);
17646 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17647 continue;
17648 }
17649 }
17650
17651 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
17652 // A variable of class type (or array thereof) that appears in a
17653 // lastprivate clause requires an accessible, unambiguous default
17654 // constructor for the class type, unless the list item is also specified
17655 // in a firstprivate clause.
17656 // A variable of class type (or array thereof) that appears in a
17657 // lastprivate clause requires an accessible, unambiguous copy assignment
17658 // operator for the class type.
17659 Type = Context.getBaseElementType(Type).getNonReferenceType();
17660 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
17661 Type.getUnqualifiedType(), ".lastprivate.src",
17662 D->hasAttrs() ? &D->getAttrs() : nullptr);
17663 DeclRefExpr *PseudoSrcExpr =
17664 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
17665 VarDecl *DstVD =
17666 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
17667 D->hasAttrs() ? &D->getAttrs() : nullptr);
17668 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
17669 // For arrays generate assignment operation for single element and replace
17670 // it by the original array element in CodeGen.
17671 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
17672 PseudoDstExpr, PseudoSrcExpr);
17673 if (AssignmentOp.isInvalid())
17674 continue;
17675 AssignmentOp =
17676 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
17677 if (AssignmentOp.isInvalid())
17678 continue;
17679
17680 DeclRefExpr *Ref = nullptr;
17681 if (!VD && !CurContext->isDependentContext()) {
17682 if (TopDVar.CKind == OMPC_firstprivate) {
17683 Ref = TopDVar.PrivateCopy;
17684 } else {
17685 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17686 if (!isOpenMPCapturedDecl(D))
17687 ExprCaptures.push_back(Ref->getDecl());
17688 }
17689 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
17690 (!isOpenMPCapturedDecl(D) &&
17691 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
17692 ExprResult RefRes = DefaultLvalueConversion(Ref);
17693 if (!RefRes.isUsable())
17694 continue;
17695 ExprResult PostUpdateRes =
17696 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17697 RefRes.get());
17698 if (!PostUpdateRes.isUsable())
17699 continue;
17700 ExprPostUpdates.push_back(
17701 IgnoredValueConversions(PostUpdateRes.get()).get());
17702 }
17703 }
17704 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
17705 Vars.push_back((VD || CurContext->isDependentContext())
17706 ? RefExpr->IgnoreParens()
17707 : Ref);
17708 SrcExprs.push_back(PseudoSrcExpr);
17709 DstExprs.push_back(PseudoDstExpr);
17710 AssignmentOps.push_back(AssignmentOp.get());
17711 }
17712
17713 if (Vars.empty())
17714 return nullptr;
17715
17716 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17717 Vars, SrcExprs, DstExprs, AssignmentOps,
17718 LPKind, LPKindLoc, ColonLoc,
17719 buildPreInits(Context, ExprCaptures),
17720 buildPostUpdate(*this, ExprPostUpdates));
17721}
17722
17723OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
17724 SourceLocation StartLoc,
17725 SourceLocation LParenLoc,
17726 SourceLocation EndLoc) {
17727 SmallVector<Expr *, 8> Vars;
17728 for (Expr *RefExpr : VarList) {
17729 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 17729, __extension__ __PRETTY_FUNCTION__
))
;
17730 SourceLocation ELoc;
17731 SourceRange ERange;
17732 Expr *SimpleRefExpr = RefExpr;
17733 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17734 if (Res.second) {
17735 // It will be analyzed later.
17736 Vars.push_back(RefExpr);
17737 }
17738 ValueDecl *D = Res.first;
17739 if (!D)
17740 continue;
17741
17742 auto *VD = dyn_cast<VarDecl>(D);
17743 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17744 // in a Construct]
17745 // Variables with the predetermined data-sharing attributes may not be
17746 // listed in data-sharing attributes clauses, except for the cases
17747 // listed below. For these exceptions only, listing a predetermined
17748 // variable in a data-sharing attribute clause is allowed and overrides
17749 // the variable's predetermined data-sharing attributes.
17750 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17751 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
17752 DVar.RefExpr) {
17753 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17754 << getOpenMPClauseName(OMPC_shared);
17755 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17756 continue;
17757 }
17758
17759 DeclRefExpr *Ref = nullptr;
17760 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
17761 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17762 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
17763 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
17764 ? RefExpr->IgnoreParens()
17765 : Ref);
17766 }
17767
17768 if (Vars.empty())
17769 return nullptr;
17770
17771 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
17772}
17773
17774namespace {
17775class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
17776 DSAStackTy *Stack;
17777
17778public:
17779 bool VisitDeclRefExpr(DeclRefExpr *E) {
17780 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
17781 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
17782 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
17783 return false;
17784 if (DVar.CKind != OMPC_unknown)
17785 return true;
17786 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
17787 VD,
17788 [](OpenMPClauseKind C, bool AppliedToPointee) {
17789 return isOpenMPPrivate(C) && !AppliedToPointee;
17790 },
17791 [](OpenMPDirectiveKind) { return true; },
17792 /*FromParent=*/true);
17793 return DVarPrivate.CKind != OMPC_unknown;
17794 }
17795 return false;
17796 }
17797 bool VisitStmt(Stmt *S) {
17798 for (Stmt *Child : S->children()) {
17799 if (Child && Visit(Child))
17800 return true;
17801 }
17802 return false;
17803 }
17804 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
17805};
17806} // namespace
17807
17808namespace {
17809// Transform MemberExpression for specified FieldDecl of current class to
17810// DeclRefExpr to specified OMPCapturedExprDecl.
17811class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
17812 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
17813 ValueDecl *Field = nullptr;
17814 DeclRefExpr *CapturedExpr = nullptr;
17815
17816public:
17817 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
17818 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
17819
17820 ExprResult TransformMemberExpr(MemberExpr *E) {
17821 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
17822 E->getMemberDecl() == Field) {
17823 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
17824 return CapturedExpr;
17825 }
17826 return BaseTransform::TransformMemberExpr(E);
17827 }
17828 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
17829};
17830} // namespace
17831
17832template <typename T, typename U>
17833static T filterLookupForUDReductionAndMapper(
17834 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
17835 for (U &Set : Lookups) {
17836 for (auto *D : Set) {
17837 if (T Res = Gen(cast<ValueDecl>(D)))
17838 return Res;
17839 }
17840 }
17841 return T();
17842}
17843
17844static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
17845 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")(static_cast <bool> (!LookupResult::isVisible(SemaRef, D
) && "not in slow case") ? void (0) : __assert_fail (
"!LookupResult::isVisible(SemaRef, D) && \"not in slow case\""
, "clang/lib/Sema/SemaOpenMP.cpp", 17845, __extension__ __PRETTY_FUNCTION__
))
;
17846
17847 for (auto RD : D->redecls()) {
17848 // Don't bother with extra checks if we already know this one isn't visible.
17849 if (RD == D)
17850 continue;
17851
17852 auto ND = cast<NamedDecl>(RD);
17853 if (LookupResult::isVisible(SemaRef, ND))
17854 return ND;
17855 }
17856
17857 return nullptr;
17858}
17859
17860static void
17861argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
17862 SourceLocation Loc, QualType Ty,
17863 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
17864 // Find all of the associated namespaces and classes based on the
17865 // arguments we have.
17866 Sema::AssociatedNamespaceSet AssociatedNamespaces;
17867 Sema::AssociatedClassSet AssociatedClasses;
17868 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
17869 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
17870 AssociatedClasses);
17871
17872 // C++ [basic.lookup.argdep]p3:
17873 // Let X be the lookup set produced by unqualified lookup (3.4.1)
17874 // and let Y be the lookup set produced by argument dependent
17875 // lookup (defined as follows). If X contains [...] then Y is
17876 // empty. Otherwise Y is the set of declarations found in the
17877 // namespaces associated with the argument types as described
17878 // below. The set of declarations found by the lookup of the name
17879 // is the union of X and Y.
17880 //
17881 // Here, we compute Y and add its members to the overloaded
17882 // candidate set.
17883 for (auto *NS : AssociatedNamespaces) {
17884 // When considering an associated namespace, the lookup is the
17885 // same as the lookup performed when the associated namespace is
17886 // used as a qualifier (3.4.3.2) except that:
17887 //
17888 // -- Any using-directives in the associated namespace are
17889 // ignored.
17890 //
17891 // -- Any namespace-scope friend functions declared in
17892 // associated classes are visible within their respective
17893 // namespaces even if they are not visible during an ordinary
17894 // lookup (11.4).
17895 DeclContext::lookup_result R = NS->lookup(Id.getName());
17896 for (auto *D : R) {
17897 auto *Underlying = D;
17898 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
17899 Underlying = USD->getTargetDecl();
17900
17901 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
17902 !isa<OMPDeclareMapperDecl>(Underlying))
17903 continue;
17904
17905 if (!SemaRef.isVisible(D)) {
17906 D = findAcceptableDecl(SemaRef, D);
17907 if (!D)
17908 continue;
17909 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
17910 Underlying = USD->getTargetDecl();
17911 }
17912 Lookups.emplace_back();
17913 Lookups.back().addDecl(Underlying);
17914 }
17915 }
17916}
17917
17918static ExprResult
17919buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
17920 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
17921 const DeclarationNameInfo &ReductionId, QualType Ty,
17922 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
17923 if (ReductionIdScopeSpec.isInvalid())
17924 return ExprError();
17925 SmallVector<UnresolvedSet<8>, 4> Lookups;
17926 if (S) {
17927 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
17928 Lookup.suppressDiagnostics();
17929 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
17930 NamedDecl *D = Lookup.getRepresentativeDecl();
17931 do {
17932 S = S->getParent();
17933 } while (S && !S->isDeclScope(D));
17934 if (S)
17935 S = S->getParent();
17936 Lookups.emplace_back();
17937 Lookups.back().append(Lookup.begin(), Lookup.end());
17938 Lookup.clear();
17939 }
17940 } else if (auto *ULE =
17941 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
17942 Lookups.push_back(UnresolvedSet<8>());
17943 Decl *PrevD = nullptr;
17944 for (NamedDecl *D : ULE->decls()) {
17945 if (D == PrevD)
17946 Lookups.push_back(UnresolvedSet<8>());
17947 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
17948 Lookups.back().addDecl(DRD);
17949 PrevD = D;
17950 }
17951 }
17952 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
17953 Ty->isInstantiationDependentType() ||
17954 Ty->containsUnexpandedParameterPack() ||
17955 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17956 return !D->isInvalidDecl() &&
17957 (D->getType()->isDependentType() ||
17958 D->getType()->isInstantiationDependentType() ||
17959 D->getType()->containsUnexpandedParameterPack());
17960 })) {
17961 UnresolvedSet<8> ResSet;
17962 for (const UnresolvedSet<8> &Set : Lookups) {
17963 if (Set.empty())
17964 continue;
17965 ResSet.append(Set.begin(), Set.end());
17966 // The last item marks the end of all declarations at the specified scope.
17967 ResSet.addDecl(Set[Set.size() - 1]);
17968 }
17969 return UnresolvedLookupExpr::Create(
17970 SemaRef.Context, /*NamingClass=*/nullptr,
17971 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
17972 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
17973 }
17974 // Lookup inside the classes.
17975 // C++ [over.match.oper]p3:
17976 // For a unary operator @ with an operand of a type whose
17977 // cv-unqualified version is T1, and for a binary operator @ with
17978 // a left operand of a type whose cv-unqualified version is T1 and
17979 // a right operand of a type whose cv-unqualified version is T2,
17980 // three sets of candidate functions, designated member
17981 // candidates, non-member candidates and built-in candidates, are
17982 // constructed as follows:
17983 // -- If T1 is a complete class type or a class currently being
17984 // defined, the set of member candidates is the result of the
17985 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
17986 // the set of member candidates is empty.
17987 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
17988 Lookup.suppressDiagnostics();
17989 if (const auto *TyRec = Ty->getAs<RecordType>()) {
17990 // Complete the type if it can be completed.
17991 // If the type is neither complete nor being defined, bail out now.
17992 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
17993 TyRec->getDecl()->getDefinition()) {
17994 Lookup.clear();
17995 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
17996 if (Lookup.empty()) {
17997 Lookups.emplace_back();
17998 Lookups.back().append(Lookup.begin(), Lookup.end());
17999 }
18000 }
18001 }
18002 // Perform ADL.
18003 if (SemaRef.getLangOpts().CPlusPlus)
18004 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
18005 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18006 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
18007 if (!D->isInvalidDecl() &&
18008 SemaRef.Context.hasSameType(D->getType(), Ty))
18009 return D;
18010 return nullptr;
18011 }))
18012 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
18013 VK_LValue, Loc);
18014 if (SemaRef.getLangOpts().CPlusPlus) {
18015 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18016 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
18017 if (!D->isInvalidDecl() &&
18018 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
18019 !Ty.isMoreQualifiedThan(D->getType()))
18020 return D;
18021 return nullptr;
18022 })) {
18023 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18024 /*DetectVirtual=*/false);
18025 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
18026 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18027 VD->getType().getUnqualifiedType()))) {
18028 if (SemaRef.CheckBaseClassAccess(
18029 Loc, VD->getType(), Ty, Paths.front(),
18030 /*DiagID=*/0) != Sema::AR_inaccessible) {
18031 SemaRef.BuildBasePathArray(Paths, BasePath);
18032 return SemaRef.BuildDeclRefExpr(
18033 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
18034 }
18035 }
18036 }
18037 }
18038 }
18039 if (ReductionIdScopeSpec.isSet()) {
18040 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18041 << Ty << Range;
18042 return ExprError();
18043 }
18044 return ExprEmpty();
18045}
18046
18047namespace {
18048/// Data for the reduction-based clauses.
18049struct ReductionData {
18050 /// List of original reduction items.
18051 SmallVector<Expr *, 8> Vars;
18052 /// List of private copies of the reduction items.
18053 SmallVector<Expr *, 8> Privates;
18054 /// LHS expressions for the reduction_op expressions.
18055 SmallVector<Expr *, 8> LHSs;
18056 /// RHS expressions for the reduction_op expressions.
18057 SmallVector<Expr *, 8> RHSs;
18058 /// Reduction operation expression.
18059 SmallVector<Expr *, 8> ReductionOps;
18060 /// inscan copy operation expressions.
18061 SmallVector<Expr *, 8> InscanCopyOps;
18062 /// inscan copy temp array expressions for prefix sums.
18063 SmallVector<Expr *, 8> InscanCopyArrayTemps;
18064 /// inscan copy temp array element expressions for prefix sums.
18065 SmallVector<Expr *, 8> InscanCopyArrayElems;
18066 /// Taskgroup descriptors for the corresponding reduction items in
18067 /// in_reduction clauses.
18068 SmallVector<Expr *, 8> TaskgroupDescriptors;
18069 /// List of captures for clause.
18070 SmallVector<Decl *, 4> ExprCaptures;
18071 /// List of postupdate expressions.
18072 SmallVector<Expr *, 4> ExprPostUpdates;
18073 /// Reduction modifier.
18074 unsigned RedModifier = 0;
18075 ReductionData() = delete;
18076 /// Reserves required memory for the reduction data.
18077 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
18078 Vars.reserve(Size);
18079 Privates.reserve(Size);
18080 LHSs.reserve(Size);
18081 RHSs.reserve(Size);
18082 ReductionOps.reserve(Size);
18083 if (RedModifier == OMPC_REDUCTION_inscan) {
18084 InscanCopyOps.reserve(Size);
18085 InscanCopyArrayTemps.reserve(Size);
18086 InscanCopyArrayElems.reserve(Size);
18087 }
18088 TaskgroupDescriptors.reserve(Size);
18089 ExprCaptures.reserve(Size);
18090 ExprPostUpdates.reserve(Size);
18091 }
18092 /// Stores reduction item and reduction operation only (required for dependent
18093 /// reduction item).
18094 void push(Expr *Item, Expr *ReductionOp) {
18095 Vars.emplace_back(Item);
18096 Privates.emplace_back(nullptr);
18097 LHSs.emplace_back(nullptr);
18098 RHSs.emplace_back(nullptr);
18099 ReductionOps.emplace_back(ReductionOp);
18100 TaskgroupDescriptors.emplace_back(nullptr);
18101 if (RedModifier == OMPC_REDUCTION_inscan) {
18102 InscanCopyOps.push_back(nullptr);
18103 InscanCopyArrayTemps.push_back(nullptr);
18104 InscanCopyArrayElems.push_back(nullptr);
18105 }
18106 }
18107 /// Stores reduction data.
18108 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
18109 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
18110 Expr *CopyArrayElem) {
18111 Vars.emplace_back(Item);
18112 Privates.emplace_back(Private);
18113 LHSs.emplace_back(LHS);
18114 RHSs.emplace_back(RHS);
18115 ReductionOps.emplace_back(ReductionOp);
18116 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
18117 if (RedModifier == OMPC_REDUCTION_inscan) {
18118 InscanCopyOps.push_back(CopyOp);
18119 InscanCopyArrayTemps.push_back(CopyArrayTemp);
18120 InscanCopyArrayElems.push_back(CopyArrayElem);
18121 } else {
18122 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&(static_cast <bool> (CopyOp == nullptr && CopyArrayTemp
== nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? void (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 18124, __extension__ __PRETTY_FUNCTION__
))
18123 CopyArrayElem == nullptr &&(static_cast <bool> (CopyOp == nullptr && CopyArrayTemp
== nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? void (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 18124, __extension__ __PRETTY_FUNCTION__
))
18124 "Copy operation must be used for inscan reductions only.")(static_cast <bool> (CopyOp == nullptr && CopyArrayTemp
== nullptr && CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? void (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 18124, __extension__ __PRETTY_FUNCTION__
))
;
18125 }
18126 }
18127};
18128} // namespace
18129
18130static bool checkOMPArraySectionConstantForReduction(
18131 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
18132 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
18133 const Expr *Length = OASE->getLength();
18134 if (Length == nullptr) {
18135 // For array sections of the form [1:] or [:], we would need to analyze
18136 // the lower bound...
18137 if (OASE->getColonLocFirst().isValid())
18138 return false;
18139
18140 // This is an array subscript which has implicit length 1!
18141 SingleElement = true;
18142 ArraySizes.push_back(llvm::APSInt::get(1));
18143 } else {
18144 Expr::EvalResult Result;
18145 if (!Length->EvaluateAsInt(Result, Context))
18146 return false;
18147
18148 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18149 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
18150 ArraySizes.push_back(ConstantLengthValue);
18151 }
18152
18153 // Get the base of this array section and walk up from there.
18154 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
18155
18156 // We require length = 1 for all array sections except the right-most to
18157 // guarantee that the memory region is contiguous and has no holes in it.
18158 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
18159 Length = TempOASE->getLength();
18160 if (Length == nullptr) {
18161 // For array sections of the form [1:] or [:], we would need to analyze
18162 // the lower bound...
18163 if (OASE->getColonLocFirst().isValid())
18164 return false;
18165
18166 // This is an array subscript which has implicit length 1!
18167 ArraySizes.push_back(llvm::APSInt::get(1));
18168 } else {
18169 Expr::EvalResult Result;
18170 if (!Length->EvaluateAsInt(Result, Context))
18171 return false;
18172
18173 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18174 if (ConstantLengthValue.getSExtValue() != 1)
18175 return false;
18176
18177 ArraySizes.push_back(ConstantLengthValue);
18178 }
18179 Base = TempOASE->getBase()->IgnoreParenImpCasts();
18180 }
18181
18182 // If we have a single element, we don't need to add the implicit lengths.
18183 if (!SingleElement) {
18184 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
18185 // Has implicit length 1!
18186 ArraySizes.push_back(llvm::APSInt::get(1));
18187 Base = TempASE->getBase()->IgnoreParenImpCasts();
18188 }
18189 }
18190
18191 // This array section can be privatized as a single value or as a constant
18192 // sized array.
18193 return true;
18194}
18195
18196static BinaryOperatorKind
18197getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
18198 if (BOK == BO_Add)
18199 return BO_AddAssign;
18200 if (BOK == BO_Mul)
18201 return BO_MulAssign;
18202 if (BOK == BO_And)
18203 return BO_AndAssign;
18204 if (BOK == BO_Or)
18205 return BO_OrAssign;
18206 if (BOK == BO_Xor)
18207 return BO_XorAssign;
18208 return BOK;
18209}
18210
18211static bool actOnOMPReductionKindClause(
18212 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
18213 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18214 SourceLocation ColonLoc, SourceLocation EndLoc,
18215 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18216 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
18217 DeclarationName DN = ReductionId.getName();
18218 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
18219 BinaryOperatorKind BOK = BO_Comma;
18220
18221 ASTContext &Context = S.Context;
18222 // OpenMP [2.14.3.6, reduction clause]
18223 // C
18224 // reduction-identifier is either an identifier or one of the following
18225 // operators: +, -, *, &, |, ^, && and ||
18226 // C++
18227 // reduction-identifier is either an id-expression or one of the following
18228 // operators: +, -, *, &, |, ^, && and ||
18229 switch (OOK) {
18230 case OO_Plus:
18231 case OO_Minus:
18232 BOK = BO_Add;
18233 break;
18234 case OO_Star:
18235 BOK = BO_Mul;
18236 break;
18237 case OO_Amp:
18238 BOK = BO_And;
18239 break;
18240 case OO_Pipe:
18241 BOK = BO_Or;
18242 break;
18243 case OO_Caret:
18244 BOK = BO_Xor;
18245 break;
18246 case OO_AmpAmp:
18247 BOK = BO_LAnd;
18248 break;
18249 case OO_PipePipe:
18250 BOK = BO_LOr;
18251 break;
18252 case OO_New:
18253 case OO_Delete:
18254 case OO_Array_New:
18255 case OO_Array_Delete:
18256 case OO_Slash:
18257 case OO_Percent:
18258 case OO_Tilde:
18259 case OO_Exclaim:
18260 case OO_Equal:
18261 case OO_Less:
18262 case OO_Greater:
18263 case OO_LessEqual:
18264 case OO_GreaterEqual:
18265 case OO_PlusEqual:
18266 case OO_MinusEqual:
18267 case OO_StarEqual:
18268 case OO_SlashEqual:
18269 case OO_PercentEqual:
18270 case OO_CaretEqual:
18271 case OO_AmpEqual:
18272 case OO_PipeEqual:
18273 case OO_LessLess:
18274 case OO_GreaterGreater:
18275 case OO_LessLessEqual:
18276 case OO_GreaterGreaterEqual:
18277 case OO_EqualEqual:
18278 case OO_ExclaimEqual:
18279 case OO_Spaceship:
18280 case OO_PlusPlus:
18281 case OO_MinusMinus:
18282 case OO_Comma:
18283 case OO_ArrowStar:
18284 case OO_Arrow:
18285 case OO_Call:
18286 case OO_Subscript:
18287 case OO_Conditional:
18288 case OO_Coawait:
18289 case NUM_OVERLOADED_OPERATORS:
18290 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "clang/lib/Sema/SemaOpenMP.cpp", 18290)
;
18291 case OO_None:
18292 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
18293 if (II->isStr("max"))
18294 BOK = BO_GT;
18295 else if (II->isStr("min"))
18296 BOK = BO_LT;
18297 }
18298 break;
18299 }
18300 SourceRange ReductionIdRange;
18301 if (ReductionIdScopeSpec.isValid())
18302 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
18303 else
18304 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
18305 ReductionIdRange.setEnd(ReductionId.getEndLoc());
18306
18307 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
18308 bool FirstIter = true;
18309 for (Expr *RefExpr : VarList) {
18310 assert(RefExpr && "nullptr expr in OpenMP reduction clause.")(static_cast <bool> (RefExpr && "nullptr expr in OpenMP reduction clause."
) ? void (0) : __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 18310, __extension__ __PRETTY_FUNCTION__
))
;
18311 // OpenMP [2.1, C/C++]
18312 // A list item is a variable or array section, subject to the restrictions
18313 // specified in Section 2.4 on page 42 and in each of the sections
18314 // describing clauses and directives for which a list appears.
18315 // OpenMP [2.14.3.3, Restrictions, p.1]
18316 // A variable that is part of another variable (as an array or
18317 // structure element) cannot appear in a private clause.
18318 if (!FirstIter && IR != ER)
18319 ++IR;
18320 FirstIter = false;
18321 SourceLocation ELoc;
18322 SourceRange ERange;
18323 Expr *SimpleRefExpr = RefExpr;
18324 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
18325 /*AllowArraySection=*/true);
18326 if (Res.second) {
18327 // Try to find 'declare reduction' corresponding construct before using
18328 // builtin/overloaded operators.
18329 QualType Type = Context.DependentTy;
18330 CXXCastPath BasePath;
18331 ExprResult DeclareReductionRef = buildDeclareReductionRef(
18332 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18333 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18334 Expr *ReductionOp = nullptr;
18335 if (S.CurContext->isDependentContext() &&
18336 (DeclareReductionRef.isUnset() ||
18337 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
18338 ReductionOp = DeclareReductionRef.get();
18339 // It will be analyzed later.
18340 RD.push(RefExpr, ReductionOp);
18341 }
18342 ValueDecl *D = Res.first;
18343 if (!D)
18344 continue;
18345
18346 Expr *TaskgroupDescriptor = nullptr;
18347 QualType Type;
18348 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
18349 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
18350 if (ASE) {
18351 Type = ASE->getType().getNonReferenceType();
18352 } else if (OASE) {
18353 QualType BaseType =
18354 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18355 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18356 Type = ATy->getElementType();
18357 else
18358 Type = BaseType->getPointeeType();
18359 Type = Type.getNonReferenceType();
18360 } else {
18361 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
18362 }
18363 auto *VD = dyn_cast<VarDecl>(D);
18364
18365 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18366 // A variable that appears in a private clause must not have an incomplete
18367 // type or a reference type.
18368 if (S.RequireCompleteType(ELoc, D->getType(),
18369 diag::err_omp_reduction_incomplete_type))
18370 continue;
18371 // OpenMP [2.14.3.6, reduction clause, Restrictions]
18372 // A list item that appears in a reduction clause must not be
18373 // const-qualified.
18374 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
18375 /*AcceptIfMutable*/ false, ASE || OASE))
18376 continue;
18377
18378 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
18379 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
18380 // If a list-item is a reference type then it must bind to the same object
18381 // for all threads of the team.
18382 if (!ASE && !OASE) {
18383 if (VD) {
18384 VarDecl *VDDef = VD->getDefinition();
18385 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
18386 DSARefChecker Check(Stack);
18387 if (Check.Visit(VDDef->getInit())) {
18388 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
18389 << getOpenMPClauseName(ClauseKind) << ERange;
18390 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
18391 continue;
18392 }
18393 }
18394 }
18395
18396 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18397 // in a Construct]
18398 // Variables with the predetermined data-sharing attributes may not be
18399 // listed in data-sharing attributes clauses, except for the cases
18400 // listed below. For these exceptions only, listing a predetermined
18401 // variable in a data-sharing attribute clause is allowed and overrides
18402 // the variable's predetermined data-sharing attributes.
18403 // OpenMP [2.14.3.6, Restrictions, p.3]
18404 // Any number of reduction clauses can be specified on the directive,
18405 // but a list item can appear only once in the reduction clauses for that
18406 // directive.
18407 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18408 if (DVar.CKind == OMPC_reduction) {
18409 S.Diag(ELoc, diag::err_omp_once_referenced)
18410 << getOpenMPClauseName(ClauseKind);
18411 if (DVar.RefExpr)
18412 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
18413 continue;
18414 }
18415 if (DVar.CKind != OMPC_unknown) {
18416 S.Diag(ELoc, diag::err_omp_wrong_dsa)
18417 << getOpenMPClauseName(DVar.CKind)
18418 << getOpenMPClauseName(OMPC_reduction);
18419 reportOriginalDsa(S, Stack, D, DVar);
18420 continue;
18421 }
18422
18423 // OpenMP [2.14.3.6, Restrictions, p.1]
18424 // A list item that appears in a reduction clause of a worksharing
18425 // construct must be shared in the parallel regions to which any of the
18426 // worksharing regions arising from the worksharing construct bind.
18427 if (isOpenMPWorksharingDirective(CurrDir) &&
18428 !isOpenMPParallelDirective(CurrDir) &&
18429 !isOpenMPTeamsDirective(CurrDir)) {
18430 DVar = Stack->getImplicitDSA(D, true);
18431 if (DVar.CKind != OMPC_shared) {
18432 S.Diag(ELoc, diag::err_omp_required_access)
18433 << getOpenMPClauseName(OMPC_reduction)
18434 << getOpenMPClauseName(OMPC_shared);
18435 reportOriginalDsa(S, Stack, D, DVar);
18436 continue;
18437 }
18438 }
18439 } else {
18440 // Threadprivates cannot be shared between threads, so dignose if the base
18441 // is a threadprivate variable.
18442 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18443 if (DVar.CKind == OMPC_threadprivate) {
18444 S.Diag(ELoc, diag::err_omp_wrong_dsa)
18445 << getOpenMPClauseName(DVar.CKind)
18446 << getOpenMPClauseName(OMPC_reduction);
18447 reportOriginalDsa(S, Stack, D, DVar);
18448 continue;
18449 }
18450 }
18451
18452 // Try to find 'declare reduction' corresponding construct before using
18453 // builtin/overloaded operators.
18454 CXXCastPath BasePath;
18455 ExprResult DeclareReductionRef = buildDeclareReductionRef(
18456 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18457 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18458 if (DeclareReductionRef.isInvalid())
18459 continue;
18460 if (S.CurContext->isDependentContext() &&
18461 (DeclareReductionRef.isUnset() ||
18462 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
18463 RD.push(RefExpr, DeclareReductionRef.get());
18464 continue;
18465 }
18466 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
18467 // Not allowed reduction identifier is found.
18468 S.Diag(ReductionId.getBeginLoc(),
18469 diag::err_omp_unknown_reduction_identifier)
18470 << Type << ReductionIdRange;
18471 continue;
18472 }
18473
18474 // OpenMP [2.14.3.6, reduction clause, Restrictions]
18475 // The type of a list item that appears in a reduction clause must be valid
18476 // for the reduction-identifier. For a max or min reduction in C, the type
18477 // of the list item must be an allowed arithmetic data type: char, int,
18478 // float, double, or _Bool, possibly modified with long, short, signed, or
18479 // unsigned. For a max or min reduction in C++, the type of the list item
18480 // must be an allowed arithmetic data type: char, wchar_t, int, float,
18481 // double, or bool, possibly modified with long, short, signed, or unsigned.
18482 if (DeclareReductionRef.isUnset()) {
18483 if ((BOK == BO_GT || BOK == BO_LT) &&
18484 !(Type->isScalarType() ||
18485 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
18486 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
18487 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
18488 if (!ASE && !OASE) {
18489 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18490 VarDecl::DeclarationOnly;
18491 S.Diag(D->getLocation(),
18492 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18493 << D;
18494 }
18495 continue;
18496 }
18497 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
18498 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
18499 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
18500 << getOpenMPClauseName(ClauseKind);
18501 if (!ASE && !OASE) {
18502 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18503 VarDecl::DeclarationOnly;
18504 S.Diag(D->getLocation(),
18505 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18506 << D;
18507 }
18508 continue;
18509 }
18510 }
18511
18512 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
18513 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
18514 D->hasAttrs() ? &D->getAttrs() : nullptr);
18515 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
18516 D->hasAttrs() ? &D->getAttrs() : nullptr);
18517 QualType PrivateTy = Type;
18518
18519 // Try if we can determine constant lengths for all array sections and avoid
18520 // the VLA.
18521 bool ConstantLengthOASE = false;
18522 if (OASE) {
18523 bool SingleElement;
18524 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
18525 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
18526 Context, OASE, SingleElement, ArraySizes);
18527
18528 // If we don't have a single element, we must emit a constant array type.
18529 if (ConstantLengthOASE && !SingleElement) {
18530 for (llvm::APSInt &Size : ArraySizes)
18531 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
18532 ArrayType::Normal,
18533 /*IndexTypeQuals=*/0);
18534 }
18535 }
18536
18537 if ((OASE && !ConstantLengthOASE) ||
18538 (!OASE && !ASE &&
18539 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
18540 if (!Context.getTargetInfo().isVLASupported()) {
18541 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
18542 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18543 S.Diag(ELoc, diag::note_vla_unsupported);
18544 continue;
18545 } else {
18546 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18547 S.targetDiag(ELoc, diag::note_vla_unsupported);
18548 }
18549 }
18550 // For arrays/array sections only:
18551 // Create pseudo array type for private copy. The size for this array will
18552 // be generated during codegen.
18553 // For array subscripts or single variables Private Ty is the same as Type
18554 // (type of the variable or single array element).
18555 PrivateTy = Context.getVariableArrayType(
18556 Type,
18557 new (Context)
18558 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
18559 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
18560 } else if (!ASE && !OASE &&
18561 Context.getAsArrayType(D->getType().getNonReferenceType())) {
18562 PrivateTy = D->getType().getNonReferenceType();
18563 }
18564 // Private copy.
18565 VarDecl *PrivateVD =
18566 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18567 D->hasAttrs() ? &D->getAttrs() : nullptr,
18568 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18569 // Add initializer for private variable.
18570 Expr *Init = nullptr;
18571 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
18572 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
18573 if (DeclareReductionRef.isUsable()) {
18574 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
18575 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
18576 if (DRD->getInitializer()) {
18577 Init = DRDRef;
18578 RHSVD->setInit(DRDRef);
18579 RHSVD->setInitStyle(VarDecl::CallInit);
18580 }
18581 } else {
18582 switch (BOK) {
18583 case BO_Add:
18584 case BO_Xor:
18585 case BO_Or:
18586 case BO_LOr:
18587 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
18588 if (Type->isScalarType() || Type->isAnyComplexType())
18589 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
18590 break;
18591 case BO_Mul:
18592 case BO_LAnd:
18593 if (Type->isScalarType() || Type->isAnyComplexType()) {
18594 // '*' and '&&' reduction ops - initializer is '1'.
18595 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
18596 }
18597 break;
18598 case BO_And: {
18599 // '&' reduction op - initializer is '~0'.
18600 QualType OrigType = Type;
18601 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
18602 Type = ComplexTy->getElementType();
18603 if (Type->isRealFloatingType()) {
18604 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
18605 Context.getFloatTypeSemantics(Type));
18606 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18607 Type, ELoc);
18608 } else if (Type->isScalarType()) {
18609 uint64_t Size = Context.getTypeSize(Type);
18610 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
18611 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
18612 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18613 }
18614 if (Init && OrigType->isAnyComplexType()) {
18615 // Init = 0xFFFF + 0xFFFFi;
18616 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
18617 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
18618 }
18619 Type = OrigType;
18620 break;
18621 }
18622 case BO_LT:
18623 case BO_GT: {
18624 // 'min' reduction op - initializer is 'Largest representable number in
18625 // the reduction list item type'.
18626 // 'max' reduction op - initializer is 'Least representable number in
18627 // the reduction list item type'.
18628 if (Type->isIntegerType() || Type->isPointerType()) {
18629 bool IsSigned = Type->hasSignedIntegerRepresentation();
18630 uint64_t Size = Context.getTypeSize(Type);
18631 QualType IntTy =
18632 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
18633 llvm::APInt InitValue =
18634 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
18635 : llvm::APInt::getMinValue(Size)
18636 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
18637 : llvm::APInt::getMaxValue(Size);
18638 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18639 if (Type->isPointerType()) {
18640 // Cast to pointer type.
18641 ExprResult CastExpr = S.BuildCStyleCastExpr(
18642 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
18643 if (CastExpr.isInvalid())
18644 continue;
18645 Init = CastExpr.get();
18646 }
18647 } else if (Type->isRealFloatingType()) {
18648 llvm::APFloat InitValue = llvm::APFloat::getLargest(
18649 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
18650 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18651 Type, ELoc);
18652 }
18653 break;
18654 }
18655 case BO_PtrMemD:
18656 case BO_PtrMemI:
18657 case BO_MulAssign:
18658 case BO_Div:
18659 case BO_Rem:
18660 case BO_Sub:
18661 case BO_Shl:
18662 case BO_Shr:
18663 case BO_LE:
18664 case BO_GE:
18665 case BO_EQ:
18666 case BO_NE:
18667 case BO_Cmp:
18668 case BO_AndAssign:
18669 case BO_XorAssign:
18670 case BO_OrAssign:
18671 case BO_Assign:
18672 case BO_AddAssign:
18673 case BO_SubAssign:
18674 case BO_DivAssign:
18675 case BO_RemAssign:
18676 case BO_ShlAssign:
18677 case BO_ShrAssign:
18678 case BO_Comma:
18679 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "clang/lib/Sema/SemaOpenMP.cpp", 18679)
;
18680 }
18681 }
18682 if (Init && DeclareReductionRef.isUnset()) {
18683 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
18684 // Store initializer for single element in private copy. Will be used
18685 // during codegen.
18686 PrivateVD->setInit(RHSVD->getInit());
18687 PrivateVD->setInitStyle(RHSVD->getInitStyle());
18688 } else if (!Init) {
18689 S.ActOnUninitializedDecl(RHSVD);
18690 // Store initializer for single element in private copy. Will be used
18691 // during codegen.
18692 PrivateVD->setInit(RHSVD->getInit());
18693 PrivateVD->setInitStyle(RHSVD->getInitStyle());
18694 }
18695 if (RHSVD->isInvalidDecl())
18696 continue;
18697 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
18698 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
18699 << Type << ReductionIdRange;
18700 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18701 VarDecl::DeclarationOnly;
18702 S.Diag(D->getLocation(),
18703 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18704 << D;
18705 continue;
18706 }
18707 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
18708 ExprResult ReductionOp;
18709 if (DeclareReductionRef.isUsable()) {
18710 QualType RedTy = DeclareReductionRef.get()->getType();
18711 QualType PtrRedTy = Context.getPointerType(RedTy);
18712 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
18713 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
18714 if (!BasePath.empty()) {
18715 LHS = S.DefaultLvalueConversion(LHS.get());
18716 RHS = S.DefaultLvalueConversion(RHS.get());
18717 LHS = ImplicitCastExpr::Create(
18718 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
18719 LHS.get()->getValueKind(), FPOptionsOverride());
18720 RHS = ImplicitCastExpr::Create(
18721 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
18722 RHS.get()->getValueKind(), FPOptionsOverride());
18723 }
18724 FunctionProtoType::ExtProtoInfo EPI;
18725 QualType Params[] = {PtrRedTy, PtrRedTy};
18726 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
18727 auto *OVE = new (Context) OpaqueValueExpr(
18728 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
18729 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
18730 Expr *Args[] = {LHS.get(), RHS.get()};
18731 ReductionOp =
18732 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
18733 S.CurFPFeatureOverrides());
18734 } else {
18735 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
18736 if (Type->isRecordType() && CombBOK != BOK) {
18737 Sema::TentativeAnalysisScope Trap(S);
18738 ReductionOp =
18739 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18740 CombBOK, LHSDRE, RHSDRE);
18741 }
18742 if (!ReductionOp.isUsable()) {
18743 ReductionOp =
18744 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
18745 LHSDRE, RHSDRE);
18746 if (ReductionOp.isUsable()) {
18747 if (BOK != BO_LT && BOK != BO_GT) {
18748 ReductionOp =
18749 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18750 BO_Assign, LHSDRE, ReductionOp.get());
18751 } else {
18752 auto *ConditionalOp = new (Context)
18753 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
18754 RHSDRE, Type, VK_LValue, OK_Ordinary);
18755 ReductionOp =
18756 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18757 BO_Assign, LHSDRE, ConditionalOp);
18758 }
18759 }
18760 }
18761 if (ReductionOp.isUsable())
18762 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
18763 /*DiscardedValue*/ false);
18764 if (!ReductionOp.isUsable())
18765 continue;
18766 }
18767
18768 // Add copy operations for inscan reductions.
18769 // LHS = RHS;
18770 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
18771 if (ClauseKind == OMPC_reduction &&
18772 RD.RedModifier == OMPC_REDUCTION_inscan) {
18773 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
18774 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
18775 RHS.get());
18776 if (!CopyOpRes.isUsable())
18777 continue;
18778 CopyOpRes =
18779 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
18780 if (!CopyOpRes.isUsable())
18781 continue;
18782 // For simd directive and simd-based directives in simd mode no need to
18783 // construct temp array, need just a single temp element.
18784 if (Stack->getCurrentDirective() == OMPD_simd ||
18785 (S.getLangOpts().OpenMPSimd &&
18786 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
18787 VarDecl *TempArrayVD =
18788 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18789 D->hasAttrs() ? &D->getAttrs() : nullptr);
18790 // Add a constructor to the temp decl.
18791 S.ActOnUninitializedDecl(TempArrayVD);
18792 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
18793 } else {
18794 // Build temp array for prefix sum.
18795 auto *Dim = new (S.Context)
18796 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
18797 QualType ArrayTy =
18798 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
18799 /*IndexTypeQuals=*/0, {ELoc, ELoc});
18800 VarDecl *TempArrayVD =
18801 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
18802 D->hasAttrs() ? &D->getAttrs() : nullptr);
18803 // Add a constructor to the temp decl.
18804 S.ActOnUninitializedDecl(TempArrayVD);
18805 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
18806 TempArrayElem =
18807 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
18808 auto *Idx = new (S.Context)
18809 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
18810 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
18811 ELoc, Idx, ELoc);
18812 }
18813 }
18814
18815 // OpenMP [2.15.4.6, Restrictions, p.2]
18816 // A list item that appears in an in_reduction clause of a task construct
18817 // must appear in a task_reduction clause of a construct associated with a
18818 // taskgroup region that includes the participating task in its taskgroup
18819 // set. The construct associated with the innermost region that meets this
18820 // condition must specify the same reduction-identifier as the in_reduction
18821 // clause.
18822 if (ClauseKind == OMPC_in_reduction) {
18823 SourceRange ParentSR;
18824 BinaryOperatorKind ParentBOK;
18825 const Expr *ParentReductionOp = nullptr;
18826 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
18827 DSAStackTy::DSAVarData ParentBOKDSA =
18828 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
18829 ParentBOKTD);
18830 DSAStackTy::DSAVarData ParentReductionOpDSA =
18831 Stack->getTopMostTaskgroupReductionData(
18832 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
18833 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
18834 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
18835 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
18836 (DeclareReductionRef.isUsable() && IsParentBOK) ||
18837 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
18838 bool EmitError = true;
18839 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
18840 llvm::FoldingSetNodeID RedId, ParentRedId;
18841 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
18842 DeclareReductionRef.get()->Profile(RedId, Context,
18843 /*Canonical=*/true);
18844 EmitError = RedId != ParentRedId;
18845 }
18846 if (EmitError) {
18847 S.Diag(ReductionId.getBeginLoc(),
18848 diag::err_omp_reduction_identifier_mismatch)
18849 << ReductionIdRange << RefExpr->getSourceRange();
18850 S.Diag(ParentSR.getBegin(),
18851 diag::note_omp_previous_reduction_identifier)
18852 << ParentSR
18853 << (IsParentBOK ? ParentBOKDSA.RefExpr
18854 : ParentReductionOpDSA.RefExpr)
18855 ->getSourceRange();
18856 continue;
18857 }
18858 }
18859 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
18860 }
18861
18862 DeclRefExpr *Ref = nullptr;
18863 Expr *VarsExpr = RefExpr->IgnoreParens();
18864 if (!VD && !S.CurContext->isDependentContext()) {
18865 if (ASE || OASE) {
18866 TransformExprToCaptures RebuildToCapture(S, D);
18867 VarsExpr =
18868 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
18869 Ref = RebuildToCapture.getCapturedExpr();
18870 } else {
18871 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
18872 }
18873 if (!S.isOpenMPCapturedDecl(D)) {
18874 RD.ExprCaptures.emplace_back(Ref->getDecl());
18875 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
18876 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
18877 if (!RefRes.isUsable())
18878 continue;
18879 ExprResult PostUpdateRes =
18880 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18881 RefRes.get());
18882 if (!PostUpdateRes.isUsable())
18883 continue;
18884 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
18885 Stack->getCurrentDirective() == OMPD_taskgroup) {
18886 S.Diag(RefExpr->getExprLoc(),
18887 diag::err_omp_reduction_non_addressable_expression)
18888 << RefExpr->getSourceRange();
18889 continue;
18890 }
18891 RD.ExprPostUpdates.emplace_back(
18892 S.IgnoredValueConversions(PostUpdateRes.get()).get());
18893 }
18894 }
18895 }
18896 // All reduction items are still marked as reduction (to do not increase
18897 // code base size).
18898 unsigned Modifier = RD.RedModifier;
18899 // Consider task_reductions as reductions with task modifier. Required for
18900 // correct analysis of in_reduction clauses.
18901 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
18902 Modifier = OMPC_REDUCTION_task;
18903 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
18904 ASE || OASE);
18905 if (Modifier == OMPC_REDUCTION_task &&
18906 (CurrDir == OMPD_taskgroup ||
18907 ((isOpenMPParallelDirective(CurrDir) ||
18908 isOpenMPWorksharingDirective(CurrDir)) &&
18909 !isOpenMPSimdDirective(CurrDir)))) {
18910 if (DeclareReductionRef.isUsable())
18911 Stack->addTaskgroupReductionData(D, ReductionIdRange,
18912 DeclareReductionRef.get());
18913 else
18914 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
18915 }
18916 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
18917 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
18918 TempArrayElem.get());
18919 }
18920 return RD.Vars.empty();
18921}
18922
18923OMPClause *Sema::ActOnOpenMPReductionClause(
18924 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
18925 SourceLocation StartLoc, SourceLocation LParenLoc,
18926 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
18927 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18928 ArrayRef<Expr *> UnresolvedReductions) {
18929 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
18930 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
18931 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
18932 /*Last=*/OMPC_REDUCTION_unknown)
18933 << getOpenMPClauseName(OMPC_reduction);
18934 return nullptr;
18935 }
18936 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
18937 // A reduction clause with the inscan reduction-modifier may only appear on a
18938 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
18939 // construct, a parallel worksharing-loop construct or a parallel
18940 // worksharing-loop SIMD construct.
18941 if (Modifier == OMPC_REDUCTION_inscan &&
18942 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
18943 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
18944 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
18945 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
18946 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
18947 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
18948 return nullptr;
18949 }
18950
18951 ReductionData RD(VarList.size(), Modifier);
18952 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
18953 StartLoc, LParenLoc, ColonLoc, EndLoc,
18954 ReductionIdScopeSpec, ReductionId,
18955 UnresolvedReductions, RD))
18956 return nullptr;
18957
18958 return OMPReductionClause::Create(
18959 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
18960 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18961 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
18962 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
18963 buildPreInits(Context, RD.ExprCaptures),
18964 buildPostUpdate(*this, RD.ExprPostUpdates));
18965}
18966
18967OMPClause *Sema::ActOnOpenMPTaskReductionClause(
18968 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18969 SourceLocation ColonLoc, SourceLocation EndLoc,
18970 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18971 ArrayRef<Expr *> UnresolvedReductions) {
18972 ReductionData RD(VarList.size());
18973 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
18974 StartLoc, LParenLoc, ColonLoc, EndLoc,
18975 ReductionIdScopeSpec, ReductionId,
18976 UnresolvedReductions, RD))
18977 return nullptr;
18978
18979 return OMPTaskReductionClause::Create(
18980 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
18981 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18982 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
18983 buildPreInits(Context, RD.ExprCaptures),
18984 buildPostUpdate(*this, RD.ExprPostUpdates));
18985}
18986
18987OMPClause *Sema::ActOnOpenMPInReductionClause(
18988 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18989 SourceLocation ColonLoc, SourceLocation EndLoc,
18990 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18991 ArrayRef<Expr *> UnresolvedReductions) {
18992 ReductionData RD(VarList.size());
18993 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
18994 StartLoc, LParenLoc, ColonLoc, EndLoc,
18995 ReductionIdScopeSpec, ReductionId,
18996 UnresolvedReductions, RD))
18997 return nullptr;
18998
18999 return OMPInReductionClause::Create(
19000 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19001 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19002 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
19003 buildPreInits(Context, RD.ExprCaptures),
19004 buildPostUpdate(*this, RD.ExprPostUpdates));
19005}
19006
19007bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
19008 SourceLocation LinLoc) {
19009 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19010 LinKind == OMPC_LINEAR_unknown) {
19011 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
19012 return true;
19013 }
19014 return false;
19015}
19016
19017bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
19018 OpenMPLinearClauseKind LinKind, QualType Type,
19019 bool IsDeclareSimd) {
19020 const auto *VD = dyn_cast_or_null<VarDecl>(D);
19021 // A variable must not have an incomplete type or a reference type.
19022 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
19023 return true;
19024 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19025 !Type->isReferenceType()) {
19026 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19027 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
19028 return true;
19029 }
19030 Type = Type.getNonReferenceType();
19031
19032 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19033 // A variable that is privatized must not have a const-qualified type
19034 // unless it is of class type with a mutable member. This restriction does
19035 // not apply to the firstprivate clause, nor to the linear clause on
19036 // declarative directives (like declare simd).
19037 if (!IsDeclareSimd &&
19038 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
19039 return true;
19040
19041 // A list item must be of integral or pointer type.
19042 Type = Type.getUnqualifiedType().getCanonicalType();
19043 const auto *Ty = Type.getTypePtrOrNull();
19044 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
19045 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
19046 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
19047 if (D) {
19048 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19049 VarDecl::DeclarationOnly;
19050 Diag(D->getLocation(),
19051 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19052 << D;
19053 }
19054 return true;
19055 }
19056 return false;
19057}
19058
19059OMPClause *Sema::ActOnOpenMPLinearClause(
19060 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
19061 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
19062 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19063 SmallVector<Expr *, 8> Vars;
19064 SmallVector<Expr *, 8> Privates;
19065 SmallVector<Expr *, 8> Inits;
19066 SmallVector<Decl *, 4> ExprCaptures;
19067 SmallVector<Expr *, 4> ExprPostUpdates;
19068 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
19069 LinKind = OMPC_LINEAR_val;
19070 for (Expr *RefExpr : VarList) {
19071 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP linear clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19071, __extension__ __PRETTY_FUNCTION__
))
;
19072 SourceLocation ELoc;
19073 SourceRange ERange;
19074 Expr *SimpleRefExpr = RefExpr;
19075 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19076 if (Res.second) {
19077 // It will be analyzed later.
19078 Vars.push_back(RefExpr);
19079 Privates.push_back(nullptr);
19080 Inits.push_back(nullptr);
19081 }
19082 ValueDecl *D = Res.first;
19083 if (!D)
19084 continue;
19085
19086 QualType Type = D->getType();
19087 auto *VD = dyn_cast<VarDecl>(D);
19088
19089 // OpenMP [2.14.3.7, linear clause]
19090 // A list-item cannot appear in more than one linear clause.
19091 // A list-item that appears in a linear clause cannot appear in any
19092 // other data-sharing attribute clause.
19093 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
19094 if (DVar.RefExpr) {
19095 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19096 << getOpenMPClauseName(OMPC_linear);
19097 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
19098 continue;
19099 }
19100
19101 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
19102 continue;
19103 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19104
19105 // Build private copy of original var.
19106 VarDecl *Private =
19107 buildVarDecl(*this, ELoc, Type, D->getName(),
19108 D->hasAttrs() ? &D->getAttrs() : nullptr,
19109 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19110 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
19111 // Build var to save initial value.
19112 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
19113 Expr *InitExpr;
19114 DeclRefExpr *Ref = nullptr;
19115 if (!VD && !CurContext->isDependentContext()) {
19116 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19117 if (!isOpenMPCapturedDecl(D)) {
19118 ExprCaptures.push_back(Ref->getDecl());
19119 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19120 ExprResult RefRes = DefaultLvalueConversion(Ref);
19121 if (!RefRes.isUsable())
19122 continue;
19123 ExprResult PostUpdateRes =
19124 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
19125 SimpleRefExpr, RefRes.get());
19126 if (!PostUpdateRes.isUsable())
19127 continue;
19128 ExprPostUpdates.push_back(
19129 IgnoredValueConversions(PostUpdateRes.get()).get());
19130 }
19131 }
19132 }
19133 if (LinKind == OMPC_LINEAR_uval)
19134 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
19135 else
19136 InitExpr = VD ? SimpleRefExpr : Ref;
19137 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
19138 /*DirectInit=*/false);
19139 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
19140
19141 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
19142 Vars.push_back((VD || CurContext->isDependentContext())
19143 ? RefExpr->IgnoreParens()
19144 : Ref);
19145 Privates.push_back(PrivateRef);
19146 Inits.push_back(InitRef);
19147 }
19148
19149 if (Vars.empty())
19150 return nullptr;
19151
19152 Expr *StepExpr = Step;
19153 Expr *CalcStepExpr = nullptr;
19154 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
19155 !Step->isInstantiationDependent() &&
19156 !Step->containsUnexpandedParameterPack()) {
19157 SourceLocation StepLoc = Step->getBeginLoc();
19158 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
19159 if (Val.isInvalid())
19160 return nullptr;
19161 StepExpr = Val.get();
19162
19163 // Build var to save the step value.
19164 VarDecl *SaveVar =
19165 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
19166 ExprResult SaveRef =
19167 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
19168 ExprResult CalcStep =
19169 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
19170 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
19171
19172 // Warn about zero linear step (it would be probably better specified as
19173 // making corresponding variables 'const').
19174 if (Optional<llvm::APSInt> Result =
19175 StepExpr->getIntegerConstantExpr(Context)) {
19176 if (!Result->isNegative() && !Result->isStrictlyPositive())
19177 Diag(StepLoc, diag::warn_omp_linear_step_zero)
19178 << Vars[0] << (Vars.size() > 1);
19179 } else if (CalcStep.isUsable()) {
19180 // Calculate the step beforehand instead of doing this on each iteration.
19181 // (This is not used if the number of iterations may be kfold-ed).
19182 CalcStepExpr = CalcStep.get();
19183 }
19184 }
19185
19186 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
19187 ColonLoc, EndLoc, Vars, Privates, Inits,
19188 StepExpr, CalcStepExpr,
19189 buildPreInits(Context, ExprCaptures),
19190 buildPostUpdate(*this, ExprPostUpdates));
19191}
19192
19193static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
19194 Expr *NumIterations, Sema &SemaRef,
19195 Scope *S, DSAStackTy *Stack) {
19196 // Walk the vars and build update/final expressions for the CodeGen.
19197 SmallVector<Expr *, 8> Updates;
19198 SmallVector<Expr *, 8> Finals;
19199 SmallVector<Expr *, 8> UsedExprs;
19200 Expr *Step = Clause.getStep();
19201 Expr *CalcStep = Clause.getCalcStep();
19202 // OpenMP [2.14.3.7, linear clause]
19203 // If linear-step is not specified it is assumed to be 1.
19204 if (!Step)
19205 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
19206 else if (CalcStep)
19207 Step = cast<BinaryOperator>(CalcStep)->getLHS();
19208 bool HasErrors = false;
19209 auto CurInit = Clause.inits().begin();
19210 auto CurPrivate = Clause.privates().begin();
19211 OpenMPLinearClauseKind LinKind = Clause.getModifier();
19212 for (Expr *RefExpr : Clause.varlists()) {
19213 SourceLocation ELoc;
19214 SourceRange ERange;
19215 Expr *SimpleRefExpr = RefExpr;
19216 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19217 ValueDecl *D = Res.first;
19218 if (Res.second || !D) {
19219 Updates.push_back(nullptr);
19220 Finals.push_back(nullptr);
19221 HasErrors = true;
19222 continue;
19223 }
19224 auto &&Info = Stack->isLoopControlVariable(D);
19225 // OpenMP [2.15.11, distribute simd Construct]
19226 // A list item may not appear in a linear clause, unless it is the loop
19227 // iteration variable.
19228 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
19229 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
19230 SemaRef.Diag(ELoc,
19231 diag::err_omp_linear_distribute_var_non_loop_iteration);
19232 Updates.push_back(nullptr);
19233 Finals.push_back(nullptr);
19234 HasErrors = true;
19235 continue;
19236 }
19237 Expr *InitExpr = *CurInit;
19238
19239 // Build privatized reference to the current linear var.
19240 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
19241 Expr *CapturedRef;
19242 if (LinKind == OMPC_LINEAR_uval)
19243 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
19244 else
19245 CapturedRef =
19246 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
19247 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
19248 /*RefersToCapture=*/true);
19249
19250 // Build update: Var = InitExpr + IV * Step
19251 ExprResult Update;
19252 if (!Info.first)
19253 Update = buildCounterUpdate(
19254 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
19255 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
19256 else
19257 Update = *CurPrivate;
19258 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
19259 /*DiscardedValue*/ false);
19260
19261 // Build final: Var = PrivCopy;
19262 ExprResult Final;
19263 if (!Info.first)
19264 Final = SemaRef.BuildBinOp(
19265 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
19266 SemaRef.DefaultLvalueConversion(*CurPrivate).get());
19267 else
19268 Final = *CurPrivate;
19269 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
19270 /*DiscardedValue*/ false);
19271
19272 if (!Update.isUsable() || !Final.isUsable()) {
19273 Updates.push_back(nullptr);
19274 Finals.push_back(nullptr);
19275 UsedExprs.push_back(nullptr);
19276 HasErrors = true;
19277 } else {
19278 Updates.push_back(Update.get());
19279 Finals.push_back(Final.get());
19280 if (!Info.first)
19281 UsedExprs.push_back(SimpleRefExpr);
19282 }
19283 ++CurInit;
19284 ++CurPrivate;
19285 }
19286 if (Expr *S = Clause.getStep())
19287 UsedExprs.push_back(S);
19288 // Fill the remaining part with the nullptr.
19289 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
19290 Clause.setUpdates(Updates);
19291 Clause.setFinals(Finals);
19292 Clause.setUsedExprs(UsedExprs);
19293 return HasErrors;
19294}
19295
19296OMPClause *Sema::ActOnOpenMPAlignedClause(
19297 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
19298 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19299 SmallVector<Expr *, 8> Vars;
19300 for (Expr *RefExpr : VarList) {
19301 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP linear clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19301, __extension__ __PRETTY_FUNCTION__
))
;
19302 SourceLocation ELoc;
19303 SourceRange ERange;
19304 Expr *SimpleRefExpr = RefExpr;
19305 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19306 if (Res.second) {
19307 // It will be analyzed later.
19308 Vars.push_back(RefExpr);
19309 }
19310 ValueDecl *D = Res.first;
19311 if (!D)
19312 continue;
19313
19314 QualType QType = D->getType();
19315 auto *VD = dyn_cast<VarDecl>(D);
19316
19317 // OpenMP [2.8.1, simd construct, Restrictions]
19318 // The type of list items appearing in the aligned clause must be
19319 // array, pointer, reference to array, or reference to pointer.
19320 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19321 const Type *Ty = QType.getTypePtrOrNull();
19322 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
19323 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
19324 << QType << getLangOpts().CPlusPlus << ERange;
19325 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19326 VarDecl::DeclarationOnly;
19327 Diag(D->getLocation(),
19328 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19329 << D;
19330 continue;
19331 }
19332
19333 // OpenMP [2.8.1, simd construct, Restrictions]
19334 // A list-item cannot appear in more than one aligned clause.
19335 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
19336 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19337 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
19338 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19339 << getOpenMPClauseName(OMPC_aligned);
19340 continue;
19341 }
19342
19343 DeclRefExpr *Ref = nullptr;
19344 if (!VD && isOpenMPCapturedDecl(D))
19345 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19346 Vars.push_back(DefaultFunctionArrayConversion(
19347 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
19348 .get());
19349 }
19350
19351 // OpenMP [2.8.1, simd construct, Description]
19352 // The parameter of the aligned clause, alignment, must be a constant
19353 // positive integer expression.
19354 // If no optional parameter is specified, implementation-defined default
19355 // alignments for SIMD instructions on the target platforms are assumed.
19356 if (Alignment != nullptr) {
19357 ExprResult AlignResult =
19358 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
19359 if (AlignResult.isInvalid())
19360 return nullptr;
19361 Alignment = AlignResult.get();
19362 }
19363 if (Vars.empty())
19364 return nullptr;
19365
19366 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19367 EndLoc, Vars, Alignment);
19368}
19369
19370OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
19371 SourceLocation StartLoc,
19372 SourceLocation LParenLoc,
19373 SourceLocation EndLoc) {
19374 SmallVector<Expr *, 8> Vars;
19375 SmallVector<Expr *, 8> SrcExprs;
19376 SmallVector<Expr *, 8> DstExprs;
19377 SmallVector<Expr *, 8> AssignmentOps;
19378 for (Expr *RefExpr : VarList) {
19379 assert(RefExpr && "NULL expr in OpenMP copyin clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP copyin clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19379, __extension__ __PRETTY_FUNCTION__
))
;
19380 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19381 // It will be analyzed later.
19382 Vars.push_back(RefExpr);
19383 SrcExprs.push_back(nullptr);
19384 DstExprs.push_back(nullptr);
19385 AssignmentOps.push_back(nullptr);
19386 continue;
19387 }
19388
19389 SourceLocation ELoc = RefExpr->getExprLoc();
19390 // OpenMP [2.1, C/C++]
19391 // A list item is a variable name.
19392 // OpenMP [2.14.4.1, Restrictions, p.1]
19393 // A list item that appears in a copyin clause must be threadprivate.
19394 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
19395 if (!DE || !isa<VarDecl>(DE->getDecl())) {
19396 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
19397 << 0 << RefExpr->getSourceRange();
19398 continue;
19399 }
19400
19401 Decl *D = DE->getDecl();
19402 auto *VD = cast<VarDecl>(D);
19403
19404 QualType Type = VD->getType();
19405 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
19406 // It will be analyzed later.
19407 Vars.push_back(DE);
19408 SrcExprs.push_back(nullptr);
19409 DstExprs.push_back(nullptr);
19410 AssignmentOps.push_back(nullptr);
19411 continue;
19412 }
19413
19414 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
19415 // A list item that appears in a copyin clause must be threadprivate.
19416 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
19417 Diag(ELoc, diag::err_omp_required_access)
19418 << getOpenMPClauseName(OMPC_copyin)
19419 << getOpenMPDirectiveName(OMPD_threadprivate);
19420 continue;
19421 }
19422
19423 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19424 // A variable of class type (or array thereof) that appears in a
19425 // copyin clause requires an accessible, unambiguous copy assignment
19426 // operator for the class type.
19427 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
19428 VarDecl *SrcVD =
19429 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
19430 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19431 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
19432 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
19433 VarDecl *DstVD =
19434 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
19435 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19436 DeclRefExpr *PseudoDstExpr =
19437 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
19438 // For arrays generate assignment operation for single element and replace
19439 // it by the original array element in CodeGen.
19440 ExprResult AssignmentOp =
19441 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
19442 PseudoSrcExpr);
19443 if (AssignmentOp.isInvalid())
19444 continue;
19445 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
19446 /*DiscardedValue*/ false);
19447 if (AssignmentOp.isInvalid())
19448 continue;
19449
19450 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
19451 Vars.push_back(DE);
19452 SrcExprs.push_back(PseudoSrcExpr);
19453 DstExprs.push_back(PseudoDstExpr);
19454 AssignmentOps.push_back(AssignmentOp.get());
19455 }
19456
19457 if (Vars.empty())
19458 return nullptr;
19459
19460 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
19461 SrcExprs, DstExprs, AssignmentOps);
19462}
19463
19464OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
19465 SourceLocation StartLoc,
19466 SourceLocation LParenLoc,
19467 SourceLocation EndLoc) {
19468 SmallVector<Expr *, 8> Vars;
19469 SmallVector<Expr *, 8> SrcExprs;
19470 SmallVector<Expr *, 8> DstExprs;
19471 SmallVector<Expr *, 8> AssignmentOps;
19472 for (Expr *RefExpr : VarList) {
19473 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP linear clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19473, __extension__ __PRETTY_FUNCTION__
))
;
19474 SourceLocation ELoc;
19475 SourceRange ERange;
19476 Expr *SimpleRefExpr = RefExpr;
19477 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19478 if (Res.second) {
19479 // It will be analyzed later.
19480 Vars.push_back(RefExpr);
19481 SrcExprs.push_back(nullptr);
19482 DstExprs.push_back(nullptr);
19483 AssignmentOps.push_back(nullptr);
19484 }
19485 ValueDecl *D = Res.first;
19486 if (!D)
19487 continue;
19488
19489 QualType Type = D->getType();
19490 auto *VD = dyn_cast<VarDecl>(D);
19491
19492 // OpenMP [2.14.4.2, Restrictions, p.2]
19493 // A list item that appears in a copyprivate clause may not appear in a
19494 // private or firstprivate clause on the single construct.
19495 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
19496 DSAStackTy::DSAVarData DVar =
19497 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
19498 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
19499 DVar.RefExpr) {
19500 Diag(ELoc, diag::err_omp_wrong_dsa)
19501 << getOpenMPClauseName(DVar.CKind)
19502 << getOpenMPClauseName(OMPC_copyprivate);
19503 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
19504 continue;
19505 }
19506
19507 // OpenMP [2.11.4.2, Restrictions, p.1]
19508 // All list items that appear in a copyprivate clause must be either
19509 // threadprivate or private in the enclosing context.
19510 if (DVar.CKind == OMPC_unknown) {
19511 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
19512 if (DVar.CKind == OMPC_shared) {
19513 Diag(ELoc, diag::err_omp_required_access)
19514 << getOpenMPClauseName(OMPC_copyprivate)
19515 << "threadprivate or private in the enclosing context";
19516 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
19517 continue;
19518 }
19519 }
19520 }
19521
19522 // Variably modified types are not supported.
19523 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
19524 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
19525 << getOpenMPClauseName(OMPC_copyprivate) << Type
19526 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
19527 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19528 VarDecl::DeclarationOnly;
19529 Diag(D->getLocation(),
19530 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19531 << D;
19532 continue;
19533 }
19534
19535 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19536 // A variable of class type (or array thereof) that appears in a
19537 // copyin clause requires an accessible, unambiguous copy assignment
19538 // operator for the class type.
19539 Type = Context.getBaseElementType(Type.getNonReferenceType())
19540 .getUnqualifiedType();
19541 VarDecl *SrcVD =
19542 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
19543 D->hasAttrs() ? &D->getAttrs() : nullptr);
19544 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
19545 VarDecl *DstVD =
19546 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
19547 D->hasAttrs() ? &D->getAttrs() : nullptr);
19548 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
19549 ExprResult AssignmentOp = BuildBinOp(
19550 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
19551 if (AssignmentOp.isInvalid())
19552 continue;
19553 AssignmentOp =
19554 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
19555 if (AssignmentOp.isInvalid())
19556 continue;
19557
19558 // No need to mark vars as copyprivate, they are already threadprivate or
19559 // implicitly private.
19560 assert(VD || isOpenMPCapturedDecl(D))(static_cast <bool> (VD || isOpenMPCapturedDecl(D)) ? void
(0) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "clang/lib/Sema/SemaOpenMP.cpp"
, 19560, __extension__ __PRETTY_FUNCTION__))
;
19561 Vars.push_back(
19562 VD ? RefExpr->IgnoreParens()
19563 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
19564 SrcExprs.push_back(PseudoSrcExpr);
19565 DstExprs.push_back(PseudoDstExpr);
19566 AssignmentOps.push_back(AssignmentOp.get());
19567 }
19568
19569 if (Vars.empty())
19570 return nullptr;
19571
19572 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19573 Vars, SrcExprs, DstExprs, AssignmentOps);
19574}
19575
19576OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
19577 SourceLocation StartLoc,
19578 SourceLocation LParenLoc,
19579 SourceLocation EndLoc) {
19580 if (VarList.empty())
19581 return nullptr;
19582
19583 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
19584}
19585
19586/// Tries to find omp_depend_t. type.
19587static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
19588 bool Diagnose = true) {
19589 QualType OMPDependT = Stack->getOMPDependT();
19590 if (!OMPDependT.isNull())
19591 return true;
19592 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
19593 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
19594 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19595 if (Diagnose)
19596 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
19597 return false;
19598 }
19599 Stack->setOMPDependT(PT.get());
19600 return true;
19601}
19602
19603OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
19604 SourceLocation LParenLoc,
19605 SourceLocation EndLoc) {
19606 if (!Depobj)
19607 return nullptr;
19608
19609 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
19610
19611 // OpenMP 5.0, 2.17.10.1 depobj Construct
19612 // depobj is an lvalue expression of type omp_depend_t.
19613 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
19614 !Depobj->isInstantiationDependent() &&
19615 !Depobj->containsUnexpandedParameterPack() &&
19616 (OMPDependTFound &&
19617 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
19618 /*CompareUnqualified=*/true))) {
19619 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19620 << 0 << Depobj->getType() << Depobj->getSourceRange();
19621 }
19622
19623 if (!Depobj->isLValue()) {
19624 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19625 << 1 << Depobj->getSourceRange();
19626 }
19627
19628 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
19629}
19630
19631OMPClause *
19632Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
19633 SourceLocation DepLoc, SourceLocation ColonLoc,
19634 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19635 SourceLocation LParenLoc, SourceLocation EndLoc) {
19636 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
19637 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
19638 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
19639 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
19640 return nullptr;
19641 }
19642 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_taskwait &&
19643 DepKind == OMPC_DEPEND_mutexinoutset) {
19644 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
19645 return nullptr;
19646 }
19647 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
19648 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
19649 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
19650 DepKind == OMPC_DEPEND_sink ||
19651 ((LangOpts.OpenMP < 50 ||
19652 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
19653 DepKind == OMPC_DEPEND_depobj))) {
19654 SmallVector<unsigned, 3> Except;
19655 Except.push_back(OMPC_DEPEND_source);
19656 Except.push_back(OMPC_DEPEND_sink);
19657 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
19658 Except.push_back(OMPC_DEPEND_depobj);
19659 if (LangOpts.OpenMP < 51)
19660 Except.push_back(OMPC_DEPEND_inoutset);
19661 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
19662 ? "depend modifier(iterator) or "
19663 : "";
19664 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
19665 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
19666 /*Last=*/OMPC_DEPEND_unknown,
19667 Except)
19668 << getOpenMPClauseName(OMPC_depend);
19669 return nullptr;
19670 }
19671 if (DepModifier &&
19672 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
19673 Diag(DepModifier->getExprLoc(),
19674 diag::err_omp_depend_sink_source_with_modifier);
19675 return nullptr;
19676 }
19677 if (DepModifier &&
19678 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
19679 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
19680
19681 SmallVector<Expr *, 8> Vars;
19682 DSAStackTy::OperatorOffsetTy OpsOffs;
19683 llvm::APSInt DepCounter(/*BitWidth=*/32);
19684 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
19685 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
19686 if (const Expr *OrderedCountExpr =
19687 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
19688 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
19689 TotalDepCount.setIsUnsigned(/*Val=*/true);
19690 }
19691 }
19692 for (Expr *RefExpr : VarList) {
19693 assert(RefExpr && "NULL expr in OpenMP shared clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP shared clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19693, __extension__ __PRETTY_FUNCTION__
))
;
19694 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19695 // It will be analyzed later.
19696 Vars.push_back(RefExpr);
19697 continue;
19698 }
19699
19700 SourceLocation ELoc = RefExpr->getExprLoc();
19701 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
19702 if (DepKind == OMPC_DEPEND_sink) {
19703 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
19704 DepCounter >= TotalDepCount) {
19705 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
19706 continue;
19707 }
19708 ++DepCounter;
19709 // OpenMP [2.13.9, Summary]
19710 // depend(dependence-type : vec), where dependence-type is:
19711 // 'sink' and where vec is the iteration vector, which has the form:
19712 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
19713 // where n is the value specified by the ordered clause in the loop
19714 // directive, xi denotes the loop iteration variable of the i-th nested
19715 // loop associated with the loop directive, and di is a constant
19716 // non-negative integer.
19717 if (CurContext->isDependentContext()) {
19718 // It will be analyzed later.
19719 Vars.push_back(RefExpr);
19720 continue;
19721 }
19722 SimpleExpr = SimpleExpr->IgnoreImplicit();
19723 OverloadedOperatorKind OOK = OO_None;
19724 SourceLocation OOLoc;
19725 Expr *LHS = SimpleExpr;
19726 Expr *RHS = nullptr;
19727 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
19728 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
19729 OOLoc = BO->getOperatorLoc();
19730 LHS = BO->getLHS()->IgnoreParenImpCasts();
19731 RHS = BO->getRHS()->IgnoreParenImpCasts();
19732 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
19733 OOK = OCE->getOperator();
19734 OOLoc = OCE->getOperatorLoc();
19735 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19736 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
19737 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
19738 OOK = MCE->getMethodDecl()
19739 ->getNameInfo()
19740 .getName()
19741 .getCXXOverloadedOperator();
19742 OOLoc = MCE->getCallee()->getExprLoc();
19743 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
19744 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19745 }
19746 SourceLocation ELoc;
19747 SourceRange ERange;
19748 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
19749 if (Res.second) {
19750 // It will be analyzed later.
19751 Vars.push_back(RefExpr);
19752 }
19753 ValueDecl *D = Res.first;
19754 if (!D)
19755 continue;
19756
19757 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
19758 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
19759 continue;
19760 }
19761 if (RHS) {
19762 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
19763 RHS, OMPC_depend, /*StrictlyPositive=*/false);
19764 if (RHSRes.isInvalid())
19765 continue;
19766 }
19767 if (!CurContext->isDependentContext() &&
19768 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
19769 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
19770 const ValueDecl *VD =
19771 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
19772 if (VD)
19773 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
19774 << 1 << VD;
19775 else
19776 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
19777 continue;
19778 }
19779 OpsOffs.emplace_back(RHS, OOK);
19780 } else {
19781 bool OMPDependTFound = LangOpts.OpenMP >= 50;
19782 if (OMPDependTFound)
19783 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
19784 DepKind == OMPC_DEPEND_depobj);
19785 if (DepKind == OMPC_DEPEND_depobj) {
19786 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
19787 // List items used in depend clauses with the depobj dependence type
19788 // must be expressions of the omp_depend_t type.
19789 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
19790 !RefExpr->isInstantiationDependent() &&
19791 !RefExpr->containsUnexpandedParameterPack() &&
19792 (OMPDependTFound &&
19793 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
19794 RefExpr->getType()))) {
19795 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
19796 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
19797 continue;
19798 }
19799 if (!RefExpr->isLValue()) {
19800 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
19801 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
19802 continue;
19803 }
19804 } else {
19805 // OpenMP 5.0 [2.17.11, Restrictions]
19806 // List items used in depend clauses cannot be zero-length array
19807 // sections.
19808 QualType ExprTy = RefExpr->getType().getNonReferenceType();
19809 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
19810 if (OASE) {
19811 QualType BaseType =
19812 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19813 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19814 ExprTy = ATy->getElementType();
19815 else
19816 ExprTy = BaseType->getPointeeType();
19817 ExprTy = ExprTy.getNonReferenceType();
19818 const Expr *Length = OASE->getLength();
19819 Expr::EvalResult Result;
19820 if (Length && !Length->isValueDependent() &&
19821 Length->EvaluateAsInt(Result, Context) &&
19822 Result.Val.getInt().isZero()) {
19823 Diag(ELoc,
19824 diag::err_omp_depend_zero_length_array_section_not_allowed)
19825 << SimpleExpr->getSourceRange();
19826 continue;
19827 }
19828 }
19829
19830 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
19831 // List items used in depend clauses with the in, out, inout,
19832 // inoutset, or mutexinoutset dependence types cannot be
19833 // expressions of the omp_depend_t type.
19834 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
19835 !RefExpr->isInstantiationDependent() &&
19836 !RefExpr->containsUnexpandedParameterPack() &&
19837 (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
19838 (OMPDependTFound &&
19839 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
19840 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19841 << (LangOpts.OpenMP >= 50 ? 1 : 0)
19842 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19843 continue;
19844 }
19845
19846 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
19847 if (ASE && !ASE->getBase()->isTypeDependent() &&
19848 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
19849 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
19850 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19851 << (LangOpts.OpenMP >= 50 ? 1 : 0)
19852 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19853 continue;
19854 }
19855
19856 ExprResult Res;
19857 {
19858 Sema::TentativeAnalysisScope Trap(*this);
19859 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
19860 RefExpr->IgnoreParenImpCasts());
19861 }
19862 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19863 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19864 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19865 << (LangOpts.OpenMP >= 50 ? 1 : 0)
19866 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19867 continue;
19868 }
19869 }
19870 }
19871 Vars.push_back(RefExpr->IgnoreParenImpCasts());
19872 }
19873
19874 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
19875 TotalDepCount > VarList.size() &&
19876 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
19877 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
19878 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
19879 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
19880 }
19881 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
19882 Vars.empty())
19883 return nullptr;
19884
19885 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19886 DepModifier, DepKind, DepLoc, ColonLoc,
19887 Vars, TotalDepCount.getZExtValue());
19888 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
19889 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
19890 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
19891 return C;
19892}
19893
19894OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
19895 Expr *Device, SourceLocation StartLoc,
19896 SourceLocation LParenLoc,
19897 SourceLocation ModifierLoc,
19898 SourceLocation EndLoc) {
19899 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&(static_cast <bool> ((ModifierLoc.isInvalid() || LangOpts
.OpenMP >= 50) && "Unexpected device modifier in OpenMP < 50."
) ? void (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19900, __extension__ __PRETTY_FUNCTION__
))
19900 "Unexpected device modifier in OpenMP < 50.")(static_cast <bool> ((ModifierLoc.isInvalid() || LangOpts
.OpenMP >= 50) && "Unexpected device modifier in OpenMP < 50."
) ? void (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19900, __extension__ __PRETTY_FUNCTION__
))
;
19901
19902 bool ErrorFound = false;
19903 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
19904 std::string Values =
19905 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
19906 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
19907 << Values << getOpenMPClauseName(OMPC_device);
19908 ErrorFound = true;
19909 }
19910
19911 Expr *ValExpr = Device;
19912 Stmt *HelperValStmt = nullptr;
19913
19914 // OpenMP [2.9.1, Restrictions]
19915 // The device expression must evaluate to a non-negative integer value.
19916 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
19917 /*StrictlyPositive=*/false) ||
19918 ErrorFound;
19919 if (ErrorFound)
19920 return nullptr;
19921
19922 // OpenMP 5.0 [2.12.5, Restrictions]
19923 // In case of ancestor device-modifier, a requires directive with
19924 // the reverse_offload clause must be specified.
19925 if (Modifier == OMPC_DEVICE_ancestor) {
19926 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
19927 targetDiag(
19928 StartLoc,
19929 diag::err_omp_device_ancestor_without_requires_reverse_offload);
19930 ErrorFound = true;
19931 }
19932 }
19933
19934 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
19935 OpenMPDirectiveKind CaptureRegion =
19936 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
19937 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19938 ValExpr = MakeFullExpr(ValExpr).get();
19939 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19940 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19941 HelperValStmt = buildPreInits(Context, Captures);
19942 }
19943
19944 return new (Context)
19945 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
19946 LParenLoc, ModifierLoc, EndLoc);
19947}
19948
19949static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
19950 DSAStackTy *Stack, QualType QTy,
19951 bool FullCheck = true) {
19952 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
19953 return false;
19954 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
19955 !QTy.isTriviallyCopyableType(SemaRef.Context))
19956 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
19957 return true;
19958}
19959
19960/// Return true if it can be proven that the provided array expression
19961/// (array section or array subscript) does NOT specify the whole size of the
19962/// array whose base type is \a BaseQTy.
19963static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
19964 const Expr *E,
19965 QualType BaseQTy) {
19966 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
19967
19968 // If this is an array subscript, it refers to the whole size if the size of
19969 // the dimension is constant and equals 1. Also, an array section assumes the
19970 // format of an array subscript if no colon is used.
19971 if (isa<ArraySubscriptExpr>(E) ||
19972 (OASE && OASE->getColonLocFirst().isInvalid())) {
19973 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
19974 return ATy->getSize().getSExtValue() != 1;
19975 // Size can't be evaluated statically.
19976 return false;
19977 }
19978
19979 assert(OASE && "Expecting array section if not an array subscript.")(static_cast <bool> (OASE && "Expecting array section if not an array subscript."
) ? void (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 19979, __extension__ __PRETTY_FUNCTION__
))
;
19980 const Expr *LowerBound = OASE->getLowerBound();
19981 const Expr *Length = OASE->getLength();
19982
19983 // If there is a lower bound that does not evaluates to zero, we are not
19984 // covering the whole dimension.
19985 if (LowerBound) {
19986 Expr::EvalResult Result;
19987 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
19988 return false; // Can't get the integer value as a constant.
19989
19990 llvm::APSInt ConstLowerBound = Result.Val.getInt();
19991 if (ConstLowerBound.getSExtValue())
19992 return true;
19993 }
19994
19995 // If we don't have a length we covering the whole dimension.
19996 if (!Length)
19997 return false;
19998
19999 // If the base is a pointer, we don't have a way to get the size of the
20000 // pointee.
20001 if (BaseQTy->isPointerType())
20002 return false;
20003
20004 // We can only check if the length is the same as the size of the dimension
20005 // if we have a constant array.
20006 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
20007 if (!CATy)
20008 return false;
20009
20010 Expr::EvalResult Result;
20011 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20012 return false; // Can't get the integer value as a constant.
20013
20014 llvm::APSInt ConstLength = Result.Val.getInt();
20015 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
20016}
20017
20018// Return true if it can be proven that the provided array expression (array
20019// section or array subscript) does NOT specify a single element of the array
20020// whose base type is \a BaseQTy.
20021static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
20022 const Expr *E,
20023 QualType BaseQTy) {
20024 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20025
20026 // An array subscript always refer to a single element. Also, an array section
20027 // assumes the format of an array subscript if no colon is used.
20028 if (isa<ArraySubscriptExpr>(E) ||
20029 (OASE && OASE->getColonLocFirst().isInvalid()))
20030 return false;
20031
20032 assert(OASE && "Expecting array section if not an array subscript.")(static_cast <bool> (OASE && "Expecting array section if not an array subscript."
) ? void (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20032, __extension__ __PRETTY_FUNCTION__
))
;
20033 const Expr *Length = OASE->getLength();
20034
20035 // If we don't have a length we have to check if the array has unitary size
20036 // for this dimension. Also, we should always expect a length if the base type
20037 // is pointer.
20038 if (!Length) {
20039 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20040 return ATy->getSize().getSExtValue() != 1;
20041 // We cannot assume anything.
20042 return false;
20043 }
20044
20045 // Check if the length evaluates to 1.
20046 Expr::EvalResult Result;
20047 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20048 return false; // Can't get the integer value as a constant.
20049
20050 llvm::APSInt ConstLength = Result.Val.getInt();
20051 return ConstLength.getSExtValue() != 1;
20052}
20053
20054// The base of elements of list in a map clause have to be either:
20055// - a reference to variable or field.
20056// - a member expression.
20057// - an array expression.
20058//
20059// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
20060// reference to 'r'.
20061//
20062// If we have:
20063//
20064// struct SS {
20065// Bla S;
20066// foo() {
20067// #pragma omp target map (S.Arr[:12]);
20068// }
20069// }
20070//
20071// We want to retrieve the member expression 'this->S';
20072
20073// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
20074// If a list item is an array section, it must specify contiguous storage.
20075//
20076// For this restriction it is sufficient that we make sure only references
20077// to variables or fields and array expressions, and that no array sections
20078// exist except in the rightmost expression (unless they cover the whole
20079// dimension of the array). E.g. these would be invalid:
20080//
20081// r.ArrS[3:5].Arr[6:7]
20082//
20083// r.ArrS[3:5].x
20084//
20085// but these would be valid:
20086// r.ArrS[3].Arr[6:7]
20087//
20088// r.ArrS[3].x
20089namespace {
20090class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
20091 Sema &SemaRef;
20092 OpenMPClauseKind CKind = OMPC_unknown;
20093 OpenMPDirectiveKind DKind = OMPD_unknown;
20094 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
20095 bool IsNonContiguous = false;
20096 bool NoDiagnose = false;
20097 const Expr *RelevantExpr = nullptr;
20098 bool AllowUnitySizeArraySection = true;
20099 bool AllowWholeSizeArraySection = true;
20100 bool AllowAnotherPtr = true;
20101 SourceLocation ELoc;
20102 SourceRange ERange;
20103
20104 void emitErrorMsg() {
20105 // If nothing else worked, this is not a valid map clause expression.
20106 if (SemaRef.getLangOpts().OpenMP < 50) {
20107 SemaRef.Diag(ELoc,
20108 diag::err_omp_expected_named_var_member_or_array_expression)
20109 << ERange;
20110 } else {
20111 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20112 << getOpenMPClauseName(CKind) << ERange;
20113 }
20114 }
20115
20116public:
20117 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
20118 if (!isa<VarDecl>(DRE->getDecl())) {
20119 emitErrorMsg();
20120 return false;
20121 }
20122 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast <bool> (!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? void (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20122, __extension__ __PRETTY_FUNCTION__
))
;
20123 RelevantExpr = DRE;
20124 // Record the component.
20125 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
20126 return true;
20127 }
20128
20129 bool VisitMemberExpr(MemberExpr *ME) {
20130 Expr *E = ME;
20131 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
20132
20133 if (isa<CXXThisExpr>(BaseE)) {
20134 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast <bool> (!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? void (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20134, __extension__ __PRETTY_FUNCTION__
))
;
20135 // We found a base expression: this->Val.
20136 RelevantExpr = ME;
20137 } else {
20138 E = BaseE;
20139 }
20140
20141 if (!isa<FieldDecl>(ME->getMemberDecl())) {
20142 if (!NoDiagnose) {
20143 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
20144 << ME->getSourceRange();
20145 return false;
20146 }
20147 if (RelevantExpr)
20148 return false;
20149 return Visit(E);
20150 }
20151
20152 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
20153
20154 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
20155 // A bit-field cannot appear in a map clause.
20156 //
20157 if (FD->isBitField()) {
20158 if (!NoDiagnose) {
20159 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
20160 << ME->getSourceRange() << getOpenMPClauseName(CKind);
20161 return false;
20162 }
20163 if (RelevantExpr)
20164 return false;
20165 return Visit(E);
20166 }
20167
20168 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20169 // If the type of a list item is a reference to a type T then the type
20170 // will be considered to be T for all purposes of this clause.
20171 QualType CurType = BaseE->getType().getNonReferenceType();
20172
20173 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
20174 // A list item cannot be a variable that is a member of a structure with
20175 // a union type.
20176 //
20177 if (CurType->isUnionType()) {
20178 if (!NoDiagnose) {
20179 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
20180 << ME->getSourceRange();
20181 return false;
20182 }
20183 return RelevantExpr || Visit(E);
20184 }
20185
20186 // If we got a member expression, we should not expect any array section
20187 // before that:
20188 //
20189 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
20190 // If a list item is an element of a structure, only the rightmost symbol
20191 // of the variable reference can be an array section.
20192 //
20193 AllowUnitySizeArraySection = false;
20194 AllowWholeSizeArraySection = false;
20195
20196 // Record the component.
20197 Components.emplace_back(ME, FD, IsNonContiguous);
20198 return RelevantExpr || Visit(E);
20199 }
20200
20201 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
20202 Expr *E = AE->getBase()->IgnoreParenImpCasts();
20203
20204 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
20205 if (!NoDiagnose) {
20206 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20207 << 0 << AE->getSourceRange();
20208 return false;
20209 }
20210 return RelevantExpr || Visit(E);
20211 }
20212
20213 // If we got an array subscript that express the whole dimension we
20214 // can have any array expressions before. If it only expressing part of
20215 // the dimension, we can only have unitary-size array expressions.
20216 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
20217 AllowWholeSizeArraySection = false;
20218
20219 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
20220 Expr::EvalResult Result;
20221 if (!AE->getIdx()->isValueDependent() &&
20222 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
20223 !Result.Val.getInt().isZero()) {
20224 SemaRef.Diag(AE->getIdx()->getExprLoc(),
20225 diag::err_omp_invalid_map_this_expr);
20226 SemaRef.Diag(AE->getIdx()->getExprLoc(),
20227 diag::note_omp_invalid_subscript_on_this_ptr_map);
20228 }
20229 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast <bool> (!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? void (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20229, __extension__ __PRETTY_FUNCTION__
))
;
20230 RelevantExpr = TE;
20231 }
20232
20233 // Record the component - we don't have any declaration associated.
20234 Components.emplace_back(AE, nullptr, IsNonContiguous);
20235
20236 return RelevantExpr || Visit(E);
20237 }
20238
20239 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
20240 // After OMP 5.0 Array section in reduction clause will be implicitly
20241 // mapped
20242 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&(static_cast <bool> (!(SemaRef.getLangOpts().OpenMP <
50 && NoDiagnose) && "Array sections cannot be implicitly mapped."
) ? void (0) : __assert_fail ("!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && \"Array sections cannot be implicitly mapped.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20243, __extension__ __PRETTY_FUNCTION__
))
20243 "Array sections cannot be implicitly mapped.")(static_cast <bool> (!(SemaRef.getLangOpts().OpenMP <
50 && NoDiagnose) && "Array sections cannot be implicitly mapped."
) ? void (0) : __assert_fail ("!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && \"Array sections cannot be implicitly mapped.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20243, __extension__ __PRETTY_FUNCTION__
))
;
20244 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20245 QualType CurType =
20246 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
20247
20248 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20249 // If the type of a list item is a reference to a type T then the type
20250 // will be considered to be T for all purposes of this clause.
20251 if (CurType->isReferenceType())
20252 CurType = CurType->getPointeeType();
20253
20254 bool IsPointer = CurType->isAnyPointerType();
20255
20256 if (!IsPointer && !CurType->isArrayType()) {
20257 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20258 << 0 << OASE->getSourceRange();
20259 return false;
20260 }
20261
20262 bool NotWhole =
20263 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
20264 bool NotUnity =
20265 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
20266
20267 if (AllowWholeSizeArraySection) {
20268 // Any array section is currently allowed. Allowing a whole size array
20269 // section implies allowing a unity array section as well.
20270 //
20271 // If this array section refers to the whole dimension we can still
20272 // accept other array sections before this one, except if the base is a
20273 // pointer. Otherwise, only unitary sections are accepted.
20274 if (NotWhole || IsPointer)
20275 AllowWholeSizeArraySection = false;
20276 } else if (DKind == OMPD_target_update &&
20277 SemaRef.getLangOpts().OpenMP >= 50) {
20278 if (IsPointer && !AllowAnotherPtr)
20279 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
20280 << /*array of unknown bound */ 1;
20281 else
20282 IsNonContiguous = true;
20283 } else if (AllowUnitySizeArraySection && NotUnity) {
20284 // A unity or whole array section is not allowed and that is not
20285 // compatible with the properties of the current array section.
20286 if (NoDiagnose)
20287 return false;
20288 SemaRef.Diag(ELoc,
20289 diag::err_array_section_does_not_specify_contiguous_storage)
20290 << OASE->getSourceRange();
20291 return false;
20292 }
20293
20294 if (IsPointer)
20295 AllowAnotherPtr = false;
20296
20297 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
20298 Expr::EvalResult ResultR;
20299 Expr::EvalResult ResultL;
20300 if (!OASE->getLength()->isValueDependent() &&
20301 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
20302 !ResultR.Val.getInt().isOne()) {
20303 SemaRef.Diag(OASE->getLength()->getExprLoc(),
20304 diag::err_omp_invalid_map_this_expr);
20305 SemaRef.Diag(OASE->getLength()->getExprLoc(),
20306 diag::note_omp_invalid_length_on_this_ptr_mapping);
20307 }
20308 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
20309 OASE->getLowerBound()->EvaluateAsInt(ResultL,
20310 SemaRef.getASTContext()) &&
20311 !ResultL.Val.getInt().isZero()) {
20312 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20313 diag::err_omp_invalid_map_this_expr);
20314 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20315 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
20316 }
20317 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast <bool> (!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? void (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20317, __extension__ __PRETTY_FUNCTION__
))
;
20318 RelevantExpr = TE;
20319 }
20320
20321 // Record the component - we don't have any declaration associated.
20322 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
20323 return RelevantExpr || Visit(E);
20324 }
20325 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
20326 Expr *Base = E->getBase();
20327
20328 // Record the component - we don't have any declaration associated.
20329 Components.emplace_back(E, nullptr, IsNonContiguous);
20330
20331 return Visit(Base->IgnoreParenImpCasts());
20332 }
20333
20334 bool VisitUnaryOperator(UnaryOperator *UO) {
20335 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
20336 UO->getOpcode() != UO_Deref) {
20337 emitErrorMsg();
20338 return false;
20339 }
20340 if (!RelevantExpr) {
20341 // Record the component if haven't found base decl.
20342 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
20343 }
20344 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
20345 }
20346 bool VisitBinaryOperator(BinaryOperator *BO) {
20347 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
20348 emitErrorMsg();
20349 return false;
20350 }
20351
20352 // Pointer arithmetic is the only thing we expect to happen here so after we
20353 // make sure the binary operator is a pointer type, the we only thing need
20354 // to to is to visit the subtree that has the same type as root (so that we
20355 // know the other subtree is just an offset)
20356 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
20357 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
20358 Components.emplace_back(BO, nullptr, false);
20359 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||(static_cast <bool> ((LE->getType().getTypePtr() == BO
->getType().getTypePtr() || RE->getType().getTypePtr() ==
BO->getType().getTypePtr()) && "Either LHS or RHS have base decl inside"
) ? void (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20361, __extension__ __PRETTY_FUNCTION__
))
20360 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&(static_cast <bool> ((LE->getType().getTypePtr() == BO
->getType().getTypePtr() || RE->getType().getTypePtr() ==
BO->getType().getTypePtr()) && "Either LHS or RHS have base decl inside"
) ? void (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20361, __extension__ __PRETTY_FUNCTION__
))
20361 "Either LHS or RHS have base decl inside")(static_cast <bool> ((LE->getType().getTypePtr() == BO
->getType().getTypePtr() || RE->getType().getTypePtr() ==
BO->getType().getTypePtr()) && "Either LHS or RHS have base decl inside"
) ? void (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20361, __extension__ __PRETTY_FUNCTION__
))
;
20362 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
20363 return RelevantExpr || Visit(LE);
20364 return RelevantExpr || Visit(RE);
20365 }
20366 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
20367 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast <bool> (!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? void (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20367, __extension__ __PRETTY_FUNCTION__
))
;
20368 RelevantExpr = CTE;
20369 Components.emplace_back(CTE, nullptr, IsNonContiguous);
20370 return true;
20371 }
20372 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
20373 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")(static_cast <bool> (!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? void (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20373, __extension__ __PRETTY_FUNCTION__
))
;
20374 Components.emplace_back(COCE, nullptr, IsNonContiguous);
20375 return true;
20376 }
20377 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
20378 Expr *Source = E->getSourceExpr();
20379 if (!Source) {
20380 emitErrorMsg();
20381 return false;
20382 }
20383 return Visit(Source);
20384 }
20385 bool VisitStmt(Stmt *) {
20386 emitErrorMsg();
20387 return false;
20388 }
20389 const Expr *getFoundBase() const { return RelevantExpr; }
20390 explicit MapBaseChecker(
20391 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
20392 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
20393 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
20394 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
20395 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
20396};
20397} // namespace
20398
20399/// Return the expression of the base of the mappable expression or null if it
20400/// cannot be determined and do all the necessary checks to see if the
20401/// expression is valid as a standalone mappable expression. In the process,
20402/// record all the components of the expression.
20403static const Expr *checkMapClauseExpressionBase(
20404 Sema &SemaRef, Expr *E,
20405 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
20406 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
20407 SourceLocation ELoc = E->getExprLoc();
20408 SourceRange ERange = E->getSourceRange();
20409 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
20410 ERange);
20411 if (Checker.Visit(E->IgnoreParens())) {
20412 // Check if the highest dimension array section has length specified
20413 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
20414 (CKind == OMPC_to || CKind == OMPC_from)) {
20415 auto CI = CurComponents.rbegin();
20416 auto CE = CurComponents.rend();
20417 for (; CI != CE; ++CI) {
20418 const auto *OASE =
20419 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
20420 if (!OASE)
20421 continue;
20422 if (OASE && OASE->getLength())
20423 break;
20424 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
20425 << ERange;
20426 }
20427 }
20428 return Checker.getFoundBase();
20429 }
20430 return nullptr;
20431}
20432
20433// Return true if expression E associated with value VD has conflicts with other
20434// map information.
20435static bool checkMapConflicts(
20436 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
20437 bool CurrentRegionOnly,
20438 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
20439 OpenMPClauseKind CKind) {
20440 assert(VD && E)(static_cast <bool> (VD && E) ? void (0) : __assert_fail
("VD && E", "clang/lib/Sema/SemaOpenMP.cpp", 20440, __extension__
__PRETTY_FUNCTION__))
;
20441 SourceLocation ELoc = E->getExprLoc();
20442 SourceRange ERange = E->getSourceRange();
20443
20444 // In order to easily check the conflicts we need to match each component of
20445 // the expression under test with the components of the expressions that are
20446 // already in the stack.
20447
20448 assert(!CurComponents.empty() && "Map clause expression with no components!")(static_cast <bool> (!CurComponents.empty() && "Map clause expression with no components!"
) ? void (0) : __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20448, __extension__ __PRETTY_FUNCTION__
))
;
20449 assert(CurComponents.back().getAssociatedDeclaration() == VD &&(static_cast <bool> (CurComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20450, __extension__ __PRETTY_FUNCTION__
))
20450 "Map clause expression with unexpected base!")(static_cast <bool> (CurComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20450, __extension__ __PRETTY_FUNCTION__
))
;
20451
20452 // Variables to help detecting enclosing problems in data environment nests.
20453 bool IsEnclosedByDataEnvironmentExpr = false;
20454 const Expr *EnclosingExpr = nullptr;
20455
20456 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
20457 VD, CurrentRegionOnly,
20458 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
20459 ERange, CKind, &EnclosingExpr,
20460 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
20461 StackComponents,
20462 OpenMPClauseKind Kind) {
20463 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
20464 return false;
20465 assert(!StackComponents.empty() &&(static_cast <bool> (!StackComponents.empty() &&
"Map clause expression with no components!") ? void (0) : __assert_fail
("!StackComponents.empty() && \"Map clause expression with no components!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20466, __extension__ __PRETTY_FUNCTION__
))
20466 "Map clause expression with no components!")(static_cast <bool> (!StackComponents.empty() &&
"Map clause expression with no components!") ? void (0) : __assert_fail
("!StackComponents.empty() && \"Map clause expression with no components!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20466, __extension__ __PRETTY_FUNCTION__
))
;
20467 assert(StackComponents.back().getAssociatedDeclaration() == VD &&(static_cast <bool> (StackComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20468, __extension__ __PRETTY_FUNCTION__
))
20468 "Map clause expression with unexpected base!")(static_cast <bool> (StackComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20468, __extension__ __PRETTY_FUNCTION__
))
;
20469 (void)VD;
20470
20471 // The whole expression in the stack.
20472 const Expr *RE = StackComponents.front().getAssociatedExpression();
20473
20474 // Expressions must start from the same base. Here we detect at which
20475 // point both expressions diverge from each other and see if we can
20476 // detect if the memory referred to both expressions is contiguous and
20477 // do not overlap.
20478 auto CI = CurComponents.rbegin();
20479 auto CE = CurComponents.rend();
20480 auto SI = StackComponents.rbegin();
20481 auto SE = StackComponents.rend();
20482 for (; CI != CE && SI != SE; ++CI, ++SI) {
20483
20484 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
20485 // At most one list item can be an array item derived from a given
20486 // variable in map clauses of the same construct.
20487 if (CurrentRegionOnly &&
20488 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
20489 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
20490 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
20491 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
20492 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
20493 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
20494 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
20495 diag::err_omp_multiple_array_items_in_map_clause)
20496 << CI->getAssociatedExpression()->getSourceRange();
20497 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
20498 diag::note_used_here)
20499 << SI->getAssociatedExpression()->getSourceRange();
20500 return true;
20501 }
20502
20503 // Do both expressions have the same kind?
20504 if (CI->getAssociatedExpression()->getStmtClass() !=
20505 SI->getAssociatedExpression()->getStmtClass())
20506 break;
20507
20508 // Are we dealing with different variables/fields?
20509 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
20510 break;
20511 }
20512 // Check if the extra components of the expressions in the enclosing
20513 // data environment are redundant for the current base declaration.
20514 // If they are, the maps completely overlap, which is legal.
20515 for (; SI != SE; ++SI) {
20516 QualType Type;
20517 if (const auto *ASE =
20518 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
20519 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
20520 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
20521 SI->getAssociatedExpression())) {
20522 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20523 Type =
20524 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
20525 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
20526 SI->getAssociatedExpression())) {
20527 Type = OASE->getBase()->getType()->getPointeeType();
20528 }
20529 if (Type.isNull() || Type->isAnyPointerType() ||
20530 checkArrayExpressionDoesNotReferToWholeSize(
20531 SemaRef, SI->getAssociatedExpression(), Type))
20532 break;
20533 }
20534
20535 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20536 // List items of map clauses in the same construct must not share
20537 // original storage.
20538 //
20539 // If the expressions are exactly the same or one is a subset of the
20540 // other, it means they are sharing storage.
20541 if (CI == CE && SI == SE) {
20542 if (CurrentRegionOnly) {
20543 if (CKind == OMPC_map) {
20544 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20545 } else {
20546 assert(CKind == OMPC_to || CKind == OMPC_from)(static_cast <bool> (CKind == OMPC_to || CKind == OMPC_from
) ? void (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "clang/lib/Sema/SemaOpenMP.cpp", 20546, __extension__ __PRETTY_FUNCTION__
))
;
20547 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20548 << ERange;
20549 }
20550 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20551 << RE->getSourceRange();
20552 return true;
20553 }
20554 // If we find the same expression in the enclosing data environment,
20555 // that is legal.
20556 IsEnclosedByDataEnvironmentExpr = true;
20557 return false;
20558 }
20559
20560 QualType DerivedType =
20561 std::prev(CI)->getAssociatedDeclaration()->getType();
20562 SourceLocation DerivedLoc =
20563 std::prev(CI)->getAssociatedExpression()->getExprLoc();
20564
20565 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20566 // If the type of a list item is a reference to a type T then the type
20567 // will be considered to be T for all purposes of this clause.
20568 DerivedType = DerivedType.getNonReferenceType();
20569
20570 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
20571 // A variable for which the type is pointer and an array section
20572 // derived from that variable must not appear as list items of map
20573 // clauses of the same construct.
20574 //
20575 // Also, cover one of the cases in:
20576 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20577 // If any part of the original storage of a list item has corresponding
20578 // storage in the device data environment, all of the original storage
20579 // must have corresponding storage in the device data environment.
20580 //
20581 if (DerivedType->isAnyPointerType()) {
20582 if (CI == CE || SI == SE) {
20583 SemaRef.Diag(
20584 DerivedLoc,
20585 diag::err_omp_pointer_mapped_along_with_derived_section)
20586 << DerivedLoc;
20587 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20588 << RE->getSourceRange();
20589 return true;
20590 }
20591 if (CI->getAssociatedExpression()->getStmtClass() !=
20592 SI->getAssociatedExpression()->getStmtClass() ||
20593 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
20594 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
20595 assert(CI != CE && SI != SE)(static_cast <bool> (CI != CE && SI != SE) ? void
(0) : __assert_fail ("CI != CE && SI != SE", "clang/lib/Sema/SemaOpenMP.cpp"
, 20595, __extension__ __PRETTY_FUNCTION__))
;
20596 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
20597 << DerivedLoc;
20598 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20599 << RE->getSourceRange();
20600 return true;
20601 }
20602 }
20603
20604 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20605 // List items of map clauses in the same construct must not share
20606 // original storage.
20607 //
20608 // An expression is a subset of the other.
20609 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
20610 if (CKind == OMPC_map) {
20611 if (CI != CE || SI != SE) {
20612 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
20613 // a pointer.
20614 auto Begin =
20615 CI != CE ? CurComponents.begin() : StackComponents.begin();
20616 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
20617 auto It = Begin;
20618 while (It != End && !It->getAssociatedDeclaration())
20619 std::advance(It, 1);
20620 assert(It != End &&(static_cast <bool> (It != End && "Expected at least one component with the declaration."
) ? void (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20621, __extension__ __PRETTY_FUNCTION__
))
20621 "Expected at least one component with the declaration.")(static_cast <bool> (It != End && "Expected at least one component with the declaration."
) ? void (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20621, __extension__ __PRETTY_FUNCTION__
))
;
20622 if (It != Begin && It->getAssociatedDeclaration()
20623 ->getType()
20624 .getCanonicalType()
20625 ->isAnyPointerType()) {
20626 IsEnclosedByDataEnvironmentExpr = false;
20627 EnclosingExpr = nullptr;
20628 return false;
20629 }
20630 }
20631 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20632 } else {
20633 assert(CKind == OMPC_to || CKind == OMPC_from)(static_cast <bool> (CKind == OMPC_to || CKind == OMPC_from
) ? void (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "clang/lib/Sema/SemaOpenMP.cpp", 20633, __extension__ __PRETTY_FUNCTION__
))
;
20634 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20635 << ERange;
20636 }
20637 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20638 << RE->getSourceRange();
20639 return true;
20640 }
20641
20642 // The current expression uses the same base as other expression in the
20643 // data environment but does not contain it completely.
20644 if (!CurrentRegionOnly && SI != SE)
20645 EnclosingExpr = RE;
20646
20647 // The current expression is a subset of the expression in the data
20648 // environment.
20649 IsEnclosedByDataEnvironmentExpr |=
20650 (!CurrentRegionOnly && CI != CE && SI == SE);
20651
20652 return false;
20653 });
20654
20655 if (CurrentRegionOnly)
20656 return FoundError;
20657
20658 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20659 // If any part of the original storage of a list item has corresponding
20660 // storage in the device data environment, all of the original storage must
20661 // have corresponding storage in the device data environment.
20662 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
20663 // If a list item is an element of a structure, and a different element of
20664 // the structure has a corresponding list item in the device data environment
20665 // prior to a task encountering the construct associated with the map clause,
20666 // then the list item must also have a corresponding list item in the device
20667 // data environment prior to the task encountering the construct.
20668 //
20669 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
20670 SemaRef.Diag(ELoc,
20671 diag::err_omp_original_storage_is_shared_and_does_not_contain)
20672 << ERange;
20673 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
20674 << EnclosingExpr->getSourceRange();
20675 return true;
20676 }
20677
20678 return FoundError;
20679}
20680
20681// Look up the user-defined mapper given the mapper name and mapped type, and
20682// build a reference to it.
20683static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
20684 CXXScopeSpec &MapperIdScopeSpec,
20685 const DeclarationNameInfo &MapperId,
20686 QualType Type,
20687 Expr *UnresolvedMapper) {
20688 if (MapperIdScopeSpec.isInvalid())
20689 return ExprError();
20690 // Get the actual type for the array type.
20691 if (Type->isArrayType()) {
20692 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")(static_cast <bool> (Type->getAsArrayTypeUnsafe() &&
"Expect to get a valid array type") ? void (0) : __assert_fail
("Type->getAsArrayTypeUnsafe() && \"Expect to get a valid array type\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20692, __extension__ __PRETTY_FUNCTION__
))
;
20693 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
20694 }
20695 // Find all user-defined mappers with the given MapperId.
20696 SmallVector<UnresolvedSet<8>, 4> Lookups;
20697 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
20698 Lookup.suppressDiagnostics();
20699 if (S) {
20700 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
20701 NamedDecl *D = Lookup.getRepresentativeDecl();
20702 while (S && !S->isDeclScope(D))
20703 S = S->getParent();
20704 if (S)
20705 S = S->getParent();
20706 Lookups.emplace_back();
20707 Lookups.back().append(Lookup.begin(), Lookup.end());
20708 Lookup.clear();
20709 }
20710 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
20711 // Extract the user-defined mappers with the given MapperId.
20712 Lookups.push_back(UnresolvedSet<8>());
20713 for (NamedDecl *D : ULE->decls()) {
20714 auto *DMD = cast<OMPDeclareMapperDecl>(D);
20715 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")(static_cast <bool> (DMD && "Expect valid OMPDeclareMapperDecl during instantiation."
) ? void (0) : __assert_fail ("DMD && \"Expect valid OMPDeclareMapperDecl during instantiation.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20715, __extension__ __PRETTY_FUNCTION__
))
;
20716 Lookups.back().addDecl(DMD);
20717 }
20718 }
20719 // Defer the lookup for dependent types. The results will be passed through
20720 // UnresolvedMapper on instantiation.
20721 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
20722 Type->isInstantiationDependentType() ||
20723 Type->containsUnexpandedParameterPack() ||
20724 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
20725 return !D->isInvalidDecl() &&
20726 (D->getType()->isDependentType() ||
20727 D->getType()->isInstantiationDependentType() ||
20728 D->getType()->containsUnexpandedParameterPack());
20729 })) {
20730 UnresolvedSet<8> URS;
20731 for (const UnresolvedSet<8> &Set : Lookups) {
20732 if (Set.empty())
20733 continue;
20734 URS.append(Set.begin(), Set.end());
20735 }
20736 return UnresolvedLookupExpr::Create(
20737 SemaRef.Context, /*NamingClass=*/nullptr,
20738 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
20739 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
20740 }
20741 SourceLocation Loc = MapperId.getLoc();
20742 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
20743 // The type must be of struct, union or class type in C and C++
20744 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
20745 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
20746 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
20747 return ExprError();
20748 }
20749 // Perform argument dependent lookup.
20750 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
20751 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
20752 // Return the first user-defined mapper with the desired type.
20753 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
20754 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
20755 if (!D->isInvalidDecl() &&
20756 SemaRef.Context.hasSameType(D->getType(), Type))
20757 return D;
20758 return nullptr;
20759 }))
20760 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
20761 // Find the first user-defined mapper with a type derived from the desired
20762 // type.
20763 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
20764 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
20765 if (!D->isInvalidDecl() &&
20766 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
20767 !Type.isMoreQualifiedThan(D->getType()))
20768 return D;
20769 return nullptr;
20770 })) {
20771 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
20772 /*DetectVirtual=*/false);
20773 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
20774 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
20775 VD->getType().getUnqualifiedType()))) {
20776 if (SemaRef.CheckBaseClassAccess(
20777 Loc, VD->getType(), Type, Paths.front(),
20778 /*DiagID=*/0) != Sema::AR_inaccessible) {
20779 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
20780 }
20781 }
20782 }
20783 }
20784 // Report error if a mapper is specified, but cannot be found.
20785 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
20786 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
20787 << Type << MapperId.getName();
20788 return ExprError();
20789 }
20790 return ExprEmpty();
20791}
20792
20793namespace {
20794// Utility struct that gathers all the related lists associated with a mappable
20795// expression.
20796struct MappableVarListInfo {
20797 // The list of expressions.
20798 ArrayRef<Expr *> VarList;
20799 // The list of processed expressions.
20800 SmallVector<Expr *, 16> ProcessedVarList;
20801 // The mappble components for each expression.
20802 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
20803 // The base declaration of the variable.
20804 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
20805 // The reference to the user-defined mapper associated with every expression.
20806 SmallVector<Expr *, 16> UDMapperList;
20807
20808 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
20809 // We have a list of components and base declarations for each entry in the
20810 // variable list.
20811 VarComponents.reserve(VarList.size());
20812 VarBaseDeclarations.reserve(VarList.size());
20813 }
20814};
20815} // namespace
20816
20817// Check the validity of the provided variable list for the provided clause kind
20818// \a CKind. In the check process the valid expressions, mappable expression
20819// components, variables, and user-defined mappers are extracted and used to
20820// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
20821// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
20822// and \a MapperId are expected to be valid if the clause kind is 'map'.
20823static void checkMappableExpressionList(
20824 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
20825 MappableVarListInfo &MVLI, SourceLocation StartLoc,
20826 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
20827 ArrayRef<Expr *> UnresolvedMappers,
20828 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
20829 ArrayRef<OpenMPMapModifierKind> Modifiers = None,
20830 bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
20831 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
20832 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(static_cast <bool> ((CKind == OMPC_map || CKind == OMPC_to
|| CKind == OMPC_from) && "Unexpected clause kind with mappable expressions!"
) ? void (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20833, __extension__ __PRETTY_FUNCTION__
))
20833 "Unexpected clause kind with mappable expressions!")(static_cast <bool> ((CKind == OMPC_map || CKind == OMPC_to
|| CKind == OMPC_from) && "Unexpected clause kind with mappable expressions!"
) ? void (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20833, __extension__ __PRETTY_FUNCTION__
))
;
20834
20835 // If the identifier of user-defined mapper is not specified, it is "default".
20836 // We do not change the actual name in this clause to distinguish whether a
20837 // mapper is specified explicitly, i.e., it is not explicitly specified when
20838 // MapperId.getName() is empty.
20839 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
20840 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
20841 MapperId.setName(DeclNames.getIdentifier(
20842 &SemaRef.getASTContext().Idents.get("default")));
20843 MapperId.setLoc(StartLoc);
20844 }
20845
20846 // Iterators to find the current unresolved mapper expression.
20847 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
20848 bool UpdateUMIt = false;
20849 Expr *UnresolvedMapper = nullptr;
20850
20851 bool HasHoldModifier =
20852 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
20853
20854 // Keep track of the mappable components and base declarations in this clause.
20855 // Each entry in the list is going to have a list of components associated. We
20856 // record each set of the components so that we can build the clause later on.
20857 // In the end we should have the same amount of declarations and component
20858 // lists.
20859
20860 for (Expr *RE : MVLI.VarList) {
20861 assert(RE && "Null expr in omp to/from/map clause")(static_cast <bool> (RE && "Null expr in omp to/from/map clause"
) ? void (0) : __assert_fail ("RE && \"Null expr in omp to/from/map clause\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20861, __extension__ __PRETTY_FUNCTION__
))
;
20862 SourceLocation ELoc = RE->getExprLoc();
20863
20864 // Find the current unresolved mapper expression.
20865 if (UpdateUMIt && UMIt != UMEnd) {
20866 UMIt++;
20867 assert((static_cast <bool> (UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? void (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20869, __extension__ __PRETTY_FUNCTION__
))
20868 UMIt != UMEnd &&(static_cast <bool> (UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? void (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20869, __extension__ __PRETTY_FUNCTION__
))
20869 "Expect the size of UnresolvedMappers to match with that of VarList")(static_cast <bool> (UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? void (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20869, __extension__ __PRETTY_FUNCTION__
))
;
20870 }
20871 UpdateUMIt = true;
20872 if (UMIt != UMEnd)
20873 UnresolvedMapper = *UMIt;
20874
20875 const Expr *VE = RE->IgnoreParenLValueCasts();
20876
20877 if (VE->isValueDependent() || VE->isTypeDependent() ||
20878 VE->isInstantiationDependent() ||
20879 VE->containsUnexpandedParameterPack()) {
20880 // Try to find the associated user-defined mapper.
20881 ExprResult ER = buildUserDefinedMapperRef(
20882 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
20883 VE->getType().getCanonicalType(), UnresolvedMapper);
20884 if (ER.isInvalid())
20885 continue;
20886 MVLI.UDMapperList.push_back(ER.get());
20887 // We can only analyze this information once the missing information is
20888 // resolved.
20889 MVLI.ProcessedVarList.push_back(RE);
20890 continue;
20891 }
20892
20893 Expr *SimpleExpr = RE->IgnoreParenCasts();
20894
20895 if (!RE->isLValue()) {
20896 if (SemaRef.getLangOpts().OpenMP < 50) {
20897 SemaRef.Diag(
20898 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
20899 << RE->getSourceRange();
20900 } else {
20901 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20902 << getOpenMPClauseName(CKind) << RE->getSourceRange();
20903 }
20904 continue;
20905 }
20906
20907 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
20908 ValueDecl *CurDeclaration = nullptr;
20909
20910 // Obtain the array or member expression bases if required. Also, fill the
20911 // components array with all the components identified in the process.
20912 const Expr *BE =
20913 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
20914 DSAS->getCurrentDirective(), NoDiagnose);
20915 if (!BE)
20916 continue;
20917
20918 assert(!CurComponents.empty() &&(static_cast <bool> (!CurComponents.empty() && "Invalid mappable expression information."
) ? void (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20919, __extension__ __PRETTY_FUNCTION__
))
20919 "Invalid mappable expression information.")(static_cast <bool> (!CurComponents.empty() && "Invalid mappable expression information."
) ? void (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20919, __extension__ __PRETTY_FUNCTION__
))
;
20920
20921 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
20922 // Add store "this" pointer to class in DSAStackTy for future checking
20923 DSAS->addMappedClassesQualTypes(TE->getType());
20924 // Try to find the associated user-defined mapper.
20925 ExprResult ER = buildUserDefinedMapperRef(
20926 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
20927 VE->getType().getCanonicalType(), UnresolvedMapper);
20928 if (ER.isInvalid())
20929 continue;
20930 MVLI.UDMapperList.push_back(ER.get());
20931 // Skip restriction checking for variable or field declarations
20932 MVLI.ProcessedVarList.push_back(RE);
20933 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20934 MVLI.VarComponents.back().append(CurComponents.begin(),
20935 CurComponents.end());
20936 MVLI.VarBaseDeclarations.push_back(nullptr);
20937 continue;
20938 }
20939
20940 // For the following checks, we rely on the base declaration which is
20941 // expected to be associated with the last component. The declaration is
20942 // expected to be a variable or a field (if 'this' is being mapped).
20943 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
20944 assert(CurDeclaration && "Null decl on map clause.")(static_cast <bool> (CurDeclaration && "Null decl on map clause."
) ? void (0) : __assert_fail ("CurDeclaration && \"Null decl on map clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20944, __extension__ __PRETTY_FUNCTION__
))
;
20945 assert((static_cast <bool> (CurDeclaration->isCanonicalDecl
() && "Expecting components to have associated only canonical declarations."
) ? void (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20947, __extension__ __PRETTY_FUNCTION__
))
20946 CurDeclaration->isCanonicalDecl() &&(static_cast <bool> (CurDeclaration->isCanonicalDecl
() && "Expecting components to have associated only canonical declarations."
) ? void (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20947, __extension__ __PRETTY_FUNCTION__
))
20947 "Expecting components to have associated only canonical declarations.")(static_cast <bool> (CurDeclaration->isCanonicalDecl
() && "Expecting components to have associated only canonical declarations."
) ? void (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20947, __extension__ __PRETTY_FUNCTION__
))
;
20948
20949 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
20950 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
20951
20952 assert((VD || FD) && "Only variables or fields are expected here!")(static_cast <bool> ((VD || FD) && "Only variables or fields are expected here!"
) ? void (0) : __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20952, __extension__ __PRETTY_FUNCTION__
))
;
20953 (void)FD;
20954
20955 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
20956 // threadprivate variables cannot appear in a map clause.
20957 // OpenMP 4.5 [2.10.5, target update Construct]
20958 // threadprivate variables cannot appear in a from clause.
20959 if (VD && DSAS->isThreadPrivate(VD)) {
20960 if (NoDiagnose)
20961 continue;
20962 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
20963 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
20964 << getOpenMPClauseName(CKind);
20965 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
20966 continue;
20967 }
20968
20969 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
20970 // A list item cannot appear in both a map clause and a data-sharing
20971 // attribute clause on the same construct.
20972
20973 // Check conflicts with other map clause expressions. We check the conflicts
20974 // with the current construct separately from the enclosing data
20975 // environment, because the restrictions are different. We only have to
20976 // check conflicts across regions for the map clauses.
20977 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
20978 /*CurrentRegionOnly=*/true, CurComponents, CKind))
20979 break;
20980 if (CKind == OMPC_map &&
20981 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
20982 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
20983 /*CurrentRegionOnly=*/false, CurComponents, CKind))
20984 break;
20985
20986 // OpenMP 4.5 [2.10.5, target update Construct]
20987 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20988 // If the type of a list item is a reference to a type T then the type will
20989 // be considered to be T for all purposes of this clause.
20990 auto I = llvm::find_if(
20991 CurComponents,
20992 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
20993 return MC.getAssociatedDeclaration();
20994 });
20995 assert(I != CurComponents.end() && "Null decl on map clause.")(static_cast <bool> (I != CurComponents.end() &&
"Null decl on map clause.") ? void (0) : __assert_fail ("I != CurComponents.end() && \"Null decl on map clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 20995, __extension__ __PRETTY_FUNCTION__
))
;
20996 (void)I;
20997 QualType Type;
20998 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
20999 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
21000 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
21001 if (ASE) {
21002 Type = ASE->getType().getNonReferenceType();
21003 } else if (OASE) {
21004 QualType BaseType =
21005 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
21006 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21007 Type = ATy->getElementType();
21008 else
21009 Type = BaseType->getPointeeType();
21010 Type = Type.getNonReferenceType();
21011 } else if (OAShE) {
21012 Type = OAShE->getBase()->getType()->getPointeeType();
21013 } else {
21014 Type = VE->getType();
21015 }
21016
21017 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
21018 // A list item in a to or from clause must have a mappable type.
21019 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21020 // A list item must have a mappable type.
21021 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
21022 DSAS, Type, /*FullCheck=*/true))
21023 continue;
21024
21025 if (CKind == OMPC_map) {
21026 // target enter data
21027 // OpenMP [2.10.2, Restrictions, p. 99]
21028 // A map-type must be specified in all map clauses and must be either
21029 // to or alloc.
21030 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
21031 if (DKind == OMPD_target_enter_data &&
21032 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
21033 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21034 << (IsMapTypeImplicit ? 1 : 0)
21035 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21036 << getOpenMPDirectiveName(DKind);
21037 continue;
21038 }
21039
21040 // target exit_data
21041 // OpenMP [2.10.3, Restrictions, p. 102]
21042 // A map-type must be specified in all map clauses and must be either
21043 // from, release, or delete.
21044 if (DKind == OMPD_target_exit_data &&
21045 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
21046 MapType == OMPC_MAP_delete)) {
21047 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21048 << (IsMapTypeImplicit ? 1 : 0)
21049 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21050 << getOpenMPDirectiveName(DKind);
21051 continue;
21052 }
21053
21054 // The 'ompx_hold' modifier is specifically intended to be used on a
21055 // 'target' or 'target data' directive to prevent data from being unmapped
21056 // during the associated statement. It is not permitted on a 'target
21057 // enter data' or 'target exit data' directive, which have no associated
21058 // statement.
21059 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
21060 HasHoldModifier) {
21061 SemaRef.Diag(StartLoc,
21062 diag::err_omp_invalid_map_type_modifier_for_directive)
21063 << getOpenMPSimpleClauseTypeName(OMPC_map,
21064 OMPC_MAP_MODIFIER_ompx_hold)
21065 << getOpenMPDirectiveName(DKind);
21066 continue;
21067 }
21068
21069 // target, target data
21070 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
21071 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
21072 // A map-type in a map clause must be to, from, tofrom or alloc
21073 if ((DKind == OMPD_target_data ||
21074 isOpenMPTargetExecutionDirective(DKind)) &&
21075 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
21076 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
21077 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21078 << (IsMapTypeImplicit ? 1 : 0)
21079 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21080 << getOpenMPDirectiveName(DKind);
21081 continue;
21082 }
21083
21084 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
21085 // A list item cannot appear in both a map clause and a data-sharing
21086 // attribute clause on the same construct
21087 //
21088 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
21089 // A list item cannot appear in both a map clause and a data-sharing
21090 // attribute clause on the same construct unless the construct is a
21091 // combined construct.
21092 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
21093 isOpenMPTargetExecutionDirective(DKind)) ||
21094 DKind == OMPD_target)) {
21095 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21096 if (isOpenMPPrivate(DVar.CKind)) {
21097 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
21098 << getOpenMPClauseName(DVar.CKind)
21099 << getOpenMPClauseName(OMPC_map)
21100 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
21101 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
21102 continue;
21103 }
21104 }
21105 }
21106
21107 // Try to find the associated user-defined mapper.
21108 ExprResult ER = buildUserDefinedMapperRef(
21109 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21110 Type.getCanonicalType(), UnresolvedMapper);
21111 if (ER.isInvalid())
21112 continue;
21113 MVLI.UDMapperList.push_back(ER.get());
21114
21115 // Save the current expression.
21116 MVLI.ProcessedVarList.push_back(RE);
21117
21118 // Store the components in the stack so that they can be used to check
21119 // against other clauses later on.
21120 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
21121 /*WhereFoundClauseKind=*/OMPC_map);
21122
21123 // Save the components and declaration to create the clause. For purposes of
21124 // the clause creation, any component list that has has base 'this' uses
21125 // null as base declaration.
21126 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21127 MVLI.VarComponents.back().append(CurComponents.begin(),
21128 CurComponents.end());
21129 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
21130 : CurDeclaration);
21131 }
21132}
21133
21134OMPClause *Sema::ActOnOpenMPMapClause(
21135 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
21136 ArrayRef<SourceLocation> MapTypeModifiersLoc,
21137 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
21138 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
21139 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
21140 const OMPVarListLocTy &Locs, bool NoDiagnose,
21141 ArrayRef<Expr *> UnresolvedMappers) {
21142 OpenMPMapModifierKind Modifiers[] = {
21143 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21144 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21145 OMPC_MAP_MODIFIER_unknown};
21146 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
21147
21148 // Process map-type-modifiers, flag errors for duplicate modifiers.
21149 unsigned Count = 0;
21150 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
21151 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
21152 llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
21153 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
21154 continue;
21155 }
21156 assert(Count < NumberOfOMPMapClauseModifiers &&(static_cast <bool> (Count < NumberOfOMPMapClauseModifiers
&& "Modifiers exceed the allowed number of map type modifiers"
) ? void (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21157, __extension__ __PRETTY_FUNCTION__
))
21157 "Modifiers exceed the allowed number of map type modifiers")(static_cast <bool> (Count < NumberOfOMPMapClauseModifiers
&& "Modifiers exceed the allowed number of map type modifiers"
) ? void (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21157, __extension__ __PRETTY_FUNCTION__
))
;
21158 Modifiers[Count] = MapTypeModifiers[I];
21159 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
21160 ++Count;
21161 }
21162
21163 MappableVarListInfo MVLI(VarList);
21164 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
21165 MapperIdScopeSpec, MapperId, UnresolvedMappers,
21166 MapType, Modifiers, IsMapTypeImplicit,
21167 NoDiagnose);
21168
21169 // We need to produce a map clause even if we don't have variables so that
21170 // other diagnostics related with non-existing map clauses are accurate.
21171 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
21172 MVLI.VarBaseDeclarations, MVLI.VarComponents,
21173 MVLI.UDMapperList, Modifiers, ModifiersLoc,
21174 MapperIdScopeSpec.getWithLocInContext(Context),
21175 MapperId, MapType, IsMapTypeImplicit, MapLoc);
21176}
21177
21178QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
21179 TypeResult ParsedType) {
21180 assert(ParsedType.isUsable())(static_cast <bool> (ParsedType.isUsable()) ? void (0) :
__assert_fail ("ParsedType.isUsable()", "clang/lib/Sema/SemaOpenMP.cpp"
, 21180, __extension__ __PRETTY_FUNCTION__))
;
21181
21182 QualType ReductionType = GetTypeFromParser(ParsedType.get());
21183 if (ReductionType.isNull())
21184 return QualType();
21185
21186 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
21187 // A type name in a declare reduction directive cannot be a function type, an
21188 // array type, a reference type, or a type qualified with const, volatile or
21189 // restrict.
21190 if (ReductionType.hasQualifiers()) {
21191 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
21192 return QualType();
21193 }
21194
21195 if (ReductionType->isFunctionType()) {
21196 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
21197 return QualType();
21198 }
21199 if (ReductionType->isReferenceType()) {
21200 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
21201 return QualType();
21202 }
21203 if (ReductionType->isArrayType()) {
21204 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
21205 return QualType();
21206 }
21207 return ReductionType;
21208}
21209
21210Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
21211 Scope *S, DeclContext *DC, DeclarationName Name,
21212 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
21213 AccessSpecifier AS, Decl *PrevDeclInScope) {
21214 SmallVector<Decl *, 8> Decls;
21215 Decls.reserve(ReductionTypes.size());
21216
21217 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
21218 forRedeclarationInCurContext());
21219 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
21220 // A reduction-identifier may not be re-declared in the current scope for the
21221 // same type or for a type that is compatible according to the base language
21222 // rules.
21223 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21224 OMPDeclareReductionDecl *PrevDRD = nullptr;
21225 bool InCompoundScope = true;
21226 if (S != nullptr) {
21227 // Find previous declaration with the same name not referenced in other
21228 // declarations.
21229 FunctionScopeInfo *ParentFn = getEnclosingFunction();
21230 InCompoundScope =
21231 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
21232 LookupName(Lookup, S);
21233 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
21234 /*AllowInlineNamespace=*/false);
21235 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
21236 LookupResult::Filter Filter = Lookup.makeFilter();
21237 while (Filter.hasNext()) {
21238 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
21239 if (InCompoundScope) {
21240 auto I = UsedAsPrevious.find(PrevDecl);
21241 if (I == UsedAsPrevious.end())
21242 UsedAsPrevious[PrevDecl] = false;
21243 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
21244 UsedAsPrevious[D] = true;
21245 }
21246 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21247 PrevDecl->getLocation();
21248 }
21249 Filter.done();
21250 if (InCompoundScope) {
21251 for (const auto &PrevData : UsedAsPrevious) {
21252 if (!PrevData.second) {
21253 PrevDRD = PrevData.first;
21254 break;
21255 }
21256 }
21257 }
21258 } else if (PrevDeclInScope != nullptr) {
21259 auto *PrevDRDInScope = PrevDRD =
21260 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
21261 do {
21262 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
21263 PrevDRDInScope->getLocation();
21264 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
21265 } while (PrevDRDInScope != nullptr);
21266 }
21267 for (const auto &TyData : ReductionTypes) {
21268 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
21269 bool Invalid = false;
21270 if (I != PreviousRedeclTypes.end()) {
21271 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
21272 << TyData.first;
21273 Diag(I->second, diag::note_previous_definition);
21274 Invalid = true;
21275 }
21276 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
21277 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
21278 Name, TyData.first, PrevDRD);
21279 DC->addDecl(DRD);
21280 DRD->setAccess(AS);
21281 Decls.push_back(DRD);
21282 if (Invalid)
21283 DRD->setInvalidDecl();
21284 else
21285 PrevDRD = DRD;
21286 }
21287
21288 return DeclGroupPtrTy::make(
21289 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
21290}
21291
21292void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
21293 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21294
21295 // Enter new function scope.
21296 PushFunctionScope();
21297 setFunctionHasBranchProtectedScope();
21298 getCurFunction()->setHasOMPDeclareReductionCombiner();
21299
21300 if (S != nullptr)
21301 PushDeclContext(S, DRD);
21302 else
21303 CurContext = DRD;
21304
21305 PushExpressionEvaluationContext(
21306 ExpressionEvaluationContext::PotentiallyEvaluated);
21307
21308 QualType ReductionType = DRD->getType();
21309 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
21310 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
21311 // uses semantics of argument handles by value, but it should be passed by
21312 // reference. C lang does not support references, so pass all parameters as
21313 // pointers.
21314 // Create 'T omp_in;' variable.
21315 VarDecl *OmpInParm =
21316 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
21317 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
21318 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
21319 // uses semantics of argument handles by value, but it should be passed by
21320 // reference. C lang does not support references, so pass all parameters as
21321 // pointers.
21322 // Create 'T omp_out;' variable.
21323 VarDecl *OmpOutParm =
21324 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
21325 if (S != nullptr) {
21326 PushOnScopeChains(OmpInParm, S);
21327 PushOnScopeChains(OmpOutParm, S);
21328 } else {
21329 DRD->addDecl(OmpInParm);
21330 DRD->addDecl(OmpOutParm);
21331 }
21332 Expr *InE =
21333 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
21334 Expr *OutE =
21335 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
21336 DRD->setCombinerData(InE, OutE);
21337}
21338
21339void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
21340 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21341 DiscardCleanupsInEvaluationContext();
21342 PopExpressionEvaluationContext();
21343
21344 PopDeclContext();
21345 PopFunctionScopeInfo();
21346
21347 if (Combiner != nullptr)
21348 DRD->setCombiner(Combiner);
21349 else
21350 DRD->setInvalidDecl();
21351}
21352
21353VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
21354 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21355
21356 // Enter new function scope.
21357 PushFunctionScope();
21358 setFunctionHasBranchProtectedScope();
21359
21360 if (S != nullptr)
21361 PushDeclContext(S, DRD);
21362 else
21363 CurContext = DRD;
21364
21365 PushExpressionEvaluationContext(
21366 ExpressionEvaluationContext::PotentiallyEvaluated);
21367
21368 QualType ReductionType = DRD->getType();
21369 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
21370 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
21371 // uses semantics of argument handles by value, but it should be passed by
21372 // reference. C lang does not support references, so pass all parameters as
21373 // pointers.
21374 // Create 'T omp_priv;' variable.
21375 VarDecl *OmpPrivParm =
21376 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
21377 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
21378 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
21379 // uses semantics of argument handles by value, but it should be passed by
21380 // reference. C lang does not support references, so pass all parameters as
21381 // pointers.
21382 // Create 'T omp_orig;' variable.
21383 VarDecl *OmpOrigParm =
21384 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
21385 if (S != nullptr) {
21386 PushOnScopeChains(OmpPrivParm, S);
21387 PushOnScopeChains(OmpOrigParm, S);
21388 } else {
21389 DRD->addDecl(OmpPrivParm);
21390 DRD->addDecl(OmpOrigParm);
21391 }
21392 Expr *OrigE =
21393 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
21394 Expr *PrivE =
21395 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
21396 DRD->setInitializerData(OrigE, PrivE);
21397 return OmpPrivParm;
21398}
21399
21400void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
21401 VarDecl *OmpPrivParm) {
21402 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21403 DiscardCleanupsInEvaluationContext();
21404 PopExpressionEvaluationContext();
21405
21406 PopDeclContext();
21407 PopFunctionScopeInfo();
21408
21409 if (Initializer != nullptr) {
21410 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
21411 } else if (OmpPrivParm->hasInit()) {
21412 DRD->setInitializer(OmpPrivParm->getInit(),
21413 OmpPrivParm->isDirectInit()
21414 ? OMPDeclareReductionDecl::DirectInit
21415 : OMPDeclareReductionDecl::CopyInit);
21416 } else {
21417 DRD->setInvalidDecl();
21418 }
21419}
21420
21421Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
21422 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
21423 for (Decl *D : DeclReductions.get()) {
21424 if (IsValid) {
21425 if (S)
21426 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
21427 /*AddToContext=*/false);
21428 } else {
21429 D->setInvalidDecl();
21430 }
21431 }
21432 return DeclReductions;
21433}
21434
21435TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
21436 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
21437 QualType T = TInfo->getType();
21438 if (D.isInvalidType())
21439 return true;
21440
21441 if (getLangOpts().CPlusPlus) {
21442 // Check that there are no default arguments (C++ only).
21443 CheckExtraCXXDefaultArguments(D);
21444 }
21445
21446 return CreateParsedType(T, TInfo);
21447}
21448
21449QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
21450 TypeResult ParsedType) {
21451 assert(ParsedType.isUsable() && "Expect usable parsed mapper type")(static_cast <bool> (ParsedType.isUsable() && "Expect usable parsed mapper type"
) ? void (0) : __assert_fail ("ParsedType.isUsable() && \"Expect usable parsed mapper type\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21451, __extension__ __PRETTY_FUNCTION__
))
;
21452
21453 QualType MapperType = GetTypeFromParser(ParsedType.get());
21454 assert(!MapperType.isNull() && "Expect valid mapper type")(static_cast <bool> (!MapperType.isNull() && "Expect valid mapper type"
) ? void (0) : __assert_fail ("!MapperType.isNull() && \"Expect valid mapper type\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21454, __extension__ __PRETTY_FUNCTION__
))
;
21455
21456 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21457 // The type must be of struct, union or class type in C and C++
21458 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
21459 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
21460 return QualType();
21461 }
21462 return MapperType;
21463}
21464
21465Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
21466 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
21467 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
21468 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
21469 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
21470 forRedeclarationInCurContext());
21471 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21472 // A mapper-identifier may not be redeclared in the current scope for the
21473 // same type or for a type that is compatible according to the base language
21474 // rules.
21475 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21476 OMPDeclareMapperDecl *PrevDMD = nullptr;
21477 bool InCompoundScope = true;
21478 if (S != nullptr) {
21479 // Find previous declaration with the same name not referenced in other
21480 // declarations.
21481 FunctionScopeInfo *ParentFn = getEnclosingFunction();
21482 InCompoundScope =
21483 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
21484 LookupName(Lookup, S);
21485 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
21486 /*AllowInlineNamespace=*/false);
21487 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
21488 LookupResult::Filter Filter = Lookup.makeFilter();
21489 while (Filter.hasNext()) {
21490 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
21491 if (InCompoundScope) {
21492 auto I = UsedAsPrevious.find(PrevDecl);
21493 if (I == UsedAsPrevious.end())
21494 UsedAsPrevious[PrevDecl] = false;
21495 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
21496 UsedAsPrevious[D] = true;
21497 }
21498 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21499 PrevDecl->getLocation();
21500 }
21501 Filter.done();
21502 if (InCompoundScope) {
21503 for (const auto &PrevData : UsedAsPrevious) {
21504 if (!PrevData.second) {
21505 PrevDMD = PrevData.first;
21506 break;
21507 }
21508 }
21509 }
21510 } else if (PrevDeclInScope) {
21511 auto *PrevDMDInScope = PrevDMD =
21512 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
21513 do {
21514 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
21515 PrevDMDInScope->getLocation();
21516 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
21517 } while (PrevDMDInScope != nullptr);
21518 }
21519 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
21520 bool Invalid = false;
21521 if (I != PreviousRedeclTypes.end()) {
21522 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
21523 << MapperType << Name;
21524 Diag(I->second, diag::note_previous_definition);
21525 Invalid = true;
21526 }
21527 // Build expressions for implicit maps of data members with 'default'
21528 // mappers.
21529 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
21530 Clauses.end());
21531 if (LangOpts.OpenMP >= 50)
21532 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ClausesWithImplicit);
21533 auto *DMD =
21534 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
21535 ClausesWithImplicit, PrevDMD);
21536 if (S)
21537 PushOnScopeChains(DMD, S);
21538 else
21539 DC->addDecl(DMD);
21540 DMD->setAccess(AS);
21541 if (Invalid)
21542 DMD->setInvalidDecl();
21543
21544 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
21545 VD->setDeclContext(DMD);
21546 VD->setLexicalDeclContext(DMD);
21547 DMD->addDecl(VD);
21548 DMD->setMapperVarRef(MapperVarRef);
21549
21550 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
21551}
21552
21553ExprResult
21554Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
21555 SourceLocation StartLoc,
21556 DeclarationName VN) {
21557 TypeSourceInfo *TInfo =
21558 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
21559 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
21560 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
21561 MapperType, TInfo, SC_None);
21562 if (S)
21563 PushOnScopeChains(VD, S, /*AddToContext=*/false);
21564 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
21565 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
21566 return E;
21567}
21568
21569bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
21570 assert(LangOpts.OpenMP && "Expected OpenMP mode.")(static_cast <bool> (LangOpts.OpenMP && "Expected OpenMP mode."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21570, __extension__ __PRETTY_FUNCTION__
))
;
21571 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
21572 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
21573 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
21574 return true;
21575 if (VD->isUsableInConstantExpressions(Context))
21576 return true;
21577 return false;
21578 }
21579 return true;
21580}
21581
21582const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
21583 assert(LangOpts.OpenMP && "Expected OpenMP mode.")(static_cast <bool> (LangOpts.OpenMP && "Expected OpenMP mode."
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21583, __extension__ __PRETTY_FUNCTION__
))
;
21584 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
21585}
21586
21587OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
21588 SourceLocation StartLoc,
21589 SourceLocation LParenLoc,
21590 SourceLocation EndLoc) {
21591 Expr *ValExpr = NumTeams;
21592 Stmt *HelperValStmt = nullptr;
21593
21594 // OpenMP [teams Constrcut, Restrictions]
21595 // The num_teams expression must evaluate to a positive integer value.
21596 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
21597 /*StrictlyPositive=*/true))
21598 return nullptr;
21599
21600 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
21601 OpenMPDirectiveKind CaptureRegion =
21602 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
21603 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21604 ValExpr = MakeFullExpr(ValExpr).get();
21605 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21606 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21607 HelperValStmt = buildPreInits(Context, Captures);
21608 }
21609
21610 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
21611 StartLoc, LParenLoc, EndLoc);
21612}
21613
21614OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
21615 SourceLocation StartLoc,
21616 SourceLocation LParenLoc,
21617 SourceLocation EndLoc) {
21618 Expr *ValExpr = ThreadLimit;
21619 Stmt *HelperValStmt = nullptr;
21620
21621 // OpenMP [teams Constrcut, Restrictions]
21622 // The thread_limit expression must evaluate to a positive integer value.
21623 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
21624 /*StrictlyPositive=*/true))
21625 return nullptr;
21626
21627 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
21628 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
21629 DKind, OMPC_thread_limit, LangOpts.OpenMP);
21630 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21631 ValExpr = MakeFullExpr(ValExpr).get();
21632 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21633 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21634 HelperValStmt = buildPreInits(Context, Captures);
21635 }
21636
21637 return new (Context) OMPThreadLimitClause(
21638 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
21639}
21640
21641OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
21642 SourceLocation StartLoc,
21643 SourceLocation LParenLoc,
21644 SourceLocation EndLoc) {
21645 Expr *ValExpr = Priority;
21646 Stmt *HelperValStmt = nullptr;
21647 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21648
21649 // OpenMP [2.9.1, task Constrcut]
21650 // The priority-value is a non-negative numerical scalar expression.
21651 if (!isNonNegativeIntegerValue(
21652 ValExpr, *this, OMPC_priority,
21653 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
21654 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21655 return nullptr;
21656
21657 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
21658 StartLoc, LParenLoc, EndLoc);
21659}
21660
21661OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
21662 SourceLocation StartLoc,
21663 SourceLocation LParenLoc,
21664 SourceLocation EndLoc) {
21665 Expr *ValExpr = Grainsize;
21666 Stmt *HelperValStmt = nullptr;
21667 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21668
21669 // OpenMP [2.9.2, taskloop Constrcut]
21670 // The parameter of the grainsize clause must be a positive integer
21671 // expression.
21672 if (!isNonNegativeIntegerValue(
21673 ValExpr, *this, OMPC_grainsize,
21674 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
21675 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21676 return nullptr;
21677
21678 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
21679 StartLoc, LParenLoc, EndLoc);
21680}
21681
21682OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
21683 SourceLocation StartLoc,
21684 SourceLocation LParenLoc,
21685 SourceLocation EndLoc) {
21686 Expr *ValExpr = NumTasks;
21687 Stmt *HelperValStmt = nullptr;
21688 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21689
21690 // OpenMP [2.9.2, taskloop Constrcut]
21691 // The parameter of the num_tasks clause must be a positive integer
21692 // expression.
21693 if (!isNonNegativeIntegerValue(
21694 ValExpr, *this, OMPC_num_tasks,
21695 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
21696 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21697 return nullptr;
21698
21699 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
21700 StartLoc, LParenLoc, EndLoc);
21701}
21702
21703OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
21704 SourceLocation LParenLoc,
21705 SourceLocation EndLoc) {
21706 // OpenMP [2.13.2, critical construct, Description]
21707 // ... where hint-expression is an integer constant expression that evaluates
21708 // to a valid lock hint.
21709 ExprResult HintExpr =
21710 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
21711 if (HintExpr.isInvalid())
21712 return nullptr;
21713 return new (Context)
21714 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
21715}
21716
21717/// Tries to find omp_event_handle_t type.
21718static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
21719 DSAStackTy *Stack) {
21720 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
21721 if (!OMPEventHandleT.isNull())
21722 return true;
21723 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
21724 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
21725 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
21726 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
21727 return false;
21728 }
21729 Stack->setOMPEventHandleT(PT.get());
21730 return true;
21731}
21732
21733OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
21734 SourceLocation LParenLoc,
21735 SourceLocation EndLoc) {
21736 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
21737 !Evt->isInstantiationDependent() &&
21738 !Evt->containsUnexpandedParameterPack()) {
21739 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
21740 return nullptr;
21741 // OpenMP 5.0, 2.10.1 task Construct.
21742 // event-handle is a variable of the omp_event_handle_t type.
21743 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
21744 if (!Ref) {
21745 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21746 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
21747 return nullptr;
21748 }
21749 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
21750 if (!VD) {
21751 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21752 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
21753 return nullptr;
21754 }
21755 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
21756 VD->getType()) ||
21757 VD->getType().isConstant(Context)) {
21758 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21759 << "omp_event_handle_t" << 1 << VD->getType()
21760 << Evt->getSourceRange();
21761 return nullptr;
21762 }
21763 // OpenMP 5.0, 2.10.1 task Construct
21764 // [detach clause]... The event-handle will be considered as if it was
21765 // specified on a firstprivate clause.
21766 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
21767 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
21768 DVar.RefExpr) {
21769 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
21770 << getOpenMPClauseName(DVar.CKind)
21771 << getOpenMPClauseName(OMPC_firstprivate);
21772 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
21773 return nullptr;
21774 }
21775 }
21776
21777 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
21778}
21779
21780OMPClause *Sema::ActOnOpenMPDistScheduleClause(
21781 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
21782 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
21783 SourceLocation EndLoc) {
21784 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
21785 std::string Values;
21786 Values += "'";
21787 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
21788 Values += "'";
21789 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21790 << Values << getOpenMPClauseName(OMPC_dist_schedule);
21791 return nullptr;
21792 }
21793 Expr *ValExpr = ChunkSize;
21794 Stmt *HelperValStmt = nullptr;
21795 if (ChunkSize) {
21796 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
21797 !ChunkSize->isInstantiationDependent() &&
21798 !ChunkSize->containsUnexpandedParameterPack()) {
21799 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
21800 ExprResult Val =
21801 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
21802 if (Val.isInvalid())
21803 return nullptr;
21804
21805 ValExpr = Val.get();
21806
21807 // OpenMP [2.7.1, Restrictions]
21808 // chunk_size must be a loop invariant integer expression with a positive
21809 // value.
21810 if (Optional<llvm::APSInt> Result =
21811 ValExpr->getIntegerConstantExpr(Context)) {
21812 if (Result->isSigned() && !Result->isStrictlyPositive()) {
21813 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
21814 << "dist_schedule" << ChunkSize->getSourceRange();
21815 return nullptr;
21816 }
21817 } else if (getOpenMPCaptureRegionForClause(
21818 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
21819 LangOpts.OpenMP) != OMPD_unknown &&
21820 !CurContext->isDependentContext()) {
21821 ValExpr = MakeFullExpr(ValExpr).get();
21822 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21823 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21824 HelperValStmt = buildPreInits(Context, Captures);
21825 }
21826 }
21827 }
21828
21829 return new (Context)
21830 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
21831 Kind, ValExpr, HelperValStmt);
21832}
21833
21834OMPClause *Sema::ActOnOpenMPDefaultmapClause(
21835 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
21836 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
21837 SourceLocation KindLoc, SourceLocation EndLoc) {
21838 if (getLangOpts().OpenMP < 50) {
21839 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
21840 Kind != OMPC_DEFAULTMAP_scalar) {
21841 std::string Value;
21842 SourceLocation Loc;
21843 Value += "'";
21844 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
21845 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
21846 OMPC_DEFAULTMAP_MODIFIER_tofrom);
21847 Loc = MLoc;
21848 } else {
21849 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
21850 OMPC_DEFAULTMAP_scalar);
21851 Loc = KindLoc;
21852 }
21853 Value += "'";
21854 Diag(Loc, diag::err_omp_unexpected_clause_value)
21855 << Value << getOpenMPClauseName(OMPC_defaultmap);
21856 return nullptr;
21857 }
21858 } else {
21859 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
21860 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
21861 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
21862 if (!isDefaultmapKind || !isDefaultmapModifier) {
21863 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
21864 if (LangOpts.OpenMP == 50) {
21865 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
21866 "'firstprivate', 'none', 'default'";
21867 if (!isDefaultmapKind && isDefaultmapModifier) {
21868 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21869 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21870 } else if (isDefaultmapKind && !isDefaultmapModifier) {
21871 Diag(MLoc, diag::err_omp_unexpected_clause_value)
21872 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21873 } else {
21874 Diag(MLoc, diag::err_omp_unexpected_clause_value)
21875 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21876 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21877 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21878 }
21879 } else {
21880 StringRef ModifierValue =
21881 "'alloc', 'from', 'to', 'tofrom', "
21882 "'firstprivate', 'none', 'default', 'present'";
21883 if (!isDefaultmapKind && isDefaultmapModifier) {
21884 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21885 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21886 } else if (isDefaultmapKind && !isDefaultmapModifier) {
21887 Diag(MLoc, diag::err_omp_unexpected_clause_value)
21888 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21889 } else {
21890 Diag(MLoc, diag::err_omp_unexpected_clause_value)
21891 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21892 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21893 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21894 }
21895 }
21896 return nullptr;
21897 }
21898
21899 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
21900 // At most one defaultmap clause for each category can appear on the
21901 // directive.
21902 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
21903 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
21904 return nullptr;
21905 }
21906 }
21907 if (Kind == OMPC_DEFAULTMAP_unknown) {
21908 // Variable category is not specified - mark all categories.
21909 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
21910 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
21911 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
21912 } else {
21913 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
21914 }
21915
21916 return new (Context)
21917 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
21918}
21919
21920bool Sema::ActOnStartOpenMPDeclareTargetContext(
21921 DeclareTargetContextInfo &DTCI) {
21922 DeclContext *CurLexicalContext = getCurLexicalContext();
21923 if (!CurLexicalContext->isFileContext() &&
21924 !CurLexicalContext->isExternCContext() &&
21925 !CurLexicalContext->isExternCXXContext() &&
21926 !isa<CXXRecordDecl>(CurLexicalContext) &&
21927 !isa<ClassTemplateDecl>(CurLexicalContext) &&
21928 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
21929 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
21930 Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
21931 return false;
21932 }
21933 DeclareTargetNesting.push_back(DTCI);
21934 return true;
21935}
21936
21937const Sema::DeclareTargetContextInfo
21938Sema::ActOnOpenMPEndDeclareTargetDirective() {
21939 assert(!DeclareTargetNesting.empty() &&(static_cast <bool> (!DeclareTargetNesting.empty() &&
"check isInOpenMPDeclareTargetContext() first!") ? void (0) :
__assert_fail ("!DeclareTargetNesting.empty() && \"check isInOpenMPDeclareTargetContext() first!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21940, __extension__ __PRETTY_FUNCTION__
))
21940 "check isInOpenMPDeclareTargetContext() first!")(static_cast <bool> (!DeclareTargetNesting.empty() &&
"check isInOpenMPDeclareTargetContext() first!") ? void (0) :
__assert_fail ("!DeclareTargetNesting.empty() && \"check isInOpenMPDeclareTargetContext() first!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21940, __extension__ __PRETTY_FUNCTION__
))
;
21941 return DeclareTargetNesting.pop_back_val();
21942}
21943
21944void Sema::ActOnFinishedOpenMPDeclareTargetContext(
21945 DeclareTargetContextInfo &DTCI) {
21946 for (auto &It : DTCI.ExplicitlyMapped)
21947 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
21948}
21949
21950NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
21951 CXXScopeSpec &ScopeSpec,
21952 const DeclarationNameInfo &Id) {
21953 LookupResult Lookup(*this, Id, LookupOrdinaryName);
21954 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
21955
21956 if (Lookup.isAmbiguous())
21957 return nullptr;
21958 Lookup.suppressDiagnostics();
21959
21960 if (!Lookup.isSingleResult()) {
21961 VarOrFuncDeclFilterCCC CCC(*this);
21962 if (TypoCorrection Corrected =
21963 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
21964 CTK_ErrorRecovery)) {
21965 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
21966 << Id.getName());
21967 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
21968 return nullptr;
21969 }
21970
21971 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
21972 return nullptr;
21973 }
21974
21975 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
21976 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
21977 !isa<FunctionTemplateDecl>(ND)) {
21978 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
21979 return nullptr;
21980 }
21981 return ND;
21982}
21983
21984void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
21985 OMPDeclareTargetDeclAttr::MapTypeTy MT,
21986 DeclareTargetContextInfo &DTCI) {
21987 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||(static_cast <bool> ((isa<VarDecl>(ND) || isa<
FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) &&
"Expected variable, function or function template.") ? void (
0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21989, __extension__ __PRETTY_FUNCTION__
))
21988 isa<FunctionTemplateDecl>(ND)) &&(static_cast <bool> ((isa<VarDecl>(ND) || isa<
FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) &&
"Expected variable, function or function template.") ? void (
0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21989, __extension__ __PRETTY_FUNCTION__
))
21989 "Expected variable, function or function template.")(static_cast <bool> ((isa<VarDecl>(ND) || isa<
FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) &&
"Expected variable, function or function template.") ? void (
0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 21989, __extension__ __PRETTY_FUNCTION__
))
;
21990
21991 // Diagnose marking after use as it may lead to incorrect diagnosis and
21992 // codegen.
21993 if (LangOpts.OpenMP >= 50 &&
21994 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
21995 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
21996
21997 // Explicit declare target lists have precedence.
21998 const unsigned Level = -1;
21999
22000 auto *VD = cast<ValueDecl>(ND);
22001 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22002 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22003 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DTCI.DT &&
22004 ActiveAttr.getValue()->getLevel() == Level) {
22005 Diag(Loc, diag::err_omp_device_type_mismatch)
22006 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
22007 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22008 ActiveAttr.getValue()->getDevType());
22009 return;
22010 }
22011 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
22012 ActiveAttr.getValue()->getLevel() == Level) {
22013 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
22014 return;
22015 }
22016
22017 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
22018 return;
22019
22020 Expr *IndirectE = nullptr;
22021 bool IsIndirect = false;
22022 if (DTCI.Indirect.hasValue()) {
22023 IndirectE = DTCI.Indirect.getValue();
22024 if (!IndirectE)
22025 IsIndirect = true;
22026 }
22027 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22028 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
22029 SourceRange(Loc, Loc));
22030 ND->addAttr(A);
22031 if (ASTMutationListener *ML = Context.getASTMutationListener())
22032 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
22033 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
22034}
22035
22036static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
22037 Sema &SemaRef, Decl *D) {
22038 if (!D || !isa<VarDecl>(D))
22039 return;
22040 auto *VD = cast<VarDecl>(D);
22041 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
22042 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
22043 if (SemaRef.LangOpts.OpenMP >= 50 &&
22044 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
22045 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
22046 VD->hasGlobalStorage()) {
22047 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
22048 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
22049 // If a lambda declaration and definition appears between a
22050 // declare target directive and the matching end declare target
22051 // directive, all variables that are captured by the lambda
22052 // expression must also appear in a to clause.
22053 SemaRef.Diag(VD->getLocation(),
22054 diag::err_omp_lambda_capture_in_declare_target_not_to);
22055 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
22056 << VD << 0 << SR;
22057 return;
22058 }
22059 }
22060 if (MapTy.hasValue())
22061 return;
22062 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
22063 SemaRef.Diag(SL, diag::note_used_here) << SR;
22064}
22065
22066static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
22067 Sema &SemaRef, DSAStackTy *Stack,
22068 ValueDecl *VD) {
22069 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
22070 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
22071 /*FullCheck=*/false);
22072}
22073
22074void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
22075 SourceLocation IdLoc) {
22076 if (!D || D->isInvalidDecl())
22077 return;
22078 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
22079 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
22080 if (auto *VD = dyn_cast<VarDecl>(D)) {
22081 // Only global variables can be marked as declare target.
22082 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
22083 !VD->isStaticDataMember())
22084 return;
22085 // 2.10.6: threadprivate variable cannot appear in a declare target
22086 // directive.
22087 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
22088 Diag(SL, diag::err_omp_threadprivate_in_target);
22089 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
22090 return;
22091 }
22092 }
22093 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
22094 D = FTD->getTemplatedDecl();
22095 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
22096 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
22097 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
22098 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
22099 Diag(IdLoc, diag::err_omp_function_in_link_clause);
22100 Diag(FD->getLocation(), diag::note_defined_here) << FD;
22101 return;
22102 }
22103 }
22104 if (auto *VD = dyn_cast<ValueDecl>(D)) {
22105 // Problem if any with var declared with incomplete type will be reported
22106 // as normal, so no need to check it here.
22107 if ((E || !VD->getType()->isIncompleteType()) &&
22108 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
22109 return;
22110 if (!E && isInOpenMPDeclareTargetContext()) {
22111 // Checking declaration inside declare target region.
22112 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
22113 isa<FunctionTemplateDecl>(D)) {
22114 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22115 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22116 unsigned Level = DeclareTargetNesting.size();
22117 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
22118 return;
22119 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22120 Expr *IndirectE = nullptr;
22121 bool IsIndirect = false;
22122 if (DTCI.Indirect.hasValue()) {
22123 IndirectE = DTCI.Indirect.getValue();
22124 if (!IndirectE)
22125 IsIndirect = true;
22126 }
22127 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22128 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE,
22129 IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc));
22130 D->addAttr(A);
22131 if (ASTMutationListener *ML = Context.getASTMutationListener())
22132 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
22133 }
22134 return;
22135 }
22136 }
22137 if (!E)
22138 return;
22139 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
22140}
22141
22142OMPClause *Sema::ActOnOpenMPToClause(
22143 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22144 ArrayRef<SourceLocation> MotionModifiersLoc,
22145 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22146 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22147 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22148 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
22149 OMPC_MOTION_MODIFIER_unknown};
22150 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
22151
22152 // Process motion-modifiers, flag errors for duplicate modifiers.
22153 unsigned Count = 0;
22154 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22155 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22156 llvm::is_contained(Modifiers, MotionModifiers[I])) {
22157 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22158 continue;
22159 }
22160 assert(Count < NumberOfOMPMotionModifiers &&(static_cast <bool> (Count < NumberOfOMPMotionModifiers
&& "Modifiers exceed the allowed number of motion modifiers"
) ? void (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22161, __extension__ __PRETTY_FUNCTION__
))
22161 "Modifiers exceed the allowed number of motion modifiers")(static_cast <bool> (Count < NumberOfOMPMotionModifiers
&& "Modifiers exceed the allowed number of motion modifiers"
) ? void (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22161, __extension__ __PRETTY_FUNCTION__
))
;
22162 Modifiers[Count] = MotionModifiers[I];
22163 ModifiersLoc[Count] = MotionModifiersLoc[I];
22164 ++Count;
22165 }
22166
22167 MappableVarListInfo MVLI(VarList);
22168 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
22169 MapperIdScopeSpec, MapperId, UnresolvedMappers);
22170 if (MVLI.ProcessedVarList.empty())
22171 return nullptr;
22172
22173 return OMPToClause::Create(
22174 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22175 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22176 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
22177}
22178
22179OMPClause *Sema::ActOnOpenMPFromClause(
22180 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22181 ArrayRef<SourceLocation> MotionModifiersLoc,
22182 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22183 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22184 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22185 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
22186 OMPC_MOTION_MODIFIER_unknown};
22187 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
22188
22189 // Process motion-modifiers, flag errors for duplicate modifiers.
22190 unsigned Count = 0;
22191 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22192 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22193 llvm::is_contained(Modifiers, MotionModifiers[I])) {
22194 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22195 continue;
22196 }
22197 assert(Count < NumberOfOMPMotionModifiers &&(static_cast <bool> (Count < NumberOfOMPMotionModifiers
&& "Modifiers exceed the allowed number of motion modifiers"
) ? void (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22198, __extension__ __PRETTY_FUNCTION__
))
22198 "Modifiers exceed the allowed number of motion modifiers")(static_cast <bool> (Count < NumberOfOMPMotionModifiers
&& "Modifiers exceed the allowed number of motion modifiers"
) ? void (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22198, __extension__ __PRETTY_FUNCTION__
))
;
22199 Modifiers[Count] = MotionModifiers[I];
22200 ModifiersLoc[Count] = MotionModifiersLoc[I];
22201 ++Count;
22202 }
22203
22204 MappableVarListInfo MVLI(VarList);
22205 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
22206 MapperIdScopeSpec, MapperId, UnresolvedMappers);
22207 if (MVLI.ProcessedVarList.empty())
22208 return nullptr;
22209
22210 return OMPFromClause::Create(
22211 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22212 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22213 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
22214}
22215
22216OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
22217 const OMPVarListLocTy &Locs) {
22218 MappableVarListInfo MVLI(VarList);
22219 SmallVector<Expr *, 8> PrivateCopies;
22220 SmallVector<Expr *, 8> Inits;
22221
22222 for (Expr *RefExpr : VarList) {
22223 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP use_device_ptr clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22223, __extension__ __PRETTY_FUNCTION__
))
;
22224 SourceLocation ELoc;
22225 SourceRange ERange;
22226 Expr *SimpleRefExpr = RefExpr;
22227 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22228 if (Res.second) {
22229 // It will be analyzed later.
22230 MVLI.ProcessedVarList.push_back(RefExpr);
22231 PrivateCopies.push_back(nullptr);
22232 Inits.push_back(nullptr);
22233 }
22234 ValueDecl *D = Res.first;
22235 if (!D)
22236 continue;
22237
22238 QualType Type = D->getType();
22239 Type = Type.getNonReferenceType().getUnqualifiedType();
22240
22241 auto *VD = dyn_cast<VarDecl>(D);
22242
22243 // Item should be a pointer or reference to pointer.
22244 if (!Type->isPointerType()) {
22245 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
22246 << 0 << RefExpr->getSourceRange();
22247 continue;
22248 }
22249
22250 // Build the private variable and the expression that refers to it.
22251 auto VDPrivate =
22252 buildVarDecl(*this, ELoc, Type, D->getName(),
22253 D->hasAttrs() ? &D->getAttrs() : nullptr,
22254 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
22255 if (VDPrivate->isInvalidDecl())
22256 continue;
22257
22258 CurContext->addDecl(VDPrivate);
22259 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
22260 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
22261
22262 // Add temporary variable to initialize the private copy of the pointer.
22263 VarDecl *VDInit =
22264 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
22265 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
22266 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
22267 AddInitializerToDecl(VDPrivate,
22268 DefaultLvalueConversion(VDInitRefExpr).get(),
22269 /*DirectInit=*/false);
22270
22271 // If required, build a capture to implement the privatization initialized
22272 // with the current list item value.
22273 DeclRefExpr *Ref = nullptr;
22274 if (!VD)
22275 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22276 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22277 PrivateCopies.push_back(VDPrivateRefExpr);
22278 Inits.push_back(VDInitRefExpr);
22279
22280 // We need to add a data sharing attribute for this variable to make sure it
22281 // is correctly captured. A variable that shows up in a use_device_ptr has
22282 // similar properties of a first private variable.
22283 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22284
22285 // Create a mappable component for the list item. List items in this clause
22286 // only need a component.
22287 MVLI.VarBaseDeclarations.push_back(D);
22288 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22289 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
22290 /*IsNonContiguous=*/false);
22291 }
22292
22293 if (MVLI.ProcessedVarList.empty())
22294 return nullptr;
22295
22296 return OMPUseDevicePtrClause::Create(
22297 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
22298 MVLI.VarBaseDeclarations, MVLI.VarComponents);
22299}
22300
22301OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
22302 const OMPVarListLocTy &Locs) {
22303 MappableVarListInfo MVLI(VarList);
22304
22305 for (Expr *RefExpr : VarList) {
22306 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP use_device_addr clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_addr clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22306, __extension__ __PRETTY_FUNCTION__
))
;
22307 SourceLocation ELoc;
22308 SourceRange ERange;
22309 Expr *SimpleRefExpr = RefExpr;
22310 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22311 /*AllowArraySection=*/true);
22312 if (Res.second) {
22313 // It will be analyzed later.
22314 MVLI.ProcessedVarList.push_back(RefExpr);
22315 }
22316 ValueDecl *D = Res.first;
22317 if (!D)
22318 continue;
22319 auto *VD = dyn_cast<VarDecl>(D);
22320
22321 // If required, build a capture to implement the privatization initialized
22322 // with the current list item value.
22323 DeclRefExpr *Ref = nullptr;
22324 if (!VD)
22325 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22326 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22327
22328 // We need to add a data sharing attribute for this variable to make sure it
22329 // is correctly captured. A variable that shows up in a use_device_addr has
22330 // similar properties of a first private variable.
22331 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22332
22333 // Create a mappable component for the list item. List items in this clause
22334 // only need a component.
22335 MVLI.VarBaseDeclarations.push_back(D);
22336 MVLI.VarComponents.emplace_back();
22337 Expr *Component = SimpleRefExpr;
22338 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
22339 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
22340 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
22341 MVLI.VarComponents.back().emplace_back(Component, D,
22342 /*IsNonContiguous=*/false);
22343 }
22344
22345 if (MVLI.ProcessedVarList.empty())
22346 return nullptr;
22347
22348 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22349 MVLI.VarBaseDeclarations,
22350 MVLI.VarComponents);
22351}
22352
22353OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
22354 const OMPVarListLocTy &Locs) {
22355 MappableVarListInfo MVLI(VarList);
22356 for (Expr *RefExpr : VarList) {
22357 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP is_device_ptr clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22357, __extension__ __PRETTY_FUNCTION__
))
;
22358 SourceLocation ELoc;
22359 SourceRange ERange;
22360 Expr *SimpleRefExpr = RefExpr;
22361 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22362 if (Res.second) {
22363 // It will be analyzed later.
22364 MVLI.ProcessedVarList.push_back(RefExpr);
22365 }
22366 ValueDecl *D = Res.first;
22367 if (!D)
22368 continue;
22369
22370 QualType Type = D->getType();
22371 // item should be a pointer or array or reference to pointer or array
22372 if (!Type.getNonReferenceType()->isPointerType() &&
22373 !Type.getNonReferenceType()->isArrayType()) {
22374 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
22375 << 0 << RefExpr->getSourceRange();
22376 continue;
22377 }
22378
22379 // Check if the declaration in the clause does not show up in any data
22380 // sharing attribute.
22381 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
22382 if (isOpenMPPrivate(DVar.CKind)) {
22383 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22384 << getOpenMPClauseName(DVar.CKind)
22385 << getOpenMPClauseName(OMPC_is_device_ptr)
22386 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
22387 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
22388 continue;
22389 }
22390
22391 const Expr *ConflictExpr;
22392 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
22393 D, /*CurrentRegionOnly=*/true,
22394 [&ConflictExpr](
22395 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
22396 OpenMPClauseKind) -> bool {
22397 ConflictExpr = R.front().getAssociatedExpression();
22398 return true;
22399 })) {
22400 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
22401 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
22402 << ConflictExpr->getSourceRange();
22403 continue;
22404 }
22405
22406 // Store the components in the stack so that they can be used to check
22407 // against other clauses later on.
22408 OMPClauseMappableExprCommon::MappableComponent MC(
22409 SimpleRefExpr, D, /*IsNonContiguous=*/false);
22410 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
22411 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
22412
22413 // Record the expression we've just processed.
22414 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
22415
22416 // Create a mappable component for the list item. List items in this clause
22417 // only need a component. We use a null declaration to signal fields in
22418 // 'this'.
22419 assert((isa<DeclRefExpr>(SimpleRefExpr) ||(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22421, __extension__ __PRETTY_FUNCTION__
))
22420 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22421, __extension__ __PRETTY_FUNCTION__
))
22421 "Unexpected device pointer expression!")(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22421, __extension__ __PRETTY_FUNCTION__
))
;
22422 MVLI.VarBaseDeclarations.push_back(
22423 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
22424 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22425 MVLI.VarComponents.back().push_back(MC);
22426 }
22427
22428 if (MVLI.ProcessedVarList.empty())
22429 return nullptr;
22430
22431 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22432 MVLI.VarBaseDeclarations,
22433 MVLI.VarComponents);
22434}
22435
22436OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
22437 const OMPVarListLocTy &Locs) {
22438 MappableVarListInfo MVLI(VarList);
22439 for (Expr *RefExpr : VarList) {
22440 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP has_device_addr clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP has_device_addr clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22440, __extension__ __PRETTY_FUNCTION__
))
;
22441 SourceLocation ELoc;
22442 SourceRange ERange;
22443 Expr *SimpleRefExpr = RefExpr;
22444 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22445 /*AllowArraySection=*/true);
22446 if (Res.second) {
22447 // It will be analyzed later.
22448 MVLI.ProcessedVarList.push_back(RefExpr);
22449 }
22450 ValueDecl *D = Res.first;
22451 if (!D)
22452 continue;
22453
22454 // Check if the declaration in the clause does not show up in any data
22455 // sharing attribute.
22456 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
22457 if (isOpenMPPrivate(DVar.CKind)) {
22458 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22459 << getOpenMPClauseName(DVar.CKind)
22460 << getOpenMPClauseName(OMPC_has_device_addr)
22461 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
22462 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
22463 continue;
22464 }
22465
22466 const Expr *ConflictExpr;
22467 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
22468 D, /*CurrentRegionOnly=*/true,
22469 [&ConflictExpr](
22470 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
22471 OpenMPClauseKind) -> bool {
22472 ConflictExpr = R.front().getAssociatedExpression();
22473 return true;
22474 })) {
22475 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
22476 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
22477 << ConflictExpr->getSourceRange();
22478 continue;
22479 }
22480
22481 // Store the components in the stack so that they can be used to check
22482 // against other clauses later on.
22483 OMPClauseMappableExprCommon::MappableComponent MC(
22484 SimpleRefExpr, D, /*IsNonContiguous=*/false);
22485 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
22486 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
22487
22488 // Record the expression we've just processed.
22489 auto *VD = dyn_cast<VarDecl>(D);
22490 if (!VD && !CurContext->isDependentContext()) {
22491 DeclRefExpr *Ref =
22492 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22493 assert(Ref && "has_device_addr capture failed")(static_cast <bool> (Ref && "has_device_addr capture failed"
) ? void (0) : __assert_fail ("Ref && \"has_device_addr capture failed\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22493, __extension__ __PRETTY_FUNCTION__
))
;
22494 MVLI.ProcessedVarList.push_back(Ref);
22495 } else
22496 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
22497
22498 // Create a mappable component for the list item. List items in this clause
22499 // only need a component. We use a null declaration to signal fields in
22500 // 'this'.
22501 assert((isa<DeclRefExpr>(SimpleRefExpr) ||(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22503, __extension__ __PRETTY_FUNCTION__
))
22502 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22503, __extension__ __PRETTY_FUNCTION__
))
22503 "Unexpected device pointer expression!")(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22503, __extension__ __PRETTY_FUNCTION__
))
;
22504 MVLI.VarBaseDeclarations.push_back(
22505 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
22506 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22507 MVLI.VarComponents.back().push_back(MC);
22508 }
22509
22510 if (MVLI.ProcessedVarList.empty())
22511 return nullptr;
22512
22513 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22514 MVLI.VarBaseDeclarations,
22515 MVLI.VarComponents);
22516}
22517
22518OMPClause *Sema::ActOnOpenMPAllocateClause(
22519 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
22520 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
22521 if (Allocator) {
22522 // OpenMP [2.11.4 allocate Clause, Description]
22523 // allocator is an expression of omp_allocator_handle_t type.
22524 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
22525 return nullptr;
22526
22527 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
22528 if (AllocatorRes.isInvalid())
22529 return nullptr;
22530 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
22531 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
22532 Sema::AA_Initializing,
22533 /*AllowExplicit=*/true);
22534 if (AllocatorRes.isInvalid())
22535 return nullptr;
22536 Allocator = AllocatorRes.get();
22537 } else {
22538 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
22539 // allocate clauses that appear on a target construct or on constructs in a
22540 // target region must specify an allocator expression unless a requires
22541 // directive with the dynamic_allocators clause is present in the same
22542 // compilation unit.
22543 if (LangOpts.OpenMPIsDevice &&
22544 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
22545 targetDiag(StartLoc, diag::err_expected_allocator_expression);
22546 }
22547 // Analyze and build list of variables.
22548 SmallVector<Expr *, 8> Vars;
22549 for (Expr *RefExpr : VarList) {
22550 assert(RefExpr && "NULL expr in OpenMP private clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP private clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22550, __extension__ __PRETTY_FUNCTION__
))
;
22551 SourceLocation ELoc;
22552 SourceRange ERange;
22553 Expr *SimpleRefExpr = RefExpr;
22554 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22555 if (Res.second) {
22556 // It will be analyzed later.
22557 Vars.push_back(RefExpr);
22558 }
22559 ValueDecl *D = Res.first;
22560 if (!D)
22561 continue;
22562
22563 auto *VD = dyn_cast<VarDecl>(D);
22564 DeclRefExpr *Ref = nullptr;
22565 if (!VD && !CurContext->isDependentContext())
22566 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
22567 Vars.push_back((VD || CurContext->isDependentContext())
22568 ? RefExpr->IgnoreParens()
22569 : Ref);
22570 }
22571
22572 if (Vars.empty())
22573 return nullptr;
22574
22575 if (Allocator)
22576 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
22577 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
22578 ColonLoc, EndLoc, Vars);
22579}
22580
22581OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
22582 SourceLocation StartLoc,
22583 SourceLocation LParenLoc,
22584 SourceLocation EndLoc) {
22585 SmallVector<Expr *, 8> Vars;
22586 for (Expr *RefExpr : VarList) {
22587 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22587, __extension__ __PRETTY_FUNCTION__
))
;
22588 SourceLocation ELoc;
22589 SourceRange ERange;
22590 Expr *SimpleRefExpr = RefExpr;
22591 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22592 if (Res.second)
22593 // It will be analyzed later.
22594 Vars.push_back(RefExpr);
22595 ValueDecl *D = Res.first;
22596 if (!D)
22597 continue;
22598
22599 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
22600 // A list-item cannot appear in more than one nontemporal clause.
22601 if (const Expr *PrevRef =
22602 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
22603 Diag(ELoc, diag::err_omp_used_in_clause_twice)
22604 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
22605 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
22606 << getOpenMPClauseName(OMPC_nontemporal);
22607 continue;
22608 }
22609
22610 Vars.push_back(RefExpr);
22611 }
22612
22613 if (Vars.empty())
22614 return nullptr;
22615
22616 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
22617 Vars);
22618}
22619
22620OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
22621 SourceLocation StartLoc,
22622 SourceLocation LParenLoc,
22623 SourceLocation EndLoc) {
22624 SmallVector<Expr *, 8> Vars;
22625 for (Expr *RefExpr : VarList) {
22626 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22626, __extension__ __PRETTY_FUNCTION__
))
;
22627 SourceLocation ELoc;
22628 SourceRange ERange;
22629 Expr *SimpleRefExpr = RefExpr;
22630 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22631 /*AllowArraySection=*/true);
22632 if (Res.second)
22633 // It will be analyzed later.
22634 Vars.push_back(RefExpr);
22635 ValueDecl *D = Res.first;
22636 if (!D)
22637 continue;
22638
22639 const DSAStackTy::DSAVarData DVar =
22640 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
22641 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
22642 // A list item that appears in the inclusive or exclusive clause must appear
22643 // in a reduction clause with the inscan modifier on the enclosing
22644 // worksharing-loop, worksharing-loop SIMD, or simd construct.
22645 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
22646 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
22647 << RefExpr->getSourceRange();
22648
22649 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
22650 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
22651 Vars.push_back(RefExpr);
22652 }
22653
22654 if (Vars.empty())
22655 return nullptr;
22656
22657 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
22658}
22659
22660OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
22661 SourceLocation StartLoc,
22662 SourceLocation LParenLoc,
22663 SourceLocation EndLoc) {
22664 SmallVector<Expr *, 8> Vars;
22665 for (Expr *RefExpr : VarList) {
22666 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22666, __extension__ __PRETTY_FUNCTION__
))
;
22667 SourceLocation ELoc;
22668 SourceRange ERange;
22669 Expr *SimpleRefExpr = RefExpr;
22670 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22671 /*AllowArraySection=*/true);
22672 if (Res.second)
22673 // It will be analyzed later.
22674 Vars.push_back(RefExpr);
22675 ValueDecl *D = Res.first;
22676 if (!D)
22677 continue;
22678
22679 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
22680 DSAStackTy::DSAVarData DVar;
22681 if (ParentDirective != OMPD_unknown)
22682 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
22683 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
22684 // A list item that appears in the inclusive or exclusive clause must appear
22685 // in a reduction clause with the inscan modifier on the enclosing
22686 // worksharing-loop, worksharing-loop SIMD, or simd construct.
22687 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
22688 DVar.Modifier != OMPC_REDUCTION_inscan) {
22689 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
22690 << RefExpr->getSourceRange();
22691 } else {
22692 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
22693 }
22694 Vars.push_back(RefExpr);
22695 }
22696
22697 if (Vars.empty())
22698 return nullptr;
22699
22700 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
22701}
22702
22703/// Tries to find omp_alloctrait_t type.
22704static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
22705 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
22706 if (!OMPAlloctraitT.isNull())
22707 return true;
22708 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
22709 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
22710 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22711 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
22712 return false;
22713 }
22714 Stack->setOMPAlloctraitT(PT.get());
22715 return true;
22716}
22717
22718OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
22719 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
22720 ArrayRef<UsesAllocatorsData> Data) {
22721 // OpenMP [2.12.5, target Construct]
22722 // allocator is an identifier of omp_allocator_handle_t type.
22723 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
22724 return nullptr;
22725 // OpenMP [2.12.5, target Construct]
22726 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
22727 if (llvm::any_of(
22728 Data,
22729 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
22730 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
22731 return nullptr;
22732 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
22733 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
22734 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
22735 StringRef Allocator =
22736 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
22737 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
22738 PredefinedAllocators.insert(LookupSingleName(
22739 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
22740 }
22741
22742 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
22743 for (const UsesAllocatorsData &D : Data) {
22744 Expr *AllocatorExpr = nullptr;
22745 // Check allocator expression.
22746 if (D.Allocator->isTypeDependent()) {
22747 AllocatorExpr = D.Allocator;
22748 } else {
22749 // Traits were specified - need to assign new allocator to the specified
22750 // allocator, so it must be an lvalue.
22751 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
22752 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
22753 bool IsPredefinedAllocator = false;
22754 if (DRE)
22755 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
22756 if (!DRE ||
22757 !(Context.hasSameUnqualifiedType(
22758 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
22759 Context.typesAreCompatible(AllocatorExpr->getType(),
22760 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
22761 /*CompareUnqualified=*/true)) ||
22762 (!IsPredefinedAllocator &&
22763 (AllocatorExpr->getType().isConstant(Context) ||
22764 !AllocatorExpr->isLValue()))) {
22765 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
22766 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
22767 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
22768 continue;
22769 }
22770 // OpenMP [2.12.5, target Construct]
22771 // Predefined allocators appearing in a uses_allocators clause cannot have
22772 // traits specified.
22773 if (IsPredefinedAllocator && D.AllocatorTraits) {
22774 Diag(D.AllocatorTraits->getExprLoc(),
22775 diag::err_omp_predefined_allocator_with_traits)
22776 << D.AllocatorTraits->getSourceRange();
22777 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
22778 << cast<NamedDecl>(DRE->getDecl())->getName()
22779 << D.Allocator->getSourceRange();
22780 continue;
22781 }
22782 // OpenMP [2.12.5, target Construct]
22783 // Non-predefined allocators appearing in a uses_allocators clause must
22784 // have traits specified.
22785 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
22786 Diag(D.Allocator->getExprLoc(),
22787 diag::err_omp_nonpredefined_allocator_without_traits);
22788 continue;
22789 }
22790 // No allocator traits - just convert it to rvalue.
22791 if (!D.AllocatorTraits)
22792 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
22793 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
22794 DRE->getDecl(),
22795 IsPredefinedAllocator
22796 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
22797 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
22798 }
22799 Expr *AllocatorTraitsExpr = nullptr;
22800 if (D.AllocatorTraits) {
22801 if (D.AllocatorTraits->isTypeDependent()) {
22802 AllocatorTraitsExpr = D.AllocatorTraits;
22803 } else {
22804 // OpenMP [2.12.5, target Construct]
22805 // Arrays that contain allocator traits that appear in a uses_allocators
22806 // clause must be constant arrays, have constant values and be defined
22807 // in the same scope as the construct in which the clause appears.
22808 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
22809 // Check that traits expr is a constant array.
22810 QualType TraitTy;
22811 if (const ArrayType *Ty =
22812 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
22813 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
22814 TraitTy = ConstArrayTy->getElementType();
22815 if (TraitTy.isNull() ||
22816 !(Context.hasSameUnqualifiedType(TraitTy,
22817 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
22818 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
22819 /*CompareUnqualified=*/true))) {
22820 Diag(D.AllocatorTraits->getExprLoc(),
22821 diag::err_omp_expected_array_alloctraits)
22822 << AllocatorTraitsExpr->getType();
22823 continue;
22824 }
22825 // Do not map by default allocator traits if it is a standalone
22826 // variable.
22827 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
22828 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
22829 DRE->getDecl(),
22830 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
22831 }
22832 }
22833 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
22834 NewD.Allocator = AllocatorExpr;
22835 NewD.AllocatorTraits = AllocatorTraitsExpr;
22836 NewD.LParenLoc = D.LParenLoc;
22837 NewD.RParenLoc = D.RParenLoc;
22838 }
22839 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
22840 NewData);
22841}
22842
22843OMPClause *Sema::ActOnOpenMPAffinityClause(
22844 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
22845 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
22846 SmallVector<Expr *, 8> Vars;
22847 for (Expr *RefExpr : Locators) {
22848 assert(RefExpr && "NULL expr in OpenMP shared clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP shared clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22848, __extension__ __PRETTY_FUNCTION__
))
;
22849 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
22850 // It will be analyzed later.
22851 Vars.push_back(RefExpr);
22852 continue;
22853 }
22854
22855 SourceLocation ELoc = RefExpr->getExprLoc();
22856 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
22857
22858 if (!SimpleExpr->isLValue()) {
22859 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
22860 << 1 << 0 << RefExpr->getSourceRange();
22861 continue;
22862 }
22863
22864 ExprResult Res;
22865 {
22866 Sema::TentativeAnalysisScope Trap(*this);
22867 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
22868 }
22869 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
22870 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
22871 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
22872 << 1 << 0 << RefExpr->getSourceRange();
22873 continue;
22874 }
22875 Vars.push_back(SimpleExpr);
22876 }
22877
22878 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
22879 EndLoc, Modifier, Vars);
22880}
22881
22882OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
22883 SourceLocation KindLoc,
22884 SourceLocation StartLoc,
22885 SourceLocation LParenLoc,
22886 SourceLocation EndLoc) {
22887 if (Kind == OMPC_BIND_unknown) {
22888 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22889 << getListOfPossibleValues(OMPC_bind, /*First=*/0,
22890 /*Last=*/unsigned(OMPC_BIND_unknown))
22891 << getOpenMPClauseName(OMPC_bind);
22892 return nullptr;
22893 }
22894
22895 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
22896 EndLoc);
22897}